per-tx gas limit under consensus
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
+55
-18
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user