diff --git a/cmd/geth/retesteth.go b/cmd/geth/retesteth.go index e7f91fa78..9b72d0d19 100644 --- a/cmd/geth/retesteth.go +++ b/cmd/geth/retesteth.go @@ -208,6 +208,10 @@ func (e *NoRewardEngine) VerifyHeaders(chain consensus.ChainReader, headers []*t return e.inner.VerifyHeaders(chain, headers, seals) } +func (e *NoRewardEngine) VerifyTransactions(chain consensus.ChainReader, block *types.Block) error { + return e.inner.VerifyTransactions(chain, block) +} + func (e *NoRewardEngine) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { return e.inner.VerifyUncles(chain, block) } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 174557531..a3a696446 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -39,7 +39,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" - lru "github.com/hashicorp/golang-lru" + "github.com/hashicorp/golang-lru" "golang.org/x/crypto/sha3" ) @@ -135,6 +135,9 @@ var ( // errRecentlySigned is returned if a header is signed by an authorized entity // that already signed a header recently, thus is temporarily not allowed to. errRecentlySigned = errors.New("recently signed") + + // errExceedGasLimit is returned if a transaction uses more gas than the allowed per-tx limit + errExceedGasLimit = errors.New("transaction gas usage exceeds the per-transaction limit") ) // SignerFn is a signer callback function to request a header to be signed by a @@ -301,6 +304,18 @@ func (c *Clique) verifyHeader(chain consensus.ChainReader, header *types.Header, return c.verifyCascadingFields(chain, header, parents) } +// VerifyTransactions verifies a the transactions in a block do not exceed the per-transaction gas limit +func (*Clique) VerifyTransactions(chain consensus.ChainReader, block *types.Block) error { + if chain.Config().IsEIP1559(block.Number()) { + for _, tx := range block.Transactions() { + if tx.Gas() > params.PerTransactionGasLimit { + return errExceedGasLimit + } + } + } + return nil +} + // verifyCascadingFields verifies all the header fields that are not standalone, // rather depend on a batch of previous headers. The caller may optionally pass // in a batch of parents (ascending order) to avoid looking those up from the @@ -715,23 +730,45 @@ func CliqueRLP(header *types.Header) []byte { } func encodeSigHeader(w io.Writer, header *types.Header) { - err := rlp.Encode(w, []interface{}{ - header.ParentHash, - header.UncleHash, - header.Coinbase, - header.Root, - header.TxHash, - header.ReceiptHash, - header.Bloom, - header.Difficulty, - header.Number, - header.GasLimit, - header.GasUsed, - header.Time, - header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short - header.MixDigest, - header.Nonce, - }) + var err error + if header.BaseFee == nil { + err = rlp.Encode(w, []interface{}{ + header.ParentHash, + header.UncleHash, + header.Coinbase, + header.Root, + header.TxHash, + header.ReceiptHash, + header.Bloom, + header.Difficulty, + header.Number, + header.GasLimit, + header.GasUsed, + header.Time, + header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short + header.MixDigest, + header.Nonce, + }) + } else { + err = rlp.Encode(w, []interface{}{ + header.ParentHash, + header.UncleHash, + header.Coinbase, + header.Root, + header.TxHash, + header.ReceiptHash, + header.Bloom, + header.Difficulty, + header.Number, + header.GasLimit, + header.GasUsed, + header.Time, + header.Extra[:len(header.Extra)-crypto.SignatureLength], // Yes, this will panic if extra is too short + header.MixDigest, + header.Nonce, + header.BaseFee, + }) + } if err != nil { panic("can't encode: " + err.Error()) } diff --git a/consensus/consensus.go b/consensus/consensus.go index f753af550..8a7b30c68 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -67,6 +67,10 @@ type Engine interface { // the input slice). VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) + // VerifyTransactions verifies that none of the block's transactions + // exceed the per-transaction gas limit (post EIP1559 only) + VerifyTransactions(chain ChainReader, block *types.Block) error + // VerifyUncles verifies that the given block's uncles conform to the consensus // rules of a given engine. VerifyUncles(chain ChainReader, block *types.Block) error diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 3e9cbeefa..0240689d1 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -24,7 +24,7 @@ import ( "runtime" "time" - mapset "github.com/deckarep/golang-set" + "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" @@ -76,7 +76,7 @@ var ( errInvalidDifficulty = errors.New("non-positive difficulty") errInvalidMixDigest = errors.New("invalid mix digest") errInvalidPoW = errors.New("invalid proof-of-work") - errGasLimitSet = errors.New("GasLimit should not be set after EIP1559 has finalized") + errExceedGasLimit = errors.New("transaction gas usage exceeds the per-transaction limit") ) // Author implements consensus.Engine, returning the header's coinbase as the @@ -170,6 +170,18 @@ func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*type return abort, errorsOut } +// VerifyTransactions verifies a the transactions in a block do not exceed the per-transaction gas limit +func (*Ethash) VerifyTransactions(chain consensus.ChainReader, block *types.Block) error { + if chain.Config().IsEIP1559(block.Number()) { + for _, tx := range block.Transactions() { + if tx.Gas() > params.PerTransactionGasLimit { + return errExceedGasLimit + } + } + } + return nil +} + func (ethash *Ethash) verifyHeaderWorker(chain consensus.ChainReader, headers []*types.Header, seals []bool, index int) error { var parent *types.Header if index == 0 { diff --git a/core/block_validator.go b/core/block_validator.go index af8a77c92..7db25486c 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -60,6 +60,9 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error { if err := v.engine.VerifyUncles(v.bc, block); err != nil { return err } + if err := v.engine.VerifyTransactions(v.bc, block); err != nil { + return err + } if hash := types.CalcUncleHash(block.Uncles()); hash != header.UncleHash { return fmt.Errorf("uncle root hash mismatch: have %x, want %x", hash, header.UncleHash) }