Skip to content

Commit

Permalink
feat(taiko-client): support TaikoL1.proposeBlocksV2 (#18116)
Browse files Browse the repository at this point in the history
Co-authored-by: maskpp <[email protected]>
  • Loading branch information
davidtaikocha and mask-pp authored Sep 23, 2024
1 parent e1420ed commit d0c0fed
Show file tree
Hide file tree
Showing 27 changed files with 413 additions and 211 deletions.
2 changes: 1 addition & 1 deletion packages/taiko-client/bindings/.githead
Original file line number Diff line number Diff line change
@@ -1 +1 @@
adc47f408282c25c7a50c26e31130fc495734dcc
db7b7a03af3797d37cce04cc2b05614c8dfeece4
23 changes: 22 additions & 1 deletion packages/taiko-client/bindings/gen_prover_set.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/taiko-client/bindings/metadata/metadata_legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type TaikoDataBlockMetadataLegacy struct {

// NewTaikoDataBlockMetadataLegacy creates a new instance of TaikoDataBlockMetadataLegacy
// from the TaikoL1.BlockProposed event.
func NewTaikoDataBlockMetadataLegacy(e *bindings.LibProposingBlockProposed) *TaikoDataBlockMetadataLegacy {
func NewTaikoDataBlockMetadataLegacy(e *bindings.TaikoL1ClientBlockProposed) *TaikoDataBlockMetadataLegacy {
return &TaikoDataBlockMetadataLegacy{
TaikoDataBlockMetadata: e.Meta,
Log: e.Raw,
Expand Down
2 changes: 1 addition & 1 deletion packages/taiko-client/bindings/metadata/metadata_ontake.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type TaikoDataBlockMetadataOntake struct {

// NewTaikoDataBlockMetadataOntake creates a new instance of TaikoDataBlockMetadataOntake
// from the TaikoL1.BlockProposedV2 event.
func NewTaikoDataBlockMetadataOntake(e *bindings.LibProposingBlockProposedV2) *TaikoDataBlockMetadataOntake {
func NewTaikoDataBlockMetadataOntake(e *bindings.TaikoL1ClientBlockProposedV2) *TaikoDataBlockMetadataOntake {
return &TaikoDataBlockMetadataOntake{
TaikoDataBlockMetadataV2: e.Meta,
Log: e.Raw,
Expand Down
1 change: 0 additions & 1 deletion packages/taiko-client/driver/chain_syncer/blob/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ func (s *Syncer) processL1Blocks(ctx context.Context) error {
iter, err := eventIterator.NewBlockProposedIterator(ctx, &eventIterator.BlockProposedIteratorConfig{
Client: s.rpc.L1,
TaikoL1: s.rpc.TaikoL1,
LibProposing: s.rpc.LibProposing,
StartHeight: s.state.GetL1Current().Number,
EndHeight: l1End.Number,
FilterQuery: nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func (s *BlobSyncerTestSuite) TestTreasuryIncomeAllAnchors() {
s.Nil(err)

s.Greater(headAfter, headBefore)
s.Zero(balanceAfter.Cmp(balance))
s.Equal(1, balanceAfter.Cmp(balance))
}

func (s *BlobSyncerTestSuite) TestTreasuryIncome() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

"github.com/taikoxyz/taiko-mono/packages/taiko-client/driver/state"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/internal/testutils"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/pkg/jwt"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/pkg/rpc"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/proposer"
)
Expand Down Expand Up @@ -50,11 +51,15 @@ func (s *ChainSyncerTestSuite) SetupTest() {
prop := new(proposer.Proposer)
l1ProposerPrivKey, err := crypto.ToECDSA(common.FromHex(os.Getenv("L1_PROPOSER_PRIVATE_KEY")))
s.Nil(err)
jwtSecret, err := jwt.ParseSecretFromFile(os.Getenv("JWT_SECRET"))
s.Nil(err)

s.Nil(prop.InitFromConfig(context.Background(), &proposer.Config{
ClientConfig: &rpc.ClientConfig{
L1Endpoint: os.Getenv("L1_WS"),
L2Endpoint: os.Getenv("L2_WS"),
L2EngineEndpoint: os.Getenv("L2_AUTH"),
JwtSecret: string(jwtSecret),
TaikoL1Address: common.HexToAddress(os.Getenv("TAIKO_L1")),
TaikoL2Address: common.HexToAddress(os.Getenv("TAIKO_L2")),
TaikoTokenAddress: common.HexToAddress(os.Getenv("TAIKO_TOKEN")),
Expand Down
12 changes: 5 additions & 7 deletions packages/taiko-client/driver/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (s *DriverTestSuite) TestProcessL1Blocks() {

txCount, err := s.d.rpc.L2.TransactionCount(context.Background(), header.Hash())
s.Nil(err)
s.Equal(uint(1), txCount)
s.GreaterOrEqual(txCount, uint(1))

anchorTx, err := s.d.rpc.L2.TransactionInBlock(context.Background(), header.Hash(), 0)
s.Nil(err)
Expand Down Expand Up @@ -132,16 +132,14 @@ func (s *DriverTestSuite) TestCheckL1ReorgToHigherFork() {
// Because of evm_revert operation, the nonce of the proposer need to be adjusted.
// Propose ten blocks on another fork
for i := 0; i < 10; i++ {
s.ProposeInvalidTxListBytes(s.p)
s.ProposeAndInsertValidBlock(s.p, s.d.ChainSyncer().BlobSyncer())
}

l1Head4, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)

s.Greater(l1Head4.Number.Uint64(), l1Head2.Number.Uint64())

s.Nil(s.d.ChainSyncer().BlobSyncer().ProcessL1Blocks(context.Background()))

l2Head3, err := s.d.rpc.L2.HeaderByNumber(context.Background(), nil)
s.Nil(err)

Expand Down Expand Up @@ -190,7 +188,7 @@ func (s *DriverTestSuite) TestCheckL1ReorgToLowerFork() {
s.GreaterOrEqual(l1Head3.Number.Uint64(), l1Head1.Number.Uint64())

// Propose one blocks on another fork
s.ProposeInvalidTxListBytes(s.p)
s.ProposeValidBlock(s.p)

l1Head4, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)
Expand Down Expand Up @@ -246,9 +244,9 @@ func (s *DriverTestSuite) TestCheckL1ReorgToSameHeightFork() {
s.GreaterOrEqual(l1Head3.Number.Uint64(), l1Head1.Number.Uint64())

// Propose two blocks on another fork
s.ProposeInvalidTxListBytes(s.p)
s.ProposeValidBlock(s.p)
time.Sleep(3 * time.Second)
s.ProposeInvalidTxListBytes(s.p)
s.ProposeValidBlock(s.p)

l1Head4, err := s.d.rpc.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)
Expand Down
12 changes: 6 additions & 6 deletions packages/taiko-client/driver/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ func (s *State) init(ctx context.Context) error {
return err
}

log.Info("Genesis L1 height", "height", stateVars.A.GenesisHeight)
s.GenesisL1Height = new(big.Int).SetUint64(stateVars.A.GenesisHeight)
log.Info("Genesis L1 height", "height", stateVars.A.GenesisHeight)

s.OnTakeForkHeight = new(big.Int).SetUint64(encoding.GetProtocolConfig(s.rpc.L2.ChainID.Uint64()).OntakeForkHeight)
log.Info("OnTake fork height", "L2 height", s.OnTakeForkHeight)
log.Info("OnTake fork height", "height", s.OnTakeForkHeight)

// Set the L2 head's latest known L1 origin as current L1 sync cursor.
latestL2KnownL1Header, err := s.rpc.LatestL2KnownL1Header(ctx)
Expand Down Expand Up @@ -107,21 +107,21 @@ func (s *State) eventLoop(ctx context.Context) {
// Channels for subscriptions.
l1HeadCh = make(chan *types.Header, 10)
l2HeadCh = make(chan *types.Header, 10)
blockProposedCh = make(chan *bindings.LibProposingBlockProposed, 10)
blockProposedCh = make(chan *bindings.TaikoL1ClientBlockProposed, 10)
transitionProvedCh = make(chan *bindings.TaikoL1ClientTransitionProved, 10)
blockVerifiedCh = make(chan *bindings.TaikoL1ClientBlockVerified, 10)
blockProposedV2Ch = make(chan *bindings.LibProposingBlockProposedV2, 10)
blockProposedV2Ch = make(chan *bindings.TaikoL1ClientBlockProposedV2, 10)
transitionProvedV2Ch = make(chan *bindings.TaikoL1ClientTransitionProvedV2, 10)
blockVerifiedV2Ch = make(chan *bindings.TaikoL1ClientBlockVerifiedV2, 10)

// Subscriptions.
l1HeadSub = rpc.SubscribeChainHead(s.rpc.L1, l1HeadCh)
l2HeadSub = rpc.SubscribeChainHead(s.rpc.L2, l2HeadCh)
l2BlockVerifiedSub = rpc.SubscribeBlockVerified(s.rpc.TaikoL1, blockVerifiedCh)
l2BlockProposedSub = rpc.SubscribeBlockProposed(s.rpc.LibProposing, blockProposedCh)
l2BlockProposedSub = rpc.SubscribeBlockProposed(s.rpc.TaikoL1, blockProposedCh)
l2TransitionProvedSub = rpc.SubscribeTransitionProved(s.rpc.TaikoL1, transitionProvedCh)
l2BlockVerifiedV2Sub = rpc.SubscribeBlockVerifiedV2(s.rpc.TaikoL1, blockVerifiedV2Ch)
l2BlockProposedV2Sub = rpc.SubscribeBlockProposedV2(s.rpc.LibProposing, blockProposedV2Ch)
l2BlockProposedV2Sub = rpc.SubscribeBlockProposedV2(s.rpc.TaikoL1, blockProposedV2Ch)
l2TransitionProvedV2Sub = rpc.SubscribeTransitionProvedV2(s.rpc.TaikoL1, transitionProvedV2Ch)
)

Expand Down
119 changes: 59 additions & 60 deletions packages/taiko-client/internal/testutils/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,16 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/phayes/freeport"

"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings/encoding"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/bindings/metadata"
"github.com/taikoxyz/taiko-mono/packages/taiko-client/pkg/rpc"
)

func (s *ClientTestSuite) ProposeInvalidTxListBytes(proposer Proposer) {
invalidTxListBytes := RandomBytes(256)

s.Nil(proposer.ProposeTxList(context.Background(), invalidTxListBytes, 1))
}

func (s *ClientTestSuite) proposeEmptyBlockOp(ctx context.Context, proposer Proposer) {
emptyTxListBytes, err := rlp.EncodeToBytes(types.Transactions{})
s.Nil(err)
s.Nil(proposer.ProposeTxList(ctx, emptyTxListBytes, 0))
s.Nil(proposer.ProposeTxLists(ctx, []types.Transactions{{}}))
}

func (s *ClientTestSuite) ProposeAndInsertEmptyBlocks(
Expand All @@ -43,35 +35,33 @@ func (s *ClientTestSuite) ProposeAndInsertEmptyBlocks(
l1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)

sink := make(chan *bindings.LibProposingBlockProposed)

sub, err := s.RPCClient.LibProposing.WatchBlockProposed(nil, sink, nil, nil)
sink := make(chan *bindings.TaikoL1ClientBlockProposed)
sub, err := s.RPCClient.TaikoL1.WatchBlockProposed(nil, sink, nil, nil)
s.Nil(err)
defer func() {
sub.Unsubscribe()
close(sink)
}()

sink2 := make(chan *bindings.LibProposingBlockProposedV2)

sub2, err := s.RPCClient.LibProposing.WatchBlockProposedV2(nil, sink2, nil)
sink2 := make(chan *bindings.TaikoL1ClientBlockProposedV2)
sub2, err := s.RPCClient.TaikoL1.WatchBlockProposedV2(nil, sink2, nil)
s.Nil(err)
defer func() {
sub2.Unsubscribe()
close(sink2)
}()

// RLP encoded empty list
var emptyTxs []types.Transaction
encoded, err := rlp.EncodeToBytes(emptyTxs)
s.Nil(err)

s.Nil(proposer.ProposeTxList(context.Background(), encoded, 0))
s.Nil(proposer.ProposeTxLists(context.Background(), []types.Transactions{{}}))
s.Nil(blobSyncer.ProcessL1Blocks(context.Background()))

s.ProposeInvalidTxListBytes(proposer)
// Valid transactions lists.
s.ProposeValidBlock(proposer)
s.Nil(blobSyncer.ProcessL1Blocks(context.Background()))

// Random bytes txList
s.proposeEmptyBlockOp(context.Background(), proposer)
s.Nil(blobSyncer.ProcessL1Blocks(context.Background()))

var txHash common.Hash
for i := 0; i < 3; i++ {
Expand All @@ -93,13 +83,6 @@ func (s *ClientTestSuite) ProposeAndInsertEmptyBlocks(
s.Nil(err)
s.Greater(newL1Head.Number.Uint64(), l1Head.Number.Uint64())

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

s.Nil(backoff.Retry(func() error {
return blobSyncer.ProcessL1Blocks(ctx)
}, backoff.NewExponentialBackOff()))

s.Nil(s.RPCClient.WaitTillL2ExecutionEngineSynced(context.Background()))

return metadataList
Expand All @@ -114,39 +97,31 @@ func (s *ClientTestSuite) ProposeAndInsertValidBlock(
l1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)

l2Head, err := s.RPCClient.L2.HeaderByNumber(context.Background(), nil)
s.Nil(err)

// Propose txs in L2 execution engine's mempool
sink := make(chan *bindings.LibProposingBlockProposed)

sub, err := s.RPCClient.LibProposing.WatchBlockProposed(nil, sink, nil, nil)
sink := make(chan *bindings.TaikoL1ClientBlockProposed)
sub, err := s.RPCClient.TaikoL1.WatchBlockProposed(nil, sink, nil, nil)
s.Nil(err)
defer func() {
sub.Unsubscribe()
close(sink)
}()

sink2 := make(chan *bindings.LibProposingBlockProposedV2)
sub2, err := s.RPCClient.LibProposing.WatchBlockProposedV2(nil, sink2, nil)
sink2 := make(chan *bindings.TaikoL1ClientBlockProposedV2)
sub2, err := s.RPCClient.TaikoL1.WatchBlockProposedV2(nil, sink2, nil)
s.Nil(err)

defer func() {
sub.Unsubscribe()
sub2.Unsubscribe()
close(sink)
close(sink2)
}()

baseFeeInfo, err := s.RPCClient.TaikoL2.GetBasefee(nil, l1Head.Number.Uint64()+1, uint32(l2Head.GasUsed))
s.Nil(err)

nonce, err := s.RPCClient.L2.PendingNonceAt(context.Background(), s.TestAddr)
s.Nil(err)

tx := types.NewTransaction(
nonce,
common.BytesToAddress(RandomBytes(32)),
common.Big1,
100000,
new(big.Int).SetUint64(uint64(10*params.GWei)+baseFeeInfo.Basefee.Uint64()),
common.Big0,
100_000,
new(big.Int).SetUint64(uint64(10*params.GWei)),
[]byte{},
)
signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(s.RPCClient.L2.ChainID), s.TestAddrPrivKey)
Expand Down Expand Up @@ -197,24 +172,44 @@ func (s *ClientTestSuite) ProposeAndInsertValidBlock(

func (s *ClientTestSuite) ProposeValidBlock(
proposer Proposer,
) *bindings.LibProposingBlockProposed {
) {
l1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)

l2Head, err := s.RPCClient.L2.HeaderByNumber(context.Background(), nil)
state, err := s.RPCClient.GetProtocolStateVariables(nil)
s.Nil(err)

l2Head, err := s.RPCClient.L2.HeaderByNumber(context.Background(), new(big.Int).SetUint64(state.B.NumBlocks-1))
s.Nil(err)

// Propose txs in L2 execution engine's mempool
sink := make(chan *bindings.LibProposingBlockProposed)
sink := make(chan *bindings.TaikoL1ClientBlockProposed)
sink2 := make(chan *bindings.TaikoL1ClientBlockProposedV2)

sub, err := s.RPCClient.TaikoL1.WatchBlockProposed(nil, sink, nil, nil)
s.Nil(err)

sub, err := s.RPCClient.LibProposing.WatchBlockProposed(nil, sink, nil, nil)
sub2, err := s.RPCClient.TaikoL1.WatchBlockProposedV2(nil, sink2, nil)
s.Nil(err)

defer func() {
sub.Unsubscribe()
sub2.Unsubscribe()
close(sink)
close(sink2)
}()

baseFeeInfo, err := s.RPCClient.TaikoL2.GetBasefee(nil, l1Head.Number.Uint64()+1, uint32(l2Head.GasUsed))
ontakeForkHeight, err := s.RPCClient.TaikoL2.OntakeForkHeight(nil)
s.Nil(err)

baseFee, err := s.RPCClient.CalculateBaseFee(
context.Background(),
l2Head,
l1Head.Number,
l2Head.Number.Uint64()+1 >= ontakeForkHeight,
&encoding.InternlDevnetProtocolConfig.BaseFeeConfig,
l1Head.Time,
)
s.Nil(err)

nonce, err := s.RPCClient.L2.PendingNonceAt(context.Background(), s.TestAddr)
Expand All @@ -223,9 +218,9 @@ func (s *ClientTestSuite) ProposeValidBlock(
tx := types.NewTransaction(
nonce,
common.BytesToAddress(RandomBytes(32)),
common.Big1,
100000,
new(big.Int).SetUint64(uint64(10*params.GWei)+baseFeeInfo.Basefee.Uint64()),
common.Big0,
100_000,
new(big.Int).SetUint64(uint64(10*params.GWei)+baseFee.Uint64()),
[]byte{},
)
signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(s.RPCClient.L2.ChainID), s.TestAddrPrivKey)
Expand All @@ -234,21 +229,25 @@ func (s *ClientTestSuite) ProposeValidBlock(

s.Nil(proposer.ProposeOp(context.Background()))

event := <-sink
var txHash common.Hash
select {
case event := <-sink:
txHash = event.Raw.TxHash
case event := <-sink2:
txHash = event.Raw.TxHash
}

_, isPending, err := s.RPCClient.L1.TransactionByHash(context.Background(), event.Raw.TxHash)
_, isPending, err := s.RPCClient.L1.TransactionByHash(context.Background(), txHash)
s.Nil(err)
s.False(isPending)

receipt, err := s.RPCClient.L1.TransactionReceipt(context.Background(), event.Raw.TxHash)
receipt, err := s.RPCClient.L1.TransactionReceipt(context.Background(), txHash)
s.Nil(err)
s.Equal(types.ReceiptStatusSuccessful, receipt.Status)

newL1Head, err := s.RPCClient.L1.HeaderByNumber(context.Background(), nil)
s.Nil(err)
s.Greater(newL1Head.Number.Uint64(), l1Head.Number.Uint64())

return event
}

// RandomHash generates a random blob of data and returns it as a hash.
Expand Down
Loading

0 comments on commit d0c0fed

Please sign in to comment.