Commit a59cae17 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into jg/remove_examples

parents 8c25ad4a f6ae9f02
...@@ -102,19 +102,13 @@ func (a *Agent) step(claim Claim, game Game) error { ...@@ -102,19 +102,13 @@ func (a *Agent) step(claim Claim, game Game) error {
a.log.Warn("Failed to get a step", "err", err) a.log.Warn("Failed to get a step", "err", err)
return err return err
} }
stateData, err := a.trace.GetPreimage(step.PreStateTraceIndex)
if err != nil {
a.log.Warn("Failed to get a state data", "err", err)
return err
}
a.log.Info("Performing step", a.log.Info("Performing step", "is_attack", step.IsAttack,
"depth", step.LeafClaim.Depth(), "index_at_depth", step.LeafClaim.IndexAtDepth(), "value", step.LeafClaim.Value, "depth", step.LeafClaim.Depth(), "index_at_depth", step.LeafClaim.IndexAtDepth(), "value", step.LeafClaim.Value)
"is_attack", step.IsAttack, "prestate_trace_index", step.PreStateTraceIndex)
callData := StepCallData{ callData := StepCallData{
ClaimIndex: uint64(step.LeafClaim.ContractIndex), ClaimIndex: uint64(step.LeafClaim.ContractIndex),
IsAttack: step.IsAttack, IsAttack: step.IsAttack,
StateData: stateData, StateData: step.PreState,
} }
return a.responder.Step(context.TODO(), callData) return a.responder.Step(context.TODO(), callData)
} }
...@@ -8,6 +8,8 @@ import ( ...@@ -8,6 +8,8 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
) )
var _ TraceProvider = (*AlphabetProvider)(nil)
// AlphabetProvider is a [TraceProvider] that provides claims for specific // AlphabetProvider is a [TraceProvider] that provides claims for specific
// indices in the given trace. // indices in the given trace.
type AlphabetProvider struct { type AlphabetProvider struct {
...@@ -45,6 +47,12 @@ func (ap *AlphabetProvider) Get(i uint64) (common.Hash, error) { ...@@ -45,6 +47,12 @@ func (ap *AlphabetProvider) Get(i uint64) (common.Hash, error) {
return crypto.Keccak256Hash(claimBytes), nil return crypto.Keccak256Hash(claimBytes), nil
} }
func (ap *AlphabetProvider) AbsolutePreState() []byte {
out := make([]byte, 32)
out[31] = 140 // ascii character 140 is "`"
return out
}
// BuildAlphabetPreimage constructs the claim bytes for the index and state item. // BuildAlphabetPreimage constructs the claim bytes for the index and state item.
func BuildAlphabetPreimage(i uint64, letter string) []byte { func BuildAlphabetPreimage(i uint64, letter string) []byte {
return append(IndexToBytes(i), LetterToBytes(letter)...) return append(IndexToBytes(i), LetterToBytes(letter)...)
......
...@@ -26,14 +26,6 @@ type Game interface { ...@@ -26,14 +26,6 @@ type Game interface {
// IsDuplicate returns true if the provided [Claim] already exists in the game state. // IsDuplicate returns true if the provided [Claim] already exists in the game state.
IsDuplicate(claim Claim) bool IsDuplicate(claim Claim) bool
// PreStateClaim gets the claim which commits to the pre-state of this specific claim.
// This will return an error if it is called with a non-leaf claim.
PreStateClaim(claim Claim) (Claim, error)
// PostStateClaim gets the claim which commits to the post-state of this specific claim.
// This will return an error if it is called with a non-leaf claim.
PostStateClaim(claim Claim) (Claim, error)
// AgreeWithLevel returns if the game state agrees with the provided claim level. // AgreeWithLevel returns if the game state agrees with the provided claim level.
AgreeWithClaimLevel(claim Claim) bool AgreeWithClaimLevel(claim Claim) bool
} }
...@@ -140,45 +132,3 @@ func (g *gameState) getParent(claim Claim) (Claim, error) { ...@@ -140,45 +132,3 @@ func (g *gameState) getParent(claim Claim) (Claim, error) {
return parent.self, nil return parent.self, nil
} }
} }
func (g *gameState) PreStateClaim(claim Claim) (Claim, error) {
// Do checks in PreStateClaim because these do not hold while walking the tree
if claim.Depth() != int(g.depth) {
return Claim{}, errors.New("Only leaf claims have pre or post state")
}
// If the claim is the far left most claim, the pre-state is pulled from the contracts & we can supply at contract index.
if claim.IndexAtDepth() == 0 {
return Claim{
ContractIndex: -1,
}, nil
}
return g.preStateClaim(claim)
}
// preStateClaim is the internal tree walker which does not do error handling
func (g *gameState) preStateClaim(claim Claim) (Claim, error) {
parent, _ := g.getParent(claim)
if claim.DefendsParent() {
return parent, nil
} else {
return g.preStateClaim(parent)
}
}
func (g *gameState) PostStateClaim(claim Claim) (Claim, error) {
// Do checks in PostStateClaim because these do not hold while walking the tree
if claim.Depth() != int(g.depth) {
return Claim{}, errors.New("Only leaf claims have pre or post state")
}
return g.postStateClaim(claim)
}
// postStateClaim is the internal tree walker which does not do error handling
func (g *gameState) postStateClaim(claim Claim) (Claim, error) {
parent, _ := g.getParent(claim)
if claim.DefendsParent() {
return g.postStateClaim(parent)
} else {
return parent, nil
}
}
...@@ -195,46 +195,6 @@ func TestGame_ClaimPairs(t *testing.T) { ...@@ -195,46 +195,6 @@ func TestGame_ClaimPairs(t *testing.T) {
require.ElementsMatch(t, expected, claims) require.ElementsMatch(t, expected, claims)
} }
// TestPrePostStateOnlyOnLeafClaim tests that if PreStateClaim or PostStateClaim is called with an non-leaf claim
// those functions return an error.
func TestPrePostStateOnlyOnLeafClaim(t *testing.T) {
root, top, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.PutAll([]Claim{top, middle, bottom}))
_, err := g.PreStateClaim(middle)
require.Error(t, err)
_, err = g.PostStateClaim(middle)
require.Error(t, err)
}
func TestPreStateClaim(t *testing.T) {
root, top, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.Put(top))
require.NoError(t, g.Put(middle))
require.NoError(t, g.Put(bottom))
// Bottom trace index is 4. Pre trace index is then 3
pre, err := g.PreStateClaim(bottom)
require.NoError(t, err)
require.Equal(t, top, pre)
}
func TestPostStateClaim(t *testing.T) {
root, top, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.Put(top))
require.NoError(t, g.Put(middle))
require.NoError(t, g.Put(bottom))
// Bottom trace index is 4. Post trace index is then 5
post, err := g.PostStateClaim(bottom)
require.NoError(t, err)
require.Equal(t, middle, post)
}
func TestAgreeWithClaimLevelDisagreeWithOutput(t *testing.T) { func TestAgreeWithClaimLevelDisagreeWithOutput(t *testing.T) {
// Setup the game state. // Setup the game state.
root, top, middle, bottom := createTestClaims() root, top, middle, bottom := createTestClaims()
......
...@@ -64,9 +64,9 @@ func (s *Solver) handleMiddle(claim Claim) (*Claim, error) { ...@@ -64,9 +64,9 @@ func (s *Solver) handleMiddle(claim Claim) (*Claim, error) {
} }
type StepData struct { type StepData struct {
LeafClaim Claim LeafClaim Claim
IsAttack bool IsAttack bool
PreStateTraceIndex uint64 PreState []byte
} }
// AttemptStep determines what step should occur for a given leaf claim. // AttemptStep determines what step should occur for a given leaf claim.
...@@ -80,14 +80,25 @@ func (s *Solver) AttemptStep(claim Claim) (StepData, error) { ...@@ -80,14 +80,25 @@ func (s *Solver) AttemptStep(claim Claim) (StepData, error) {
return StepData{}, err return StepData{}, err
} }
index := claim.TraceIndex(s.gameDepth) index := claim.TraceIndex(s.gameDepth)
// TODO(CLI-4198): Handle case where we dispute trace index 0 var preState []byte
if !claimCorrect { // If we are attacking index 0, we provide the absolute pre-state, not an intermediate state
index -= 1 if index == 0 && !claimCorrect {
preState = s.AbsolutePreState()
} else {
// If attacking, get the state just before, other get the state after
if !claimCorrect {
index = index - 1
}
preState, err = s.GetPreimage(index)
if err != nil {
return StepData{}, err
}
} }
return StepData{ return StepData{
LeafClaim: claim, LeafClaim: claim,
IsAttack: !claimCorrect, IsAttack: !claimCorrect,
PreStateTraceIndex: index, PreState: preState,
}, nil }, nil
} }
......
...@@ -102,17 +102,27 @@ func TestAttemptStep(t *testing.T) { ...@@ -102,17 +102,27 @@ func TestAttemptStep(t *testing.T) {
maxDepth := 3 maxDepth := 3
canonicalProvider := NewAlphabetProvider("abcdefgh", uint64(maxDepth)) canonicalProvider := NewAlphabetProvider("abcdefgh", uint64(maxDepth))
solver := NewSolver(maxDepth, canonicalProvider) solver := NewSolver(maxDepth, canonicalProvider)
root, top, middle, bottom := createTestClaims() _, _, middle, bottom := createTestClaims()
g := NewGameState(false, root, testMaxDepth)
require.NoError(t, g.Put(top)) zero := Claim{
require.NoError(t, g.Put(middle)) ClaimData: ClaimData{
require.NoError(t, g.Put(bottom)) // Zero value is a purposely disagree with claim value "a"
Position: NewPosition(3, 0),
},
}
step, err := solver.AttemptStep(bottom) step, err := solver.AttemptStep(bottom)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, bottom, step.LeafClaim) require.Equal(t, bottom, step.LeafClaim)
require.True(t, step.IsAttack) require.True(t, step.IsAttack)
require.Equal(t, step.PreState, BuildAlphabetPreimage(3, "d"))
_, err = solver.AttemptStep(middle) _, err = solver.AttemptStep(middle)
require.Error(t, err) require.Error(t, err)
step, err = solver.AttemptStep(zero)
require.NoError(t, err)
require.Equal(t, zero, step.LeafClaim)
require.True(t, step.IsAttack)
require.Equal(t, canonicalProvider.AbsolutePreState(), step.PreState)
} }
...@@ -22,10 +22,12 @@ type StepCallData struct { ...@@ -22,10 +22,12 @@ type StepCallData struct {
// TraceProvider is a generic way to get a claim value at a specific // TraceProvider is a generic way to get a claim value at a specific
// step in the trace. // step in the trace.
// The [AlphabetProvider] is a minimal implementation of this interface. // Get(i) = Keccak256(GetPreimage(i))
// AbsolutePreState is the value of the trace that transitions to the trace value at index 0
type TraceProvider interface { type TraceProvider interface {
Get(i uint64) (common.Hash, error) Get(i uint64) (common.Hash, error)
GetPreimage(i uint64) ([]byte, error) GetPreimage(i uint64) ([]byte, error)
AbsolutePreState() []byte
} }
// ClaimData is the core of a claim. It must be unique inside a specific game. // ClaimData is the core of a claim. It must be unique inside a specific game.
......
...@@ -59,7 +59,11 @@ func (cfg *L2EndpointConfig) Setup(ctx context.Context, log log.Logger, rollupCf ...@@ -59,7 +59,11 @@ func (cfg *L2EndpointConfig) Setup(ctx context.Context, log log.Logger, rollupCf
return nil, nil, err return nil, nil, err
} }
auth := rpc.WithHTTPAuth(gn.NewJWTAuth(cfg.L2EngineJWTSecret)) auth := rpc.WithHTTPAuth(gn.NewJWTAuth(cfg.L2EngineJWTSecret))
l2Node, err := client.NewRPC(ctx, log, cfg.L2EngineAddr, client.WithGethRPCOptions(auth)) opts := []client.RPCOption{
client.WithGethRPCOptions(auth),
client.WithDialBackoff(10),
}
l2Node, err := client.NewRPC(ctx, log, cfg.L2EngineAddr, opts...)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
......
...@@ -44,6 +44,6 @@ ...@@ -44,6 +44,6 @@
"l1GenesisBlockTimestamp": "0x64935846", "l1GenesisBlockTimestamp": "0x64935846",
"l1StartingBlockTag": "earliest", "l1StartingBlockTag": "earliest",
"l2GenesisRegolithTimeOffset": "0x0", "l2GenesisRegolithTimeOffset": "0x0",
"faultGameAbsolutePrestate": 15, "faultGameAbsolutePrestate": 140,
"faultGameMaxDepth": 4 "faultGameMaxDepth": 4
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment