diff --git a/op-enclave/enclave/client.go b/op-enclave/enclave/client.go index dc92d15..0af7eac 100644 --- a/op-enclave/enclave/client.go +++ b/op-enclave/enclave/client.go @@ -50,9 +50,9 @@ func (c *Client) SetSignerKey(ctx context.Context, encrypted hexutil.Bytes) erro return c.callContext(ctx, nil, "setSignerKey", encrypted) } -func (c *Client) ExecuteStateless(ctx context.Context, config *PerChainConfig, l1Origin *types.Header, l1Receipts types.Receipts, previousBlockTxs []hexutil.Bytes, blockHeader *types.Header, blockTxs []hexutil.Bytes, witness *stateless.ExecutionWitness, messageAccount *eth.AccountResult, prevMessageAccountHash common.Hash) (*Proposal, error) { +func (c *Client) ExecuteStateless(ctx context.Context, config *PerChainConfig, l1Origin *types.Header, l1Receipts types.Receipts, previousBlockTxs []hexutil.Bytes, blockHeader *types.Header, sequencedTxs []hexutil.Bytes, witness *stateless.ExecutionWitness, messageAccount *eth.AccountResult, prevMessageAccountHash common.Hash) (*Proposal, error) { var result Proposal - return &result, c.callContext(ctx, &result, "executeStateless", config, l1Origin, l1Receipts, previousBlockTxs, blockHeader, blockTxs, witness, messageAccount, prevMessageAccountHash) + return &result, c.callContext(ctx, &result, "executeStateless", config, l1Origin, l1Receipts, previousBlockTxs, blockHeader, sequencedTxs, witness, messageAccount, prevMessageAccountHash) } func (c *Client) Aggregate(ctx context.Context, configHash common.Hash, prevOutputRoot common.Hash, proposals []*Proposal) (*Proposal, error) { diff --git a/op-enclave/enclave/rpc.go b/op-enclave/enclave/rpc.go index 561bcc8..991d9f5 100644 --- a/op-enclave/enclave/rpc.go +++ b/op-enclave/enclave/rpc.go @@ -26,7 +26,7 @@ type RPC interface { l1Receipts types.Receipts, previousBlockTxs []hexutil.Bytes, blockHeader *types.Header, - blockTxs []hexutil.Bytes, + sequencedTxs []hexutil.Bytes, witness *stateless.ExecutionWitness, messageAccount *eth.AccountResult, prevMessageAccountHash common.Hash, diff --git a/op-enclave/enclave/server.go b/op-enclave/enclave/server.go index 9cc9b27..950307a 100644 --- a/op-enclave/enclave/server.go +++ b/op-enclave/enclave/server.go @@ -243,7 +243,7 @@ func (s *Server) ExecuteStateless( l1Receipts types.Receipts, previousBlockTxs []hexutil.Bytes, blockHeader *types.Header, - blockTxs []hexutil.Bytes, + sequencedTxs []hexutil.Bytes, witness *stateless.ExecutionWitness, messageAccount *eth.AccountResult, prevMessageAccountHash common.Hash, @@ -267,7 +267,7 @@ func (s *Server) ExecuteStateless( previousBlockHeader := w.Headers[0] err = ExecuteStateless(ctx, config.ChainConfig, config.ToRollupConfig(), - l1Origin, l1Receipts, previousBlockTxs, blockHeader, blockTxs, w, messageAccount) + l1Origin, l1Receipts, previousBlockTxs, blockHeader, sequencedTxs, w, messageAccount) if err != nil { return nil, err } diff --git a/op-enclave/enclave/stateless.go b/op-enclave/enclave/stateless.go index aab7e80..a6121f2 100644 --- a/op-enclave/enclave/stateless.go +++ b/op-enclave/enclave/stateless.go @@ -1,7 +1,6 @@ package enclave import ( - "bytes" "context" "errors" "fmt" @@ -26,7 +25,7 @@ func ExecuteStateless( l1Receipts types.Receipts, previousBlockTxs []hexutil.Bytes, blockHeader *types.Header, - blockTxs []hexutil.Bytes, + sequencedTxs []hexutil.Bytes, witness *stateless.Witness, messageAccount *eth.AccountResult, ) error { @@ -42,6 +41,11 @@ func ExecuteStateless( return errors.New("invalid parent hash") } + // block must only contain deposit transactions if it is outside the sequencer drift + if len(sequencedTxs) > 0 && blockHeader.Time > l1Origin.Time+maxSequencerDriftFjord { + return errors.New("l1 origin is too old") + } + unmarshalTxs := func(rlp []hexutil.Bytes) (types.Transactions, error) { txs := make(types.Transactions, len(rlp)) for i, tx := range rlp { @@ -56,10 +60,6 @@ func ExecuteStateless( if err != nil { return err } - txs, err := unmarshalTxs(blockTxs) - if err != nil { - return err - } previousTxHash := types.DeriveSha(previousTxs, trie.NewStackTrie(nil)) if previousTxHash != previousBlockHeader.TxHash { @@ -90,25 +90,23 @@ func ExecuteStateless( return fmt.Errorf("failed to prepare payload attributes: %w", err) } - if txs.Len() < len(payload.Transactions) { - return errors.New("invalid transaction count") + // sequencer cannot include manual deposit transactions; otherwise it could mint funds arbitrarily + txs, err := unmarshalTxs(sequencedTxs) + if err != nil { + return err } - - for i, payloadTx := range payload.Transactions { - tx := txs[i] - if !tx.IsDepositTx() { - return errors.New("invalid transaction type") - } - if !bytes.Equal(blockTxs[i], payloadTx) { - return errors.New("invalid deposit transaction") + for _, tx := range txs { + if tx.IsDepositTx() { + return errors.New("sequenced txs cannot include deposits") } } - // block must only contain deposit transactions if it is outside the sequencer drift - if txs.Len() > len(payload.Transactions) && - blockHeader.Time > l1Origin.Time+maxSequencerDriftFjord { - return errors.New("L1 origin is too old") + // now add the deposits from L1 (and any from fork upgrades) + payloadTxs, err := unmarshalTxs(payload.Transactions) + if err != nil { + return fmt.Errorf("failed to parse payload transactions: %w", err) } + txs = append(payloadTxs, txs...) expectedRoot := blockHeader.Root expectedReceiptHash := blockHeader.ReceiptHash diff --git a/op-proposer/proposer/prover.go b/op-proposer/proposer/prover.go index c4b82f5..5359e35 100644 --- a/op-proposer/proposer/prover.go +++ b/op-proposer/proposer/prover.go @@ -118,21 +118,25 @@ func (o *Prover) Generate(ctx context.Context, block *types.Block) (*Proposal, e return nil, &multierror.Error{Errors: errors} } - marshalTxs := func(txs types.Transactions) ([]hexutil.Bytes, error) { - rlp := make([]hexutil.Bytes, len(txs)) - var err error - for i, tx := range txs { - if rlp[i], err = tx.MarshalBinary(); err != nil { + marshalTxs := func(txs types.Transactions, includeDeposits bool) ([]hexutil.Bytes, error) { + var rlps []hexutil.Bytes + for _, tx := range txs { + if !includeDeposits && tx.IsDepositTx() { + continue + } + rlp, err := tx.MarshalBinary() + if err != nil { return nil, fmt.Errorf("failed to marshal transaction: %w", err) } + rlps = append(rlps, rlp) } - return rlp, nil + return rlps, nil } - previousTxs, err := marshalTxs(previousBlock.value.Transactions()) + previousTxs, err := marshalTxs(previousBlock.value.Transactions(), true) if err != nil { return nil, err } - txs, err := marshalTxs(block.Transactions()) + sequencedTxs, err := marshalTxs(block.Transactions(), false) if err != nil { return nil, err } @@ -144,7 +148,7 @@ func (o *Prover) Generate(ctx context.Context, block *types.Block) (*Proposal, e l1Receipts.value, previousTxs, block.Header(), - txs, + sequencedTxs, witness.value, messageAccount.value, prevMessageAccount.value.StorageHash,