From dd7809cbfa81d7d445a4567cce7b89a6a0382ced Mon Sep 17 00:00:00 2001 From: chao Date: Sat, 14 Dec 2019 20:40:29 -0800 Subject: [PATCH] checking to.address() is staking validator addr or not; avoid create cxReceipts when smart contract call failed --- core/evm.go | 6 ++++++ core/state_processor.go | 3 ++- core/vm/evm.go | 17 ++++++++++++++++- core/vm/runtime/env.go | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/core/evm.go b/core/evm.go index 0e529ba20..de92b8c3c 100644 --- a/core/evm.go +++ b/core/evm.go @@ -57,6 +57,7 @@ func NewEVMContext(msg Message, header *block.Header, chain ChainContext, author return vm.Context{ CanTransfer: CanTransfer, Transfer: Transfer, + IsValidator: IsValidator, GetHash: GetHashFn(header, chain), Origin: msg.From(), Coinbase: beneficiary, @@ -100,6 +101,11 @@ func CanTransfer(db vm.StateDB, addr common.Address, amount *big.Int) bool { return db.GetBalance(addr).Cmp(amount) >= 0 } +// IsValidator determines whether it is a validator address or not +func IsValidator(db vm.StateDB, addr common.Address) bool { + return db.IsValidator(addr) +} + // Transfer subtracts amount from sender and adds amount to recipient using the given Db func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int, txType types.TransactionType) { if txType == types.SameShardTx || txType == types.SubtractionOnly { diff --git a/core/state_processor.go b/core/state_processor.go index ee0f8bc41..bf74b2c6f 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -193,7 +193,8 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) var cxReceipt *types.CXReceipt - if txType == types.SubtractionOnly { + // Do not create cxReceipt if EVM call failed + if txType == types.SubtractionOnly && !failed { cxReceipt = &types.CXReceipt{tx.Hash(), msg.From(), msg.To(), tx.ShardID(), tx.ToShardID(), msg.Value()} } else { cxReceipt = nil diff --git a/core/vm/evm.go b/core/vm/evm.go index 90b783e7f..01758f7e6 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -35,6 +35,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil) type ( // CanTransferFunc is the signature of a transfer guard function CanTransferFunc func(StateDB, common.Address, *big.Int) bool + // IsValidatorFunc is the signature of IsValidator function + IsValidatorFunc func(StateDB, common.Address) bool // TransferFunc is the signature of a transfer function TransferFunc func(StateDB, common.Address, common.Address, *big.Int, types.TransactionType) // GetHashFunc returns the nth block hash in the blockchain @@ -80,6 +82,10 @@ type Context struct { // GetHash returns the hash corresponding to n GetHash GetHashFunc + // IsValidator determines whether the address corresponds to a validator or a smart contract + // true: is a validator address; false: is smart contract address + IsValidator IsValidatorFunc + // Message information Origin common.Address // Provides information for ORIGIN GasPrice *big.Int // Provides information for GASPRICE @@ -224,10 +230,19 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas evm.StateDB.CreateAccount(addr) } evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value, txType) + + codeHash := evm.StateDB.GetCodeHash(addr) + code := evm.StateDB.GetCode(addr) + // If address is a validator address, then it's not a smart contract address + // we don't use its code and codeHash fields + if evm.Context.IsValidator(evm.StateDB, addr) { + codeHash = emptyCodeHash + code = nil + } // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. contract := NewContract(caller, to, value, gas) - contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr), evm.StateDB.GetCode(addr)) + contract.SetCallCode(&addr, codeHash, code) // Even if the account has no code, we need to continue because it might be a precompile start := time.Now() diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index b32396f7d..8b59d8edb 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -27,6 +27,7 @@ func NewEnv(cfg *Config) *vm.EVM { context := vm.Context{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, + IsValidator: core.IsValidator, GetHash: func(uint64) common.Hash { return common.Hash{} }, Origin: cfg.Origin,