1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package super
import (
"context"
"errors"
"math/big"
"testing"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/trace/split"
"github.com/ethereum-optimism/optimism/op-challenger/game/fault/types"
interopTypes "github.com/ethereum-optimism/optimism/op-program/client/interop/types"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/testlog"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
)
var creatorError = errors.New("captured args")
func TestSplitAdapter(t *testing.T) {
depth := types.Depth(30)
prestateTimestamp := uint64(150)
poststateTimestamp := uint64(200)
t.Run("FromAbsolutePrestate", func(t *testing.T) {
creator, rootProvider, adapter := setupSplitAdapterTest(t, depth, prestateTimestamp, poststateTimestamp)
prestateResponse := eth.SuperRootResponse{
Timestamp: prestateTimestamp,
}
rootProvider.Add(prestateResponse)
postClaim := types.Claim{
ClaimData: types.ClaimData{
Value: common.Hash{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
Position: types.NewPosition(depth, big.NewInt(0)),
},
}
expectedClaimInfo := ClaimInfo{
AgreedPrestate: responseToSuper(prestateResponse).Marshal(),
Claim: postClaim.Value,
}
_, err := adapter(context.Background(), depth, types.Claim{}, postClaim)
require.ErrorIs(t, err, creatorError)
require.Equal(t, split.CreateLocalContext(types.Claim{}, postClaim), creator.localContext)
require.Equal(t, expectedClaimInfo, creator.claimInfo)
})
t.Run("AfterClaimedBlock", func(t *testing.T) {
creator, rootProvider, adapter := setupSplitAdapterTest(t, depth, prestateTimestamp, poststateTimestamp)
prestateResponse := eth.SuperRootResponse{
Timestamp: poststateTimestamp,
}
rootProvider.Add(prestateResponse)
preClaim := types.Claim{
ClaimData: types.ClaimData{
Value: common.Hash{0x11},
Position: types.NewPosition(depth, big.NewInt(999_999)),
},
}
postClaim := types.Claim{
ClaimData: types.ClaimData{
Value: common.Hash{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
Position: types.NewPosition(depth, big.NewInt(1_000_000)),
},
}
expectedClaimInfo := ClaimInfo{
AgreedPrestate: responseToSuper(prestateResponse).Marshal(),
Claim: postClaim.Value,
}
_, err := adapter(context.Background(), depth, preClaim, postClaim)
require.ErrorIs(t, err, creatorError)
require.Equal(t, split.CreateLocalContext(preClaim, postClaim), creator.localContext)
require.Equal(t, expectedClaimInfo, creator.claimInfo)
})
t.Run("MiddleOfTimestampTransition", func(t *testing.T) {
creator, rootProvider, adapter := setupSplitAdapterTest(t, depth, prestateTimestamp, poststateTimestamp)
prestateResponse := eth.SuperRootResponse{
Timestamp: prestateTimestamp,
}
rootProvider.Add(prestateResponse)
rootProvider.Add(eth.SuperRootResponse{
Timestamp: prestateTimestamp + 1,
})
preClaim := types.Claim{
ClaimData: types.ClaimData{
Value: common.Hash{0x11},
Position: types.NewPosition(depth, big.NewInt(2)),
},
}
postClaim := types.Claim{
ClaimData: types.ClaimData{
Value: common.Hash{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
Position: types.NewPosition(depth, big.NewInt(3)),
},
}
expectedPrestate := interopTypes.TransitionState{
SuperRoot: responseToSuper(prestateResponse).Marshal(),
Step: 3,
}
expectedClaimInfo := ClaimInfo{
AgreedPrestate: expectedPrestate.Marshal(),
Claim: postClaim.Value,
}
_, err := adapter(context.Background(), depth, preClaim, postClaim)
require.ErrorIs(t, err, creatorError)
require.Equal(t, split.CreateLocalContext(preClaim, postClaim), creator.localContext)
require.Equal(t, expectedClaimInfo, creator.claimInfo)
})
}
func setupSplitAdapterTest(t *testing.T, depth types.Depth, prestateTimestamp uint64, poststateTimestamp uint64) (*capturingCreator, *stubRootProvider, split.ProviderCreator) {
creator := &capturingCreator{}
rootProvider := &stubRootProvider{}
prestateProvider := NewSuperRootPrestateProvider(rootProvider, prestateTimestamp)
traceProvider := NewSuperTraceProvider(testlog.Logger(t, log.LvlInfo), prestateProvider, rootProvider, eth.BlockID{}, depth, prestateTimestamp, poststateTimestamp)
adapter := SuperRootSplitAdapter(traceProvider, creator.Create)
return creator, rootProvider, adapter
}
type capturingCreator struct {
localContext common.Hash
claimInfo ClaimInfo
}
func (c *capturingCreator) Create(_ context.Context, localContext common.Hash, _ types.Depth, claimInfo ClaimInfo) (types.TraceProvider, error) {
c.localContext = localContext
c.claimInfo = claimInfo
return nil, creatorError
}