Commit 9d9bbc93 authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

Merge pull request #2011 from tuxcanfly/tux/replica-fwd

l2geth: forward tx to sequencer
parents e67e8508 805a42cd
...@@ -71,5 +71,32 @@ describe('Replica Tests', () => { ...@@ -71,5 +71,32 @@ describe('Replica Tests', () => {
expect(sequencerBlock.stateRoot).to.deep.eq(replicaBlock.stateRoot) expect(sequencerBlock.stateRoot).to.deep.eq(replicaBlock.stateRoot)
expect(sequencerBlock.hash).to.deep.eq(replicaBlock.hash) 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)
})
}) })
}) })
...@@ -163,6 +163,7 @@ var ( ...@@ -163,6 +163,7 @@ var (
utils.RollupEnforceFeesFlag, utils.RollupEnforceFeesFlag,
utils.RollupFeeThresholdDownFlag, utils.RollupFeeThresholdDownFlag,
utils.RollupFeeThresholdUpFlag, utils.RollupFeeThresholdUpFlag,
utils.SequencerClientHttpFlag,
} }
rpcFlags = []cli.Flag{ rpcFlags = []cli.Flag{
......
...@@ -77,6 +77,7 @@ var AppHelpFlagGroups = []flagGroup{ ...@@ -77,6 +77,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.RollupEnforceFeesFlag, utils.RollupEnforceFeesFlag,
utils.RollupFeeThresholdDownFlag, utils.RollupFeeThresholdDownFlag,
utils.RollupFeeThresholdUpFlag, utils.RollupFeeThresholdUpFlag,
utils.SequencerClientHttpFlag,
}, },
}, },
{ {
......
...@@ -861,6 +861,11 @@ var ( ...@@ -861,6 +861,11 @@ var (
Usage: "Allow txs with fees above the current fee up to this amount, must be > 1", Usage: "Allow txs with fees above the current fee up to this amount, must be > 1",
EnvVar: "ROLLUP_FEE_THRESHOLD_UP", 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 // MakeDataDir retrieves the currently requested data directory, terminating
...@@ -1137,6 +1142,9 @@ func setRollup(ctx *cli.Context, cfg *rollup.Config) { ...@@ -1137,6 +1142,9 @@ func setRollup(ctx *cli.Context, cfg *rollup.Config) {
val := ctx.GlobalFloat64(RollupFeeThresholdUpFlag.Name) val := ctx.GlobalFloat64(RollupFeeThresholdUpFlag.Name)
cfg.FeeThresholdUp = new(big.Float).SetFloat64(val) 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. // setLes configures the les server and ultra light client settings from the command line flags.
......
...@@ -136,6 +136,10 @@ func (b *EthAPIBackend) IngestTransactions(txs []*types.Transaction) error { ...@@ -136,6 +136,10 @@ func (b *EthAPIBackend) IngestTransactions(txs []*types.Transaction) error {
return nil 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) { func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
// Pending block is only known by the miner // Pending block is only known by the miner
if number == rpc.PendingBlockNumber { if number == rpc.PendingBlockNumber {
......
...@@ -40,6 +40,7 @@ import ( ...@@ -40,6 +40,7 @@ import (
"github.com/ethereum-optimism/optimism/l2geth/core/types" "github.com/ethereum-optimism/optimism/l2geth/core/types"
"github.com/ethereum-optimism/optimism/l2geth/core/vm" "github.com/ethereum-optimism/optimism/l2geth/core/vm"
"github.com/ethereum-optimism/optimism/l2geth/crypto" "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/log"
"github.com/ethereum-optimism/optimism/l2geth/p2p" "github.com/ethereum-optimism/optimism/l2geth/p2p"
"github.com/ethereum-optimism/optimism/l2geth/params" "github.com/ethereum-optimism/optimism/l2geth/params"
...@@ -51,6 +52,12 @@ import ( ...@@ -51,6 +52,12 @@ import (
var errOVMUnsupported = errors.New("OVM: Unsupported RPC Method") 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. // PublicEthereumAPI provides an API to access Ethereum related information.
// It offers only methods that operate on public data that is freely available to anyone. // It offers only methods that operate on public data that is freely available to anyone.
type PublicEthereumAPI struct { type PublicEthereumAPI struct {
...@@ -1289,6 +1296,18 @@ func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransa ...@@ -1289,6 +1296,18 @@ func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransa
return nil 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 // PublicTransactionPoolAPI exposes methods for the RPC interface
type PublicTransactionPoolAPI struct { type PublicTransactionPoolAPI struct {
b Backend b Backend
...@@ -1649,18 +1668,27 @@ func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args Sen ...@@ -1649,18 +1668,27 @@ func (s *PublicTransactionPoolAPI) FillTransaction(ctx context.Context, args Sen
// SendRawTransaction will add the signed transaction to the transaction pool. // SendRawTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce. // 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) { func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) {
if s.b.IsVerifier() { tx := new(types.Transaction)
return common.Hash{}, errors.New("Cannot send raw transaction in verifier mode") if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err
} }
if s.b.IsSyncing() { if s.b.IsSyncing() {
return common.Hash{}, errors.New("Cannot send raw transaction while syncing") return common.Hash{}, errors.New("Cannot send raw transaction while syncing")
} }
tx := new(types.Transaction) if s.b.IsVerifier() {
if err := rlp.DecodeBytes(encodedTx, tx); err != nil { client, err := dialSequencerClientWithTimeout(ctx, s.b.SequencerClientHttp())
return common.Hash{}, err 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 // L1Timestamp and L1BlockNumber will be set right before execution
txMeta := types.NewTransactionMeta(nil, 0, nil, types.QueueOriginSequencer, nil, nil, encodedTx) txMeta := types.NewTransactionMeta(nil, 0, nil, types.QueueOriginSequencer, nil, nil, encodedTx)
tx.SetTransactionMeta(txMeta) tx.SetTransactionMeta(txMeta)
......
...@@ -96,6 +96,7 @@ type Backend interface { ...@@ -96,6 +96,7 @@ type Backend interface {
SuggestL2GasPrice(context.Context) (*big.Int, error) SuggestL2GasPrice(context.Context) (*big.Int, error)
SetL2GasPrice(context.Context, *big.Int) error SetL2GasPrice(context.Context, *big.Int) error
IngestTransactions([]*types.Transaction) error IngestTransactions([]*types.Transaction) error
SequencerClientHttp() string
} }
func GetAPIs(apiBackend Backend) []rpc.API { func GetAPIs(apiBackend Backend) []rpc.API {
......
...@@ -86,6 +86,10 @@ func (b *LesApiBackend) IngestTransactions([]*types.Transaction) error { ...@@ -86,6 +86,10 @@ func (b *LesApiBackend) IngestTransactions([]*types.Transaction) error {
panic("not implemented") 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) { func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {
if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber { if number == rpc.LatestBlockNumber || number == rpc.PendingBlockNumber {
return b.eth.blockchain.CurrentHeader(), nil return b.eth.blockchain.CurrentHeader(), nil
......
...@@ -37,4 +37,6 @@ type Config struct { ...@@ -37,4 +37,6 @@ type Config struct {
// quoted and the transaction being executed // quoted and the transaction being executed
FeeThresholdDown *big.Float FeeThresholdDown *big.Float
FeeThresholdUp *big.Float FeeThresholdUp *big.Float
// HTTP endpoint of the sequencer
SequencerClientHttp string
} }
...@@ -159,6 +159,7 @@ services: ...@@ -159,6 +159,7 @@ services:
replica: replica:
depends_on: depends_on:
- dtl - dtl
- l2geth
deploy: deploy:
replicas: 1 replicas: 1
build: build:
...@@ -169,6 +170,7 @@ services: ...@@ -169,6 +170,7 @@ services:
- ./envs/geth.env - ./envs/geth.env
environment: environment:
ETH1_HTTP: http://l1_chain:8545 ETH1_HTTP: http://l1_chain:8545
SEQUENCER_CLIENT_HTTP: http://l2geth:8545
ROLLUP_STATE_DUMP_PATH: http://deployer:8081/state-dump.latest.json ROLLUP_STATE_DUMP_PATH: http://deployer:8081/state-dump.latest.json
ROLLUP_CLIENT_HTTP: http://dtl:7878 ROLLUP_CLIENT_HTTP: http://dtl:7878
ROLLUP_BACKEND: 'l2' ROLLUP_BACKEND: 'l2'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment