Skip to content
This repository has been archived by the owner on May 11, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into integrate-anchor-circuits
Browse files Browse the repository at this point in the history
  • Loading branch information
davidtaikocha authored Jul 23, 2023
2 parents aea72aa + b292754 commit 7a17f22
Show file tree
Hide file tree
Showing 10 changed files with 381 additions and 54 deletions.
15 changes: 15 additions & 0 deletions cmd/flags/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ var (
Usage: "Comma separated accounts to treat as locals (priority inclusion)",
Category: proposerCategory,
}
TxPoolLocalsOnly = &cli.BoolFlag{
Name: "txpool.localsOnly",
Usage: "If set to true, proposer will only propose transactions of local accounts",
Value: false,
Category: proposerCategory,
}
ProposeEmptyBlocksInterval = &cli.StringFlag{
Name: "proposeEmptyBlockInterval",
Usage: "Time interval to propose empty blocks",
Expand All @@ -57,6 +63,13 @@ var (
}
ProposeBlockTxGasLimit = &cli.Uint64Flag{
Name: "proposeBlockTxGasLimit",
Usage: "Gas limit will be used for TaikoL1.proposeBlock transactions",
Category: proposerCategory,
}
ProposeBlockTxReplacementMultiplier = &cli.Uint64Flag{
Name: "proposeBlockTxReplacementMultiplier",
Value: 2,
Usage: "Gas tip multiplier when replacing a TaikoL1.proposeBlock transaction with same nonce",
Category: proposerCategory,
}
)
Expand All @@ -69,8 +82,10 @@ var ProposerFlags = MergeFlags(CommonFlags, []cli.Flag{
ProposeInterval,
CommitSlot,
TxPoolLocals,
TxPoolLocalsOnly,
ProposeEmptyBlocksInterval,
MinBlockGasLimit,
MaxProposedTxListsPerEpoch,
ProposeBlockTxGasLimit,
ProposeBlockTxReplacementMultiplier,
})
21 changes: 20 additions & 1 deletion driver/chain_syncer/calldata/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,29 @@ func (s *Syncer) ProcessL1Blocks(ctx context.Context, l1End *types.Header) error
s.reorgDetectedFlag = false
firstTry = false

startHeight := s.state.GetL1Current().Number
// If there is a L1 reorg, sometimes this will happen.
if startHeight.Uint64() >= l1End.Number.Uint64() {
startHeight = new(big.Int).Sub(l1End.Number, common.Big1)
newL1Current, err := s.rpc.L1.HeaderByNumber(ctx, startHeight)
if err != nil {
return err
}
s.state.SetL1Current(newL1Current)
s.lastInsertedBlockID = nil

log.Info(
"Reorg detected",
"oldL1Current", s.state.GetL1Current().Number,
"newL1Current", startHeight,
"l1Head", l1End.Number,
)
}

