Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(taiko-client): support TaikoL1.proposeBlocksV2 #18116

Merged
merged 15 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading