core/state: add GetStateAndCommittedState

This commit is contained in:
Marius van der Wijden 2025-04-07 13:48:00 +02:00 committed by Gary Rong
parent 62a17fdb25
commit ee68abeaa1
6 changed files with 49 additions and 3 deletions

View file

@ -389,6 +389,15 @@ func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) commo
return common.Hash{} 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. // Database retrieves the low level database supporting the lower level trie ops.
func (s *StateDB) Database() Database { func (s *StateDB) Database() Database {
return s.db return s.db

View file

@ -89,6 +89,10 @@ func (s *hookedStateDB) GetCommittedState(addr common.Address, hash common.Hash)
return s.inner.GetCommittedState(addr, 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 { func (s *hookedStateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
return s.inner.GetState(addr, hash) return s.inner.GetState(addr, hash)
} }

View file

@ -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 // Gas sentry honoured, do the actual gas calculation based on the stored value
var ( var (
y, x = stack.Back(1), stack.Back(0) y, x = stack.Back(1), stack.Back(0)
current = evm.StateDB.GetState(contract.Address(), x.Bytes32()) current, original = evm.StateDB.GetStateAndCommittedState(contract.Address(), x.Bytes32())
) )
value := common.Hash(y.Bytes32()) value := common.Hash(y.Bytes32())
if current == value { // noop (1) if current == value { // noop (1)
return params.SloadGasEIP2200, nil return params.SloadGasEIP2200, nil
} }
original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32())
if original == current { if original == current {
if original == (common.Hash{}) { // create slot (2.1.1) if original == (common.Hash{}) { // create slot (2.1.1)
return params.SstoreSetGasEIP2200, nil return params.SstoreSetGasEIP2200, nil

View file

@ -51,6 +51,7 @@ type StateDB interface {
GetRefund() uint64 GetRefund() uint64
GetCommittedState(common.Address, common.Hash) common.Hash GetCommittedState(common.Address, common.Hash) common.Hash
GetStateAndCommittedState(common.Address, common.Hash) (common.Hash, common.Hash)
GetState(common.Address, common.Hash) common.Hash GetState(common.Address, common.Hash) common.Hash
SetState(common.Address, common.Hash, common.Hash) common.Hash SetState(common.Address, common.Hash, common.Hash) common.Hash
GetStorageRoot(addr common.Address) common.Hash GetStorageRoot(addr common.Address) common.Hash

View file

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

View file

@ -117,6 +117,10 @@ func (st *Stack) dup(n int) {
st.push(&st.data[st.len()-n]) st.push(&st.data[st.len()-n])
} }
func (st *Stack) dup1() {
st.push(&st.data[st.len()-1])
}
func (st *Stack) peek() *uint256.Int { func (st *Stack) peek() *uint256.Int {
return &st.data[st.len()-1] return &st.data[st.len()-1]
} }