Skip to content
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
27 changes: 27 additions & 0 deletions integration-tests/test/replica.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,32 @@ describe('Replica Tests', () => {
expect(sequencerBlock.stateRoot).to.deep.eq(replicaBlock.stateRoot)
expect(sequencerBlock.hash).to.deep.eq(replicaBlock.hash)
})

it('should forward tx to sequencer', async () => {
const tx = {
...defaultTransactionFactory(),
nonce: await env.l2Wallet.getTransactionCount(),
gasPrice: await gasPriceForL2(env),
}
const signed = await env.l2Wallet.signTransaction(tx)
const result = await env.replicaProvider.sendTransaction(signed)

let receipt: TransactionReceipt
while (!receipt) {
receipt = await env.replicaProvider.getTransactionReceipt(result.hash)
await sleep(200)
}

const sequencerBlock = (await env.l2Provider.getBlock(
result.blockNumber
)) as any

const replicaBlock = (await env.replicaProvider.getBlock(
result.blockNumber
)) as any

expect(sequencerBlock.stateRoot).to.deep.eq(replicaBlock.stateRoot)
expect(sequencerBlock.hash).to.deep.eq(replicaBlock.hash)
})
})
})
1 change: 1 addition & 0 deletions l2geth/cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ var (
utils.RollupEnforceFeesFlag,
utils.RollupFeeThresholdDownFlag,
utils.RollupFeeThresholdUpFlag,
utils.SequencerClientHttpFlag,
}

rpcFlags = []cli.Flag{
Expand Down
1 change: 1 addition & 0 deletions l2geth/cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.RollupEnforceFeesFlag,
utils.RollupFeeThresholdDownFlag,
utils.RollupFeeThresholdUpFlag,
utils.SequencerClientHttpFlag,
},
},
{
Expand Down
8 changes: 8 additions & 0 deletions l2geth/cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -861,6 +861,11 @@ var (
Usage: "Allow txs with fees above the current fee up to this amount, must be > 1",
EnvVar: "ROLLUP_FEE_THRESHOLD_UP",
}
SequencerClientHttpFlag = cli.StringFlag{
Name: "sequencer.clienthttp",
Usage: "HTTP endpoint for the sequencer client",
EnvVar: "SEQUENCER_CLIENT_HTTP",
}
)

// MakeDataDir retrieves the currently requested data directory, terminating
Expand Down Expand Up @@ -1137,6 +1142,9 @@ func setRollup(ctx *cli.Context, cfg *rollup.Config) {
val := ctx.GlobalFloat64(RollupFeeThresholdUpFlag.Name)
cfg.FeeThresholdUp = new(big.Float).SetFloat64(val)
}
if ctx.GlobalIsSet(SequencerClientHttpFlag.Name) {
cfg.SequencerClientHttp = ctx.GlobalString(SequencerClientHttpFlag.Name)
}
}

// setLes configures the les server and ultra light client settings from the command line flags.
Expand Down
4 changes: 4 additions & 0 deletions l2geth/eth/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ func (b *EthAPIBackend) IngestTransactions(txs []*types.Transaction) error {
return nil
}

func (b *EthAPIBackend) SequencerClientHttp() string {
return b.eth.config.Rollup.SequencerClientHttp
}

func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
// Pending block is only known by the miner
if number == rpc.PendingBlockNumber {
Expand Down
38 changes: 33 additions & 5 deletions l2geth/internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"github.com/ethereum-optimism/optimism/l2geth/core/types"
"github.com/ethereum-optimism/optimism/l2geth/core/vm"
"github.com/ethereum-optimism/optimism/l2geth/crypto"
"github.com/ethereum-optimism/optimism/l2geth/ethclient"
"github.com/ethereum-optimism/optimism/l2geth/log"
"github.com/ethereum-optimism/optimism/l2geth/p2p"
"github.com/ethereum-optimism/optimism/l2geth/params"
Expand All @@ -51,6 +52,12 @@ import (

var errOVMUnsupported = errors.New("OVM: Unsupported RPC Method")

const (
// defaultDialTimeout is default duration the service will wait on
// startup to make a connection to either the L1 or L2 backends.
defaultDialTimeout = 5 * time.Second
)

// PublicEthereumAPI provides an API to access Ethereum related information.
// It offers only methods that operate on public data that is freely available to anyone.
type PublicEthereumAPI struct {
Expand Down Expand Up @@ -1289,6 +1296,18 @@ func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransa
return nil
}

// dialSequencerClientWithTimeout attempts to dial the Sequencer using the
// provided URL. If the dial doesn't complete within defaultDialTimeout
// seconds, this method will return an error.
func dialSequencerClientWithTimeout(ctx context.Context, url string) (
*ethclient.Client, error) {

ctxt, cancel := context.WithTimeout(ctx, defaultDialTimeout)
defer cancel()

return ethclient.DialContext(ctxt, url)
}

// PublicTransactionPoolAPI exposes methods for the RPC interface
type PublicTransactionPoolAPI struct {
b Backend
Expand Down Expand Up @@ -1649,18 +1668,27 @@ func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args Sen
// SendRawTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) {
if s.b.IsVerifier() {
return common.Hash{}, errors.New("Cannot send raw transaction in verifier mode")
tx := new(types.Transaction)
if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err
}

if s.b.IsSyncing() {
return common.Hash{}, errors.New("Cannot send raw transaction while syncing")
}

tx := new(types.Transaction)
if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err
if s.b.IsVerifier() {
client, err := dialSequencerClientWithTimeout(ctx, s.b.SequencerClientHttp())
if err != nil {
return common.Hash{}, err
}
err = client.SendTransaction(context.Background(), tx)
if err != nil {
return common.Hash{}, err
}
return tx.Hash(), nil
}

// L1Timestamp and L1BlockNumber will be set right before execution
txMeta := types.NewTransactionMeta(nil, 0, nil, types.QueueOriginSequencer, nil, nil, encodedTx)
tx.SetTransactionMeta(txMeta)
Expand Down
1 change: 1 addition & 0 deletions l2geth/internal/ethapi/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ type Backend interface {
SuggestL2GasPrice(context.Context) (*big.Int, error)
SetL2GasPrice(context.Context, *big.Int) error
IngestTransactions([]*types.Transaction) error
SequencerClientHttp() string
}

func GetAPIs(apiBackend Backend) []rpc.API {
Expand Down
4 changes: 4 additions & 0 deletions l2geth/les/api_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ func (b *LesApiBackend) IngestTransactions([]*types.Transaction) error {
panic("not implemented")
}

func (b *LesApiBackend) SequencerClientHttp() string {
return b.eth.config.Rollup.SequencerClientHttp
}

func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber {
return b.eth.blockchain.CurrentHeader(), nil
Expand Down
2 changes: 2 additions & 0 deletions l2geth/rollup/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ type Config struct {
// quoted and the transaction being executed
FeeThresholdDown *big.Float
FeeThresholdUp *big.Float
// HTTP endpoint of the sequencer
SequencerClientHttp string
}
2 changes: 2 additions & 0 deletions ops/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ services:
replica:
depends_on:
- dtl
- l2geth
deploy:
replicas: 1
build:
Expand All @@ -165,6 +166,7 @@ services:
- ./envs/geth.env
environment:
ETH1_HTTP: http://l1_chain:8545
SEQUENCER_CLIENT_HTTP: http://l2geth:8545
ROLLUP_STATE_DUMP_PATH: http://deployer:8081/state-dump.latest.json
ROLLUP_CLIENT_HTTP: http://dtl:7878
ROLLUP_BACKEND: 'l2'
Expand Down