From c9ec6477bc33b4fdf3106af10980740c2bce2960 Mon Sep 17 00:00:00 2001 From: Rongjian Lan Date: Mon, 30 Aug 2021 10:17:03 -0700 Subject: [PATCH] Add fork condition for datacopy bug in evm (#3858) --- core/vm/contract.go | 5 +++-- core/vm/evm.go | 4 ++++ core/vm/instructions.go | 16 ++++++++++++---- internal/params/config.go | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/core/vm/contract.go b/core/vm/contract.go index 20baa6e75..aa18231e0 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -57,8 +57,9 @@ type Contract struct { CodeAddr *common.Address Input []byte - Gas uint64 - value *big.Int + Gas uint64 + value *big.Int + WithDataCopyFix bool // with fix for https://github.com/ethereum/go-ethereum/pull/23446 } // NewContract returns a new contract environment for the execution of EVM. diff --git a/core/vm/evm.go b/core/vm/evm.go index 8a386db6b..61a3269a3 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -94,6 +94,10 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err }(evm.interpreter) evm.interpreter = interpreter } + + if evm.ChainConfig().IsDataCopyFixEpoch(evm.EpochNumber) { + contract.WithDataCopyFix = true + } return interpreter.Run(contract, input, readOnly) } diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 5e814fb9c..44f1c2b7e 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -767,7 +767,9 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == ErrExecutionReverted { - ret = common.CopyBytes(ret) + if contract.WithDataCopyFix { + ret = common.CopyBytes(ret) + } memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas @@ -797,7 +799,9 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, contract *Contract, mem stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == ErrExecutionReverted { - ret = common.CopyBytes(ret) + if contract.WithDataCopyFix { + ret = common.CopyBytes(ret) + } memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas @@ -823,7 +827,9 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == ErrExecutionReverted { - ret = common.CopyBytes(ret) + if contract.WithDataCopyFix { + ret = common.CopyBytes(ret) + } memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas @@ -849,7 +855,9 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, m stack.push(interpreter.intPool.get().SetUint64(1)) } if err == nil || err == ErrExecutionReverted { - ret = common.CopyBytes(ret) + if contract.WithDataCopyFix { + ret = common.CopyBytes(ret) + } memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) } contract.Gas += returnGas diff --git a/internal/params/config.go b/internal/params/config.go index e307ee56f..0ec90c5ac 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -59,6 +59,7 @@ var ( EPoSBound35Epoch: big.NewInt(631), // Around Wed July 7th 2021 EIP155Epoch: big.NewInt(28), S3Epoch: big.NewInt(28), + DataCopyFixEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time IstanbulEpoch: big.NewInt(314), ReceiptLogEpoch: big.NewInt(101), } @@ -88,6 +89,7 @@ var ( EPoSBound35Epoch: big.NewInt(73880), EIP155Epoch: big.NewInt(0), S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(74412), IstanbulEpoch: big.NewInt(43800), ReceiptLogEpoch: big.NewInt(0), } @@ -118,6 +120,7 @@ var ( EPoSBound35Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0), S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), IstanbulEpoch: big.NewInt(0), ReceiptLogEpoch: big.NewInt(0), } @@ -148,6 +151,7 @@ var ( EPoSBound35Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0), S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), IstanbulEpoch: big.NewInt(0), ReceiptLogEpoch: big.NewInt(0), } @@ -178,6 +182,7 @@ var ( EPoSBound35Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0), S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), IstanbulEpoch: big.NewInt(0), ReceiptLogEpoch: big.NewInt(0), } @@ -207,6 +212,7 @@ var ( EPoSBound35Epoch: big.NewInt(0), EIP155Epoch: big.NewInt(0), S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), IstanbulEpoch: big.NewInt(0), ReceiptLogEpoch: big.NewInt(0), } @@ -238,6 +244,7 @@ var ( big.NewInt(0), // EPoSBound35Epoch big.NewInt(0), // EIP155Epoch big.NewInt(0), // S3Epoch + big.NewInt(0), // DataCopyFixEpoch big.NewInt(0), // IstanbulEpoch big.NewInt(0), // ReceiptLogEpoch } @@ -269,6 +276,7 @@ var ( big.NewInt(0), // EPoSBound35Epoch big.NewInt(0), // EIP155Epoch big.NewInt(0), // S3Epoch + big.NewInt(0), // DataCopyFixEpoch big.NewInt(0), // IstanbulEpoch big.NewInt(0), // ReceiptLogEpoch } @@ -371,6 +379,9 @@ type ChainConfig struct { // S3 epoch is the first epoch containing S3 mainnet and all ethereum update up to Constantinople S3Epoch *big.Int `json:"s3-epoch,omitempty"` + // DataCopyFix epoch is the first epoch containing fix for evm datacopy bug. + DataCopyFixEpoch *big.Int `json:"data-copy-fix-epoch,omitempty"` + // Istanbul epoch IstanbulEpoch *big.Int `json:"istanbul-epoch,omitempty"` @@ -501,6 +512,11 @@ func (c *ChainConfig) IsS3(epoch *big.Int) bool { return isForked(c.S3Epoch, epoch) } +// IsDataCopyFixEpoch returns whether epoch has the fix for DataCopy evm bug. +func (c *ChainConfig) IsDataCopyFixEpoch(epoch *big.Int) bool { + return isForked(c.DataCopyFixEpoch, epoch) +} + // IsIstanbul returns whether epoch is either equal to the Istanbul fork epoch or greater. func (c *ChainConfig) IsIstanbul(epoch *big.Int) bool { return isForked(c.IstanbulEpoch, epoch)