Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mtgnoah committed Dec 18, 2023
1 parent c50337a commit 4b736c1
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 39 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Build Docker
on:
push:
branches:
- main
- testfix
- release-*
tags:
# YYYYMMDD
- "20[0-9][0-9][0-1][0-9][0-3][0-9]*"
schedule:
- cron: "0 0 * * 1"
pull_request:
workflow_dispatch:

jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Setup Docker BuildKit (buildx)
uses: docker/setup-buildx-action@v2

- name: Login to Github Container Repo
uses: docker/login-action@v2
if: github.event_name != 'pull_request'
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Generate op-geth docker metadata
uses: docker/metadata-action@v4
id: op-geth
with:
images: ghcr.io/anomalyfi/op-integration/op-geth

- name: Build and push op-geth docker
uses: docker/build-push-action@v4
with:
context: ./
file: Dockerfile
platforms: linux/amd64,arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.op-geth.outputs.tags }}
labels: ${{ steps.op-geth.outputs.labels }}
6 changes: 6 additions & 0 deletions beacon/engine/gen_blockparams.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions beacon/engine/gen_ed.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 23 additions & 18 deletions beacon/engine/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ type PayloadAttributes struct {
// NoTxPool is a field for rollups: if true, the no transactions are taken out of the tx-pool,
// only transactions from the above Transactions list will be included.
NoTxPool bool `json:"noTxPool,omitempty" gencodec:"optional"`
// NodeKit indicates whether NodeKit mode is enabled. If so, invalid transactions will be
// silently rejected, instead of causing the whole block to fail.
NodeKit bool `json:"nodekit,omitempty" gencodec:"optional"`
// GasLimit is a field for rollups: if set, this sets the exact gas limit the block produced with.
GasLimit *uint64 `json:"gasLimit,omitempty" gencodec:"optional"`
}
Expand All @@ -58,23 +61,24 @@ type payloadAttributesMarshaling struct {

// ExecutableData is the data necessary to execute an EL payload.
type ExecutableData struct {
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number uint64 `json:"blockNumber" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Timestamp uint64 `json:"timestamp" gencodec:"required"`
ExtraData []byte `json:"extraData" gencodec:"required"`
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions [][]byte `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
BlobGasUsed *uint64 `json:"blobGasUsed"`
ExcessBlobGas *uint64 `json:"excessBlobGas"`
ParentHash common.Hash `json:"parentHash" gencodec:"required"`
FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"`
StateRoot common.Hash `json:"stateRoot" gencodec:"required"`
ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"`
LogsBloom []byte `json:"logsBloom" gencodec:"required"`
Random common.Hash `json:"prevRandao" gencodec:"required"`
Number uint64 `json:"blockNumber" gencodec:"required"`
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
Timestamp uint64 `json:"timestamp" gencodec:"required"`
ExtraData []byte `json:"extraData" gencodec:"required"`
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions [][]byte `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
Rejected []types.RejectedTransaction `json:"rejected" gencodec:"optional"`
BlobGasUsed *uint64 `json:"blobGasUsed"`
ExcessBlobGas *uint64 `json:"excessBlobGas"`
}

// JSON type overrides for executableData.
Expand Down Expand Up @@ -240,7 +244,7 @@ func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash,
BlobGasUsed: params.BlobGasUsed,
ParentBeaconRoot: beaconRoot,
}
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals)
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals).WithRejected(params.Rejected)
if block.Hash() != params.BlockHash {
return nil, fmt.Errorf("blockhash mismatch, want %x, got %x", params.BlockHash, block.Hash())
}
Expand All @@ -266,6 +270,7 @@ func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.
Random: block.MixDigest(),
ExtraData: block.Extra(),
Withdrawals: block.Withdrawals(),
Rejected: block.Rejected(),
BlobGasUsed: block.BlobGasUsed(),
ExcessBlobGas: block.ExcessBlobGas(),
}
Expand Down
6 changes: 3 additions & 3 deletions consensus/beacon/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,9 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.

// FinalizeAndAssemble implements consensus.Engine, setting the final state and
// assembling the block.
func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal, rejected []types.RejectedTransaction) (*types.Block, error) {
if !beacon.IsPoSHeader(header) {
return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, nil)
return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, nil, rejected)
}
shanghai := chain.Config().IsShanghai(header.Number, header.Time)
if shanghai {
Expand All @@ -386,7 +386,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
header.Root = state.IntermediateRoot(true)

// Assemble and return the final block.
return types.NewBlockWithWithdrawals(header, txs, uncles, receipts, withdrawals, trie.NewStackTrie(nil)), nil
return types.NewBlockWithWithdrawals(header, txs, uncles, receipts, withdrawals, trie.NewStackTrie(nil)).WithRejected(rejected), nil
}

// Seal generates a new sealing request for the given input block and pushes
Expand Down
4 changes: 2 additions & 2 deletions consensus/clique/clique.go
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Heade

// FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set,
// nor block rewards given, and returns the final block.
func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal, rejected []types.RejectedTransaction) (*types.Block, error) {
if len(withdrawals) > 0 {
return nil, errors.New("clique does not support withdrawals")
}
Expand All @@ -584,7 +584,7 @@ func (c *Clique) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))

// Assemble and return the final block for sealing.
return types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)), nil
return types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)).WithRejected(rejected), nil
}

// Authorize injects a private key into the consensus engine to mint new blocks
Expand Down
2 changes: 1 addition & 1 deletion consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type Engine interface {
// Note: The block header and state database might be updated to reflect any
// consensus rules that happen at finalization (e.g. block rewards).
FinalizeAndAssemble(chain ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error)
uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal, rejected []types.RejectedTransaction) (*types.Block, error)

// Seal generates a new sealing request for the given input block and pushes
// the result into the given channel.
Expand Down
4 changes: 2 additions & 2 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.

// FinalizeAndAssemble implements consensus.Engine, accumulating the block and
// uncle rewards, setting the final state and assembling the block.
func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal) (*types.Block, error) {
func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, withdrawals []*types.Withdrawal, rejected []types.RejectedTransaction) (*types.Block, error) {
if len(withdrawals) > 0 {
return nil, errors.New("ethash does not support withdrawals")
}
Expand All @@ -505,7 +505,7 @@ func (ethash *Ethash) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))

// Header seems complete, assemble into a block and return
return types.NewBlock(header, txs, uncles, receipts, trie.NewStackTrie(nil)), nil
return types.NewBlock(header, txs, uncles, receipts, trie.NewStackTrie(nil)).WithRejected(rejected), nil
}

// SealHash returns the hash of a block prior to it being sealed.
Expand Down
2 changes: 1 addition & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
gen(i, b)
}

block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals)
block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals, nil)
if err != nil {
panic(err)
}
Expand Down
48 changes: 46 additions & 2 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,30 @@ type Block struct {
transactions Transactions
withdrawals Withdrawals

// `rejected` is an OP/NodeKit extension. It collects transactions which were included by the
// OP sequencer in the batch that generated this block, but could not be included in the block
// because the failed basic consensus checks -- invalid signature, nonce too low, etc.
//
// This field is _not_ normative: it is not included in the block hash and is not considered
// part of the L2 chain data. Most block explorers will not show it. This means that the L2
// chain still has the exact same data structures and format as an L1 EVM chain. The field is
// mainly included here for plumbing: it means that when a batch is executed to produce a block,
// information is not lost when transactions from the batch are rejected. Thus, when the block
// is converted _back_ to a batch by the batcher, the resulting batch which is sent to the L1
// will include all the transactions from the original batch, including the invalid ones.
//
// Validating OP-nodes which read batches from L1 can then check that the sequencer included all
// the transactions it was required to include, if the sequencer was obligated by the NodeKit
// Sequencer to include certain transactions. Those nodes will then _derive_ the resulting block
// by sending the batch to their own engine, which will once again filter out the invalid
// transactions, rather than trusting the sequencer about which transactions were invalid.
//
// Effectively, we have removed the exclusion of invalid transactions as a responsibility of the
// sequencer and instead pushed this responsibility into the derivation pipeline/fraud proof
// mechanism. As a result, we need this extra field to keep track of the extra information --
// invalid transactions -- that is a normative part of a batch but not a block.
rejected []RejectedTransaction

// caches
hash atomic.Value
size atomic.Value
Expand All @@ -206,12 +230,21 @@ type Block struct {
ReceivedFrom interface{}
}

type RejectedTransaction struct {
// The raw data of the transaction. This allows us to include even completely malformed data
// blobs that were forced into the sequence by end users as rejected transactions.
Data []byte
// The position in the block at which this tranaction would have appeared had it been valid.
Pos uint64
}

// "external" block encoding. used for eth protocol, etc.
type extblock struct {
Header *Header
Txs []*Transaction
Uncles []*Header
Withdrawals []*Withdrawal `rlp:"optional"`
Withdrawals []*Withdrawal `rlp:"optional"`
Rejected []RejectedTransaction `rlp:"optional"`
}

// NewBlock creates a new block. The input data is copied, changes to header and to the
Expand Down Expand Up @@ -314,7 +347,7 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error {
if err := s.Decode(&eb); err != nil {
return err
}
b.header, b.uncles, b.transactions, b.withdrawals = eb.Header, eb.Uncles, eb.Txs, eb.Withdrawals
b.header, b.uncles, b.transactions, b.withdrawals, b.rejected = eb.Header, eb.Uncles, eb.Txs, eb.Withdrawals, eb.Rejected
b.size.Store(rlp.ListSize(size))
return nil
}
Expand All @@ -326,6 +359,7 @@ func (b *Block) EncodeRLP(w io.Writer) error {
Txs: b.transactions,
Uncles: b.uncles,
Withdrawals: b.withdrawals,
Rejected: b.rejected,
})
}

Expand Down Expand Up @@ -385,6 +419,10 @@ func (b *Block) BaseFee() *big.Int {

func (b *Block) BeaconRoot() *common.Hash { return b.header.ParentBeaconRoot }

func (b *Block) Rejected() []RejectedTransaction {
return b.rejected
}

func (b *Block) ExcessBlobGas() *uint64 {
var excessBlobGas *uint64
if b.header.ExcessBlobGas != nil {
Expand Down Expand Up @@ -482,6 +520,12 @@ func (b *Block) WithWithdrawals(withdrawals []*Withdrawal) *Block {
return block
}

// WithRejected sets the rejected transactions in a block, does not return a new block.
func (b *Block) WithRejected(rejected []RejectedTransaction) *Block {
b.rejected = rejected
return b
}

// Hash returns the keccak256 hash of b's header.
// The hash is computed on the first call and cached thereafter.
func (b *Block) Hash() common.Hash {
Expand Down
12 changes: 6 additions & 6 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -570,12 +570,12 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu
}
}
if config.Optimism != nil && len(txs) >= 2 { // need at least an info tx and a non-info tx
if data := txs[0].Data(); len(data) >= 4+32*8 { // function selector + 8 arguments to setL1BlockValues
l1Basefee := new(big.Int).SetBytes(data[4+32*2 : 4+32*3]) // arg index 2
overhead := new(big.Int).SetBytes(data[4+32*6 : 4+32*7]) // arg index 6
scalar := new(big.Int).SetBytes(data[4+32*7 : 4+32*8]) // arg index 7
fscalar := new(big.Float).SetInt(scalar) // legacy: format fee scalar as big Float
fdivisor := new(big.Float).SetUint64(1_000_000) // 10**6, i.e. 6 decimals
if data := txs[0].Data(); len(data) >= 4+32+32*11 { // function selector + dynamic args offset + 11 arguments to setL1BlockValues
l1Basefee := new(big.Int).SetBytes(data[36+32*2 : 36+32*3]) // arg index 2
overhead := new(big.Int).SetBytes(data[36+32*6 : 36+32*7]) // arg index 6
scalar := new(big.Int).SetBytes(data[36+32*7 : 36+32*8]) // arg index 7
fscalar := new(big.Float).SetInt(scalar) // legacy: format fee scalar as big Float
fdivisor := new(big.Float).SetUint64(1_000_000) // 10**6, i.e. 6 decimals
feeScalar := new(big.Float).Quo(fscalar, fdivisor)
for i := 0; i < len(rs); i++ {
if !txs[i].IsDepositTx() {
Expand Down
Loading

0 comments on commit 4b736c1

Please sign in to comment.