Skip to content

Commit 79061ba

Browse files
authored
Upgrade to go-ethereum v1.15.5 (#615)
* Update usage of medusa-geth API to support v1.15.5 * fix json file
1 parent a9c00cb commit 79061ba

13 files changed

+343
-220
lines changed

chain/standard_cheat_code_contract.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ func getStandardCheatCodeContract(tracer *cheatCodeTracer) (*CheatCodeContract,
340340
func(tracer *cheatCodeTracer, inputs []any) ([]any, *cheatCodeRawReturnData) {
341341
account := inputs[0].(common.Address)
342342
nonce := inputs[1].(uint64)
343-
tracer.chain.State().SetNonce(account, nonce)
343+
tracer.chain.State().SetNonce(account, nonce, tracing.NonceChangeUnspecified)
344344
return nil, nil
345345
},
346346
)
@@ -359,9 +359,9 @@ func getStandardCheatCodeContract(tracer *cheatCodeTracer) (*CheatCodeContract,
359359
// We can cast OpContext to ScopeContext because that is the type passed to OnOpcode.
360360
scopeContext := prankCallFrame.vmScope.(*vm.ScopeContext)
361361
original := scopeContext.Caller()
362-
scopeContext.Contract.CallerAddress = inputs[0].(common.Address)
362+
scopeContext.Contract.SetCaller(inputs[0].(common.Address))
363363
prankCallFrame.onFrameExitRestoreHooks.Push(func() {
364-
scopeContext.Contract.CallerAddress = original
364+
scopeContext.Contract.SetCaller(original)
365365
})
366366
})
367367
return nil, nil
@@ -380,9 +380,9 @@ func getStandardCheatCodeContract(tracer *cheatCodeTracer) (*CheatCodeContract,
380380
// We can cast OpContext to ScopeContext because that is the type passed to OnOpcode.
381381
scopeContext := cheatCodeCallerFrame.vmScope.(*vm.ScopeContext)
382382
original := scopeContext.Caller()
383-
scopeContext.Contract.CallerAddress = inputs[0].(common.Address)
383+
scopeContext.Contract.SetCaller(inputs[0].(common.Address))
384384
cheatCodeCallerFrame.onFrameExitRestoreHooks.Push(func() {
385-
scopeContext.Contract.CallerAddress = original
385+
scopeContext.Contract.SetCaller(original)
386386
})
387387
return nil, nil
388388
},
@@ -473,14 +473,14 @@ func getStandardCheatCodeContract(tracer *cheatCodeTracer) (*CheatCodeContract,
473473
// Determine if this is a delegatecall.
474474
isPrankedDelegateCall := false
475475
if prankData.delegateCall {
476-
if scopeContext.Contract.CodeAddr != nil && *scopeContext.Contract.CodeAddr != prankCallFrame.vmScope.Address() {
476+
if scopeContext.Contract.Address() != prankCallFrame.vmScope.Address() {
477477
isPrankedDelegateCall = true
478478
}
479479
}
480480

481481
// Store the original value and spoof our prank address.
482482
originalMsgSender := scopeContext.Caller()
483-
scopeContext.Contract.CallerAddress = prankData.msgSender
483+
scopeContext.Contract.SetCaller(prankData.msgSender)
484484

485485
// Spoof the CodeAddress if we're pranking a delegatecall now.
486486
originalCodeAddress := scopeContext.Contract.Address()
@@ -504,7 +504,7 @@ func getStandardCheatCodeContract(tracer *cheatCodeTracer) (*CheatCodeContract,
504504
}
505505

506506
// Restore msg.sender and, if delegatecall flag enabled, code address
507-
scopeContext.Contract.CallerAddress = originalMsgSender
507+
scopeContext.Contract.SetCaller(originalMsgSender)
508508
if isPrankedDelegateCall {
509509
// TODO: Restore CodeAddress
510510
_ = originalCodeAddress

chain/state/factories.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ type VanillaStateDbFactory struct {
5050
}
5151

5252
func (v VanillaStateDbFactory) New(root common.Hash, db state.Database) (types.MedusaStateDB, error) {
53-
return state.New(root, db, nil)
53+
return state.New(root, db)
5454
}
5555

5656
func NewVanillaStateFactory() *VanillaStateDbFactory {

chain/state/factories_test.go

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,68 @@
11
package state
22

33
import (
4+
"github.com/crytic/medusa/chain/state/cache"
45
"testing"
56

67
"github.com/crytic/medusa-geth/common"
7-
"github.com/crytic/medusa-geth/core/rawdb"
88
gethstate "github.com/crytic/medusa-geth/core/state"
99
"github.com/crytic/medusa-geth/core/tracing"
1010
"github.com/crytic/medusa-geth/core/types"
11-
"github.com/crytic/medusa-geth/triedb"
12-
"github.com/crytic/medusa/chain/state/cache"
1311
types2 "github.com/crytic/medusa/chain/types"
1412
"github.com/holiman/uint256"
1513
"github.com/stretchr/testify/assert"
1614
)
1715

18-
/* TestForkedStateDB provides unit testing for medusa-geth's ForkedStateDb */
16+
// TestForkedStateDB provides unit testing for medusa-geth's ForkedStateDb
1917
func TestForkedStateDB(t *testing.T) {
2018
fixture := newPrePopulatedBackendFixture()
2119
factory := NewForkedStateFactory(fixture.Backend)
2220

23-
db := rawdb.NewMemoryDatabase()
24-
tdb := triedb.NewDatabase(db, nil)
25-
cachingDb := gethstate.NewDatabaseWithNodeDB(db, tdb)
21+
cachingDb := gethstate.NewDatabaseForTesting()
2622

2723
stateDb1, err := factory.New(types.EmptyRootHash, cachingDb)
2824
assert.NoError(t, err)
2925
genesisSnap := stateDb1.Snapshot()
3026

31-
/* ensure the statedb is hitting the backend */
27+
// ensure the statedb is hitting the backend
3228
assert.True(t, stateDb1.Exist(fixture.StateObjectContractAddress))
3329
assert.True(t, stateDb1.Exist(fixture.StateObjectEOAAddress))
3430
assert.False(t, stateDb1.Exist(fixture.StateObjectEmptyAddress))
3531

3632
fixture.verifyAgainstState(t, stateDb1)
3733

38-
/* write some new data and make sure it's readable */
34+
// write some new data and make sure it's readable
3935
newAccount := common.BytesToAddress([]byte{1, 2, 3, 4, 5, 6})
4036
newAccountData := cache.StateObject{
4137
Balance: uint256.NewInt(5),
4238
Nonce: 99,
4339
Code: []byte{1, 2, 3},
4440
}
4541

46-
stateDb1.SetNonce(newAccount, newAccountData.Nonce)
42+
stateDb1.SetNonce(newAccount, newAccountData.Nonce, tracing.NonceChangeUnspecified)
4743
assert.True(t, stateDb1.Exist(newAccount))
4844
stateDb1.SetCode(newAccount, newAccountData.Code)
4945
stateDb1.SetBalance(newAccount, newAccountData.Balance, tracing.BalanceChangeUnspecified)
5046
checkAccountAgainstFixture(t, stateDb1, newAccount, newAccountData)
5147

52-
/* roll back to snapshot, ensure fork data still queryable and newly added data was purged */
48+
// roll back to snapshot, ensure fork data still queryable and newly added data was purged
5349
stateDb1.Snapshot()
5450
stateDb1.RevertToSnapshot(genesisSnap)
5551
fixture.verifyAgainstState(t, stateDb1)
5652
assert.False(t, stateDb1.Exist(newAccount))
5753

58-
/* now we want to test to verify our fork-populated data is being persisted */
59-
root, err := stateDb1.Commit(1, true)
54+
// now we want to test to verify our fork-populated data is being persisted
55+
root, err := stateDb1.Commit(1, true, true)
6056
assert.NoError(t, err)
6157
stateDb2, err := factory.New(root, cachingDb)
6258
assert.NoError(t, err)
6359

6460
fixture.verifyAgainstState(t, stateDb2)
6561
}
6662

67-
/*
68-
TestForkedStateFactory verifies the various independence/shared properties of each forkedStateDB created by the
69-
factory. This is because the underlying RPC/caching layer is shared between all TestChain instances globally,
70-
but this sharing relationship should not cause state to leak from one forkedStateDb to another.
71-
*/
63+
// TestForkedStateFactory verifies the various independence/shared properties of each forkedStateDB created by the
64+
// factory. This is because the underlying RPC/caching layer is shared between all TestChain instances globally,
65+
// but this sharing relationship should not cause state to leak from one forkedStateDb to another.
7266
func TestForkedStateFactory(t *testing.T) {
7367
fixture := newPrePopulatedBackendFixture()
7468
factory := NewForkedStateFactory(fixture.Backend)
@@ -81,7 +75,7 @@ func TestForkedStateFactory(t *testing.T) {
8175
assert.NoError(t, err)
8276
stateDb2.Snapshot()
8377

84-
/* naive check to ensure they're both pulling from the same remote */
78+
// naive check to ensure they're both pulling from the same remote
8579
fixture.verifyAgainstState(t, stateDb1)
8680
fixture.verifyAgainstState(t, stateDb2)
8781

@@ -91,7 +85,7 @@ func TestForkedStateFactory(t *testing.T) {
9185
stateDb1.RevertToSnapshot(0)
9286
stateDb2.RevertToSnapshot(0)
9387

94-
/* now we'll mutate a cold account in one stateDB and ensure the mutation doesn't propagate */
88+
// now we'll mutate a cold account in one stateDB and ensure the mutation doesn't propagate
9589
valueAdded := uint256.NewInt(100)
9690
expectedSum := uint256.NewInt(0).Add(fixture.StateObjectEOA.Balance, valueAdded)
9791
stateDb1.AddBalance(fixture.StateObjectEOAAddress, valueAdded, tracing.BalanceChangeUnspecified)
@@ -108,10 +102,8 @@ func TestForkedStateFactory(t *testing.T) {
108102
bal = stateDb3.GetBalance(fixture.StateObjectEOAAddress)
109103
assert.Equal(t, bal, fixture.StateObjectEOA.Balance)
110104

111-
/*
112-
now we'll emulate one stateDB obtaining a new piece of data from RPC and ensuring the other stateDB loads
113-
the same data
114-
*/
105+
// now we'll emulate one stateDB obtaining a new piece of data from RPC and ensuring the other stateDB loads
106+
// the same data
115107
newAccount := common.BytesToAddress([]byte{1, 2, 3, 4, 5, 6})
116108
slotKey := common.BytesToHash([]byte{5, 5, 5, 5, 5, 5, 5})
117109
slotData := common.BytesToHash([]byte{6, 6, 6, 6, 6, 6, 6})
@@ -127,10 +119,8 @@ func TestForkedStateFactory(t *testing.T) {
127119
assert.EqualValues(t, slotData, data)
128120
}
129121

130-
/*
131-
TestEmptyBackendFactoryDifferential tests the differential properties between a stateDB using an empty forked backend
132-
versus directly using geth's statedb.
133-
*/
122+
// TestEmptyBackendFactoryDifferential tests the differential properties between a stateDB using an empty forked backend
123+
// versus directly using geth's statedb.
134124
func TestEmptyBackendFactoryDifferential(t *testing.T) {
135125
gethFactory := &gethStateFactory{}
136126
unbackedFactory := NewUnbackedStateFactory()
@@ -141,14 +131,14 @@ func TestEmptyBackendFactoryDifferential(t *testing.T) {
141131
unbackedStateDb, err := createEmptyStateDb(unbackedFactory)
142132
assert.NoError(t, err)
143133

144-
/* start with existence/empty of an existing object. should be identical. */
134+
// start with existence/empty of an existing object. should be identical.
145135
addr := common.BytesToAddress([]byte{1})
146-
gethStateDb.SetNonce(addr, 5)
147-
unbackedStateDb.SetNonce(addr, 5)
136+
gethStateDb.SetNonce(addr, 5, tracing.NonceChangeUnspecified)
137+
unbackedStateDb.SetNonce(addr, 5, tracing.NonceChangeUnspecified)
148138
assert.EqualValues(t, gethStateDb.Exist(addr), unbackedStateDb.Exist(addr))
149139
assert.EqualValues(t, gethStateDb.Empty(addr), unbackedStateDb.Empty(addr))
150140

151-
/* existence/empty of a non-existing object, should be identical. */
141+
// existence/empty of a non-existing object, should be identical.
152142
nonExistentStateObjAddr := common.BytesToAddress([]byte{5, 5, 5, 5, 5})
153143
assert.EqualValues(t, gethStateDb.Exist(nonExistentStateObjAddr), unbackedStateDb.Exist(nonExistentStateObjAddr))
154144
assert.EqualValues(t, gethStateDb.Empty(nonExistentStateObjAddr), unbackedStateDb.Empty(nonExistentStateObjAddr))
@@ -158,19 +148,17 @@ func TestEmptyBackendFactoryDifferential(t *testing.T) {
158148
gethStateDb.SetBalance(emptyStateObjectAddr, value, tracing.BalanceChangeUnspecified)
159149
unbackedStateDb.SetBalance(emptyStateObjectAddr, value, tracing.BalanceChangeUnspecified)
160150

161-
/* existence/empty of an empty object, should be identical. */
151+
// existence/empty of an empty object, should be identical.
162152
gethStateDb.SubBalance(emptyStateObjectAddr, value, tracing.BalanceChangeUnspecified)
163153
unbackedStateDb.SubBalance(emptyStateObjectAddr, value, tracing.BalanceChangeUnspecified)
164154
assert.EqualValues(t, gethStateDb.Exist(emptyStateObjectAddr), unbackedStateDb.Exist(emptyStateObjectAddr))
165155
assert.EqualValues(t, gethStateDb.Empty(emptyStateObjectAddr), unbackedStateDb.Empty(emptyStateObjectAddr))
166156
}
167157

168-
/*
169-
TestForkedBackendDifferential tests the differential properties between a stateDB using a forked backend
170-
versus directly using geth's statedb. Consider this test a canonical definition of how our forked stateDB acts
171-
differently from geth's.
172-
Good place for future fuzz testing if we run into issues.
173-
*/
158+
// TestForkedBackendDifferential tests the differential properties between a stateDB using a forked backend
159+
// versus directly using geth's statedb. Consider this test a canonical definition of how our forked stateDB acts
160+
// differently from geth's.
161+
// Good place for future fuzz testing if we run into issues.
174162
func TestForkedBackendDifferential(t *testing.T) {
175163
fixture := newPrePopulatedBackendFixture()
176164
factory := NewForkedStateFactory(fixture.Backend)
@@ -187,14 +175,14 @@ func TestForkedBackendDifferential(t *testing.T) {
187175
fixture.StateObjectContractAddress,
188176
fixture.StateObjectContract.Balance,
189177
tracing.BalanceChangeUnspecified)
190-
gethStateDb.SetNonce(fixture.StateObjectContractAddress, fixture.StateObjectContract.Nonce)
178+
gethStateDb.SetNonce(fixture.StateObjectContractAddress, fixture.StateObjectContract.Nonce, tracing.NonceChangeUnspecified)
191179
gethStateDb.SetCode(fixture.StateObjectContractAddress, fixture.StateObjectContract.Code)
192180
// eoa
193181
gethStateDb.SetBalance(
194182
fixture.StateObjectEOAAddress,
195183
fixture.StateObjectEOA.Balance,
196184
tracing.BalanceChangeUnspecified)
197-
gethStateDb.SetNonce(fixture.StateObjectEOAAddress, fixture.StateObjectEOA.Nonce)
185+
gethStateDb.SetNonce(fixture.StateObjectEOAAddress, fixture.StateObjectEOA.Nonce, tracing.NonceChangeUnspecified)
198186
// do not set the empty account. On a live geth node, the empty account will be pruned.
199187

200188
// check exist/empty equivalence for the contract account
@@ -232,9 +220,7 @@ func TestForkedBackendDifferential(t *testing.T) {
232220

233221
// createEmptyStateDb creates an empty stateDB using the provided factory. Intended for tests only.
234222
func createEmptyStateDb(factory MedusaStateFactory) (types2.MedusaStateDB, error) {
235-
db := rawdb.NewMemoryDatabase()
236-
tdb := triedb.NewDatabase(db, nil)
237-
cachingDb := gethstate.NewDatabaseWithNodeDB(db, tdb)
223+
cachingDb := gethstate.NewDatabaseForTesting()
238224
return factory.New(types.EmptyRootHash, cachingDb)
239225
}
240226

@@ -243,5 +229,5 @@ func createEmptyStateDb(factory MedusaStateFactory) (types2.MedusaStateDB, error
243229
type gethStateFactory struct{}
244230

245231
func (f *gethStateFactory) New(root common.Hash, db gethstate.Database) (types2.MedusaStateDB, error) {
246-
return gethstate.New(root, db, nil)
232+
return gethstate.New(root, db)
247233
}

chain/test_chain.go

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import (
3030
"github.com/crytic/medusa/utils"
3131
)
3232

33+
var _, MAX_UINT_64 = utils.GetIntegerConstraints(false, 64)
34+
3335
// TestChain represents a simulated Ethereum chain used for testing. It maintains blocks in-memory and strips away
3436
// typical consensus/chain objects to allow for more specialized testing closer to the EVM.
3537
type TestChain struct {
@@ -148,14 +150,17 @@ func newTestChainWithStateFactory(
148150
return nil, err
149151
}
150152

151-
// TODO: go-ethereum doesn't set cancun start time for THEIR test `ChainConfig` struct.
153+
// TODO: go-ethereum doesn't set prague start time for THEIR test `ChainConfig` struct.
152154
// Note: We have our own `TestChainConfig` definition that is different (second argument in this function).
153155
// We should allow the user to provide a go-ethereum `ChainConfig` to do custom fork selection, inside of our
154156
// `TestChainConfig` definition. Or we should wrap it in our own struct to simplify the options and not pollute
155157
// our overall medusa project config.
156-
cancunTime := uint64(0)
157-
chainConfig.ShanghaiTime = &cancunTime
158-
chainConfig.CancunTime = &cancunTime
158+
pragueTime := uint64(0)
159+
chainConfig.PragueTime = &pragueTime
160+
chainConfig.ShanghaiTime = &pragueTime
161+
chainConfig.CancunTime = &pragueTime
162+
// Set the default blob schedule
163+
chainConfig.BlobScheduleConfig = params.DefaultBlobSchedule
159164

160165
// Create our genesis definition with our default chain config.
161166
genesisDefinition := &core.Genesis{
@@ -215,7 +220,7 @@ func newTestChainWithStateFactory(
215220
// Convert our genesis block (go-ethereum type) to a test chain block.
216221
testChainGenesisBlock := types.NewBlock(genesisBlock.Header())
217222
// Create our state database over-top our database.
218-
stateDatabase := gethState.NewDatabaseWithConfig(db, dbConfig)
223+
stateDatabase := gethState.NewDatabase(trieDB, nil)
219224

220225
// Create a tracer forwarder to support the addition of multiple tracers for transaction and call execution.
221226
transactionTracerRouter := NewTestChainTracerRouter()
@@ -252,10 +257,8 @@ func newTestChainWithStateFactory(
252257
if err != nil {
253258
return nil, err
254259
}
255-
256-
// Set our state database logger e.g. to monitor OnCodeChange events.
257-
stateDB.SetLogger(transactionTracerRouter.NativeTracer().Tracer.Hooks)
258260
chain.state = stateDB
261+
259262
return chain, nil
260263
}
261264

@@ -511,8 +514,7 @@ func (t *TestChain) CallContract(msg *core.Message, state types.MedusaStateDB, a
511514
// Set infinite balance to the fake caller account
512515
state.SetBalance(msg.From, uint256.MustFromBig(math.MaxBig256), tracing.BalanceChangeUnspecified)
513516

514-
// Create our transaction and block contexts for the vm
515-
txContext := core.NewEVMTxContext(msg)
517+
// Create our block contexts for the vm
516518
blockContext := newTestChainBlockContext(t, t.Head().Header)
517519

518520
// Create a new call tracer router that incorporates any additional tracers provided just for this call, while
@@ -522,11 +524,12 @@ func (t *TestChain) CallContract(msg *core.Message, state types.MedusaStateDB, a
522524
extendedTracerRouter.AddTracers(additionalTracers...)
523525

524526
// Create our EVM instance.
525-
evm := vm.NewEVM(blockContext, txContext, state, t.chainConfig, vm.Config{
527+
evm := vm.NewEVM(blockContext, state, t.chainConfig, vm.Config{
526528
Tracer: extendedTracerRouter.NativeTracer().Tracer.Hooks,
527529
NoBaseFee: true,
528530
ConfigExtensions: t.vmConfigExtensions,
529531
})
532+
530533
// Set our block context and chain config in order for cheatcodes to override what EVM interpreter sees.
531534
t.pendingBlockContext = &evm.Context
532535
t.pendingBlockChainConfig = evm.ChainConfig()
@@ -539,7 +542,8 @@ func (t *TestChain) CallContract(msg *core.Message, state types.MedusaStateDB, a
539542
evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From)
540543
}
541544
// Fund the gas pool, so it can execute endlessly (no block gas limit).
542-
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
545+
546+
gasPool := new(core.GasPool).AddGas(MAX_UINT_64.Uint64())
543547

544548
// Perform our state transition to obtain the result.
545549
msgResult, err := core.ApplyMessage(evm, msg, gasPool)
@@ -705,7 +709,7 @@ func (t *TestChain) PendingBlockAddTx(message *core.Message, additionalTracers .
705709
t.state.SetTxContext(tx.Hash(), len(t.pendingBlock.Messages))
706710

707711
// Create our EVM instance.
708-
evm := vm.NewEVM(blockContext, core.NewEVMTxContext(message), t.state, t.chainConfig, vmConfig)
712+
evm := vm.NewEVM(blockContext, t.state, t.chainConfig, vmConfig)
709713

710714
// Set our block context and chain config in order for cheatcodes to override what EVM interpreter sees.
711715
t.pendingBlockContext = &evm.Context
@@ -765,7 +769,7 @@ func (t *TestChain) PendingBlockCommit() error {
765769
}
766770

767771
// Perform a state commit to obtain the root hash for our block.
768-
root, err := t.state.Commit(t.pendingBlock.Header.Number.Uint64(), true)
772+
root, err := t.state.Commit(t.pendingBlock.Header.Number.Uint64(), true, true)
769773
t.pendingBlock.Header.Root = root
770774

771775
if err != nil {

0 commit comments

Comments
 (0)