Skip to content

Commit a39d138

Browse files
authored
simulators/ethereum/engine: Fix several tests (#886)
* simulators/ethereum/engine: fix versioning tests * simulators/ethereum/engine: fix transaction replacement * simulators/ethereum/engine: CLMock: Per-client payload id map * simulators/ethereum/engine: Unique Payload ID tests in Cancun
1 parent a2f657c commit a39d138

File tree

8 files changed

+66
-88
lines changed

8 files changed

+66
-88
lines changed

simulators/ethereum/engine/clmock/clmock.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ type CLMocker struct {
9191
HeaderHistory map[uint64]*types.Header
9292

9393
// Payload ID History
94-
PayloadIDHistory map[api.PayloadID]interface{}
94+
payloadIDHistory map[string]map[api.PayloadID]interface{}
9595

9696
// PoS Chain History Information
9797
PrevRandaoHistory map[uint64]common.Hash
@@ -146,7 +146,7 @@ func NewCLMocker(t *hivesim.T, genesis *core.Genesis, forkConfig *config.ForkCon
146146
PayloadProductionClientDelay: DefaultPayloadProductionClientDelay,
147147
BlockTimestampIncrement: DefaultBlockTimestampIncrement,
148148

149-
PayloadIDHistory: make(map[api.PayloadID]interface{}),
149+
payloadIDHistory: make(map[string]map[api.PayloadID]interface{}),
150150
LatestHeader: nil,
151151
FirstPoSBlockNumber: nil,
152152
LatestHeadNumber: nil,
@@ -442,14 +442,21 @@ func (cl *CLMocker) GeneratePayloadAttributes() {
442442
cl.PrevRandaoHistory[cl.LatestHeader.Number.Uint64()+1] = nextPrevRandao
443443
}
444444

445-
func (cl *CLMocker) AddPayloadID(newPayloadID *api.PayloadID) error {
445+
func (cl *CLMocker) AddPayloadID(ec client.EngineClient, newPayloadID *api.PayloadID) error {
446446
if newPayloadID == nil {
447447
return errors.New("nil payload ID")
448448
}
449-
if _, ok := cl.PayloadIDHistory[*newPayloadID]; ok {
449+
// Get map for given client
450+
if _, ok := cl.payloadIDHistory[ec.ID()]; !ok {
451+
cl.payloadIDHistory[ec.ID()] = make(map[api.PayloadID]interface{})
452+
}
453+
// Check if payload ID has been used before
454+
if _, ok := cl.payloadIDHistory[ec.ID()][*newPayloadID]; ok {
450455
return fmt.Errorf("reused payload ID: %v", *newPayloadID)
451456
}
452-
cl.PayloadIDHistory[*newPayloadID] = nil
457+
// Add payload ID to history
458+
cl.payloadIDHistory[ec.ID()][*newPayloadID] = nil
459+
fmt.Printf("CLMocker: Added payload ID %v for client %v\n", *newPayloadID, ec.ID())
453460
return nil
454461
}
455462

@@ -467,7 +474,7 @@ func (cl *CLMocker) RequestNextPayload() {
467474
if resp.PayloadStatus.LatestValidHash == nil || *resp.PayloadStatus.LatestValidHash != cl.LatestForkchoice.HeadBlockHash {
468475
cl.Fatalf("CLMocker: Unexpected forkchoiceUpdated LatestValidHash Response from Payload builder: %v != %v", resp.PayloadStatus.LatestValidHash, cl.LatestForkchoice.HeadBlockHash)
469476
}
470-
if err = cl.AddPayloadID(resp.PayloadID); err != nil {
477+
if err = cl.AddPayloadID(cl.NextBlockProducer, resp.PayloadID); err != nil {
471478
cl.Fatalf("CLMocker: Payload ID failure: %v", err)
472479
}
473480
cl.NextPayloadID = resp.PayloadID

simulators/ethereum/engine/helper/customizer.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,14 @@ type TimestampDeltaPayloadAttributesCustomizer struct {
137137
var _ PayloadAttributesCustomizer = (*TimestampDeltaPayloadAttributesCustomizer)(nil)
138138

139139
func (customData *TimestampDeltaPayloadAttributesCustomizer) GetPayloadAttributes(basePayloadAttributes *typ.PayloadAttributes) (*typ.PayloadAttributes, error) {
140-
customPayloadAttributes, err := customData.PayloadAttributesCustomizer.GetPayloadAttributes(basePayloadAttributes)
141-
if err != nil {
142-
return nil, err
140+
if customData.PayloadAttributesCustomizer != nil {
141+
var err error
142+
if basePayloadAttributes, err = customData.PayloadAttributesCustomizer.GetPayloadAttributes(basePayloadAttributes); err != nil {
143+
return nil, err
144+
}
143145
}
144-
customPayloadAttributes.Timestamp = uint64(int64(customPayloadAttributes.Timestamp) + customData.TimestampDelta)
145-
return customPayloadAttributes, nil
146+
basePayloadAttributes.Timestamp = uint64(int64(basePayloadAttributes.Timestamp) + customData.TimestampDelta)
147+
return basePayloadAttributes, nil
146148
}
147149

148150
// Customizer that makes no modifications to the forkchoice directive call.

simulators/ethereum/engine/helper/tx.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,11 @@ func (txSender *TransactionSender) GetLastNonce(ctx context.Context, node client
512512
if txSender.nonceMap != nil {
513513
txSender.nonceMapLock.Lock()
514514
defer txSender.nonceMapLock.Unlock()
515-
return txSender.nonceMap[sender.GetAddress()], nil
515+
nextNonce := txSender.nonceMap[sender.GetAddress()]
516+
if nextNonce > 0 {
517+
return nextNonce - 1, nil
518+
}
519+
return 0, fmt.Errorf("no previous nonce found in map for %s", sender.GetAddress().Hex())
516520
} else {
517521
return node.GetLastAccountNonce(ctx, sender.GetAddress(), header)
518522
}

simulators/ethereum/engine/suites/cancun/steps.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ func (step NewPayloads) Execute(t *CancunTestContext) error {
439439
r.ExpectPayloadStatus(expectedStatus)
440440
}
441441
if r.Response.PayloadID != nil {
442-
t.CLMock.AddPayloadID(r.Response.PayloadID)
442+
t.CLMock.AddPayloadID(t.Engine, r.Response.PayloadID)
443443
}
444444
}
445445
},

simulators/ethereum/engine/suites/cancun/tests.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,23 @@ func init() {
18271827
Tests = append(Tests, t)
18281828
}
18291829

1830+
// Unique Payload ID Tests
1831+
for _, t := range []suite_engine.PayloadAttributesFieldChange{
1832+
suite_engine.PayloadAttributesParentBeaconRoot,
1833+
// TODO: Remove when withdrawals suite is refactored
1834+
suite_engine.PayloadAttributesAddWithdrawal,
1835+
suite_engine.PayloadAttributesModifyWithdrawalAmount,
1836+
suite_engine.PayloadAttributesModifyWithdrawalIndex,
1837+
suite_engine.PayloadAttributesModifyWithdrawalValidator,
1838+
suite_engine.PayloadAttributesModifyWithdrawalAddress,
1839+
suite_engine.PayloadAttributesRemoveWithdrawal,
1840+
} {
1841+
Tests = append(Tests, suite_engine.UniquePayloadIDTest{
1842+
BaseSpec: baseSpec,
1843+
FieldModification: t,
1844+
})
1845+
}
1846+
18301847
// Invalid Payload Tests
18311848
for _, invalidField := range []helper.InvalidPayloadBlockField{
18321849
helper.InvalidParentBeaconBlockRoot,

simulators/ethereum/engine/suites/engine/payload_id.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@ func (tc UniquePayloadIDTest) Execute(t *test.Env) {
8080
}
8181
payloadAttributes.Withdrawals = append(types.Withdrawals{&modifiedWithdrawal}, payloadAttributes.Withdrawals[1:]...)
8282
case PayloadAttributesParentBeaconRoot:
83-
payloadAttributes.BeaconRoot[0] = payloadAttributes.BeaconRoot[0] + 1
83+
if payloadAttributes.BeaconRoot == nil {
84+
t.Fatalf("Cannot modify parent beacon root when there is no parent beacon root")
85+
}
86+
newBeaconRoot := *payloadAttributes.BeaconRoot
87+
newBeaconRoot[0] = newBeaconRoot[0] + 1
88+
payloadAttributes.BeaconRoot = &newBeaconRoot
8489
default:
8590
t.Fatalf("Unknown field change: %s", tc.FieldModification)
8691
}
@@ -89,7 +94,7 @@ func (tc UniquePayloadIDTest) Execute(t *test.Env) {
8994
r := t.TestEngine.TestEngineForkchoiceUpdated(&t.CLMock.
9095
LatestForkchoice, &payloadAttributes, t.CLMock.LatestHeader.Time)
9196
r.ExpectNoError()
92-
t.CLMock.AddPayloadID(r.Response.PayloadID)
97+
t.CLMock.AddPayloadID(t.Engine, r.Response.PayloadID)
9398
},
9499
})
95100
}

simulators/ethereum/engine/suites/engine/tests.go

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,30 +115,29 @@ func init() {
115115
Tests = append(Tests,
116116
ForkchoiceUpdatedOnPayloadRequestTest{
117117
BaseSpec: test.BaseSpec{
118-
Name: "Early upgrade",
119-
ForkHeight: 2,
118+
Name: "Early upgrade",
119+
About: `
120+
Early upgrade of ForkchoiceUpdated when requesting a payload.
121+
The test sets the fork height to 1, and the block timestamp increments to 2
122+
seconds each block.
123+
CL Mock prepares the payload attributes for the first block, which should contain
124+
the attributes of the next fork.
125+
The test then reduces the timestamp by 1, but still uses the next forkchoice updated
126+
version, which should result in UNSUPPORTED_FORK_ERROR error.
127+
`,
128+
ForkHeight: 1,
129+
BlockTimestampIncrement: 2,
120130
},
121131
ForkchoiceUpdatedCustomizer: &helper.UpgradeForkchoiceUpdatedVersion{
122132
ForkchoiceUpdatedCustomizer: &helper.BaseForkchoiceUpdatedCustomizer{
133+
PayloadAttributesCustomizer: &helper.TimestampDeltaPayloadAttributesCustomizer{
134+
PayloadAttributesCustomizer: &helper.BasePayloadAttributesCustomizer{},
135+
TimestampDelta: -1,
136+
},
123137
ExpectedError: globals.UNSUPPORTED_FORK_ERROR,
124138
},
125139
},
126140
},
127-
/*
128-
TODO: This test is failing because the upgraded version of the ForkchoiceUpdated does not contain the
129-
expected fields of the following version.
130-
ForkchoiceUpdatedOnHeadBlockUpdateTest{
131-
BaseSpec: test.BaseSpec{
132-
Name: "Early upgrade",
133-
ForkHeight: 2,
134-
},
135-
ForkchoiceUpdatedCustomizer: &helper.UpgradeForkchoiceUpdatedVersion{
136-
ForkchoiceUpdatedCustomizer: &helper.BaseForkchoiceUpdatedCustomizer{
137-
ExpectedError: globals.UNSUPPORTED_FORK_ERROR,
138-
},
139-
},
140-
},
141-
*/
142141
)
143142

144143
// Payload Execution Tests

simulators/ethereum/engine/suites/engine/versioning.go

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package suite_engine
22

33
import (
4-
api "github.com/ethereum/go-ethereum/beacon/engine"
54
"github.com/ethereum/hive/simulators/ethereum/engine/clmock"
65
"github.com/ethereum/hive/simulators/ethereum/engine/config"
76
"github.com/ethereum/hive/simulators/ethereum/engine/helper"
@@ -74,58 +73,3 @@ func (tc ForkchoiceUpdatedOnPayloadRequestTest) Execute(t *test.Env) {
7473
},
7574
})
7675
}
77-
78-
// Test modifying the ForkchoiceUpdated version on HeadBlockHash update to the previous/upcoming
79-
// version when the timestamp payload attribute does not match the upgraded/downgraded version.
80-
type ForkchoiceUpdatedOnHeadBlockUpdateTest struct {
81-
test.BaseSpec
82-
helper.ForkchoiceUpdatedCustomizer
83-
}
84-
85-
func (s ForkchoiceUpdatedOnHeadBlockUpdateTest) WithMainFork(fork config.Fork) test.Spec {
86-
specCopy := s
87-
specCopy.MainFork = fork
88-
return specCopy
89-
}
90-
91-
func (tc ForkchoiceUpdatedOnHeadBlockUpdateTest) GetName() string {
92-
return "ForkchoiceUpdated Version on Head Set: " + tc.BaseSpec.GetName()
93-
}
94-
95-
func (tc ForkchoiceUpdatedOnHeadBlockUpdateTest) Execute(t *test.Env) {
96-
// Wait until TTD is reached by this client
97-
t.CLMock.WaitForTTD()
98-
99-
t.CLMock.ProduceSingleBlock(clmock.BlockProcessCallbacks{
100-
OnPayloadAttributesGenerated: func() {
101-
var (
102-
forkchoiceState *api.ForkchoiceStateV1 = &api.ForkchoiceStateV1{
103-
HeadBlockHash: t.CLMock.LatestPayloadBuilt.BlockHash,
104-
SafeBlockHash: t.CLMock.LatestForkchoice.SafeBlockHash,
105-
FinalizedBlockHash: t.CLMock.LatestForkchoice.FinalizedBlockHash,
106-
}
107-
expectedError *int
108-
expectedStatus test.PayloadStatus = test.Valid
109-
err error
110-
)
111-
tc.SetEngineAPIVersionResolver(t.ForkConfig)
112-
testEngine := t.TestEngine.WithEngineAPIVersionResolver(tc.ForkchoiceUpdatedCustomizer)
113-
expectedError, err = tc.GetExpectedError()
114-
if err != nil {
115-
t.Fatalf("FAIL: Error getting custom expected error: %v", err)
116-
}
117-
if tc.GetExpectInvalidStatus() {
118-
expectedStatus = test.Invalid
119-
}
120-
121-
r := testEngine.TestEngineForkchoiceUpdated(forkchoiceState, nil, t.CLMock.LatestPayloadBuilt.Timestamp)
122-
r.ExpectationDescription = tc.Expectation
123-
if expectedError != nil {
124-
r.ExpectErrorCode(*expectedError)
125-
} else {
126-
r.ExpectNoError()
127-
r.ExpectPayloadStatus(expectedStatus)
128-
}
129-
},
130-
})
131-
}

0 commit comments

Comments
 (0)