From 5f9b2fe033e08289216f515c615ffbe243467106 Mon Sep 17 00:00:00 2001 From: laizy Date: Tue, 28 Mar 2023 20:03:32 +0800 Subject: [PATCH] discard stale snapshot (#1427) --- smartcontract/storage/statedb.go | 8 ++++++++ vm/evm/evm.go | 11 ++++++++++- vm/evm/interface.go | 1 + vm/evm/runtime/runtime_test.go | 9 +++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/smartcontract/storage/statedb.go b/smartcontract/storage/statedb.go index bc8942c21..6b83979ee 100644 --- a/smartcontract/storage/statedb.go +++ b/smartcontract/storage/statedb.go @@ -355,6 +355,14 @@ func (self *StateDB) Snapshot() int { return len(self.snapshots) - 1 } +func (self *StateDB) DiscardSnapshot(idx int) { + if idx+1 > len(self.snapshots) { + panic("can not to revert snapshot") + } + + self.snapshots = self.snapshots[:idx] +} + func (self *StateDB) RevertToSnapshot(idx int) { if idx+1 > len(self.snapshots) { panic("can not to revert snapshot") diff --git a/vm/evm/evm.go b/vm/evm/evm.go index 7f088b1fe..0c7694136 100644 --- a/vm/evm/evm.go +++ b/vm/evm/evm.go @@ -25,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/holiman/uint256" - "github.com/ontio/ontology/core/types" "github.com/ontio/ontology/smartcontract/service/native/utils" "github.com/ontio/ontology/vm/evm/errors" @@ -247,6 +246,8 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas if err != errors.ErrExecutionReverted { gas = 0 } + } else { + evm.StateDB.DiscardSnapshot(snapshot) } return ret, gas, err } @@ -292,6 +293,8 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, if err != errors.ErrExecutionReverted { gas = 0 } + } else { + evm.StateDB.DiscardSnapshot(snapshot) } return ret, gas, err } @@ -327,6 +330,8 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by if err != errors.ErrExecutionReverted { gas = 0 } + } else { + evm.StateDB.DiscardSnapshot(snapshot) } return ret, gas, err } @@ -378,6 +383,8 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte if err != errors.ErrExecutionReverted { gas = 0 } + } else { + evm.StateDB.DiscardSnapshot(snapshot) } return ret, gas, err } @@ -458,6 +465,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, if err != errors.ErrExecutionReverted { contract.UseGas(contract.Gas) } + } else { + evm.StateDB.DiscardSnapshot(snapshot) } // Assign err if contract code size exceeds the max while the err is still empty. if maxCodeSizeExceeded && err == nil { diff --git a/vm/evm/interface.go b/vm/evm/interface.go index 87665e425..dafc373d9 100644 --- a/vm/evm/interface.go +++ b/vm/evm/interface.go @@ -59,6 +59,7 @@ type StateDB interface { Empty(common.Address) bool RevertToSnapshot(int) + DiscardSnapshot(idx int) Snapshot() int AddLog(log *types.StorageLog) diff --git a/vm/evm/runtime/runtime_test.go b/vm/evm/runtime/runtime_test.go index e2cccafcc..044f6917a 100644 --- a/vm/evm/runtime/runtime_test.go +++ b/vm/evm/runtime/runtime_test.go @@ -1091,3 +1091,12 @@ func TestCreateOnDeletedAddress(t *testing.T) { a.Nil(err, "fail") a.True((big.NewInt(0).SetBytes(ret).Cmp(big.NewInt(0)) == 0), "should not get previous value 0x1234") } + +func TestVV(t *testing.T) { + //595b58323d5a58fa4656 + input := []byte{0x59, 0x5b, 0x58, 0x32, 0x3d, 0x5a, 0x58, 0xfa, 0x46, 0x56} + Execute(input, input, &Config{ + //GasLimit: 30000000, + GasLimit: 25000000, + }) +}