From ee68abeaa155def1c1c74196e75b159ee5d96b06 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Mon, 7 Apr 2025 13:48:00 +0200 Subject: [PATCH] core/state: add GetStateAndCommittedState --- core/state/statedb.go | 9 +++++++++ core/state/statedb_hooked.go | 4 ++++ core/vm/gas_table.go | 5 ++--- core/vm/interface.go | 1 + core/vm/interpreter_test.go | 29 +++++++++++++++++++++++++++++ core/vm/stack.go | 4 ++++ 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index 0d76e8c61c..e805885079 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -389,6 +389,15 @@ func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) commo return common.Hash{} } +// GetStateAndCommittedState returns the current value and the original value. +func (s *StateDB) GetStateAndCommittedState(addr common.Address, hash common.Hash) (common.Hash, common.Hash) { + stateObject := s.getStateObject(addr) + if stateObject != nil { + return stateObject.getState(hash) + } + return common.Hash{}, common.Hash{} +} + // Database retrieves the low level database supporting the lower level trie ops. func (s *StateDB) Database() Database { return s.db diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index a2fdfe9a21..c4596f9215 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -89,6 +89,10 @@ func (s *hookedStateDB) GetCommittedState(addr common.Address, hash common.Hash) return s.inner.GetCommittedState(addr, hash) } +func (s *hookedStateDB) GetStateAndCommittedState(addr common.Address, hash common.Hash) (common.Hash, common.Hash) { + return s.inner.GetStateAndCommittedState(addr, hash) +} + func (s *hookedStateDB) GetState(addr common.Address, hash common.Hash) common.Hash { return s.inner.GetState(addr, hash) } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 58f039df9f..89208bbc55 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -188,15 +188,14 @@ func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m } // Gas sentry honoured, do the actual gas calculation based on the stored value var ( - y, x = stack.Back(1), stack.Back(0) - current = evm.StateDB.GetState(contract.Address(), x.Bytes32()) + y, x = stack.Back(1), stack.Back(0) + current, original = evm.StateDB.GetStateAndCommittedState(contract.Address(), x.Bytes32()) ) value := common.Hash(y.Bytes32()) if current == value { // noop (1) return params.SloadGasEIP2200, nil } - original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32()) if original == current { if original == (common.Hash{}) { // create slot (2.1.1) return params.SstoreSetGasEIP2200, nil diff --git a/core/vm/interface.go b/core/vm/interface.go index 86e8c56ab0..2890865469 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -51,6 +51,7 @@ type StateDB interface { GetRefund() uint64 GetCommittedState(common.Address, common.Hash) common.Hash + GetStateAndCommittedState(common.Address, common.Hash) (common.Hash, common.Hash) GetState(common.Address, common.Hash) common.Hash SetState(common.Address, common.Hash, common.Hash) common.Hash GetStorageRoot(addr common.Address) common.Hash diff --git a/core/vm/interpreter_test.go b/core/vm/interpreter_test.go index 0b93dd59e7..001b102c81 100644 --- a/core/vm/interpreter_test.go +++ b/core/vm/interpreter_test.go @@ -74,3 +74,32 @@ func TestLoopInterrupt(t *testing.T) { } } } + +func BenchmarkInterpreter(b *testing.B) { + var ( + evm = NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) + startGas uint64 = 30_000_000 + value = uint256.NewInt(0) + contract = NewContract(common.Address{}, common.Address{}, value, startGas, nil) + ) + contract.Code = common.Hex2Bytes(loopInterruptTests[0]) + for i := 0; i < b.N; i++ { + evm.interpreter.Run(contract, []byte{}, false) + } +} + +// BenchmarkInterpreter-14 14613990 79.01 ns/op 32 B/op 2 allocs/op + +func BenchmarkDup(b *testing.B) { + stack := newstack() + stack.push(uint256.NewInt(1234)) + stack.push(uint256.NewInt(4321)) + for range b.N { + for range 1_000_000 { + //stack.dup(1) + stack.dup1() + } + } +} + +// BenchmarkDup-14 38 31579698 ns/op 188685761 B/op 2 allocs/op diff --git a/core/vm/stack.go b/core/vm/stack.go index 879dc9aa6d..685dd25dc7 100644 --- a/core/vm/stack.go +++ b/core/vm/stack.go @@ -117,6 +117,10 @@ func (st *Stack) dup(n int) { st.push(&st.data[st.len()-n]) } +func (st *Stack) dup1() { + st.push(&st.data[st.len()-1]) +} + func (st *Stack) peek() *uint256.Int { return &st.data[st.len()-1] }