Merge pull request #2037 from chaosma/evm-fix

fix mint new tokens when transfer money to validator addr
pull/2039/head
Rongjian Lan 5 years ago committed by GitHub
commit 33905bc2ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  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{ return vm.Context{
CanTransfer: CanTransfer, CanTransfer: CanTransfer,
Transfer: Transfer, Transfer: Transfer,
IsValidator: IsValidator,
GetHash: GetHashFn(header, chain), GetHash: GetHashFn(header, chain),
Origin: msg.From(), Origin: msg.From(),
Coinbase: beneficiary, 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 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 // 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) { func Transfer(db vm.StateDB, sender, recipient common.Address, amount *big.Int, txType types.TransactionType) {
if txType == types.SameShardTx || txType == types.SubtractionOnly { 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}) receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
var cxReceipt *types.CXReceipt 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()} cxReceipt = &types.CXReceipt{tx.Hash(), msg.From(), msg.To(), tx.ShardID(), tx.ToShardID(), msg.Value()}
} else { } else {
cxReceipt = nil cxReceipt = nil

@ -35,6 +35,8 @@ var emptyCodeHash = crypto.Keccak256Hash(nil)
type ( type (
// CanTransferFunc is the signature of a transfer guard function // CanTransferFunc is the signature of a transfer guard function
CanTransferFunc func(StateDB, common.Address, *big.Int) bool 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 is the signature of a transfer function
TransferFunc func(StateDB, common.Address, common.Address, *big.Int, types.TransactionType) TransferFunc func(StateDB, common.Address, common.Address, *big.Int, types.TransactionType)
// GetHashFunc returns the nth block hash in the blockchain // GetHashFunc returns the nth block hash in the blockchain
@ -80,6 +82,10 @@ type Context struct {
// GetHash returns the hash corresponding to n // GetHash returns the hash corresponding to n
GetHash GetHashFunc 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 // Message information
Origin common.Address // Provides information for ORIGIN Origin common.Address // Provides information for ORIGIN
GasPrice *big.Int // Provides information for GASPRICE 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.StateDB.CreateAccount(addr)
} }
evm.Transfer(evm.StateDB, caller.Address(), to.Address(), value, txType) 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. // 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. // The contract is a scoped environment for this execution context only.
contract := NewContract(caller, to, value, gas) 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 // Even if the account has no code, we need to continue because it might be a precompile
start := time.Now() start := time.Now()

@ -27,6 +27,7 @@ func NewEnv(cfg *Config) *vm.EVM {
context := vm.Context{ context := vm.Context{
CanTransfer: core.CanTransfer, CanTransfer: core.CanTransfer,
Transfer: core.Transfer, Transfer: core.Transfer,
IsValidator: core.IsValidator,
GetHash: func(uint64) common.Hash { return common.Hash{} }, GetHash: func(uint64) common.Hash { return common.Hash{} },
Origin: cfg.Origin, Origin: cfg.Origin,

Loading…
Cancel
Save