per-tx gas limit under consensus

This commit is contained in:
Ian Norden
2020-07-03 14:35:16 -05:00
parent 177a17e457
commit 15e07495cd
5 changed files with 80 additions and 20 deletions
+4
View File
@@ -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
View File
@@ -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())
}
+4
View File
@@ -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
+14 -2
View File
@@ -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 {
+3
View File
@@ -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)
}