diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..03f3dcf --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,27 @@ +linters: + # please, do not use `enable-all`: it's deprecated and will be removed soon. + # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint + disable-all: true + enable: + - bodyclose + - dogsled + - dupl + - errcheck + - goconst + - gocyclo + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - misspell + - nakedret + - rowserrcheck + - typecheck + - unconvert + - unparam + - unused + +run: + # ignore test file + tests: false \ No newline at end of file diff --git a/evm/contracts.go b/evm/contracts.go index ce68282..0aa0535 100644 --- a/evm/contracts.go +++ b/evm/contracts.go @@ -35,7 +35,6 @@ import ( "github.com/meshplus/bitxhub-model/constant" "github.com/meshplus/bitxhub-model/pb" //lint:ignore SA1019 Needed for precompile - "golang.org/x/crypto/ripemd160" ) // PrecompiledContract is the basic interface for native Go contracts. The implementation @@ -89,9 +88,9 @@ func (ic *interchain) Run(input []byte, caller common.Address, evm *EVM) ([]byte // PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum // contracts used in the Frontier and Homestead releases. var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + //common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, common.BytesToAddress([]byte{200}): &interchain{}, } @@ -99,9 +98,9 @@ var PrecompiledContractsHomestead = map[common.Address]PrecompiledContract{ // PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum // contracts used in the Byzantium release. var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + //common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, common.BytesToAddress([]byte{6}): &bn256AddByzantium{}, @@ -113,9 +112,9 @@ var PrecompiledContractsByzantium = map[common.Address]PrecompiledContract{ // PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum // contracts used in the Istanbul release. var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + //common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, @@ -128,9 +127,9 @@ var PrecompiledContractsIstanbul = map[common.Address]PrecompiledContract{ // PrecompiledContractsBerlin contains the default set of pre-compiled Ethereum // contracts used in the Berlin release. var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + //common.BytesToAddress([]byte{3}): &ripemd160hash{}, common.BytesToAddress([]byte{4}): &dataCopy{}, common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, @@ -260,20 +259,20 @@ func (c *sha256hash) Run(input []byte, caller common.Address, evm *EVM) ([]byte, } // RIPEMD160 implemented as a native contract. -type ripemd160hash struct{} +//type ripemd160hash struct{} // RequiredGas returns the gas required to execute the pre-compiled contract. // // This method does not require any overflow checking as the input size gas costs // required for anything significant is so high it's impossible to pay for. -func (c *ripemd160hash) RequiredGas(input []byte) uint64 { - return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas -} -func (c *ripemd160hash) Run(input []byte, caller common.Address, evm *EVM) ([]byte, error) { - ripemd := ripemd160.New() - ripemd.Write(input) - return common.LeftPadBytes(ripemd.Sum(nil), 32), nil -} +//func (c *ripemd160hash) RequiredGas(input []byte) uint64 { +// return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas +//} +//func (c *ripemd160hash) Run(input []byte, caller common.Address, evm *EVM) ([]byte, error) { +// ripemd := ripemd160.New() +// ripemd.Write(input) +// return common.LeftPadBytes(ripemd.Sum(nil), 32), nil +//} // data copy implemented as a native contract. type dataCopy struct{} @@ -771,6 +770,7 @@ func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 { return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000 } +//nolint:dupl func (c *bls12381G1MultiExp) Run(input []byte, caller common.Address, evm *EVM) ([]byte, error) { // Implements EIP-2537 G1MultiExp precompile. // G1 multiplication call expects `160*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). @@ -800,7 +800,10 @@ func (c *bls12381G1MultiExp) Run(input []byte, caller common.Address, evm *EVM) // Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1) r := g.New() - g.MultiExp(r, points, scalars) + _, err = g.MultiExp(r, points, scalars) + if err != nil { + return nil, err + } // Encode the G1 point to 128 bytes return g.EncodePoint(r), nil @@ -902,6 +905,7 @@ func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 { return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000 } +//nolint:dupl func (c *bls12381G2MultiExp) Run(input []byte, caller common.Address, evm *EVM) ([]byte, error) { // Implements EIP-2537 G2MultiExp precompile logic // > G2 multiplication call expects `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). @@ -931,7 +935,10 @@ func (c *bls12381G2MultiExp) Run(input []byte, caller common.Address, evm *EVM) // Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1) r := g.New() - g.MultiExp(r, points, scalars) + _, err = g.MultiExp(r, points, scalars) + if err != nil { + return nil, err + } // Encode the G2 point to 256 bytes. return g.EncodePoint(r), nil diff --git a/evm/instructions.go b/evm/instructions.go index b10c159..b41856e 100644 --- a/evm/instructions.go +++ b/evm/instructions.go @@ -241,7 +241,10 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt interpreter.hasher.Reset() } interpreter.hasher.Write(data) - interpreter.hasher.Read(interpreter.hasherBuf[:]) + _, err := interpreter.hasher.Read(interpreter.hasherBuf[:]) + if err != nil { + return nil, err + } evm := interpreter.evm if evm.vmConfig.EnablePreimageRecording { @@ -639,6 +642,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([] return nil, nil } +//nolint:dupl func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { stack := scope.Stack // Pop gas. The actual gas in interpreter.evm.callGasTemp. @@ -677,6 +681,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt return ret, nil } +//nolint:dupl func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { // Pop gas. The actual gas is in interpreter.evm.callGasTemp. stack := scope.Stack @@ -712,6 +717,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([ return ret, nil } +//nolint:dupl func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { stack := scope.Stack // Pop gas. The actual gas is in interpreter.evm.callGasTemp. @@ -740,6 +746,7 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext return ret, nil } +//nolint:dupl func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { // Pop gas. The actual gas is in interpreter.evm.callGasTemp. stack := scope.Stack diff --git a/evm/interpreter.go b/evm/interpreter.go index 3b67ad6..99cd9d6 100644 --- a/evm/interpreter.go +++ b/evm/interpreter.go @@ -137,6 +137,7 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { // It's important to note that any errors returned by the interpreter should be // considered a revert-and-consume-all-gas operation except for // ErrExecutionReverted which means revert-and-keep-gas-left. +// nolint func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) { // Increment the call depth which is restricted to 1024 @@ -180,7 +181,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( res []byte // result of the opcode execution function ) // Don't move this deferrred function, it's placed before the capturestate-deferred method, - // so that it get's executed _after_: the capturestate needs the stacks before + // so that it gets executed _after_: the capturestate needs the stacks before // they are returned to the pools defer func() { returnStack(stack) diff --git a/evm/logger_json.go b/evm/logger_json.go index 21b2a73..b18ec02 100644 --- a/evm/logger_json.go +++ b/evm/logger_json.go @@ -76,7 +76,10 @@ func (l *JSONLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint if !l.cfg.DisableReturnData { log.ReturnData = rData } - l.encoder.Encode(log) + err = l.encoder.Encode(log) + if err != nil { + return + } } // CaptureEnd is triggered at end of execution. @@ -88,7 +91,13 @@ func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, Err string `json:"error,omitempty"` } if err != nil { - l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()}) + err = l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, err.Error()}) + if err != nil { + return + } + } + err = l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""}) + if err != nil { + return } - l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), t, ""}) } diff --git a/evm/runtime/runtime_test.go b/evm/runtime/runtime_test.go index 2692755..16899c9 100644 --- a/evm/runtime/runtime_test.go +++ b/evm/runtime/runtime_test.go @@ -18,12 +18,6 @@ package runtime import ( "fmt" - "math/big" - "os" - "strings" - "testing" - "time" - "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" @@ -34,6 +28,10 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/params" + "math/big" + "os" + "strings" + "testing" ) func TestDefaults(t *testing.T) { @@ -321,24 +319,24 @@ func TestBlockhash(t *testing.T) { } } -type stepCounter struct { - inner *vm.JSONLogger - steps int -} +//type stepCounter struct { +// inner *vm.JSONLogger +// steps int +//} -func (s *stepCounter) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { -} +//func (s *stepCounter) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { +//} -func (s *stepCounter) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} +//func (s *stepCounter) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { +//} -func (s *stepCounter) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {} +//func (s *stepCounter) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {} -func (s *stepCounter) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - s.steps++ - // Enable this for more output - //s.inner.CaptureState(env, pc, op, gas, cost, memory, stack, rStack, contract, depth, err) -} +//func (s *stepCounter) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { +// s.steps++ +// Enable this for more output +//s.inner.CaptureState(env, pc, op, gas, cost, memory, stack, rStack, contract, depth, err) +//} // benchmarkNonModifyingCode benchmarks code, but if the code modifies the // state, this should not be used, since it does not reset the state between runs. diff --git a/evm/stack.go b/evm/stack.go index c71d265..c46ba3b 100644 --- a/evm/stack.go +++ b/evm/stack.go @@ -54,10 +54,11 @@ func (st *Stack) push(d *uint256.Int) { // NOTE push limit (1024) is checked in baseCheck st.data = append(st.data, *d) } -func (st *Stack) pushN(ds ...uint256.Int) { - // FIXME: Is there a way to pass args by pointers. - st.data = append(st.data, ds...) -} + +//func (st *Stack) pushN(ds ...uint256.Int) { +// // FIXME: Is there a way to pass args by pointers. +// st.data = append(st.data, ds...) +//} func (st *Stack) pop() (ret uint256.Int) { ret = st.data[len(st.data)-1] diff --git a/ledger/state_object.go b/ledger/state_object.go index 7e57772..696de35 100644 --- a/ledger/state_object.go +++ b/ledger/state_object.go @@ -86,7 +86,7 @@ type StateObject struct { dirtyStorage Storage // Storage entries that have been modified in the current transaction execution // Cache flags. - // When an object is marked suicided it will be delete from the trie + // When an object is marked suicided it will be deleted from the trie // during the "update" phase of the state transition. dirtyCode bool // true if the code was updated suicided bool @@ -370,7 +370,7 @@ func (s *StateObject) getTrie(db state.Database) state.Trie { // finalise moves all dirty storage slots into the pending area to be hashed or // committed later. It is invoked at the end of every transaction. -func (s *StateObject) finalise(prefetch bool) { +func (s *StateObject) finalise(bool) { slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage)) for key, value := range s.dirtyStorage { s.pendingStorage[key] = value @@ -387,7 +387,7 @@ func (s *StateObject) finalise(prefetch bool) { // It will return nil if the trie has not been loaded and no changes have been made func (s *StateObject) updateTrie(db state.Database) state.Trie { // Make sure all dirty slots are finalized into the pending storage area - s.finalise(false) // Don't prefetch any more, pull directly if need be + //s.finalise(false) // Don't prefetch anymore, pull directly if need be if len(s.pendingStorage) == 0 { return s.trie } diff --git a/ledger/statedb.go b/ledger/statedb.go index 511a2fd..f76cd0f 100644 --- a/ledger/statedb.go +++ b/ledger/statedb.go @@ -43,16 +43,16 @@ var ( emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") ) -type proofList [][]byte - -func (n *proofList) Put(key []byte, value []byte) error { - *n = append(*n, value) - return nil -} - -func (n *proofList) Delete(key []byte) error { - panic("not supported") -} +//type proofList [][]byte +// +//func (n *proofList) Put(key []byte, value []byte) error { +// *n = append(*n, value) +// return nil +//} +// +//func (n *proofList) Delete(key []byte) error { +// panic("not supported") +//} var _ StateLedger = (*ComplexStateLedger)(nil) diff --git a/types/eth_transaction.go b/types/eth_transaction.go index 03a1e4c..a7ccb95 100644 --- a/types/eth_transaction.go +++ b/types/eth_transaction.go @@ -250,7 +250,11 @@ func (e *EthTransaction) Size() int { return size.(int) } c := writeCounter(0) - rlp.Encode(&c, &e.Inner) + + err := rlp.Encode(&c, &e.Inner) + if err != nil { + fmt.Println(fmt.Errorf("encode eth tx size err: %s", err)) + } e.size.Store(int(c)) return int(c) } diff --git a/types/tx.go b/types/tx.go index 3b192e2..251117b 100644 --- a/types/tx.go +++ b/types/tx.go @@ -127,9 +127,10 @@ func (tx *AccessListTx) copy() TxData { // accessors for innerTx. -func (tx *AccessListTx) TxType() byte { return AccessListTxType } -func (tx *AccessListTx) GetChainID() *big.Int { return tx.ChainID } -func (tx *AccessListTx) protected() bool { return true } +func (tx *AccessListTx) TxType() byte { return AccessListTxType } +func (tx *AccessListTx) GetChainID() *big.Int { return tx.ChainID } + +//func (tx *AccessListTx) protected() bool { return true } func (tx *AccessListTx) GetAccessList() types.AccessList { return tx.AccessList } func (tx *AccessListTx) GetData() []byte { return tx.Data } func (tx *AccessListTx) GetGas() uint64 { return tx.Gas } @@ -245,9 +246,10 @@ func (tx *DynamicFeeTx) copy() TxData { } // accessors for innerTx. -func (tx *DynamicFeeTx) TxType() byte { return DynamicFeeTxType } -func (tx *DynamicFeeTx) GetChainID() *big.Int { return tx.ChainID } -func (tx *DynamicFeeTx) protected() bool { return true } +func (tx *DynamicFeeTx) TxType() byte { return DynamicFeeTxType } +func (tx *DynamicFeeTx) GetChainID() *big.Int { return tx.ChainID } + +//func (tx *DynamicFeeTx) protected() bool { return true } func (tx *DynamicFeeTx) GetAccessList() types.AccessList { return tx.AccessList } func (tx *DynamicFeeTx) GetData() []byte { return tx.Data } func (tx *DynamicFeeTx) GetGas() uint64 { return tx.Gas } @@ -311,8 +313,14 @@ func RlpHash(x interface{}) *common.Hash { sha := hasherPool.Get().(crypto.KeccakState) defer hasherPool.Put(sha) sha.Reset() - rlp.Encode(sha, x) - sha.Read(h[:]) + err := rlp.Encode(sha, x) + if err != nil { + return nil + } + _, err = sha.Read(h[:]) + if err != nil { + return nil + } return &h } @@ -324,8 +332,14 @@ func PrefixedRlpHash(prefix byte, x interface{}) *common.Hash { defer hasherPool.Put(sha) sha.Reset() sha.Write([]byte{prefix}) - rlp.Encode(sha, x) - sha.Read(h[:]) + err := rlp.Encode(sha, x) + if err != nil { + return nil + } + _, err = sha.Read(h[:]) + if err != nil { + return nil + } return &h }