• protolambda's avatar
    op-node: SystemConfig in derivation (#3787) · 0b40e612
    protolambda authored
    * op-node: SystemConfig in derivation
    
    * op-node: reduce sys config test boilerplate
    
    * op-node: more readable loop to find L2 block with L1 origin we look for
    
    * op-node: change test addresses to not confuse with predeploys
    
    * op-node: system config field doc comments
    
    * op-node: fix lint
    
    * contracts-bedrock: Sys config contract and L2 contract updates (#3788)
    
    * contracts-bedrock: SystemConfig contract and L2 contract updates
    Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
    
    * contracts-bedrock: SystemConfig/L1Block batcherHash typing
    
    * contracts-bedrock: test updates for SystemConfig/L1Block type changes
    
    * contracts-bedrock: initialize SystemConfig
    
    * contracts-bedrock: batcher hash initialize arg
    
    * contracts-bedrock: all mutable sys config fields now initialize
    
    * contracts-bedrock: update gas-snapshot
    
    * contracts-bedrock: rename deployment system config
    
    Prevent name collisions between contracts
    
    * contracts-bedrock: regenerate storage layout
    
    * contracts-bedrock: lint
    
    * op-bindings: regenerate
    
    * op-node: fix test build
    
    * op-chain-ops: remove dead storage config
    
    * tests: fixup
    
    * tests: fix build
    
    * op-bindings,op-chain-ops,op-node: System config bindings and integration (#3789)
    
    * op-chain-ops,op-bindings,op-node: integrate system config
    
    * op-e2e: system config action tests (#3790)
    
    * op-e2e: system config action tests
    
    * op-e2e: decimals separator formatting fix
    Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
    
    * bindings
    
    * contracts-bedrock: update gas snapshot
    
    * contracts-bedrock: sys config owner address in hardhat
    
    * op-e2e: remove temporary function usage stubs
    
    * op-e2e: add action test descriptions for batcher key and gpo updates
    
    * op-node: fix fuzzing test, batcher hash must be padded
    
    * reset go.work
    
    * update go mod/sum
    
    * remove dead import
    
    * remove more dead config
    Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
    Co-authored-by: default avatarMatthew Slipper <me@matthewslipper.com>
    0b40e612
attributes_queue.go 2.97 KB
package derive

import (
	"context"
	"fmt"
	"io"
	"time"

	"github.com/ethereum/go-ethereum/log"

	"github.com/ethereum-optimism/optimism/op-node/eth"
	"github.com/ethereum-optimism/optimism/op-node/rollup"
)

// The attributes queue sits in between the batch queue and the engine queue
// It transforms batches into payload attributes. The outputted payload
// attributes cannot be buffered because each batch->attributes transformation
// pulls in data about the current L2 safe head.
//
// It also buffers batches that have been output because multiple batches can
// be created at once.
//
// This stage can be reset by clearing it's batch buffer.
// This stage does not need to retain any references to L1 blocks.

type AttributesQueue struct {
	log    log.Logger
	config *rollup.Config
	dl     L1ReceiptsFetcher
	eng    SystemConfigL2Fetcher
	prev   *BatchQueue
	batch  *BatchData
}

func NewAttributesQueue(log log.Logger, cfg *rollup.Config, l1Fetcher L1ReceiptsFetcher, eng SystemConfigL2Fetcher, prev *BatchQueue) *AttributesQueue {
	return &AttributesQueue{
		log:    log,
		config: cfg,
		dl:     l1Fetcher,
		eng:    eng,
		prev:   prev,
	}
}

func (aq *AttributesQueue) Origin() eth.L1BlockRef {
	return aq.prev.Origin()
}

func (aq *AttributesQueue) NextAttributes(ctx context.Context, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) {
	// Get a batch if we need it
	if aq.batch == nil {
		batch, err := aq.prev.NextBatch(ctx, l2SafeHead)
		if err != nil {
			return nil, err
		}
		aq.batch = batch
	}

	// Actually generate the next attributes
	if attrs, err := aq.createNextAttributes(ctx, aq.batch, l2SafeHead); err != nil {
		return nil, err
	} else {
		// Clear out the local state once we will succeed
		aq.batch = nil
		return attrs, nil
	}

}

// createNextAttributes transforms a batch into a payload attributes. This sets `NoTxPool` and appends the batched transactions
// to the attributes transaction list
func (aq *AttributesQueue) createNextAttributes(ctx context.Context, batch *BatchData, l2SafeHead eth.L2BlockRef) (*eth.PayloadAttributes, error) {
	// sanity check parent hash
	if batch.ParentHash != l2SafeHead.Hash {
		return nil, NewResetError(fmt.Errorf("valid batch has bad parent hash %s, expected %s", batch.ParentHash, l2SafeHead.Hash))
	}
	fetchCtx, cancel := context.WithTimeout(ctx, 20*time.Second)
	defer cancel()
	attrs, err := PreparePayloadAttributes(fetchCtx, aq.config, aq.dl, aq.eng, l2SafeHead, batch.Timestamp, batch.Epoch())
	if err != nil {
		return nil, err
	}

	// we are verifying, not sequencing, we've got all transactions and do not pull from the tx-pool
	// (that would make the block derivation non-deterministic)
	attrs.NoTxPool = true
	attrs.Transactions = append(attrs.Transactions, batch.Transactions...)

	aq.log.Info("generated attributes in payload queue", "txs", len(attrs.Transactions), "timestamp", batch.Timestamp)

	return attrs, nil
}

func (aq *AttributesQueue) Reset(ctx context.Context, _ eth.L1BlockRef, _ eth.SystemConfig) error {
	return io.EOF
}