Skip to content

Commit

Permalink
[NIT-2527] Add option to enable fast confirmation for bold (#673)
Browse files Browse the repository at this point in the history
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
  • Loading branch information
amsanghi and rauljordan authored Jun 26, 2024
1 parent 9ae83e1 commit 6c151c6
Show file tree
Hide file tree
Showing 32 changed files with 24,063 additions and 14 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "contracts/lib/forge-std"]
path = contracts/lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "safe-smart-account"]
path = safe-smart-account
url = https://github.com/safe-global/safe-smart-account.git
10 changes: 10 additions & 0 deletions assertions/confirmation.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ func (m *Manager) keepTryingAssertionConfirmation(ctx context.Context, assertion
log.Error("Could not get assertion creation info", "err", err)
return
}
if m.enableFastConfirmation {
err = m.chain.FastConfirmAssertion(ctx, creationInfo)
if err != nil {
log.Error("Could not fast confirm latest assertion", "err", err)
return
}
assertionConfirmedCounter.Inc(1)
log.Info("Fast Confirmed assertion", "assertionHash", creationInfo.AssertionHash)
return
}
prevCreationInfo, err := retry.UntilSucceeds(ctx, func() (*protocol.AssertionCreatedInfo, error) {
return m.chain.ReadAssertionCreationInfo(ctx, protocol.AssertionHash{Hash: creationInfo.ParentAssertionHash})
})
Expand Down
7 changes: 7 additions & 0 deletions assertions/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ type Manager struct {
startPostingSignal chan struct{}
layerZeroHeightsCache *protocol.LayerZeroHeights
layerZeroHeightsCacheLock sync.RWMutex
enableFastConfirmation bool
}

type assertionChainData struct {
Expand All @@ -85,6 +86,12 @@ func WithPostingDisabled() Opt {
}
}

func WithFastConfirmation() Opt {
return func(m *Manager) {
m.enableFastConfirmation = true
}
}

