checking to.address() is staking validator addr or not; avoid create cxReceipts when smart contract call failed

pull/2037/head
chao 5 years ago
parent 56dc8e04d8
commit dd7809cbfa
  1. 6
      core/evm.go
  2. 3
      core/state_processor.go
  3. 17
      core/vm/evm.go
  4. 1
      core/vm/runtime/env.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 {

@ -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

@ -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()

@ -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,

Loading…
Cancel
Save