iter, err := eventIterator.NewBlockProposedIterator(ctx, &eventIterator.BlockProposedIteratorConfig{
Client: s.rpc.L1,
TaikoL1: s.rpc.TaikoL1,
StartHeight: s.state.GetL1Current().Number,
StartHeight: startHeight,
EndHeight: l1End.Number,
FilterQuery: nil,
OnBlockProposedEvent: s.onBlockProposed,
Expand Down
47 changes: 44 additions & 3 deletions pkg/rpc/methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,33 @@ func (c *Client) CheckL1Reorg(ctx context.Context, blockID *big.Int) (bool, *typ

l1Origin, err := c.L2.L1OriginByID(ctx, blockID)
if err != nil {
// If the L2 EE is just synced through P2P, there is a chance that the EE do not have
// the chain head L1Origin information recorded.
if err.Error() == ethereum.NotFound.Error() {
log.Info("L1Origin not found", "blockID", blockID)
return false, nil, nil, nil

// If the L2 EE is just synced through P2P, there is a chance that the EE do not have
// the chain head L1Origin information recorded.
justSyncedByP2P, err := c.IsJustSyncedByP2P(ctx)
if err != nil {
return false,
nil,
nil,
fmt.Errorf("failed to check whether the L2 execution engine has just finished a P2P sync: %w", err)
}

log.Info(
"Check whether the L2 execution engine has just finished a P2P sync",
"justSyncedByP2P",
justSyncedByP2P,
)

if justSyncedByP2P {
return false, nil, nil, nil
}

log.Info("Reorg detected due to L1Origin not found", "blockID", blockID)
reorged = true
blockID = new(big.Int).Sub(blockID, common.Big1)
continue
}
return false, nil, nil, err
}
Expand Down Expand Up @@ -401,3 +423,22 @@ func (c *Client) CheckL1Reorg(ctx context.Context, blockID *big.Int) (bool, *typ

return reorged, l1CurrentToReset, blockIDToReset, nil
}

// IsJustSyncedByP2P checks whether the given L2 execution engine has just finished a P2P
// sync.
func (c *Client) IsJustSyncedByP2P(ctx context.Context) (bool, error) {
l2Head, err := c.L2.HeaderByNumber(ctx, nil)
if err != nil {
return false, err
}

if _, err = c.L2.L1OriginByID(ctx, l2Head.Number); err != nil {
if err.Error() == ethereum.NotFound.Error() {
return true, nil
}

return false, err
}

return false, nil
}
41 changes: 41 additions & 0 deletions pkg/rpc/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"math/big"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -119,6 +120,46 @@ func NeedNewProof(
return false, nil
}

type AccountPoolContent map[string]map[string]*types.Transaction

// ContentFrom fetches a given account's transactions list from a node's transactions pool.
func ContentFrom(
ctx context.Context,
rawRPC *rpc.Client,
address common.Address,
) (AccountPoolContent, error) {
var result AccountPoolContent
return result, rawRPC.CallContext(
ctx,
&result,
"txpool_contentFrom",
address,
)
}

// GetPendingTxByNonce tries to retrieve a pending transaction with a given nonce in a node's mempool.
func GetPendingTxByNonce(
ctx context.Context,
cli *Client,
address common.Address,
nonce uint64,
) (*types.Transaction, error) {
content, err := ContentFrom(ctx, cli.L1RawRPC, address)
if err != nil {
return nil, err
}

for _, txMap := range content {
for txNonce, tx := range txMap {
if txNonce == strconv.Itoa(int(nonce)) {
return tx, nil
}
}
}

return nil, nil
}

// SetHead makes a `debug_setHead` RPC call to set the chain's head, should only be used
// for testing purpose.
func SetHead(ctx context.Context, rpc *rpc.Client, headNum *big.Int) error {
Expand Down
38 changes: 38 additions & 0 deletions pkg/rpc/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package rpc

import (
"context"
"os"
"strconv"
"testing"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
)

Expand All @@ -31,3 +34,38 @@ func TestStringToBytes32(t *testing.T) {
require.Equal(t, [32]byte{}, StringToBytes32(""))
require.Equal(t, [32]byte{0x61, 0x62, 0x63}, StringToBytes32("abc"))
}

func TestL1ContentFrom(t *testing.T) {
client := newTestClient(t)
l2Head, err := client.L2.HeaderByNumber(context.Background(), nil)
require.Nil(t, err)

baseFee, err := client.TaikoL2.GetBasefee(nil, 0, 60000000, uint32(l2Head.GasUsed))
require.Nil(t, err)

testAddrPrivKey, err := crypto.ToECDSA(common.Hex2Bytes(os.Getenv("L1_PROPOSER_PRIVATE_KEY")))
require.Nil(t, err)

testAddr := crypto.PubkeyToAddress(testAddrPrivKey.PublicKey)

nonce, err := client.L2.PendingNonceAt(context.Background(), testAddr)
require.Nil(t, err)

tx := types.NewTransaction(
nonce,
testAddr,
common.Big1,
100000,
baseFee,
[]byte{},
)
signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(client.L2ChainID), testAddrPrivKey)
require.Nil(t, err)
require.Nil(t, client.L2.SendTransaction(context.Background(), signedTx))

content, err := ContentFrom(context.Background(), client.L2RawRPC, testAddr)
require.Nil(t, err)

require.NotZero(t, len(content["pending"]))
require.Equal(t, signedTx.Nonce(), content["pending"][strconv.Itoa(int(signedTx.Nonce()))].Nonce())
}
68 changes: 40 additions & 28 deletions proposer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@ import (

// Config contains all configurations to initialize a Taiko proposer.
type Config struct {
L1Endpoint string
L2Endpoint string
TaikoL1Address common.Address
TaikoL2Address common.Address
L1ProposerPrivKey *ecdsa.PrivateKey
L2SuggestedFeeRecipient common.Address
ProposeInterval *time.Duration
CommitSlot uint64
LocalAddresses []common.Address
ProposeEmptyBlocksInterval *time.Duration
MinBlockGasLimit uint64
MaxProposedTxListsPerEpoch uint64
ProposeBlockTxGasLimit *uint64
BackOffRetryInterval time.Duration
L1Endpoint string
L2Endpoint string
TaikoL1Address common.Address
TaikoL2Address common.Address
L1ProposerPrivKey *ecdsa.PrivateKey
L2SuggestedFeeRecipient common.Address
ProposeInterval *time.Duration
CommitSlot uint64
LocalAddresses []common.Address
LocalAddressesOnly bool
ProposeEmptyBlocksInterval *time.Duration
MinBlockGasLimit uint64
MaxProposedTxListsPerEpoch uint64
ProposeBlockTxGasLimit *uint64
BackOffRetryInterval time.Duration
ProposeBlockTxReplacementMultiplier uint64
}

// NewConfigFromCliContext initializes a Config instance from
Expand Down Expand Up @@ -80,20 +82,30 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) {
proposeBlockTxGasLimit = &gasLimit
}

proposeBlockTxReplacementMultiplier := c.Uint64(flags.ProposeBlockTxReplacementMultiplier.Name)
if proposeBlockTxReplacementMultiplier == 0 {
return nil, fmt.Errorf(
"invalid --proposeBlockTxReplacementMultiplier value: %d",
proposeBlockTxReplacementMultiplier,
)
}

return &Config{
L1Endpoint: c.String(flags.L1WSEndpoint.Name),
L2Endpoint: c.String(flags.L2HTTPEndpoint.Name),
TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)),
TaikoL2Address: common.HexToAddress(c.String(flags.TaikoL2Address.Name)),
L1ProposerPrivKey: l1ProposerPrivKey,
L2SuggestedFeeRecipient: common.HexToAddress(l2SuggestedFeeRecipient),
ProposeInterval: proposingInterval,
CommitSlot: c.Uint64(flags.CommitSlot.Name),
LocalAddresses: localAddresses,
ProposeEmptyBlocksInterval: proposeEmptyBlocksInterval,
MinBlockGasLimit: c.Uint64(flags.MinBlockGasLimit.Name),
MaxProposedTxListsPerEpoch: c.Uint64(flags.MaxProposedTxListsPerEpoch.Name),
ProposeBlockTxGasLimit: proposeBlockTxGasLimit,
BackOffRetryInterval: time.Duration(c.Uint64(flags.BackOffRetryInterval.Name)) * time.Second,
L1Endpoint: c.String(flags.L1WSEndpoint.Name),
L2Endpoint: c.String(flags.L2HTTPEndpoint.Name),
TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)),
TaikoL2Address: common.HexToAddress(c.String(flags.TaikoL2Address.Name)),
L1ProposerPrivKey: l1ProposerPrivKey,
L2SuggestedFeeRecipient: common.HexToAddress(l2SuggestedFeeRecipient),
ProposeInterval: proposingInterval,
CommitSlot: c.Uint64(flags.CommitSlot.Name),
LocalAddresses: localAddresses,
LocalAddressesOnly: c.Bool(flags.TxPoolLocalsOnly.Name),
ProposeEmptyBlocksInterval: proposeEmptyBlocksInterval,
MinBlockGasLimit: c.Uint64(flags.MinBlockGasLimit.Name),
MaxProposedTxListsPerEpoch: c.Uint64(flags.MaxProposedTxListsPerEpoch.Name),
ProposeBlockTxGasLimit: proposeBlockTxGasLimit,
BackOffRetryInterval: time.Duration(c.Uint64(flags.BackOffRetryInterval.Name)) * time.Second,
ProposeBlockTxReplacementMultiplier: proposeBlockTxReplacementMultiplier,
}, nil
}
3 changes: 3 additions & 0 deletions proposer/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() {
&cli.StringFlag{Name: flags.ProposeInterval.Name},
&cli.Uint64Flag{Name: flags.CommitSlot.Name},
&cli.StringFlag{Name: flags.TxPoolLocals.Name},
&cli.Uint64Flag{Name: flags.ProposeBlockTxReplacementMultiplier.Name},
}
app.Action = func(ctx *cli.Context) error {
c, err := NewConfigFromCliContext(ctx)
Expand All @@ -50,6 +51,7 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() {
s.Equal(uint64(commitSlot), c.CommitSlot)
s.Equal(1, len(c.LocalAddresses))
s.Equal(goldenTouchAddress, c.LocalAddresses[0])
s.Equal(uint64(5), c.ProposeBlockTxReplacementMultiplier)
s.Nil(new(Proposer).InitFromCli(context.Background(), ctx))

return err
Expand All @@ -66,5 +68,6 @@ func (s *ProposerTestSuite) TestNewConfigFromCliContext() {
"-" + flags.ProposeInterval.Name, proposeInterval,
"-" + flags.CommitSlot.Name, strconv.Itoa(commitSlot),
"-" + flags.TxPoolLocals.Name, goldenTouchAddress.Hex(),
"-" + flags.ProposeBlockTxReplacementMultiplier.Name, "5",
}))
}
Loading

0 comments on commit 7a17f22

Please sign in to comment.