func WithDangerousReadyToPost() Opt {
return func(m *Manager) {
m.isReadyToPost = true
Expand Down
208 changes: 208 additions & 0 deletions assertions/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,214 @@ func TestComplexAssertionForkScenario(t *testing.T) {
require.NotEqual(t, charliePostState.GlobalState.BlockHash, alicePostState.GlobalState.BlockHash)
}

func TestFastConfirmation(t *testing.T) {
ctx := context.Background()
setup, err := setup.ChainsWithEdgeChallengeManager(
setup.WithMockOneStepProver(),
setup.WithChallengeTestingOpts(
challenge_testing.WithLayerZeroHeights(&protocol.LayerZeroHeights{
BlockChallengeHeight: 64,
BigStepChallengeHeight: 32,
SmallStepChallengeHeight: 32,
}),
),
setup.WithFastConfirmation(),
)
require.NoError(t, err)

bridgeBindings, err := mocksgen.NewBridgeStub(setup.Addrs.Bridge, setup.Backend)
require.NoError(t, err)

msgCount, err := bridgeBindings.SequencerMessageCount(setup.Chains[0].GetCallOptsWithDesiredRpcHeadBlockNumber(&bind.CallOpts{}))
require.NoError(t, err)
require.Equal(t, uint64(1), msgCount.Uint64())

aliceChain := setup.Chains[0]

stateManagerOpts := setup.StateManagerOpts
stateManagerOpts = append(
stateManagerOpts,
statemanager.WithNumBatchesRead(5),
)
stateManager, err := statemanager.NewForSimpleMachine(stateManagerOpts...)
require.NoError(t, err)

chalManager, err := challengemanager.New(
ctx,
aliceChain,
stateManager,
setup.Addrs.Rollup,
challengemanager.WithMode(types.ResolveMode),
challengemanager.WithFastConfirmation(),
)
require.NoError(t, err)
chalManager.Start(ctx)

preState, err := stateManager.ExecutionStateAfterPreviousState(ctx, 0, nil, 1<<26)
require.NoError(t, err)
postState, err := stateManager.ExecutionStateAfterPreviousState(ctx, 1, &preState.GlobalState, 1<<26)
require.NoError(t, err)

assertionManager, err := assertions.NewManager(
aliceChain,
stateManager,
setup.Backend,
chalManager,
aliceChain.RollupAddress(),
chalManager.ChallengeManagerAddress(),
"alice",
time.Millisecond*200, // poll interval for assertions
time.Hour, // confirmation attempt interval
stateManager,
time.Millisecond*100, // poll interval
time.Second*1,
nil,
assertions.WithDangerousReadyToPost(),
assertions.WithPostingDisabled(),
assertions.WithFastConfirmation(),
)
require.NoError(t, err)

go assertionManager.Start(ctx)

time.Sleep(time.Second)

posted, err := assertionManager.PostAssertion(ctx)
require.NoError(t, err)
require.Equal(t, true, posted.IsSome())
require.Equal(t, postState, protocol.GoExecutionStateFromSolidity(posted.Unwrap().AfterState))

<-time.After(10 * time.Millisecond)
status, err := aliceChain.AssertionStatus(ctx, protocol.AssertionHash{Hash: posted.Unwrap().AssertionHash})
require.NoError(t, err)
require.Equal(t, protocol.AssertionConfirmed, status)
}

func TestFastConfirmationWithSafe(t *testing.T) {
ctx := context.Background()
setup, err := setup.ChainsWithEdgeChallengeManager(
// setup.WithMockBridge(),
setup.WithMockOneStepProver(),
setup.WithChallengeTestingOpts(
challenge_testing.WithLayerZeroHeights(&protocol.LayerZeroHeights{
BlockChallengeHeight: 64,
BigStepChallengeHeight: 32,
SmallStepChallengeHeight: 32,
}),
),
setup.WithSafeFastConfirmation(),
)
require.NoError(t, err)

bridgeBindings, err := mocksgen.NewBridgeStub(setup.Addrs.Bridge, setup.Backend)
require.NoError(t, err)

msgCount, err := bridgeBindings.SequencerMessageCount(setup.Chains[0].GetCallOptsWithDesiredRpcHeadBlockNumber(&bind.CallOpts{}))
require.NoError(t, err)
require.Equal(t, uint64(1), msgCount.Uint64())

aliceChain := setup.Chains[0]
bobChain := setup.Chains[1]

stateManagerOpts := setup.StateManagerOpts
stateManagerOpts = append(
stateManagerOpts,
statemanager.WithNumBatchesRead(5),
)
stateManager, err := statemanager.NewForSimpleMachine(stateManagerOpts...)
require.NoError(t, err)

chalManagerAlice, err := challengemanager.New(
ctx,
aliceChain,
stateManager,
setup.Addrs.Rollup,
challengemanager.WithMode(types.ResolveMode),
challengemanager.WithFastConfirmation(),
)
require.NoError(t, err)
chalManagerAlice.Start(ctx)

preState, err := stateManager.ExecutionStateAfterPreviousState(ctx, 0, nil, 1<<26)
require.NoError(t, err)
postState, err := stateManager.ExecutionStateAfterPreviousState(ctx, 1, &preState.GlobalState, 1<<26)
require.NoError(t, err)

assertionManagerAlice, err := assertions.NewManager(
aliceChain,
stateManager,
setup.Backend,
chalManagerAlice,
aliceChain.RollupAddress(),
chalManagerAlice.ChallengeManagerAddress(),
"alice",
time.Millisecond*200, // poll interval for assertions
time.Hour, // confirmation attempt interval
stateManager,
time.Millisecond*100, // poll interval
time.Second*1,
nil,
assertions.WithDangerousReadyToPost(),
assertions.WithPostingDisabled(),
assertions.WithFastConfirmation(),
)
require.NoError(t, err)

go assertionManagerAlice.Start(ctx)

time.Sleep(time.Second)

posted, err := assertionManagerAlice.PostAssertion(ctx)
require.NoError(t, err)
require.Equal(t, true, posted.IsSome())
require.Equal(t, postState, protocol.GoExecutionStateFromSolidity(posted.Unwrap().AfterState))

<-time.After(time.Second)
status, err := aliceChain.AssertionStatus(ctx, protocol.AssertionHash{Hash: posted.Unwrap().AssertionHash})
require.NoError(t, err)
// Just one fast confirmation is not enough to confirm the assertion.
require.Equal(t, protocol.AssertionPending, status)

chalManagerBob, err := challengemanager.New(
ctx,
bobChain,
stateManager,
setup.Addrs.Rollup,
challengemanager.WithMode(types.ResolveMode),
challengemanager.WithFastConfirmation(),
)
require.NoError(t, err)
chalManagerBob.Start(ctx)

assertionManagerBob, err := assertions.NewManager(
bobChain,
stateManager,
setup.Backend,
chalManagerBob,
bobChain.RollupAddress(),
chalManagerBob.ChallengeManagerAddress(),
"bob",
time.Millisecond*200, // poll interval for assertions
time.Hour, // confirmation attempt interval
stateManager,
time.Millisecond*100, // poll interval
time.Second*1,
nil,
assertions.WithDangerousReadyToPost(),
assertions.WithPostingDisabled(),
assertions.WithFastConfirmation(),
)
require.NoError(t, err)

assertionManagerBob.Start(ctx)

<-time.After(time.Second)
status, err = aliceChain.AssertionStatus(ctx, protocol.AssertionHash{Hash: posted.Unwrap().AssertionHash})
require.NoError(t, err)
// Only after both Alice and Bob confirm the assertion, it should be confirmed.
require.Equal(t, protocol.AssertionConfirmed, status)
}

type seqMessage struct {
dataHash common.Hash
afterDelayedMessagesRead *big.Int
Expand Down
4 changes: 4 additions & 0 deletions chain-abstraction/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ type AssertionChain interface {
assertionCreationInfo *AssertionCreatedInfo,
postState *ExecutionState,
) (Assertion, error)
FastConfirmAssertion(
ctx context.Context,
assertionCreationInfo *AssertionCreatedInfo,
) error
ConfirmAssertionByTime(
ctx context.Context,
assertionHash AssertionHash,
Expand Down
2 changes: 2 additions & 0 deletions chain-abstraction/sol-implementation/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ go_library(
"//containers",
"//containers/option",
"//containers/threadsafe",
"//runtime",
"//solgen/go/bridgegen",
"//solgen/go/challengeV2gen",
"//solgen/go/contractsgen",
"//solgen/go/ospgen",
"//solgen/go/rollupgen",
"//state-commitments/history",
Expand Down
Loading

0 comments on commit 6c151c6

Please sign in to comment.