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{}
}
// 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

View file

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

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

View file

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

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])
}
func (st *Stack) dup1() {
st.push(&st.data[st.len()-1])
}
func (st *Stack) peek() *uint256.Int {
return &st.data[st.len()-1]
}