diff --git a/beacon/engine/gen_ed.go b/beacon/engine/gen_ed.go
index 336dfc6cc755..884b7160e8d7 100644
--- a/beacon/engine/gen_ed.go
+++ b/beacon/engine/gen_ed.go
@@ -32,6 +32,8 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
+ DataGasUsed *hexutil.Uint64 `json:"dataGasUsed"`
+ ExcessDataGas *hexutil.Uint64 `json:"excessDataGas"`
}
var enc ExecutableData
enc.ParentHash = e.ParentHash
@@ -54,6 +56,8 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) {
}
}
enc.Withdrawals = e.Withdrawals
+ enc.DataGasUsed = (*hexutil.Uint64)(e.DataGasUsed)
+ enc.ExcessDataGas = (*hexutil.Uint64)(e.ExcessDataGas)
return json.Marshal(&enc)
}
@@ -75,6 +79,8 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
BlockHash *common.Hash `json:"blockHash" gencodec:"required"`
Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
+ DataGasUsed *hexutil.Uint64 `json:"dataGasUsed"`
+ ExcessDataGas *hexutil.Uint64 `json:"excessDataGas"`
}
var dec ExecutableData
if err := json.Unmarshal(input, &dec); err != nil {
@@ -142,5 +148,11 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error {
if dec.Withdrawals != nil {
e.Withdrawals = dec.Withdrawals
}
+ if dec.DataGasUsed != nil {
+ e.DataGasUsed = (*uint64)(dec.DataGasUsed)
+ }
+ if dec.ExcessDataGas != nil {
+ e.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
+ }
return nil
}
diff --git a/beacon/engine/gen_epe.go b/beacon/engine/gen_epe.go
index cc66cef6cd3e..664a50fc5b29 100644
--- a/beacon/engine/gen_epe.go
+++ b/beacon/engine/gen_epe.go
@@ -17,10 +17,12 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) {
type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
+ BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
}
var enc ExecutionPayloadEnvelope
enc.ExecutionPayload = e.ExecutionPayload
enc.BlockValue = (*hexutil.Big)(e.BlockValue)
+ enc.BlobsBundle = e.BlobsBundle
return json.Marshal(&enc)
}
@@ -29,6 +31,7 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"`
+ BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
}
var dec ExecutionPayloadEnvelope
if err := json.Unmarshal(input, &dec); err != nil {
@@ -42,5 +45,8 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error {
return errors.New("missing required field 'blockValue' for ExecutionPayloadEnvelope")
}
e.BlockValue = (*big.Int)(dec.BlockValue)
+ if dec.BlobsBundle != nil {
+ e.BlobsBundle = dec.BlobsBundle
+ }
return nil
}
diff --git a/beacon/engine/types.go b/beacon/engine/types.go
index 07ebe544b438..d96bece8560b 100644
--- a/beacon/engine/types.go
+++ b/beacon/engine/types.go
@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/trie"
)
@@ -61,6 +62,8 @@ type ExecutableData struct {
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
Transactions [][]byte `json:"transactions" gencodec:"required"`
Withdrawals []*types.Withdrawal `json:"withdrawals"`
+ DataGasUsed *uint64 `json:"dataGasUsed"`
+ ExcessDataGas *uint64 `json:"excessDataGas"`
}
// JSON type overrides for executableData.
@@ -73,6 +76,8 @@ type executableDataMarshaling struct {
ExtraData hexutil.Bytes
LogsBloom hexutil.Bytes
Transactions []hexutil.Bytes
+ DataGasUsed *hexutil.Uint64
+ ExcessDataGas *hexutil.Uint64
}
//go:generate go run github.com/fjl/gencodec -type ExecutionPayloadEnvelope -field-override executionPayloadEnvelopeMarshaling -out gen_epe.go
@@ -80,6 +85,13 @@ type executableDataMarshaling struct {
type ExecutionPayloadEnvelope struct {
ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"`
BlockValue *big.Int `json:"blockValue" gencodec:"required"`
+ BlobsBundle *BlobsBundleV1 `json:"blobsBundle"`
+}
+
+type BlobsBundleV1 struct {
+ Commitments []hexutil.Bytes `json:"commitments"`
+ Proofs []hexutil.Bytes `json:"proofs"`
+ Blobs []hexutil.Bytes `json:"blobs"`
}
// JSON type overrides for ExecutionPayloadEnvelope.
@@ -152,14 +164,15 @@ func decodeTransactions(enc [][]byte) ([]*types.Transaction, error) {
// ExecutableDataToBlock constructs a block from executable data.
// It verifies that the following fields:
//
-// len(extraData) <= 32
-// uncleHash = emptyUncleHash
-// difficulty = 0
+// len(extraData) <= 32
+// uncleHash = emptyUncleHash
+// difficulty = 0
+// if versionedHashes != nil, versionedHashes match to blob transactions
//
// and that the blockhash of the constructed block matches the parameters. Nil
// Withdrawals value will propagate through the returned block. Empty
// Withdrawals value must be passed via non-nil, length 0 value in params.
-func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) {
+func ExecutableDataToBlock(params ExecutableData, versionedHashes []common.Hash) (*types.Block, error) {
txs, err := decodeTransactions(params.Transactions)
if err != nil {
return nil, err
@@ -174,6 +187,18 @@ func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) {
if params.BaseFeePerGas != nil && (params.BaseFeePerGas.Sign() == -1 || params.BaseFeePerGas.BitLen() > 256) {
return nil, fmt.Errorf("invalid baseFeePerGas: %v", params.BaseFeePerGas)
}
+ var blobHashes []common.Hash
+ for _, tx := range txs {
+ blobHashes = append(blobHashes, tx.BlobHashes()...)
+ }
+ if len(blobHashes) != len(versionedHashes) {
+ return nil, fmt.Errorf("invalid number of versionedHashes: %v blobHashes: %v", versionedHashes, blobHashes)
+ }
+ for i := 0; i < len(blobHashes); i++ {
+ if blobHashes[i] != versionedHashes[i] {
+ return nil, fmt.Errorf("invalid versionedHash at %v: %v blobHashes: %v", i, versionedHashes, blobHashes)
+ }
+ }
// Only set withdrawalsRoot if it is non-nil. This allows CLs to use
// ExecutableData before withdrawals are enabled by marshaling
// Withdrawals as the json null value.
@@ -199,6 +224,8 @@ func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) {
Extra: params.ExtraData,
MixDigest: params.Random,
WithdrawalsHash: withdrawalsRoot,
+ ExcessDataGas: params.ExcessDataGas,
+ DataGasUsed: params.DataGasUsed,
}
block := types.NewBlockWithHeader(header).WithBody(txs, nil /* uncles */).WithWithdrawals(params.Withdrawals)
if block.Hash() != params.BlockHash {
@@ -209,7 +236,7 @@ func ExecutableDataToBlock(params ExecutableData) (*types.Block, error) {
// BlockToExecutableData constructs the ExecutableData structure by filling the
// fields from the given block. It assumes the given block is post-merge block.
-func BlockToExecutableData(block *types.Block, fees *big.Int) *ExecutionPayloadEnvelope {
+func BlockToExecutableData(block *types.Block, fees *big.Int, blobs []kzg4844.Blob, commitments []kzg4844.Commitment, proofs []kzg4844.Proof) *ExecutionPayloadEnvelope {
data := &ExecutableData{
BlockHash: block.Hash(),
ParentHash: block.ParentHash(),
@@ -226,8 +253,20 @@ func BlockToExecutableData(block *types.Block, fees *big.Int) *ExecutionPayloadE
Random: block.MixDigest(),
ExtraData: block.Extra(),
Withdrawals: block.Withdrawals(),
+ DataGasUsed: block.DataGasUsed(),
+ ExcessDataGas: block.ExcessDataGas(),
+ }
+ blobsBundle := BlobsBundleV1{
+ Commitments: make([]hexutil.Bytes, 0),
+ Blobs: make([]hexutil.Bytes, 0),
+ Proofs: make([]hexutil.Bytes, 0),
+ }
+ for i := range blobs {
+ blobsBundle.Blobs = append(blobsBundle.Blobs, hexutil.Bytes(blobs[i][:]))
+ blobsBundle.Commitments = append(blobsBundle.Commitments, hexutil.Bytes(commitments[i][:]))
+ blobsBundle.Proofs = append(blobsBundle.Proofs, hexutil.Bytes(proofs[i][:]))
}
- return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees}
+ return &ExecutionPayloadEnvelope{ExecutionPayload: data, BlockValue: fees, BlobsBundle: &blobsBundle}
}
// ExecutionPayloadBodyV1 is used in the response to GetPayloadBodiesByHashV1 and GetPayloadBodiesByRangeV1
diff --git a/cmd/evm/internal/t8ntool/block.go b/cmd/evm/internal/t8ntool/block.go
index 64804a17ff64..0dd81c5b1db7 100644
--- a/cmd/evm/internal/t8ntool/block.go
+++ b/cmd/evm/internal/t8ntool/block.go
@@ -54,16 +54,20 @@ type header struct {
Nonce *types.BlockNonce `json:"nonce"`
BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
+ DataGasUsed *uint64 `json:"dataGasUsed" rlp:"optional"`
+ ExcessDataGas *uint64 `json:"excessDataGas" rlp:"optional"`
}
type headerMarshaling struct {
- Difficulty *math.HexOrDecimal256
- Number *math.HexOrDecimal256
- GasLimit math.HexOrDecimal64
- GasUsed math.HexOrDecimal64
- Time math.HexOrDecimal64
- Extra hexutil.Bytes
- BaseFee *math.HexOrDecimal256
+ Difficulty *math.HexOrDecimal256
+ Number *math.HexOrDecimal256
+ GasLimit math.HexOrDecimal64
+ GasUsed math.HexOrDecimal64
+ Time math.HexOrDecimal64
+ Extra hexutil.Bytes
+ BaseFee *math.HexOrDecimal256
+ DataGasUsed *math.HexOrDecimal64
+ ExcessDataGas *math.HexOrDecimal64
}
type bbInput struct {
@@ -129,6 +133,8 @@ func (i *bbInput) ToBlock() *types.Block {
MixDigest: i.Header.MixDigest,
BaseFee: i.Header.BaseFee,
WithdrawalsHash: i.Header.WithdrawalsHash,
+ DataGasUsed: i.Header.DataGasUsed,
+ ExcessDataGas: i.Header.ExcessDataGas,
}
// Fill optional values.
diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go
index 5633198d396e..11c14733f2e6 100644
--- a/cmd/evm/internal/t8ntool/execution.go
+++ b/cmd/evm/internal/t8ntool/execution.go
@@ -56,8 +56,10 @@ type ExecutionResult struct {
Rejected []*rejectedTx `json:"rejected,omitempty"`
Difficulty *math.HexOrDecimal256 `json:"currentDifficulty" gencodec:"required"`
GasUsed math.HexOrDecimal64 `json:"gasUsed"`
+ DataGasUsed *math.HexOrDecimal64 `json:"dataGasUsed,omitempty"`
BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"`
WithdrawalsRoot *common.Hash `json:"withdrawalsRoot,omitempty"`
+ ExcessDataGas *math.HexOrDecimal64 `json:"currentExcessDataGas,omitempty"`
}
type ommer struct {
@@ -67,37 +69,43 @@ type ommer struct {
//go:generate go run github.com/fjl/gencodec -type stEnv -field-override stEnvMarshaling -out gen_stenv.go
type stEnv struct {
- Coinbase common.Address `json:"currentCoinbase" gencodec:"required"`
- Difficulty *big.Int `json:"currentDifficulty"`
- Random *big.Int `json:"currentRandom"`
- ParentDifficulty *big.Int `json:"parentDifficulty"`
- ParentBaseFee *big.Int `json:"parentBaseFee,omitempty"`
- ParentGasUsed uint64 `json:"parentGasUsed,omitempty"`
- ParentGasLimit uint64 `json:"parentGasLimit,omitempty"`
- GasLimit uint64 `json:"currentGasLimit" gencodec:"required"`
- Number uint64 `json:"currentNumber" gencodec:"required"`
- Timestamp uint64 `json:"currentTimestamp" gencodec:"required"`
- ParentTimestamp uint64 `json:"parentTimestamp,omitempty"`
- BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
- Ommers []ommer `json:"ommers,omitempty"`
- Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
- BaseFee *big.Int `json:"currentBaseFee,omitempty"`
- ParentUncleHash common.Hash `json:"parentUncleHash"`
+ Coinbase common.Address `json:"currentCoinbase" gencodec:"required"`
+ Difficulty *big.Int `json:"currentDifficulty"`
+ Random *big.Int `json:"currentRandom"`
+ ParentDifficulty *big.Int `json:"parentDifficulty"`
+ ParentBaseFee *big.Int `json:"parentBaseFee,omitempty"`
+ ParentGasUsed uint64 `json:"parentGasUsed,omitempty"`
+ ParentGasLimit uint64 `json:"parentGasLimit,omitempty"`
+ ParentDataGasUsed *uint64 `json:"parentDataGasUsed,omitempty"`
+ ParentExcessDataGas *uint64 `json:"parentExcessDataGas,omitempty"`
+ GasLimit uint64 `json:"currentGasLimit" gencodec:"required"`
+ Number uint64 `json:"currentNumber" gencodec:"required"`
+ Timestamp uint64 `json:"currentTimestamp" gencodec:"required"`
+ ParentTimestamp uint64 `json:"parentTimestamp,omitempty"`
+ BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
+ Ommers []ommer `json:"ommers,omitempty"`
+ Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
+ BaseFee *big.Int `json:"currentBaseFee,omitempty"`
+ ParentUncleHash common.Hash `json:"parentUncleHash"`
+ ExcessDataGas *uint64 `json:"currentExcessDataGas,omitempty"`
}
type stEnvMarshaling struct {
- Coinbase common.UnprefixedAddress
- Difficulty *math.HexOrDecimal256
- Random *math.HexOrDecimal256
- ParentDifficulty *math.HexOrDecimal256
- ParentBaseFee *math.HexOrDecimal256
- ParentGasUsed math.HexOrDecimal64
- ParentGasLimit math.HexOrDecimal64
- GasLimit math.HexOrDecimal64
- Number math.HexOrDecimal64
- Timestamp math.HexOrDecimal64
- ParentTimestamp math.HexOrDecimal64
- BaseFee *math.HexOrDecimal256
+ Coinbase common.UnprefixedAddress
+ Difficulty *math.HexOrDecimal256
+ Random *math.HexOrDecimal256
+ ParentDifficulty *math.HexOrDecimal256
+ ParentBaseFee *math.HexOrDecimal256
+ ParentDataGasUsed *math.HexOrDecimal64
+ ParentGasUsed math.HexOrDecimal64
+ ParentGasLimit math.HexOrDecimal64
+ ParentExcessDataGas *math.HexOrDecimal64
+ GasLimit math.HexOrDecimal64
+ Number math.HexOrDecimal64
+ Timestamp math.HexOrDecimal64
+ ParentTimestamp math.HexOrDecimal64
+ BaseFee *math.HexOrDecimal256
+ ExcessDataGas *math.HexOrDecimal64
}
type rejectedTx struct {
@@ -154,6 +162,25 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
rnd := common.BigToHash(pre.Env.Random)
vmContext.Random = &rnd
}
+ // If excess data gas is defined, add it to vmContext
+ if chainConfig.IsCancun(new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) {
+ if pre.Env.ExcessDataGas != nil {
+ vmContext.ExcessDataGas = pre.Env.ExcessDataGas
+ } else {
+ var (
+ parentDataGasUsed = uint64(0)
+ parentExcessDataGas = uint64(0)
+ )
+ if pre.Env.ParentDataGasUsed != nil {
+ parentDataGasUsed = *pre.Env.ParentDataGasUsed
+ }
+ if pre.Env.ParentExcessDataGas != nil {
+ parentExcessDataGas = *pre.Env.ParentExcessDataGas
+ }
+ edg := misc.CalcExcessDataGas(parentExcessDataGas, parentDataGasUsed)
+ vmContext.ExcessDataGas = &edg
+ }
+ }
// If DAO is supported/enabled, we need to handle it here. In geth 'proper', it's
// done in StateProcessor.Process(block, ...), right before transactions are applied.
if chainConfig.DAOForkSupport &&
@@ -164,6 +191,16 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
for i, tx := range txs {
msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee)
+ if tx.Type() == types.BlobTxType {
+ if len(tx.BlobHashes()) == 0 {
+ err = fmt.Errorf("blob transaction with zero blobs")
+ }
+ for _, h := range tx.BlobHashes() {
+ if h[0] != params.BlobTxHashVersion {
+ err = fmt.Errorf("unversioned blob hash: %v", h)
+ }
+ }
+ }
if err != nil {
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
@@ -273,21 +310,33 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
return nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
}
execRs := &ExecutionResult{
- StateRoot: root,
- TxRoot: types.DeriveSha(includedTxs, trie.NewStackTrie(nil)),
- ReceiptRoot: types.DeriveSha(receipts, trie.NewStackTrie(nil)),
- Bloom: types.CreateBloom(receipts),
- LogsHash: rlpHash(statedb.Logs()),
- Receipts: receipts,
- Rejected: rejectedTxs,
- Difficulty: (*math.HexOrDecimal256)(vmContext.Difficulty),
- GasUsed: (math.HexOrDecimal64)(gasUsed),
- BaseFee: (*math.HexOrDecimal256)(vmContext.BaseFee),
+ StateRoot: root,
+ TxRoot: types.DeriveSha(includedTxs, trie.NewStackTrie(nil)),
+ ReceiptRoot: types.DeriveSha(receipts, trie.NewStackTrie(nil)),
+ Bloom: types.CreateBloom(receipts),
+ LogsHash: rlpHash(statedb.Logs()),
+ Receipts: receipts,
+ Rejected: rejectedTxs,
+ Difficulty: (*math.HexOrDecimal256)(vmContext.Difficulty),
+ GasUsed: (math.HexOrDecimal64)(gasUsed),
+ BaseFee: (*math.HexOrDecimal256)(vmContext.BaseFee),
+ ExcessDataGas: (*math.HexOrDecimal64)(vmContext.ExcessDataGas),
}
if pre.Env.Withdrawals != nil {
h := types.DeriveSha(types.Withdrawals(pre.Env.Withdrawals), trie.NewStackTrie(nil))
execRs.WithdrawalsRoot = &h
}
+ if vmContext.ExcessDataGas != nil {
+ // calculate and set the excess data gas at the end of this block execution
+ newBlobs := 0
+ for _, tx := range txs {
+ if tx.Type() == types.BlobTxType {
+ newBlobs += len(tx.BlobHashes())
+ }
+ }
+ dataGasUsed := uint64(newBlobs * params.BlobTxDataGasPerBlob)
+ execRs.DataGasUsed = (*math.HexOrDecimal64)(&dataGasUsed)
+ }
return statedb, execRs, nil
}
diff --git a/cmd/evm/internal/t8ntool/gen_header.go b/cmd/evm/internal/t8ntool/gen_header.go
index 76228394dc1d..bf5cfd3e46d8 100644
--- a/cmd/evm/internal/t8ntool/gen_header.go
+++ b/cmd/evm/internal/t8ntool/gen_header.go
@@ -35,6 +35,8 @@ func (h header) MarshalJSON() ([]byte, error) {
Nonce *types.BlockNonce `json:"nonce"`
BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
+ DataGasUsed *math.HexOrDecimal64 `json:"dataGasUsed" rlp:"optional"`
+ ExcessDataGas *math.HexOrDecimal64 `json:"excessDataGas" rlp:"optional"`
}
var enc header
enc.ParentHash = h.ParentHash
@@ -54,6 +56,8 @@ func (h header) MarshalJSON() ([]byte, error) {
enc.Nonce = h.Nonce
enc.BaseFee = (*math.HexOrDecimal256)(h.BaseFee)
enc.WithdrawalsHash = h.WithdrawalsHash
+ enc.DataGasUsed = (*math.HexOrDecimal64)(h.DataGasUsed)
+ enc.ExcessDataGas = (*math.HexOrDecimal64)(h.ExcessDataGas)
return json.Marshal(&enc)
}
@@ -77,6 +81,8 @@ func (h *header) UnmarshalJSON(input []byte) error {
Nonce *types.BlockNonce `json:"nonce"`
BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
+ DataGasUsed *math.HexOrDecimal64 `json:"dataGasUsed" rlp:"optional"`
+ ExcessDataGas *math.HexOrDecimal64 `json:"excessDataGas" rlp:"optional"`
}
var dec header
if err := json.Unmarshal(input, &dec); err != nil {
@@ -137,5 +143,11 @@ func (h *header) UnmarshalJSON(input []byte) error {
if dec.WithdrawalsHash != nil {
h.WithdrawalsHash = dec.WithdrawalsHash
}
+ if dec.DataGasUsed != nil {
+ h.DataGasUsed = (*uint64)(dec.DataGasUsed)
+ }
+ if dec.ExcessDataGas != nil {
+ h.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
+ }
return nil
}
diff --git a/cmd/evm/internal/t8ntool/gen_stenv.go b/cmd/evm/internal/t8ntool/gen_stenv.go
index c2cc3a2c8a38..7414142a07f2 100644
--- a/cmd/evm/internal/t8ntool/gen_stenv.go
+++ b/cmd/evm/internal/t8ntool/gen_stenv.go
@@ -17,22 +17,25 @@ var _ = (*stEnvMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (s stEnv) MarshalJSON() ([]byte, error) {
type stEnv struct {
- Coinbase common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"currentDifficulty"`
- Random *math.HexOrDecimal256 `json:"currentRandom"`
- ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"`
- ParentBaseFee *math.HexOrDecimal256 `json:"parentBaseFee,omitempty"`
- ParentGasUsed math.HexOrDecimal64 `json:"parentGasUsed,omitempty"`
- ParentGasLimit math.HexOrDecimal64 `json:"parentGasLimit,omitempty"`
- GasLimit math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
- Number math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
- Timestamp math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
- ParentTimestamp math.HexOrDecimal64 `json:"parentTimestamp,omitempty"`
- BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
- Ommers []ommer `json:"ommers,omitempty"`
- Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
- BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"`
- ParentUncleHash common.Hash `json:"parentUncleHash"`
+ Coinbase common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"currentDifficulty"`
+ Random *math.HexOrDecimal256 `json:"currentRandom"`
+ ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"`
+ ParentBaseFee *math.HexOrDecimal256 `json:"parentBaseFee,omitempty"`
+ ParentGasUsed math.HexOrDecimal64 `json:"parentGasUsed,omitempty"`
+ ParentGasLimit math.HexOrDecimal64 `json:"parentGasLimit,omitempty"`
+ ParentDataGasUsed *math.HexOrDecimal64 `json:"parentDataGasUsed,omitempty"`
+ ParentExcessDataGas *math.HexOrDecimal64 `json:"parentExcessDataGas,omitempty"`
+ GasLimit math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
+ Number math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
+ Timestamp math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
+ ParentTimestamp math.HexOrDecimal64 `json:"parentTimestamp,omitempty"`
+ BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
+ Ommers []ommer `json:"ommers,omitempty"`
+ Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
+ BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"`
+ ParentUncleHash common.Hash `json:"parentUncleHash"`
+ ExcessDataGas *math.HexOrDecimal64 `json:"currentExcessDataGas,omitempty"`
}
var enc stEnv
enc.Coinbase = common.UnprefixedAddress(s.Coinbase)
@@ -42,6 +45,8 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
enc.ParentBaseFee = (*math.HexOrDecimal256)(s.ParentBaseFee)
enc.ParentGasUsed = math.HexOrDecimal64(s.ParentGasUsed)
enc.ParentGasLimit = math.HexOrDecimal64(s.ParentGasLimit)
+ enc.ParentDataGasUsed = (*math.HexOrDecimal64)(s.ParentDataGasUsed)
+ enc.ParentExcessDataGas = (*math.HexOrDecimal64)(s.ParentExcessDataGas)
enc.GasLimit = math.HexOrDecimal64(s.GasLimit)
enc.Number = math.HexOrDecimal64(s.Number)
enc.Timestamp = math.HexOrDecimal64(s.Timestamp)
@@ -51,28 +56,32 @@ func (s stEnv) MarshalJSON() ([]byte, error) {
enc.Withdrawals = s.Withdrawals
enc.BaseFee = (*math.HexOrDecimal256)(s.BaseFee)
enc.ParentUncleHash = s.ParentUncleHash
+ enc.ExcessDataGas = (*math.HexOrDecimal64)(s.ExcessDataGas)
return json.Marshal(&enc)
}
// UnmarshalJSON unmarshals from JSON.
func (s *stEnv) UnmarshalJSON(input []byte) error {
type stEnv struct {
- Coinbase *common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"currentDifficulty"`
- Random *math.HexOrDecimal256 `json:"currentRandom"`
- ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"`
- ParentBaseFee *math.HexOrDecimal256 `json:"parentBaseFee,omitempty"`
- ParentGasUsed *math.HexOrDecimal64 `json:"parentGasUsed,omitempty"`
- ParentGasLimit *math.HexOrDecimal64 `json:"parentGasLimit,omitempty"`
- GasLimit *math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
- Number *math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
- Timestamp *math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
- ParentTimestamp *math.HexOrDecimal64 `json:"parentTimestamp,omitempty"`
- BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
- Ommers []ommer `json:"ommers,omitempty"`
- Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
- BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"`
- ParentUncleHash *common.Hash `json:"parentUncleHash"`
+ Coinbase *common.UnprefixedAddress `json:"currentCoinbase" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"currentDifficulty"`
+ Random *math.HexOrDecimal256 `json:"currentRandom"`
+ ParentDifficulty *math.HexOrDecimal256 `json:"parentDifficulty"`
+ ParentBaseFee *math.HexOrDecimal256 `json:"parentBaseFee,omitempty"`
+ ParentGasUsed *math.HexOrDecimal64 `json:"parentGasUsed,omitempty"`
+ ParentGasLimit *math.HexOrDecimal64 `json:"parentGasLimit,omitempty"`
+ ParentDataGasUsed *math.HexOrDecimal64 `json:"parentDataGasUsed,omitempty"`
+ ParentExcessDataGas *math.HexOrDecimal64 `json:"parentExcessDataGas,omitempty"`
+ GasLimit *math.HexOrDecimal64 `json:"currentGasLimit" gencodec:"required"`
+ Number *math.HexOrDecimal64 `json:"currentNumber" gencodec:"required"`
+ Timestamp *math.HexOrDecimal64 `json:"currentTimestamp" gencodec:"required"`
+ ParentTimestamp *math.HexOrDecimal64 `json:"parentTimestamp,omitempty"`
+ BlockHashes map[math.HexOrDecimal64]common.Hash `json:"blockHashes,omitempty"`
+ Ommers []ommer `json:"ommers,omitempty"`
+ Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
+ BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"`
+ ParentUncleHash *common.Hash `json:"parentUncleHash"`
+ ExcessDataGas *math.HexOrDecimal64 `json:"currentExcessDataGas,omitempty"`
}
var dec stEnv
if err := json.Unmarshal(input, &dec); err != nil {
@@ -100,6 +109,12 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
if dec.ParentGasLimit != nil {
s.ParentGasLimit = uint64(*dec.ParentGasLimit)
}
+ if dec.ParentDataGasUsed != nil {
+ s.ParentDataGasUsed = (*uint64)(dec.ParentDataGasUsed)
+ }
+ if dec.ParentExcessDataGas != nil {
+ s.ParentExcessDataGas = (*uint64)(dec.ParentExcessDataGas)
+ }
if dec.GasLimit == nil {
return errors.New("missing required field 'currentGasLimit' for stEnv")
}
@@ -130,5 +145,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error {
if dec.ParentUncleHash != nil {
s.ParentUncleHash = *dec.ParentUncleHash
}
+ if dec.ExcessDataGas != nil {
+ s.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
+ }
return nil
}
diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go
index 80ebf599c54d..bfe611ff3878 100644
--- a/cmd/evm/internal/t8ntool/transition.go
+++ b/cmd/evm/internal/t8ntool/transition.go
@@ -240,7 +240,7 @@ func Transition(ctx *cli.Context) error {
}
}
// We may have to sign the transactions.
- signer := types.MakeSigner(chainConfig, big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp)
+ signer := types.LatestSignerForChainID(chainConfig.ChainID)
if txs, err = signUnsignedTransactions(txsWithKeys, signer); err != nil {
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index dcdf0045ce25..411a33f55c27 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -77,6 +77,9 @@ var (
utils.TxPoolAccountQueueFlag,
utils.TxPoolGlobalQueueFlag,
utils.TxPoolLifetimeFlag,
+ utils.BlobPoolDataDirFlag,
+ utils.BlobPoolDataCapFlag,
+ utils.BlobPoolPriceBumpFlag,
utils.SyncModeFlag,
utils.SyncTargetFlag,
utils.ExitWhenSyncedFlag,
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index de4e58a3b150..7e16cef2a1a1 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -385,6 +385,25 @@ var (
Value: ethconfig.Defaults.TxPool.Lifetime,
Category: flags.TxPoolCategory,
}
+ // Blob transaction pool settings
+ BlobPoolDataDirFlag = &cli.StringFlag{
+ Name: "blobpool.datadir",
+ Usage: "Data directory to store blob transactions in",
+ Value: ethconfig.Defaults.BlobPool.Datadir,
+ Category: flags.BlobPoolCategory,
+ }
+ BlobPoolDataCapFlag = &cli.Uint64Flag{
+ Name: "blobpool.datacap",
+ Usage: "Disk space to allocate for pending blob transactions (soft limit)",
+ Value: ethconfig.Defaults.BlobPool.Datacap,
+ Category: flags.BlobPoolCategory,
+ }
+ BlobPoolPriceBumpFlag = &cli.Uint64Flag{
+ Name: "blobpool.pricebump",
+ Usage: "Price bump percentage to replace an already existing blob transaction",
+ Value: ethconfig.Defaults.BlobPool.PriceBump,
+ Category: flags.BlobPoolCategory,
+ }
// Performance tuning settings
CacheFlag = &cli.IntFlag{
Name: "cache",
diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go
index c5d2a12a7b26..69ed4fc0f75f 100644
--- a/consensus/beacon/consensus.go
+++ b/consensus/beacon/consensus.go
@@ -372,6 +372,14 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea
return nil, errors.New("withdrawals set before Shanghai activation")
}
}
+ if chain.Config().IsCancun(header.Number, header.Time) {
+ var blobs int
+ for _, tx := range txs {
+ blobs += len(tx.BlobHashes())
+ }
+ dataGasUsed := uint64(blobs * params.BlobTxDataGasPerBlob)
+ header.DataGasUsed = &dataGasUsed
+ }
// Finalize and assemble the block.
beacon.Finalize(chain, header, state, txs, uncles, withdrawals)
diff --git a/consensus/misc/eip4844_test.go b/consensus/misc/eip4844_test.go
index 939ca258700e..1f932e0a4284 100644
--- a/consensus/misc/eip4844_test.go
+++ b/consensus/misc/eip4844_test.go
@@ -45,8 +45,8 @@ func TestCalcExcessDataGas(t *testing.T) {
// The excess data gas should decrease by however much the target was
// under-shot, capped at zero.
{params.BlobTxTargetDataGasPerBlock, params.BlobTxTargetDataGasPerBlock / params.BlobTxDataGasPerBlob, params.BlobTxTargetDataGasPerBlock},
- {params.BlobTxTargetDataGasPerBlock, (params.BlobTxTargetDataGasPerBlock / params.BlobTxDataGasPerBlob) - 1, params.BlobTxDataGasPerBlob},
- {params.BlobTxTargetDataGasPerBlock, (params.BlobTxTargetDataGasPerBlock / params.BlobTxDataGasPerBlob) - 2, 0},
+ {params.BlobTxTargetDataGasPerBlock, (params.BlobTxTargetDataGasPerBlock / params.BlobTxDataGasPerBlob) - 1, 2 * params.BlobTxDataGasPerBlob},
+ {params.BlobTxTargetDataGasPerBlock, (params.BlobTxTargetDataGasPerBlock / params.BlobTxDataGasPerBlob) - 2, params.BlobTxDataGasPerBlob},
{params.BlobTxDataGasPerBlob - 1, (params.BlobTxTargetDataGasPerBlock / params.BlobTxDataGasPerBlob) - 1, 0},
}
for _, tt := range tests {
@@ -64,8 +64,9 @@ func TestCalcBlobFee(t *testing.T) {
}{
{0, 1},
{1542706, 1},
- {1542707, 2},
- {10 * 1024 * 1024, 111},
+ {1542707, 1},
+ {3085414, 2},
+ {10 * 1024 * 1024, 23},
}
for i, tt := range tests {
have := CalcBlobFee(tt.excessDataGas)
diff --git a/core/error.go b/core/error.go
index 872ba8d365d8..8967432a40f5 100644
--- a/core/error.go
+++ b/core/error.go
@@ -100,4 +100,8 @@ var (
// ErrSenderNoEOA is returned if the sender of a transaction is a contract.
ErrSenderNoEOA = errors.New("sender not an eoa")
+
+ // ErrBlobFeeCapTooLow is returned if the transaction fee cap is less than the
+ // data gas fee of the block.
+ ErrBlobFeeCapTooLow = errors.New("max fee per data gas less than block data gas fee")
)
diff --git a/core/evm.go b/core/evm.go
index b7ff7790295b..f4e6aa43f427 100644
--- a/core/evm.go
+++ b/core/evm.go
@@ -56,16 +56,17 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
random = &header.MixDigest
}
return vm.BlockContext{
- CanTransfer: CanTransfer,
- Transfer: Transfer,
- GetHash: GetHashFn(header, chain),
- Coinbase: beneficiary,
- BlockNumber: new(big.Int).Set(header.Number),
- Time: header.Time,
- Difficulty: new(big.Int).Set(header.Difficulty),
- BaseFee: baseFee,
- GasLimit: header.GasLimit,
- Random: random,
+ CanTransfer: CanTransfer,
+ Transfer: Transfer,
+ GetHash: GetHashFn(header, chain),
+ Coinbase: beneficiary,
+ BlockNumber: new(big.Int).Set(header.Number),
+ Time: header.Time,
+ Difficulty: new(big.Int).Set(header.Difficulty),
+ BaseFee: baseFee,
+ GasLimit: header.GasLimit,
+ Random: random,
+ ExcessDataGas: header.ExcessDataGas,
}
}
diff --git a/core/gen_genesis.go b/core/gen_genesis.go
index 4e0844e889ab..6e641e291ea2 100644
--- a/core/gen_genesis.go
+++ b/core/gen_genesis.go
@@ -18,19 +18,21 @@ var _ = (*genesisSpecMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (g Genesis) MarshalJSON() ([]byte, error) {
type Genesis struct {
- Config *params.ChainConfig `json:"config"`
- Nonce math.HexOrDecimal64 `json:"nonce"`
- Timestamp math.HexOrDecimal64 `json:"timestamp"`
- ExtraData hexutil.Bytes `json:"extraData"`
- GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
- Mixhash common.Hash `json:"mixHash"`
- Coinbase common.Address `json:"coinbase"`
- Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
- Number math.HexOrDecimal64 `json:"number"`
- GasUsed math.HexOrDecimal64 `json:"gasUsed"`
- ParentHash common.Hash `json:"parentHash"`
- BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
+ Config *params.ChainConfig `json:"config"`
+ Nonce math.HexOrDecimal64 `json:"nonce"`
+ Timestamp math.HexOrDecimal64 `json:"timestamp"`
+ ExtraData hexutil.Bytes `json:"extraData"`
+ GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
+ Mixhash common.Hash `json:"mixHash"`
+ Coinbase common.Address `json:"coinbase"`
+ Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
+ Number math.HexOrDecimal64 `json:"number"`
+ GasUsed math.HexOrDecimal64 `json:"gasUsed"`
+ ParentHash common.Hash `json:"parentHash"`
+ BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
+ DataGasUsed *math.HexOrDecimal64 `json:"dataGasUsed"`
+ ExcessDataGas *math.HexOrDecimal64 `json:"excessDataGas"`
}
var enc Genesis
enc.Config = g.Config
@@ -51,25 +53,29 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
enc.GasUsed = math.HexOrDecimal64(g.GasUsed)
enc.ParentHash = g.ParentHash
enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee)
+ enc.DataGasUsed = (*math.HexOrDecimal64)(g.DataGasUsed)
+ enc.ExcessDataGas = (*math.HexOrDecimal64)(g.ExcessDataGas)
return json.Marshal(&enc)
}
// UnmarshalJSON unmarshals from JSON.
func (g *Genesis) UnmarshalJSON(input []byte) error {
type Genesis struct {
- Config *params.ChainConfig `json:"config"`
- Nonce *math.HexOrDecimal64 `json:"nonce"`
- Timestamp *math.HexOrDecimal64 `json:"timestamp"`
- ExtraData *hexutil.Bytes `json:"extraData"`
- GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
- Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
- Mixhash *common.Hash `json:"mixHash"`
- Coinbase *common.Address `json:"coinbase"`
- Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
- Number *math.HexOrDecimal64 `json:"number"`
- GasUsed *math.HexOrDecimal64 `json:"gasUsed"`
- ParentHash *common.Hash `json:"parentHash"`
- BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
+ Config *params.ChainConfig `json:"config"`
+ Nonce *math.HexOrDecimal64 `json:"nonce"`
+ Timestamp *math.HexOrDecimal64 `json:"timestamp"`
+ ExtraData *hexutil.Bytes `json:"extraData"`
+ GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"`
+ Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"`
+ Mixhash *common.Hash `json:"mixHash"`
+ Coinbase *common.Address `json:"coinbase"`
+ Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"`
+ Number *math.HexOrDecimal64 `json:"number"`
+ GasUsed *math.HexOrDecimal64 `json:"gasUsed"`
+ ParentHash *common.Hash `json:"parentHash"`
+ BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"`
+ DataGasUsed *math.HexOrDecimal64 `json:"dataGasUsed"`
+ ExcessDataGas *math.HexOrDecimal64 `json:"excessDataGas"`
}
var dec Genesis
if err := json.Unmarshal(input, &dec); err != nil {
@@ -120,5 +126,11 @@ func (g *Genesis) UnmarshalJSON(input []byte) error {
if dec.BaseFee != nil {
g.BaseFee = (*big.Int)(dec.BaseFee)
}
+ if dec.DataGasUsed != nil {
+ g.DataGasUsed = (*uint64)(dec.DataGasUsed)
+ }
+ if dec.ExcessDataGas != nil {
+ g.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
+ }
return nil
}
diff --git a/core/genesis.go b/core/genesis.go
index 1e56845d8ad3..d819b15260a4 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -59,10 +59,12 @@ type Genesis struct {
// These fields are used for consensus tests. Please don't use them
// in actual genesis blocks.
- Number uint64 `json:"number"`
- GasUsed uint64 `json:"gasUsed"`
- ParentHash common.Hash `json:"parentHash"`
- BaseFee *big.Int `json:"baseFeePerGas"`
+ Number uint64 `json:"number"`
+ GasUsed uint64 `json:"gasUsed"`
+ ParentHash common.Hash `json:"parentHash"`
+ BaseFee *big.Int `json:"baseFeePerGas"`
+ DataGasUsed *uint64 `json:"dataGasUsed"`
+ ExcessDataGas *uint64 `json:"excessDataGas"`
}
func ReadGenesis(db ethdb.Database) (*Genesis, error) {
@@ -214,15 +216,17 @@ type GenesisAccount struct {
// field type overrides for gencodec
type genesisSpecMarshaling struct {
- Nonce math.HexOrDecimal64
- Timestamp math.HexOrDecimal64
- ExtraData hexutil.Bytes
- GasLimit math.HexOrDecimal64
- GasUsed math.HexOrDecimal64
- Number math.HexOrDecimal64
- Difficulty *math.HexOrDecimal256
- BaseFee *math.HexOrDecimal256
- Alloc map[common.UnprefixedAddress]GenesisAccount
+ Nonce math.HexOrDecimal64
+ Timestamp math.HexOrDecimal64
+ ExtraData hexutil.Bytes
+ GasLimit math.HexOrDecimal64
+ GasUsed math.HexOrDecimal64
+ Number math.HexOrDecimal64
+ Difficulty *math.HexOrDecimal256
+ BaseFee *math.HexOrDecimal256
+ DataGasUsed *math.HexOrDecimal64
+ ExcessDataGas *math.HexOrDecimal64
+ Alloc map[common.UnprefixedAddress]GenesisAccount
}
type genesisAccountMarshaling struct {
@@ -463,6 +467,20 @@ func (g *Genesis) ToBlock() *types.Block {
head.WithdrawalsHash = &types.EmptyWithdrawalsHash
withdrawals = make([]*types.Withdrawal, 0)
}
+ if g.Config != nil && g.Config.IsCancun(big.NewInt(int64(g.Number)), g.Timestamp) {
+ if g.DataGasUsed == nil {
+ var dataGasUsed uint64
+ head.DataGasUsed = &dataGasUsed
+ } else {
+ head.DataGasUsed = g.DataGasUsed
+ }
+ if g.ExcessDataGas == nil {
+ var excessDataGas uint64
+ head.ExcessDataGas = &excessDataGas
+ } else {
+ head.ExcessDataGas = g.ExcessDataGas
+ }
+ }
return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)).WithWithdrawals(withdrawals)
}
diff --git a/core/state_processor.go b/core/state_processor.go
index 4837628e6602..fcaf5a8ff3c9 100644
--- a/core/state_processor.go
+++ b/core/state_processor.go
@@ -157,6 +157,6 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
}
// Create a new context to be used in the EVM environment
blockContext := NewEVMBlockContext(header, bc, author)
- vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, cfg)
+ vmenv := vm.NewEVM(blockContext, vm.TxContext{BlobHashes: tx.BlobHashes()}, statedb, config, cfg)
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
}
diff --git a/core/state_transition.go b/core/state_transition.go
index 022238c8d640..b77add593ec1 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/common"
cmath "github.com/ethereum/go-ethereum/common/math"
+ "github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
@@ -125,17 +126,18 @@ func toWordSize(size uint64) uint64 {
// A Message contains the data derived from a single transaction that is relevant to state
// processing.
type Message struct {
- To *common.Address
- From common.Address
- Nonce uint64
- Value *big.Int
- GasLimit uint64
- GasPrice *big.Int
- GasFeeCap *big.Int
- GasTipCap *big.Int
- Data []byte
- AccessList types.AccessList
- BlobHashes []common.Hash
+ To *common.Address
+ From common.Address
+ Nonce uint64
+ Value *big.Int
+ GasLimit uint64
+ GasPrice *big.Int
+ GasFeeCap *big.Int
+ GasTipCap *big.Int
+ Data []byte
+ AccessList types.AccessList
+ BlobGasFeeCap *big.Int
+ BlobHashes []common.Hash
// When SkipAccountChecks is true, the message nonce is not checked against the
// account nonce in state. It also disables checking that the sender is an EOA.
@@ -157,6 +159,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
AccessList: tx.AccessList(),
SkipAccountChecks: false,
BlobHashes: tx.BlobHashes(),
+ BlobGasFeeCap: tx.BlobGasFeeCap(),
}
// If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil {
@@ -230,12 +233,30 @@ func (st *StateTransition) to() common.Address {
func (st *StateTransition) buyGas() error {
mgval := new(big.Int).SetUint64(st.msg.GasLimit)
mgval = mgval.Mul(mgval, st.msg.GasPrice)
+
balanceCheck := mgval
if st.msg.GasFeeCap != nil {
balanceCheck = new(big.Int).SetUint64(st.msg.GasLimit)
balanceCheck = balanceCheck.Mul(balanceCheck, st.msg.GasFeeCap)
balanceCheck.Add(balanceCheck, st.msg.Value)
}
+
+ if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) {
+ if dataGas := st.dataGasUsed(); dataGas > 0 {
+ if st.evm.Context.ExcessDataGas == nil {
+ panic("adsf")
+ }
+ // Check that the user has enough funds to cover dataGasUsed * tx.BlobGasFeeCap
+ blobBalanceCheck := new(big.Int).SetUint64(dataGas)
+ blobBalanceCheck.Mul(blobBalanceCheck, st.msg.BlobGasFeeCap)
+ balanceCheck.Add(balanceCheck, blobBalanceCheck)
+ // Pay for dataGasUsed * actual blob fee
+ blobFee := new(big.Int).SetUint64(dataGas)
+ blobFee.Mul(blobFee, misc.CalcBlobFee(*st.evm.Context.ExcessDataGas))
+ mgval.Add(mgval, blobFee)
+ }
+ }
+
if have, want := st.state.GetBalance(st.msg.From), balanceCheck; have.Cmp(want) < 0 {
return fmt.Errorf("%w: address %v have %v want %v", ErrInsufficientFunds, st.msg.From.Hex(), have, want)
}
@@ -297,6 +318,15 @@ func (st *StateTransition) preCheck() error {
}
}
}
+
+ if st.evm.ChainConfig().IsCancun(st.evm.Context.BlockNumber, st.evm.Context.Time) {
+ if st.dataGasUsed() > 0 {
+ // Check that the user is paying at least the current blob fee
+ if have, want := st.msg.BlobGasFeeCap, misc.CalcBlobFee(*st.evm.Context.ExcessDataGas); have.Cmp(want) < 0 {
+ return fmt.Errorf("%w: address %v have %v want %v", ErrBlobFeeCapTooLow, st.msg.From.Hex(), have, want)
+ }
+ }
+ }
return st.buyGas()
}
@@ -427,3 +457,8 @@ func (st *StateTransition) refundGas(refundQuotient uint64) {
func (st *StateTransition) gasUsed() uint64 {
return st.initialGas - st.gasRemaining
}
+
+// dataGasUsed returns the amount of data gas used by the message.
+func (st *StateTransition) dataGasUsed() uint64 {
+ return uint64(len(st.msg.BlobHashes) * params.BlobTxDataGasPerBlob)
+}
diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go
new file mode 100644
index 000000000000..2b90a79b57f9
--- /dev/null
+++ b/core/txpool/blobpool/blobpool.go
@@ -0,0 +1,1415 @@
+// Copyright 2022 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// Package blobpool implements the EIP-4844 blob transaction pool.
+package blobpool
+
+import (
+ "container/heap"
+ "fmt"
+ "math"
+ "math/big"
+ "os"
+ "path/filepath"
+ "sort"
+ "sync"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/misc"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/txpool"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/metrics"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/holiman/billy"
+ "github.com/holiman/uint256"
+)
+
+const (
+ // blobSize is the protocol constrained byte size of a single blob in a
+ // transaction. There can be multiple of these embedded into a single tx.
+ blobSize = params.BlobTxFieldElementsPerBlob * params.BlobTxBytesPerFieldElement
+
+ // maxBlobsPerTransaction is the maximum number of blobs a single transaction
+ // is allowed to contain. Whilst the spec states it's unlimited, the block
+ // data slots are protocol bound, which implicitly also limit this.
+ maxBlobsPerTransaction = params.BlobTxMaxDataGasPerBlock / params.BlobTxDataGasPerBlob
+
+ // txAvgSize is an approximate byte size of a transaction metadata to avoid
+ // tiny overflows causing all txs to move a shelf higher, wasting disk space.
+ txAvgSize = 4 * 1024
+
+ // txMaxSize is the maximum size a single transaction can have, outside
+ // the included blobs. Since blob transactions are pulled instead of pushed,
+ // and only a small metadata is kept in ram, the rest is on disk, there is
+ // no critical limit that should be enforced. Still, capping it to some sane
+ // limit can never hurt.
+ txMaxSize = 1024 * 1024
+
+ // pendingTransactionStore is the subfolder containing the currently queued
+ // blob transactions.
+ pendingTransactionStore = "queue"
+
+ // limboedTransactionStore is the subfolder containing the currently included
+ // but not yet finalized transaction blobs.
+ limboedTransactionStore = "limbo"
+)
+
+// blobTx is a wrapper around types.BlobTx which also contains the literal blob
+// data along with all the transaction metadata.
+type blobTx struct {
+ Tx *types.Transaction
+
+ Blobs []kzg4844.Blob
+ Commits []kzg4844.Commitment
+ Proofs []kzg4844.Proof
+}
+
+// blobTxMeta is the minimal subset of types.BlobTx necessary to validate and
+// schedule the blob transactions into the following blocks. Only ever add the
+// bare minimum needed fields to keep the size down (and thus number of entries
+// larger with the same memory consumption).
+type blobTxMeta struct {
+ hash common.Hash // Transaction hash to maintain the lookup table
+ id uint64 // Storage ID in the pool's persistent store
+ size uint32 // Byte size in the pool's persistent store
+
+ nonce uint64 // Needed to prioritize inclusion order within an account
+ costCap *uint256.Int // Needed to validate cummulative balance sufficiency
+ execTipCap *uint256.Int // Needed to prioritize inclusion order across accounts and validate replacement price bump
+ execFeeCap *uint256.Int // Needed to validate replacement price bump
+ blobFeeCap *uint256.Int // Needed to validate replacement price bump
+
+ basefeeJumps float64 // Absolute number of 1559 fee adjustments needed to reach the tx's fee cap
+ blobfeeJumps float64 // Absolute number of 4844 fee adjustments needed to reach the tx's blob fee cap
+
+ evictionExecTip *uint256.Int // Worst gas tip across all previous nonces
+ evictionExecFeeJumps float64 // Worst base fee (converted to fee jumps) across all previous nonces
+ evictionBlobFeeJumps float64 // Worse blob fee (converted to fee jumps) across all previous nonces
+}
+
+// newBlobTxMeta retrieves the indexed metadata fields from a blob transaction
+// and assembles a helper struct to track in memory.
+func newBlobTxMeta(id uint64, size uint32, tx *types.Transaction) *blobTxMeta {
+ meta := &blobTxMeta{
+ hash: tx.Hash(),
+ id: id,
+ size: size,
+ nonce: tx.Nonce(),
+ costCap: uint256.MustFromBig(tx.Cost()),
+ execTipCap: uint256.MustFromBig(tx.GasTipCap()),
+ execFeeCap: uint256.MustFromBig(tx.GasFeeCap()),
+ blobFeeCap: uint256.MustFromBig(tx.BlobGasFeeCap()),
+ }
+ meta.basefeeJumps = dynamicFeeJumps(meta.execFeeCap)
+ meta.blobfeeJumps = dynamicFeeJumps(meta.blobFeeCap)
+
+ return meta
+}
+
+// BlobTxShim is an extremely tiny subset of a blob transaction that is used by
+// the miner to sort and select transactions to include, requesting the needed
+// data only for those transactions that will really get added to the next block.
+type BlobTxShim struct {
+}
+
+// BlobPool is the transaction pool dedicated to EIP-4844 blob transactions.
+//
+// Blob transactions are special snowflakes that are designed for a very specific
+// purpose (rollups) and are expected to adhere to that specific use case. These
+// behavioral expectations allow us to design a transaction pool that is more robust
+// (i.e. resending issues) and more resilient to DoS attacks (e.g. replace-flush
+// attacks) than the generic tx pool. These improvemenets will also mean, however,
+// that we enforce a significantly more agressive strategy on entering and exiting
+// the pool:
+//
+// - Blob transactions are large. With the initial design aiming for 128KB blobs,
+// we must ensure that these only traverse the network the absolute minimum
+// number of times. Broadcasting to sqrt(peers) is out of the question, rather
+// these should only ever be announced and the remote side should request it if
+// it wants to.
+//
+// - Block blob-space is limited. With blocks being capped to a few blob txs, we
+// can make use of the very low expected churn rate within the pool. Notably,
+// we should be able to use a persistent disk backend for the pool, solving
+// the tx resend issue that plagues the generic tx pool, as long as there's no
+// artificial churn (i.e. pool wars).
+//
+// - Purpose of blobs are layer-2s. Layer-2s are meant to use blob transactions to
+// commit to their own current state, which is independent of Ethereum mainnet
+// (state, txs). This means that there's no reason for blob tx cancellation or
+// replacement, apart from a potential basefee / miner tip adjustment.
+//
+// - Replacements are expensive. Given their size, propagating a replacement
+// blob transaction to an existing one should be agressively discouraged.
+// Whilst generic transactions can start at 1 Wei gas cost and require a 10%
+// fee bump to replace, we suggest requiring a higher min cost (e.g. 1 gwei)
+// and a more agressive bump (100%).
+//
+// - Cancellation is prohibitive. Evicting an already propagated blob tx is a huge
+// DoS vector. As such, a) replacement (higher-fee) blob txs mustn't invalidate
+// already propagated (future) blob txs (cummulative fee); b) nonce-gapped blob
+// txs are disallowed; c) the presence of blob transactions exclude non-blob
+// transactions.
+//
+// - Local txs are meaningless. Mining pools historically used local transactions
+// for payouts or for backdoor deals. With 1559 in place, the basefee usually
+// dominates the final price, so 0 or non-0 tip doesn't change much. Blob txs
+// retain the 1559 2D gas pricing (and introduce on top a dynamic data gas fee),
+// so locality is moot. With a disk backed blob pool avoiding the resend issue,
+// there's also no need to save own transactions for later.
+//
+// - No-blob blob-txs are bad. Theoretically there's no strong reason to disallow
+// blob txs containing 0 blobs. In practice, admitting such txs into the pool
+// breaks the low-churn invariant as blob constaints don't apply anymore. Even
+// though we could accept blocks contaning such txs, a reorg would require moving
+// them back into the blob pool, which can break invariants.
+//
+// - Dropping blobs needs delay. When normal transactions are included, they
+// are immediately evicted from the pool since they are contained in the
+// including block. Blobs however are not included in the execution chain,
+// so a mini reorg cannot re-pool "lost" blob transactions. To support reorgs,
+// blobs are retained on disk until they are finalized.
+//
+// - Blobs can arrive via flashbots. Blocks might contain blob transactions we
+// have never seen on the network. Since we cannot recover them from blocks
+// either, the engine_newPayload needs to give them to us, and we cache them
+// until finality to support reorgs without tx losses.
+//
+// Whilst some constraints above might sound overly agressive, the general idea is
+// that the blob pool should work robustly for its intended use case and whilst
+// anyone is free to use blob transactions for arbitrary non-rollup use cases,
+// they should not be allowed to run amok the network.
+//
+// Implementation wise there are a few interesting design choices:
+//
+// - Adding a transaction to the pool blocks until persisted to disk. This is
+// viable because TPS is low (2-4 blobs per block initially, maybe 8-16 at
+// peak), so natural churn is a couple MB per block. Replacements doing O(n)
+// updates are forbidden and transaction propagation is pull based (i.e. no
+// pileup of pending data).
+//
+// - When transactions are chosen for inclusion, the primary criteria is the
+// signer tip (and having a basefee/data fee high enough of course). However,
+// same-tip tranactions will be split by their basefee/datafee, prefering
+// those that are closer to the current network limits. The idea being that
+// very relaxed ones can be included even if the fees go up, when the closer
+// ones could already be invalid.
+//
+// When the pool eventually reaches saturation, some old transactions - that may
+// never execute - will need to be evicted in favor of newer ones. The eviction
+// strategy is quite complex:
+//
+// - Exceeding capacity evicts the highest-nonce of the account with the lowest
+// paying blob transaction anywhere in the pooled nonce-sequence, as that tx
+// would be executed the furthest in the future and is thus blocking anything
+// after it. The smallest is deliberately not evicted to avoid a nonce-gap.
+//
+// - Analogously, if the pool is full, the consideration price of a new tx for
+// evicting an old one is the smallest price in the entire nonce-sequence of
+// the account. This avoids malicious users DoSing the pool with seemingly
+// high paying transactions hidden behind a low-paying blocked one.
+//
+// - Since blob transactions have 3 price parameters: execution tip, execution
+// fee cap and data fee cap, there's no singular parameter to create a total
+// price ordering on. What's more, since the base fee and blob fee can move
+// independently of one another, there's no pre-defined way to combine them
+// into a stable order either. This leads to a multi-dimentional problem to
+// solve after every block.
+//
+// - The first observation is that comparing 1559 base fees or 4844 blob fees
+// needs to happen in the context of their dynamism. Since these fees jump
+// up or down in ~1.125 multipliers (at max) across blocks, comparing fees
+// in two transactions should be based on log1.125(fee) to eliminate noise.
+//
+// - The second observation is that the basefee and blobfee move independently,
+// so there's no way to split mixed txs on their own (A has higher base fee,
+// B has higher blob fee). Rather than look at the absolute fees, the useful
+// metric is the max time it can take to exceed the transaction's fee caps.
+// Specifically, we're interested in the number of jumps needed to go from
+// the current fee to the transaction's cap:
+//
+// jumps = log1.125(txfee) - log1.125(basefee)
+//
+// - The third observation is that the base fee tends to hover around rather
+// than swing wildly. The number of jumps needed from the current fee starts
+// to get less relevant the higher it is. To remove the noise here too, the
+// pool will use log(jumps) as the delta for comparing transactions.
+//
+// delta = sign(jumps) * log(abs(jumps))
+//
+// - To establish a total order, we need to reduce the dimensionality of the
+// two base fees (log jumps) to a single value. The interesting aspect from
+// the pool's perspective is how fast will a tx get executable (fees going
+// down, crossing the smaller negative jump counter) or non-executable (fees
+// going up, crossing the smaller positive jump counter). As such, the pool
+// cares only about the min of the two delta values for eviction priority.
+//
+// priority = min(delta-basefee, delta-blobfee)
+//
+// - The above very agressive dimensionality and noise reduction should result
+// in transaction being groupped into a small number of buckets, the further
+// the fees the larger the buckets. This is good because it allows us to use
+// the miner tip meaningfully as a splitter.
+//
+// - For the scenario where the pool does not contain non-executable blob txs
+// anymore, it does not make sense to grant a later eviction priority to txs
+// with high fee caps since it could enable pool wars. As such, any positive
+// priority will be groupped together.
+//
+// priority = min(delta-basefee, delta-blobfee, 0)
+//
+// Optimization tradeoffs:
+//
+// - Eviction relies on 3 fee minimums per account (exec tip, exec cap and blob
+// cap). Maintaining these values across all transactions from the account is
+// problematic as each transaction replacement or inclusion would require a
+// rescan of all other transactions to recalcualte the minimum. Instead, the
+// pool maintains a rolling minimum across the nonce range. Updating all the
+// minimums will need to be done only starting at the swapped in/out nonce
+// and leading up to the first no-change.
+type BlobPool struct {
+ config Config // Pool configuration
+
+ store billy.Database // Persistent data store for the tx metadata and blobs
+ stored uint64 // Useful data size of all transactions on disk
+ limbo *limbo // Persistent data store for the non-finalized blobs
+
+ signer types.Signer // Transaction signer to use for sender recovery
+ chain BlockChain // Chain object to access the state through
+
+ head *types.Header // Current head of the chain
+ state *state.StateDB // Current state at the head of the chain
+ gasTip *uint256.Int // Currently accepted minimum gas tip
+
+ lookup map[common.Hash]uint64 // Lookup table mapping hashes to tx billy entries
+ index map[common.Address][]*blobTxMeta // Blob transactions groupped by accounts, sorted by nonce
+ spent map[common.Address]*uint256.Int // Expenditure tracking for individual accounts
+ evict *evictHeap // Heap of cheapest accounts for eviction when full
+
+ eventFeed event.Feed // Event feed to send out new tx events on pool inclusion
+ eventScope event.SubscriptionScope // Event scope to track and mass unsubscribe on termination
+
+ lock sync.RWMutex // Mutex protecting the pool during reorg handling
+}
+
+// New creates a new blob transaction pool to gather, sort and filter inbound
+// blob transactions from the network.
+func New(config Config, chain BlockChain) *BlobPool {
+ // Sanitize the input to ensure no vulnerable gas prices are set
+ config = (&config).sanitize()
+
+ // Create the transaction pool with its initial settings
+ return &BlobPool{
+ config: config,
+ signer: types.LatestSigner(chain.Config()),
+ chain: chain,
+ lookup: make(map[common.Hash]uint64),
+ index: make(map[common.Address][]*blobTxMeta),
+ spent: make(map[common.Address]*uint256.Int),
+ }
+}
+
+// Filter returns whether the given transaction can be consumed by the blob pool.
+func (p *BlobPool) Filter(tx *types.Transaction) bool {
+ return tx.Type() == types.BlobTxType
+}
+
+// Init sets the gas price needed to keep a transaction in the pool and the chain
+// head to allow balance / nonce checks. The transaction journal will be loaded
+// from disk and filtered based on the provided starting settings.
+func (p *BlobPool) Init(gasTip *big.Int, head *types.Header) error {
+ var (
+ queuedir = filepath.Join(p.config.Datadir, pendingTransactionStore)
+ limbodir = filepath.Join(p.config.Datadir, limboedTransactionStore)
+ )
+ state, err := p.chain.StateAt(head.Root)
+ if err != nil {
+ return err
+ }
+ p.head, p.state = head, state
+
+ // Index all transactions on disk and delete anything inprocessable
+ var fails []uint64
+ index := func(id uint64, size uint32, blob []byte) {
+ if p.parseTransaction(id, size, blob) != nil {
+ fails = append(fails, id)
+ }
+ }
+ if err := os.MkdirAll(queuedir, 0700); err != nil {
+ return err
+ }
+ store, err := billy.Open(billy.Options{Path: queuedir}, newSlotter(), index)
+ if err != nil {
+ return err
+ }
+ p.store = store
+
+ if len(fails) > 0 {
+ log.Warn("Dropping invalidated blob transactions", "ids", fails)
+ for _, id := range fails {
+ if err := p.store.Delete(id); err != nil {
+ p.Close()
+ return err
+ }
+ }
+ }
+ // Sort the indexed transactions by nonce and delete anything gapped, create
+ // the eviction heap of anyone still standing
+ for addr, _ := range p.index {
+ p.recheck(addr, nil)
+ }
+ var (
+ basefee = uint256.MustFromBig(misc.CalcBaseFee(p.chain.Config(), p.head))
+ blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinDataGasprice))
+ )
+ if p.head.ExcessDataGas != nil {
+ blobfee = uint256.MustFromBig(misc.CalcBlobFee(*p.head.ExcessDataGas))
+ }
+ p.evict = newPriceHeap(basefee, blobfee, &p.index)
+
+ // Pool initialized, attach the blob limbo to it to track blobs included
+ // recently but not yet finalized
+ p.limbo, err = newLimbo(limbodir)
+ if err != nil {
+ p.Close()
+ return err
+ }
+ // Set the configured gas tip, triggering a filtering of anything just loaded
+ basefeeGauge.Update(int64(basefee.Uint64()))
+ blobfeeGauge.Update(int64(blobfee.Uint64()))
+
+ p.SetGasTip(gasTip)
+
+ // Since the user might have modified their pool's capacity, evict anything
+ // above the current allowance
+ for p.stored > p.config.Datacap {
+ p.drop()
+ }
+ // Updat the metrics and return the cosntructed pool
+ datacapGauge.Update(int64(p.config.Datacap))
+ p.updateStorageMetrics()
+ return nil
+}
+
+// Close closes down the underlying persistent store.
+func (p *BlobPool) Close() error {
+ var errs []error
+ if err := p.limbo.Close(); err != nil {
+ errs = append(errs, err)
+ }
+ if err := p.store.Close(); err != nil {
+ errs = append(errs, err)
+ }
+ p.eventScope.Close()
+
+ switch {
+ case errs == nil:
+ return nil
+ case len(errs) == 1:
+ return errs[0]
+ default:
+ return fmt.Errorf("%v", errs)
+ }
+}
+
+// parseTransaction is a callback method on pool creation that gets called for
+// each transaction on disk to create the in-memory metadata index.
+func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error {
+ item := new(blobTx)
+ if err := rlp.DecodeBytes(blob, item); err != nil {
+ // This path is impossible unless the disk data representation changes
+ // across restarts. For that ever unprobable case, recover gracefully
+ // by ignoring this data entry.
+ log.Error("Failed to decode blob pool entry", "id", id, "err", err)
+ return err
+ }
+ meta := newBlobTxMeta(id, size, item.Tx)
+
+ sender, err := p.signer.Sender(item.Tx)
+ if err != nil {
+ // This path is impossible unless the signature validity changes across
+ // restarts. For that ever unprobable case, recover gracefully by ignoring
+ // this data entry.
+ log.Error("Failed to recover blob tx sender", "id", id, "hash", item.Tx.Hash(), "err", err)
+ return err
+ }
+ if _, ok := p.index[sender]; !ok {
+ p.index[sender] = []*blobTxMeta{}
+ p.spent[sender] = new(uint256.Int)
+ }
+ p.index[sender] = append(p.index[sender], meta)
+ p.spent[sender] = new(uint256.Int).Add(p.spent[sender], meta.costCap)
+
+ p.lookup[meta.hash] = meta.id
+ p.stored += uint64(meta.size)
+
+ return nil
+}
+
+// recheck verifies the pool's content for a specific account and drops anything
+// that does not fit anymore (dangling or filled nonce, overdraft).
+func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint64) {
+ // Sort the transactions belonging to the account so reinjects can be simpler
+ txs := p.index[addr]
+ if inclusions != nil && txs == nil { // during reorgs, we might find new accounts
+ return
+ }
+ sort.Slice(txs, func(i, j int) bool {
+ return txs[i].nonce < txs[j].nonce
+ })
+ // If there is a gap between the chain state and the blob pool, drop
+ // all the transactions as they are non-executable. Similarly, if the
+ // entire tx range was included, drop all.
+ var (
+ next = p.state.GetNonce(addr)
+ gapped = txs[0].nonce > next
+ filled = txs[len(txs)-1].nonce < next
+ )
+ if gapped || filled {
+ var (
+ ids []uint64
+ nonces []uint64
+ )
+ for i := 0; i < len(txs); i++ {
+ ids = append(ids, txs[i].id)
+ nonces = append(nonces, txs[i].nonce)
+
+ p.stored -= uint64(txs[i].size)
+ delete(p.lookup, txs[i].hash)
+
+ // Included transactions blobs need to be moved to the limbo
+ if filled && inclusions != nil {
+ p.offload(addr, txs[i].nonce, txs[i].id, inclusions)
+ }
+ }
+ delete(p.index, addr)
+ delete(p.spent, addr)
+ if inclusions != nil { // only during reorgs will the heap will be initialized
+ heap.Remove(p.evict, p.evict.index[addr])
+ }
+ if gapped {
+ log.Warn("Dropping dangling blob transactions", "from", addr, "missing", next, "drop", nonces, "ids", ids)
+ } else {
+ log.Warn("Dropping filled blob transactions", "from", addr, "filled", nonces, "ids", ids)
+ }
+ for _, id := range ids {
+ if err := p.store.Delete(id); err != nil {
+ log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
+ }
+ }
+ return
+ }
+ // If there is overlap between the chain state and the blob pool, drop
+ // anything below the current state
+ if txs[0].nonce < next {
+ var (
+ ids []uint64
+ nonces []uint64
+ )
+ for txs[0].nonce < next {
+ ids = append(ids, txs[0].id)
+ nonces = append(nonces, txs[0].nonce)
+
+ p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[0].costCap)
+ p.stored -= uint64(txs[0].size)
+ delete(p.lookup, txs[0].hash)
+
+ // Included transactions blobs need to be moved to the limbo
+ if filled && inclusions != nil {
+ p.offload(addr, txs[0].nonce, txs[0].id, inclusions)
+ }
+ txs = txs[1:]
+ }
+ log.Warn("Dropping overlapped blob transactions", "from", addr, "overlapped", nonces, "ids", ids, "left", len(txs))
+ for _, id := range ids {
+ if err := p.store.Delete(id); err != nil {
+ log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
+ }
+ }
+ p.index[addr] = txs
+ }
+ // Iterate over the transactions to initialize their eviction thresholds
+ // and to detect any nonce gaps
+ txs[0].evictionExecTip = txs[0].execTipCap
+ txs[0].evictionExecFeeJumps = txs[0].basefeeJumps
+ txs[0].evictionBlobFeeJumps = txs[0].blobfeeJumps
+
+ for i := 1; i < len(txs); i++ {
+ // If there's no nonce gap, initialize the evicion thresholds as the
+ // minimum between the cumulative thresholds and the current tx fees
+ if txs[i].nonce == txs[i-1].nonce+1 {
+ txs[i].evictionExecTip = txs[i-1].evictionExecTip
+ if txs[i].evictionExecTip.Cmp(txs[i].execTipCap) > 0 {
+ txs[i].evictionExecTip = txs[i].execTipCap
+ }
+ txs[i].evictionExecFeeJumps = txs[i-1].evictionExecFeeJumps
+ if txs[i].evictionExecFeeJumps > txs[i].basefeeJumps {
+ txs[i].evictionExecFeeJumps = txs[i].basefeeJumps
+ }
+ txs[i].evictionBlobFeeJumps = txs[i-1].evictionBlobFeeJumps
+ if txs[i].evictionBlobFeeJumps > txs[i].blobfeeJumps {
+ txs[i].evictionBlobFeeJumps = txs[i].blobfeeJumps
+ }
+ continue
+ }
+ // Sanity check that there's no double nonce. This case would be a coding
+ // error, but better know about it
+ if txs[i].nonce == txs[i-1].nonce {
+ log.Error("Duplicate nonce blob transaction", "from", addr, "nonce", txs[i].nonce)
+ }
+ // Otherwise if there's a nonce gap evict all later transactions
+ var (
+ ids []uint64
+ nonces []uint64
+ )
+ for j := i; j < len(txs); j++ {
+ ids = append(ids, txs[j].id)
+ nonces = append(nonces, txs[j].nonce)
+
+ p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[j].costCap)
+ p.stored -= uint64(txs[j].size)
+ delete(p.lookup, txs[j].hash)
+ }
+ p.index[addr] = txs[:i]
+
+ log.Warn("Dropping gapped blob transactions", "from", addr, "missing", txs[i-1].nonce+1, "drop", nonces, "ids", ids)
+ for _, id := range ids {
+ if err := p.store.Delete(id); err != nil {
+ log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
+ }
+ }
+ break
+ }
+ // Ensure that there's no over-draft, this is expected to happen when some
+ // transctions get included without publishing on the network
+ var (
+ balance = p.state.GetBalance(addr)
+ spent = p.spent[addr]
+ )
+ if spent.ToBig().Cmp(balance) > 0 {
+ // Evict the highest nonce transactions until the pending set falls under
+ // the account's available balance
+ var (
+ ids []uint64
+ nonces []uint64
+ )
+ for p.spent[addr].ToBig().Cmp(balance) > 0 {
+ last := txs[len(txs)-1]
+ txs[len(txs)-1] = nil
+ txs = txs[:len(txs)-1]
+
+ ids = append(ids, last.id)
+ nonces = append(nonces, last.nonce)
+
+ p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], last.costCap)
+ p.stored -= uint64(last.size)
+ delete(p.lookup, last.hash)
+ }
+ if len(txs) == 0 {
+ delete(p.index, addr)
+ delete(p.spent, addr)
+ if inclusions != nil { // only during reorgs will the heap will be initialized
+ heap.Remove(p.evict, p.evict.index[addr])
+ }
+ } else {
+ p.index[addr] = txs
+ }
+ log.Warn("Dropping overdrafted blob transactions", "from", addr, "balance", balance, "spent", spent, "drop", nonces, "ids", ids)
+ for _, id := range ids {
+ if err := p.store.Delete(id); err != nil {
+ log.Error("Failed to delete blob transaction", "from", addr, "id", id, "err", err)
+ }
+ }
+ }
+}
+
+// offload removes a tracked blob transaction from the pool and moves it into the
+// limbo for tracking until finality.
+//
+// The method may log errors for various unexpcted scenarios but will not return
+// any of it since there's no clear error case. Some errors may be due to coding
+// issues, others caused by signers mining MEV stuff or swapping transactions. In
+// all cases, the pool needs to continue operating.
+func (p *BlobPool) offload(addr common.Address, nonce uint64, id uint64, inclusions map[common.Hash]uint64) {
+ data, err := p.store.Get(id)
+ if err != nil {
+ log.Error("Blobs missing for included transaction", "from", addr, "nonce", nonce, "id", id, "err", err)
+ return
+ }
+ item := new(blobTx)
+ if err = rlp.DecodeBytes(data, item); err != nil {
+ log.Error("Blobs corrupted for included transaction", "from", addr, "nonce", nonce, "id", id, "err", err)
+ return
+ }
+ block, ok := inclusions[item.Tx.Hash()]
+ if !ok {
+ log.Warn("Blob transaction swapped out by signer", "from", addr, "nonce", nonce, "id", id)
+ return
+ }
+ if err := p.limbo.push(item.Tx.Hash(), block, item.Blobs, item.Commits, item.Proofs); err != nil {
+ log.Warn("Failed to offload blob tx into limbo", "err", err)
+ return
+ }
+}
+
+// Reset implements txpool.SubPool, allowing the blob pool's internal state to be
+// kept in sync with the main transacion pool's internal state.
+func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
+ waitStart := time.Now()
+ p.lock.Lock()
+ resetwaitHist.Update(time.Since(waitStart).Nanoseconds())
+ defer p.lock.Unlock()
+
+ defer func(start time.Time) {
+ resettimeHist.Update(time.Since(start).Nanoseconds())
+ }(time.Now())
+
+ statedb, err := p.chain.StateAt(newHead.Root)
+ if err != nil {
+ log.Error("Failed to reset blobpool state", "err", err)
+ return
+ }
+ p.head = newHead
+ p.state = statedb
+
+ // Run the reorg between the old and new head and figure out which accounts
+ // need to be rechecked and which transactions need to be readded
+ if reinject, inclusions := p.reorg(oldHead, newHead); reinject != nil {
+ for addr, txs := range reinject {
+ // Blindly push all the lost transactions back into the pool
+ for _, tx := range txs {
+ p.reinject(addr, tx)
+ }
+ // Recheck the account's pooled transactions to drop included and
+ // invalidated one
+ p.recheck(addr, inclusions)
+ }
+ }
+ // Flush out any blobs from limbo that are older than the latest finality
+ p.limbo.finalize(p.chain.CurrentFinalBlock())
+
+ // Reset the price heap for the new set of basefee/blobfee pairs
+ var (
+ basefee = uint256.MustFromBig(misc.CalcBaseFee(p.chain.Config(), newHead))
+ blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinDataGasprice))
+ )
+ if newHead.ExcessDataGas != nil {
+ blobfee = uint256.MustFromBig(misc.CalcBlobFee(*newHead.ExcessDataGas))
+ }
+ p.evict.reinit(basefee, blobfee, false)
+
+ basefeeGauge.Update(int64(basefee.Uint64()))
+ blobfeeGauge.Update(int64(blobfee.Uint64()))
+ p.updateStorageMetrics()
+}
+
+// reorg assembles all the transactors and missing transactions between an old
+// and new head to figure out which account's tx set needs to be rechecked and
+// which transactions need to be requeued.
+//
+// The transactionblock inclusion infos are also returned to allow tracking any
+// just-included blocks by block number in the limbo.
+func (p *BlobPool) reorg(oldHead, newHead *types.Header) (map[common.Address][]*types.Transaction, map[common.Hash]uint64) {
+ // If the pool was not yet initialized, don't do anything
+ if oldHead == nil {
+ return nil, nil
+ }
+ // If the reorg is too deep, avoid doing it (will happen during snap sync)
+ oldNum := oldHead.Number.Uint64()
+ newNum := newHead.Number.Uint64()
+
+ if depth := uint64(math.Abs(float64(oldNum) - float64(newNum))); depth > 64 {
+ return nil, nil
+ }
+ // Reorg seems shallow enough to pull in all transactions into memory
+ var (
+ transactors = make(map[common.Address]struct{})
+ discarded = make(map[common.Address][]*types.Transaction)
+ included = make(map[common.Address][]*types.Transaction)
+ inclusions = make(map[common.Hash]uint64)
+
+ rem = p.chain.GetBlock(oldHead.Hash(), oldHead.Number.Uint64())
+ add = p.chain.GetBlock(newHead.Hash(), newHead.Number.Uint64())
+ )
+ if rem == nil {
+ // This can happen if a setHead is performed, where we simply discard
+ // the old head from the chain. If that is the case, we don't have the
+ // lost transactions anymore, and there's nothing to add.
+ if newNum >= oldNum {
+ // If we reorged to a same or higher number, then it's not a case
+ // of setHead
+ log.Warn("Blobpool reset with missing old head",
+ "old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum)
+ return nil, nil
+ }
+ // If the reorg ended up on a lower number, it's indicative of setHead
+ // being the cause
+ log.Debug("Skipping blobpool reset caused by setHead",
+ "old", oldHead.Hash(), "oldnum", oldNum, "new", newHead.Hash(), "newnum", newNum)
+ return nil, nil
+ }
+ // Both old and new blocks exist, traverse through the progression chain
+ // and accumulate the transactors and transactions
+ for rem.NumberU64() > add.NumberU64() {
+ for _, tx := range rem.Transactions() {
+ from, _ := p.signer.Sender(tx)
+
+ discarded[from] = append(discarded[from], tx)
+ transactors[from] = struct{}{}
+ }
+ if rem = p.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
+ log.Error("Unrooted old chain seen by blobpool", "block", oldHead.Number, "hash", oldHead.Hash())
+ return nil, nil
+ }
+ }
+ for add.NumberU64() > rem.NumberU64() {
+ for _, tx := range add.Transactions() {
+ from, _ := p.signer.Sender(tx)
+
+ included[from] = append(included[from], tx)
+ inclusions[tx.Hash()] = add.NumberU64()
+ transactors[from] = struct{}{}
+ }
+ if add = p.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
+ log.Error("Unrooted new chain seen by blobpool", "block", newHead.Number, "hash", newHead.Hash())
+ return nil, nil
+ }
+ }
+ for rem.Hash() != add.Hash() {
+ for _, tx := range rem.Transactions() {
+ from, _ := p.signer.Sender(tx)
+
+ discarded[from] = append(discarded[from], tx)
+ transactors[from] = struct{}{}
+ }
+ if rem = p.chain.GetBlock(rem.ParentHash(), rem.NumberU64()-1); rem == nil {
+ log.Error("Unrooted old chain seen by blobpool", "block", oldHead.Number, "hash", oldHead.Hash())
+ return nil, nil
+ }
+ for _, tx := range add.Transactions() {
+ from, _ := p.signer.Sender(tx)
+
+ included[from] = append(included[from], tx)
+ inclusions[tx.Hash()] = add.NumberU64()
+ transactors[from] = struct{}{}
+ }
+ if add = p.chain.GetBlock(add.ParentHash(), add.NumberU64()-1); add == nil {
+ log.Error("Unrooted new chain seen by blobpool", "block", newHead.Number, "hash", newHead.Hash())
+ return nil, nil
+ }
+ }
+ // Generate the set of transactions per address to pull back into the pool,
+ // also updating the rest along the way
+ reinject := make(map[common.Address][]*types.Transaction)
+ for addr := range transactors {
+ // Generate the set that was lost to reinject into the pool
+ lost := make([]*types.Transaction, 0, len(discarded[addr]))
+ for _, tx := range types.TxDifference(discarded[addr], included[addr]) {
+ if p.Filter(tx) {
+ lost = append(lost, tx)
+ }
+ }
+ reinject[addr] = lost
+
+ // Update the set that was already reincluded to track the blocks in limbo
+ for _, tx := range types.TxDifference(included[addr], discarded[addr]) {
+ if p.Filter(tx) {
+ p.limbo.update(tx.Hash(), inclusions[tx.Hash()])
+ }
+ }
+ }
+ return reinject, inclusions
+}
+
+// reinject blindly pushes a transaction previously inlcuded in the chain - and
+// just reorged out - into the pool. The transaction is assumed valid (having
+// been in the chain), thus the only validation needed is nonce sorting and over-
+// draft checks after injection.
+func (p *BlobPool) reinject(addr common.Address, tx *types.Transaction) {
+ // Retrieve the associated blob from the limbo. Without the blobs, we cannot
+ // add the transaction back into the pool as it is not mineable.
+ blobs, commits, proofs, err := p.limbo.pull(tx.Hash())
+ if err != nil {
+ log.Error("Blobs unavailable, dropping reorged tx", "err", err)
+ return
+ }
+ // Serialize the transaction back into the primary datastore
+ blob, err := rlp.EncodeToBytes(&blobTx{Tx: tx, Blobs: blobs, Commits: commits, Proofs: proofs})
+ if err != nil {
+ log.Error("Failed to encode transaction for storage", "hash", tx.Hash(), "err", err)
+ return
+ }
+ id, err := p.store.Put(blob)
+ if err != nil {
+ log.Error("Failed to write transaction into storage", "hash", tx.Hash(), "err", err)
+ return
+ }
+ // Update the indixes and metrics
+ meta := newBlobTxMeta(id, p.store.Size(id), tx)
+
+ if _, ok := p.index[addr]; !ok {
+ p.index[addr] = []*blobTxMeta{meta}
+ p.spent[addr] = meta.costCap
+ p.evict.Push(addr)
+ } else {
+ p.index[addr] = append(p.index[addr], meta)
+ p.spent[addr] = new(uint256.Int).Add(p.spent[addr], meta.costCap)
+ }
+ p.lookup[meta.hash] = meta.id
+ p.stored += uint64(meta.size)
+}
+
+// SetGasTip implements txpool.SubPool, allowing the blob pool's gas requirements
+// to be kept in sync with the main transacion pool's gas requirements.
+func (p *BlobPool) SetGasTip(tip *big.Int) {
+ p.lock.Lock()
+ defer p.lock.Unlock()
+
+ // Store the new minimum gas tip
+ old := p.gasTip
+ p.gasTip = uint256.MustFromBig(tip)
+
+ // If the min miner fee increased, remove transactions below the new threshold
+ if old == nil || p.gasTip.Cmp(old) > 0 {
+ for addr, txs := range p.index {
+ for i, tx := range txs {
+ if tx.execTipCap.Cmp(p.gasTip) < 0 {
+ // Drop the offending transaction
+ var (
+ ids = []uint64{tx.id}
+ nonces = []uint64{tx.nonce}
+ )
+ p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], txs[i].costCap)
+ p.stored -= uint64(tx.size)
+ delete(p.lookup, tx.hash)
+ txs[i] = nil
+
+ // Drop everything afterwards, no gaps allowed
+ for j, tx := range txs[i+1:] {
+ ids = append(ids, tx.id)
+ nonces = append(nonces, tx.nonce)
+
+ p.spent[addr] = new(uint256.Int).Sub(p.spent[addr], tx.costCap)
+ p.stored -= uint64(tx.size)
+ delete(p.lookup, tx.hash)
+ txs[i+1+j] = nil
+ }
+ // Clear out the dropped transactions from the index
+ if i > 0 {
+ p.index[addr] = txs[:i]
+ } else {
+ delete(p.index, addr)
+ delete(p.spent, addr)
+ }
+ // Clear out the transactions from the data store
+ log.Warn("Dropping underpriced blob transaction", "from", addr, "rejected", tx.nonce, "tip", tx.execTipCap, "want", tip, "drop", nonces, "ids", ids)
+ for _, id := range ids {
+ if err := p.store.Delete(id); err != nil {
+ log.Error("Failed to delete dropped transaction", "id", id, "err", err)
+ }
+ }
+ break
+ }
+ }
+ }
+ }
+ log.Debug("Blobpool tip threshold updated", "tip", tip)
+ pooltipGague.Update(tip.Int64())
+ p.updateStorageMetrics()
+}
+
+// validateTx checks whether a transaction is valid according to the consensus
+// rules and adheres to some heuristic limits of the local node (price and size).
+func (p *BlobPool) validateTx(tx *types.Transaction, blobs []kzg4844.Blob, commits []kzg4844.Commitment, proofs []kzg4844.Proof) error {
+ // Ensure the transaction adheres to basic pool filters (type, size, tip) and
+ // consensus rules
+ baseOpts := &txpool.ValidationOptions{
+ Config: p.chain.Config(),
+ Accept: 1 << types.BlobTxType,
+ MaxSize: txMaxSize,
+ MinTip: p.gasTip.ToBig(),
+ }
+ if err := txpool.ValidateTransaction(tx, blobs, commits, proofs, p.head, p.signer, baseOpts); err != nil {
+ return err
+ }
+ // Ensure the transaction adheres to the stateful pool filters (nonce, balance)
+ stateOpts := &txpool.ValidationOptionsWithState{
+ State: p.state,
+
+ FirstNonceGap: func(addr common.Address) uint64 {
+ // Nonce gaps are not permitted in the blob pool, the first gap will
+ // be the next nonce shifted by however many transactions we already
+ // have pooled.
+ return p.state.GetNonce(addr) + uint64(len(p.index[addr]))
+ },
+ ExistingExpenditure: func(addr common.Address) *big.Int {
+ if spent := p.spent[addr]; spent != nil {
+ return spent.ToBig()
+ }
+ return new(big.Int)
+ },
+ ExistingCost: func(addr common.Address, nonce uint64) *big.Int {
+ next := p.state.GetNonce(addr)
+ if uint64(len(p.index[addr])) > nonce-next {
+ return p.index[addr][int(tx.Nonce()-next)].costCap.ToBig()
+ }
+ return nil
+ },
+ }
+ if err := txpool.ValidateTransactionWithState(tx, p.signer, stateOpts); err != nil {
+ return err
+ }
+ // If the transaction replaces an existing one, ensure that price bumps are
+ // adhered to.
+ var (
+ from, _ = p.signer.Sender(tx) // already validated above
+ next = p.state.GetNonce(from)
+ )
+ if uint64(len(p.index[from])) > tx.Nonce()-next {
+ // Account can support the replacement, but the price bump must also be met
+ prev := p.index[from][int(tx.Nonce()-next)]
+ switch {
+ case tx.GasFeeCapIntCmp(prev.execFeeCap.ToBig()) <= 0:
+ return fmt.Errorf("%w: new tx gas fee cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.execFeeCap)
+ case tx.GasTipCapIntCmp(prev.execTipCap.ToBig()) <= 0:
+ return fmt.Errorf("%w: new tx gas tip cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.execTipCap)
+ case tx.BlobGasFeeCapIntCmp(prev.blobFeeCap.ToBig()) <= 0:
+ return fmt.Errorf("%w: new tx blob gas fee cap %v <= %v queued", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.blobFeeCap)
+ }
+ var (
+ multiplier = uint256.NewInt(100 + p.config.PriceBump)
+
+ minGasFeeCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.execFeeCap), uint256.NewInt(100))
+ minGasTipCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.execTipCap), uint256.NewInt(100))
+ minBlobGasFeeCap = new(uint256.Int).Div(new(uint256.Int).Mul(multiplier, prev.blobFeeCap), uint256.NewInt(100))
+ )
+ switch {
+ case tx.GasFeeCapIntCmp(minGasFeeCap.ToBig()) < 0:
+ return fmt.Errorf("%w: new tx gas fee cap %v <= %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasFeeCap(), prev.execFeeCap, p.config.PriceBump)
+ case tx.GasTipCapIntCmp(minGasTipCap.ToBig()) < 0:
+ return fmt.Errorf("%w: new tx gas tip cap %v <= %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.GasTipCap(), prev.execTipCap, p.config.PriceBump)
+ case tx.BlobGasFeeCapIntCmp(minBlobGasFeeCap.ToBig()) < 0:
+ return fmt.Errorf("%w: new tx blob gas fee cap %v <= %v queued + %d%% replacement penalty", txpool.ErrReplaceUnderpriced, tx.BlobGasFeeCap(), prev.blobFeeCap, p.config.PriceBump)
+ }
+ }
+ return nil
+}
+
+// Has returns an indicator whether subpool has a transaction cached with the
+// given hash.
+func (p *BlobPool) Has(hash common.Hash) bool {
+ p.lock.RLock()
+ defer p.lock.RUnlock()
+
+ _, ok := p.lookup[hash]
+ return ok
+}
+
+// Get returns a transaction if it is contained in the pool, or nil otherwise.
+func (p *BlobPool) Get(hash common.Hash) *txpool.Transaction {
+ p.lock.RLock()
+ defer p.lock.RUnlock()
+
+ id, ok := p.lookup[hash]
+ if !ok {
+ return nil
+ }
+ data, err := p.store.Get(id)
+ if err != nil {
+ log.Error("Tracked blob transaction missing from store", "hash", hash, "id", id, "err", err)
+ return nil
+ }
+ item := new(blobTx)
+ if err = rlp.DecodeBytes(data, item); err != nil {
+ log.Error("Blobs corrupted for traced transaction", "hash", hash, "id", id, "err", err)
+ return nil
+ }
+ return &txpool.Transaction{
+ Tx: item.Tx,
+ BlobTxBlobs: item.Blobs,
+ BlobTxCommits: item.Commits,
+ BlobTxProofs: item.Proofs,
+ }
+}
+
+// Add inserts a set of blob transactions into the pool if they pass validation (both
+// consensus validity and pool restictions).
+func (p *BlobPool) Add(txs []*txpool.Transaction, local bool, sync bool) []error {
+ errs := make([]error, len(txs))
+ for i, tx := range txs {
+ errs[i] = p.add(tx.Tx, tx.BlobTxBlobs, tx.BlobTxCommits, tx.BlobTxProofs)
+ }
+ return errs
+}
+
+// Add inserts a new blob transaction into the pool if it passes validation (both
+// consensus validity and pool restictions).
+func (p *BlobPool) add(tx *types.Transaction, blobs []kzg4844.Blob, commits []kzg4844.Commitment, proofs []kzg4844.Proof) error {
+ // The blob pool blocks on adding a transaction. This is because blob txs are
+ // only even pulled form the network, so this method will act as the overload
+ // protection for fetches.
+ waitStart := time.Now()
+ p.lock.Lock()
+ addwaitHist.Update(time.Since(waitStart).Nanoseconds())
+ defer p.lock.Unlock()
+
+ defer func(start time.Time) {
+ addtimeHist.Update(time.Since(start).Nanoseconds())
+ }(time.Now())
+
+ // Ensure the transaction is valid from all perspectives
+ if err := p.validateTx(tx, blobs, commits, proofs); err != nil {
+ log.Trace("Transaction validation failed", "hash", tx.Hash(), "err", err)
+ return err
+ }
+ // Transaction permitted into the pool from a nonce and cost perspective,
+ // insert it into the database and update the indices
+ blob, err := rlp.EncodeToBytes(&blobTx{Tx: tx, Blobs: blobs, Commits: commits, Proofs: proofs})
+ if err != nil {
+ log.Error("Failed to encode transaction for storage", "hash", tx.Hash(), "err", err)
+ return err
+ }
+ id, err := p.store.Put(blob)
+ if err != nil {
+ return err
+ }
+ meta := newBlobTxMeta(id, p.store.Size(id), tx)
+
+ var (
+ from, _ = types.Sender(p.signer, tx) // already validated above
+ next = p.state.GetNonce(from)
+ offset = int(tx.Nonce() - next)
+ newacc = false
+ )
+ if len(p.index[from]) > offset {
+ // Transaction replaces a previously queued one
+ prev := p.index[from][offset]
+ if err := p.store.Delete(prev.id); err != nil {
+ // Shitty situation, but try to recover gracefully instead of going boom
+ log.Error("Failed to delete replaced transaction", "id", prev.id, "err", err)
+ }
+ // Update the transaction index
+ p.index[from][offset] = meta
+ p.spent[from] = new(uint256.Int).Sub(p.spent[from], prev.costCap)
+ p.spent[from] = new(uint256.Int).Add(p.spent[from], meta.costCap)
+
+ delete(p.lookup, prev.hash)
+ p.lookup[meta.hash] = meta.id
+ p.stored += uint64(meta.size) - uint64(prev.size)
+
+ } else {
+ // Transaction extends previously scheduled ones
+ p.index[from] = append(p.index[from], meta)
+ if _, ok := p.spent[from]; !ok {
+ p.spent[from] = new(uint256.Int)
+ newacc = true
+ }
+ p.spent[from] = new(uint256.Int).Add(p.spent[from], meta.costCap)
+ p.lookup[meta.hash] = meta.id
+ p.stored += uint64(meta.size)
+ }
+ // Recompute the rolling eviction fields. In case of a replacement, this will
+ // recompute all subsequent fields. In case of an append, this will only do
+ // the fresh calculation.
+ var (
+ txs = p.index[from]
+
+ oldEvictionExecFeeJumps = txs[len(txs)-1].evictionExecFeeJumps
+ oldEvictionBlobFeeJumps = txs[len(txs)-1].evictionBlobFeeJumps
+ )
+ for i := offset; i < len(txs); i++ {
+ // The first transaction will always use itself
+ if i == 0 {
+ txs[0].evictionExecTip = txs[0].execTipCap
+ txs[0].evictionExecFeeJumps = txs[0].basefeeJumps
+ txs[0].evictionBlobFeeJumps = txs[0].blobfeeJumps
+
+ continue
+ }
+ // Subsequent transactions will use a rolling calculation
+ txs[i].evictionExecTip = txs[i-1].evictionExecTip
+ if txs[i].evictionExecTip.Cmp(txs[i].execTipCap) > 0 {
+ txs[i].evictionExecTip = txs[i].execTipCap
+ }
+ txs[i].evictionExecFeeJumps = txs[i-1].evictionExecFeeJumps
+ if txs[i].evictionExecFeeJumps > txs[i].basefeeJumps {
+ txs[i].evictionExecFeeJumps = txs[i].basefeeJumps
+ }
+ txs[i].evictionBlobFeeJumps = txs[i-1].evictionBlobFeeJumps
+ if txs[i].evictionBlobFeeJumps > txs[i].blobfeeJumps {
+ txs[i].evictionBlobFeeJumps = txs[i].blobfeeJumps
+ }
+ }
+ // Update the eviction heap with the new information:
+ // - If the transaction is from a new account, add it to the heap
+ // - If the account had a singleton tx replaced, update the heap (new price caps)
+ // - If the account had it's last tx updated or appended to, update heap iff lower than prev
+ // - If the account had an internal tx updated, compare old tail price caps with new ones
+ switch {
+ case newacc:
+ heap.Push(p.evict, from)
+
+ case len(txs) == 1: // 1 tx and not a new acc, must be replacement
+ heap.Fix(p.evict, p.evict.index[from])
+
+ case offset == len(txs): // either append or last tx replacement
+ evictionExecFeeDiff := txs[offset-1].evictionExecFeeJumps - txs[offset].evictionExecFeeJumps
+ evictionBlobFeeDiff := txs[offset-1].evictionBlobFeeJumps - txs[offset].evictionBlobFeeJumps
+
+ if evictionExecFeeDiff > 0.001 || evictionBlobFeeDiff > 0.001 { // no need for math.Abs, monotonic decreasing
+ heap.Fix(p.evict, p.evict.index[from])
+ }
+
+ default: // no new account, no singleton tx, no last update; must be internal replacement
+ evictionExecFeeDiff := oldEvictionExecFeeJumps - txs[offset].evictionExecFeeJumps
+ evictionBlobFeeDiff := oldEvictionBlobFeeJumps - txs[offset].evictionBlobFeeJumps
+
+ if math.Abs(evictionExecFeeDiff) > 0.001 || math.Abs(evictionBlobFeeDiff) > 0.001 { // need math.Abs, can go up and down
+ heap.Fix(p.evict, p.evict.index[from])
+ }
+ }
+ // If the pool went over the allowed data limit, evict transactions until
+ // we're again below the threshold
+ for p.stored > p.config.Datacap {
+ p.drop()
+ }
+ p.updateStorageMetrics()
+
+ return nil
+}
+
+// drop removes the worst transaction from the pool. It is primarilly used when a
+// freshly added transaction overflows the pool and needs to evict something. The
+// method is also called on startup if the user resizes their storage, might be an
+// expensive run but it sould be fine-ish.
+func (p *BlobPool) drop() {
+ // Peek at the account with the worse transaction set to evict from (Go's heap
+ // stores the minimum at index zero of the heap slice) and retrieve it's last
+ // transaction.
+ var (
+ from = p.evict.addrs[0] // cannot call drop on empty pool
+
+ txs = p.index[from]
+ drop = txs[len(txs)-1]
+ last = len(txs) == 1
+ )
+ // Remove the transaction from the pool's index
+ if last {
+ delete(p.index, from)
+ delete(p.spent, from)
+ } else {
+ txs[len(txs)-1] = nil
+ txs = txs[:len(txs)-1]
+
+ p.index[from] = txs
+ p.spent[from] = new(uint256.Int).Sub(p.spent[from], drop.costCap)
+ }
+ p.stored -= uint64(drop.size)
+ delete(p.lookup, drop.hash)
+
+ // Remove the transation from the pool's evicion heap:
+ // - If the entire account was dropped, pop off the address
+ // - Otherwise, if the new tail has better eviction caps, fix the heap
+ if last {
+ heap.Pop(p.evict)
+ } else {
+ tail := txs[len(txs)-1] // new tail, surely exists
+
+ evictionExecFeeDiff := tail.evictionExecFeeJumps - drop.evictionExecFeeJumps
+ evictionBlobFeeDiff := tail.evictionBlobFeeJumps - drop.evictionBlobFeeJumps
+
+ if evictionExecFeeDiff > 0.001 || evictionBlobFeeDiff > 0.001 { // no need for math.Abs, monotonic decreasing
+ heap.Fix(p.evict, 0)
+ }
+ }
+ // Remove the transaction from the data store
+ log.Warn("Evicting overflown blob transaction", "from", from, "evicted", drop.nonce, "id", drop.id)
+ if err := p.store.Delete(drop.id); err != nil {
+ log.Error("Failed to drop evicted transaction", "id", drop.id, "err", err)
+ }
+}
+
+// Pending retrieves all currently processable transactions, grouped by origin
+// account and sorted by nonce.
+func (p *BlobPool) Pending(enforceTips bool) map[common.Address][]*txpool.LazyTransaction {
+ p.lock.RLock()
+ defer p.lock.RUnlock()
+
+ pending := make(map[common.Address][]*txpool.LazyTransaction)
+ for addr, txs := range p.index {
+ var lazies []*txpool.LazyTransaction
+ for _, tx := range txs {
+ lazies = append(lazies, &txpool.LazyTransaction{
+ Pool: p,
+ Hash: tx.hash,
+ Time: time.Now(), // TODO(karalabe): Maybe save these and use that?
+ GasFeeCap: tx.execFeeCap.ToBig(),
+ GasTipCap: tx.execTipCap.ToBig(),
+ })
+ }
+ if len(lazies) > 0 {
+ pending[addr] = lazies
+ }
+ }
+ return pending
+}
+
+// updateStorageMetrics retrieves a bunch of stats from the data store and pushes
+// them out as metrics.
+func (p *BlobPool) updateStorageMetrics() {
+ stats := p.store.Infos()
+
+ var (
+ dataused uint64
+ datareal uint64
+ slotused uint64
+
+ oversizedDataused uint64
+ oversizedDatagaps uint64
+ oversizedSlotused uint64
+ oversizedSlotgaps uint64
+ )
+ for _, shelf := range stats.Shelves {
+ slotDataused := shelf.FilledSlots * uint64(shelf.SlotSize)
+ slotDatagaps := shelf.GappedSlots * uint64(shelf.SlotSize)
+
+ dataused += slotDataused
+ datareal += slotDataused + slotDatagaps
+ slotused += shelf.FilledSlots
+
+ metrics.GetOrRegisterGauge(fmt.Sprintf(shelfDatausedGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(slotDataused))
+ metrics.GetOrRegisterGauge(fmt.Sprintf(shelfDatagapsGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(slotDatagaps))
+ metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotusedGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.FilledSlots))
+ metrics.GetOrRegisterGauge(fmt.Sprintf(shelfSlotgapsGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.GappedSlots))
+
+ if shelf.SlotSize/blobSize > maxBlobsPerTransaction {
+ oversizedDataused += slotDataused
+ oversizedDatagaps += slotDatagaps
+ oversizedSlotused += shelf.FilledSlots
+ oversizedSlotgaps += shelf.GappedSlots
+ }
+ }
+ datausedGauge.Update(int64(dataused))
+ datarealGauge.Update(int64(datareal))
+ slotusedGauge.Update(int64(slotused))
+
+ oversizedDatausedGauge.Update(int64(oversizedDataused))
+ oversizedDatagapsGauge.Update(int64(oversizedDatagaps))
+ oversizedSlotusedGauge.Update(int64(oversizedSlotused))
+ oversizedSlotgapsGauge.Update(int64(oversizedSlotgaps))
+
+ p.updateLimboMetrics()
+}
+
+// updateLimboMetrics retrieves a bunch of stats from the limbo store and pushes
+// // them out as metrics.
+func (p *BlobPool) updateLimboMetrics() {
+ stats := p.limbo.store.Infos()
+
+ var (
+ dataused uint64
+ datareal uint64
+ slotused uint64
+ )
+ for _, shelf := range stats.Shelves {
+ slotDataused := shelf.FilledSlots * uint64(shelf.SlotSize)
+ slotDatagaps := shelf.GappedSlots * uint64(shelf.SlotSize)
+
+ dataused += slotDataused
+ datareal += slotDataused + slotDatagaps
+ slotused += shelf.FilledSlots
+
+ metrics.GetOrRegisterGauge(fmt.Sprintf(limboShelfDatausedGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(slotDataused))
+ metrics.GetOrRegisterGauge(fmt.Sprintf(limboShelfDatagapsGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(slotDatagaps))
+ metrics.GetOrRegisterGauge(fmt.Sprintf(limboShelfSlotusedGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.FilledSlots))
+ metrics.GetOrRegisterGauge(fmt.Sprintf(limboShelfSlotgapsGaugeName, shelf.SlotSize/blobSize), nil).Update(int64(shelf.GappedSlots))
+ }
+ limboDatausedGauge.Update(int64(dataused))
+ limboDatarealGauge.Update(int64(datareal))
+ limboSlotusedGauge.Update(int64(slotused))
+}
+
+// SubscribeTransactions registers a subscription of NewTxsEvent and
+// starts sending event to the given channel.
+func (p *BlobPool) SubscribeTransactions(ch chan<- core.NewTxsEvent) event.Subscription {
+ return p.eventScope.Track(p.eventFeed.Subscribe(ch))
+}
+
+// Nonce returns the next nonce of an account, with all transactions executable
+// by the pool already applied on top.
+func (p *BlobPool) Nonce(addr common.Address) uint64 {
+ p.lock.Lock()
+ defer p.lock.Unlock()
+
+ if txs, ok := p.index[addr]; ok {
+ return txs[len(txs)-1].nonce + 1
+ }
+ return p.state.GetNonce(addr)
+}
+
+// Stats retrieves the current pool stats, namely the number of pending and the
+// number of queued (non-executable) transactions.
+func (p *BlobPool) Stats() (int, int) {
+ p.lock.Lock()
+ defer p.lock.Unlock()
+
+ var pending int
+ for _, txs := range p.index {
+ pending += len(txs)
+ }
+ return pending, 0 // No non-executable txs in the blob pool
+}
+
+// Content retrieves the data content of the transaction pool, returning all the
+// pending as well as queued transactions, grouped by account and sorted by nonce.
+//
+// For the blob pool, this method will return nothing for now.
+// TODO(karalabe): Abstract out the returned metadata.
+func (p *BlobPool) Content() (map[common.Address][]*types.Transaction, map[common.Address][]*types.Transaction) {
+ return make(map[common.Address][]*types.Transaction), make(map[common.Address][]*types.Transaction)
+}
+
+// ContentFrom retrieves the data content of the transaction pool, returning the
+// pending as well as queued transactions of this address, grouped by nonce.
+//
+// For the blob pool, this method will return nothing for now.
+// TODO(karalabe): Abstract out the returned metadata.
+func (p *BlobPool) ContentFrom(addr common.Address) ([]*types.Transaction, []*types.Transaction) {
+ return []*types.Transaction{}, []*types.Transaction{}
+}
+
+// Locals retrieves the accounts currently considered local by the pool.
+//
+// There is no notion of local accounts in the blob pool.
+func (p *BlobPool) Locals() []common.Address {
+ return []common.Address{}
+}
+
+// Status returns the known status (unknown/pending/queued) of a transaction
+// identified by their hashes.
+func (p *BlobPool) Status(hash common.Hash) txpool.TxStatus {
+ if p.Has(hash) {
+ return txpool.TxStatusPending
+ }
+ return txpool.TxStatusUnknown
+}
diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go
new file mode 100644
index 000000000000..ce973766c0ce
--- /dev/null
+++ b/core/txpool/blobpool/blobpool_test.go
@@ -0,0 +1,1065 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "crypto/ecdsa"
+ "crypto/sha256"
+ "errors"
+ "math"
+ "math/big"
+ "os"
+ "path/filepath"
+ "testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/consensus/misc"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/rawdb"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/txpool"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
+ "github.com/ethereum/go-ethereum/ethdb/memorydb"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/holiman/billy"
+ "github.com/holiman/uint256"
+)
+
+var (
+ emptyBlob = kzg4844.Blob{}
+ emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
+ emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
+ emptyBlobVHash = blobHash(emptyBlobCommit)
+)
+
+func blobHash(commit kzg4844.Commitment) common.Hash {
+ hasher := sha256.New()
+ hasher.Write(commit[:])
+ hash := hasher.Sum(nil)
+
+ var vhash common.Hash
+ vhash[0] = params.BlobTxHashVersion
+ copy(vhash[1:], hash[1:])
+
+ return vhash
+}
+
+// Chain configuration with Cancun enabled.
+//
+// TODO(karalabe): replace with params.MainnetChainConfig after Cancun.
+var testChainConfig *params.ChainConfig
+
+func init() {
+ testChainConfig = new(params.ChainConfig)
+ *testChainConfig = *params.MainnetChainConfig
+
+ testChainConfig.CancunTime = new(uint64)
+ *testChainConfig.CancunTime = uint64(time.Now().Unix())
+}
+
+// testBlockChain is a mock of the live chain for testing the pool.
+type testBlockChain struct {
+ config *params.ChainConfig
+ basefee *uint256.Int
+ blobfee *uint256.Int
+ statedb *state.StateDB
+}
+
+func (bc *testBlockChain) Config() *params.ChainConfig {
+ return bc.config
+}
+
+func (bc *testBlockChain) CurrentBlock() *types.Header {
+ // Yolo, life is too short to invert mist.CalcBaseFee and misc.CalcBlobFee,
+ // just binary search it them.
+
+ // The base fee at 5714 ETH translates into the 21000 base gas higher than
+ // mainnet ether existence, use that as a cap for the tests.
+ var (
+ blockNumber = new(big.Int).Add(bc.config.LondonBlock, big.NewInt(1))
+ blockTime = *bc.config.CancunTime + 1
+ gasLimit = uint64(30_000_000)
+ )
+ lo := new(big.Int)
+ hi := new(big.Int).Mul(big.NewInt(5714), new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))
+
+ for new(big.Int).Add(lo, big.NewInt(1)).Cmp(hi) != 0 {
+ mid := new(big.Int).Add(lo, hi)
+ mid.Div(mid, big.NewInt(2))
+
+ if misc.CalcBaseFee(bc.config, &types.Header{
+ Number: blockNumber,
+ GasLimit: gasLimit,
+ GasUsed: 0,
+ BaseFee: mid,
+ }).Cmp(bc.basefee.ToBig()) > 0 {
+ hi = mid
+ } else {
+ lo = mid
+ }
+ }
+ baseFee := lo
+
+ // The excess data gas at 2^27 translates into a blob fee higher than mainnet
+ // ether existence, use that as a cap for the tests.
+ lo = new(big.Int)
+ hi = new(big.Int).Exp(big.NewInt(2), big.NewInt(27), nil)
+
+ for new(big.Int).Add(lo, big.NewInt(1)).Cmp(hi) != 0 {
+ mid := new(big.Int).Add(lo, hi)
+ mid.Div(mid, big.NewInt(2))
+
+ if misc.CalcBlobFee(mid.Uint64()).Cmp(bc.blobfee.ToBig()) > 0 {
+ hi = mid
+ } else {
+ lo = mid
+ }
+ }
+ excessDataGas := lo.Uint64()
+
+ return &types.Header{
+ Number: blockNumber,
+ Time: blockTime,
+ GasLimit: gasLimit,
+ BaseFee: baseFee,
+ ExcessDataGas: &excessDataGas,
+ }
+}
+
+func (bc *testBlockChain) CurrentFinalBlock() *types.Header {
+ return &types.Header{
+ Number: big.NewInt(0),
+ }
+}
+
+func (bt *testBlockChain) GetBlock(hash common.Hash, number uint64) *types.Block {
+ return nil
+}
+
+func (bc *testBlockChain) StateAt(common.Hash) (*state.StateDB, error) {
+ return bc.statedb, nil
+}
+
+// makeTx is a utility method to construct a random blob transaction and sign it
+// with a valid key, only setting the interesting fields from the perspective of
+// the blob pool.
+func makeTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64, key *ecdsa.PrivateKey) *types.Transaction {
+ tx, _ := types.SignNewTx(key, types.LatestSigner(testChainConfig), makeUnsignedTx(nonce, gasTipCap, gasFeeCap, blobFeeCap))
+ return tx
+}
+
+// makeUnsignedTx is a utility method to construct a random blob tranasaction
+// without signing it.
+func makeUnsignedTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64) *types.BlobTx {
+ return &types.BlobTx{
+ ChainID: uint256.MustFromBig(testChainConfig.ChainID),
+ Nonce: nonce,
+ GasTipCap: uint256.NewInt(gasTipCap),
+ GasFeeCap: uint256.NewInt(gasFeeCap),
+ Gas: 21000,
+ BlobFeeCap: uint256.NewInt(blobFeeCap),
+ BlobHashes: []common.Hash{emptyBlobVHash},
+ Value: uint256.NewInt(100),
+ }
+}
+
+// verifyPoolInternals iterates over all the transactions in the pool and checks
+// that sort orders, calculated fields, cumulated fields are correct.
+func verifyPoolInternals(t *testing.T, pool *BlobPool) {
+ // Mark this method as a helper to remove from stack traces
+ t.Helper()
+
+ // Verify that all items in the index are present in the lookup and nothing more
+ seen := make(map[common.Hash]struct{})
+ for addr, txs := range pool.index {
+ for _, tx := range txs {
+ if _, ok := seen[tx.hash]; ok {
+ t.Errorf("duplicate hash #%x in transaction index: address %s, nonce %d", tx.hash, addr, tx.nonce)
+ }
+ seen[tx.hash] = struct{}{}
+ }
+ }
+ for hash, id := range pool.lookup {
+ if _, ok := seen[hash]; !ok {
+ t.Errorf("lookup entry missing from transaction index: hash #%x, id %d", hash, id)
+ }
+ delete(seen, hash)
+ }
+ for hash := range seen {
+ t.Errorf("indexed transaction hash #%x missing from lookup table", hash)
+ }
+ // Verify that transactions are sorted per account and contain no nonce gaps
+ for addr, txs := range pool.index {
+ for i := 1; i < len(txs); i++ {
+ if txs[i].nonce != txs[i-1].nonce+1 {
+ t.Errorf("addr %v, tx %d nonce mismatch: have %d, want %d", addr, i, txs[i].nonce, txs[i-1].nonce+1)
+ }
+ }
+ }
+ // Verify that calculated evacuation thresholds are correct
+ for addr, txs := range pool.index {
+ if !txs[0].evictionExecTip.Eq(txs[0].execTipCap) {
+ t.Errorf("addr %v, tx %d eviction execution tip mismatch: have %d, want %d", addr, 0, txs[0].evictionExecTip, txs[0].execTipCap)
+ }
+ if math.Abs(txs[0].evictionExecFeeJumps-txs[0].basefeeJumps) > 0.001 {
+ t.Errorf("addr %v, tx %d eviction execution fee jumps mismatch: have %f, want %f", addr, 0, txs[0].evictionExecFeeJumps, txs[0].basefeeJumps)
+ }
+ if math.Abs(txs[0].evictionBlobFeeJumps-txs[0].blobfeeJumps) > 0.001 {
+ t.Errorf("addr %v, tx %d eviction blob fee jumps mismatch: have %f, want %f", addr, 0, txs[0].evictionBlobFeeJumps, txs[0].blobfeeJumps)
+ }
+ for i := 1; i < len(txs); i++ {
+ wantExecTip := txs[i-1].evictionExecTip
+ if wantExecTip.Gt(txs[i].execTipCap) {
+ wantExecTip = txs[i].execTipCap
+ }
+ if !txs[i].evictionExecTip.Eq(wantExecTip) {
+ t.Errorf("addr %v, tx %d eviction execution tip mismatch: have %d, want %d", addr, i, txs[i].evictionExecTip, wantExecTip)
+ }
+
+ wantExecFeeJumps := txs[i-1].evictionExecFeeJumps
+ if wantExecFeeJumps > txs[i].basefeeJumps {
+ wantExecFeeJumps = txs[i].basefeeJumps
+ }
+ if math.Abs(txs[i].evictionExecFeeJumps-wantExecFeeJumps) > 0.001 {
+ t.Errorf("addr %v, tx %d eviction execution fee jumps mismatch: have %f, want %f", addr, i, txs[i].evictionExecFeeJumps, wantExecFeeJumps)
+ }
+
+ wantBlobFeeJumps := txs[i-1].evictionBlobFeeJumps
+ if wantBlobFeeJumps > txs[i].blobfeeJumps {
+ wantBlobFeeJumps = txs[i].blobfeeJumps
+ }
+ if math.Abs(txs[i].evictionBlobFeeJumps-wantBlobFeeJumps) > 0.001 {
+ t.Errorf("addr %v, tx %d eviction blob fee jumps mismatch: have %f, want %f", addr, i, txs[i].evictionBlobFeeJumps, wantBlobFeeJumps)
+ }
+ }
+ }
+ // Verify that account balance accumulations are correct
+ for addr, txs := range pool.index {
+ spent := new(uint256.Int)
+ for _, tx := range txs {
+ spent.Add(spent, tx.costCap)
+ }
+ if !pool.spent[addr].Eq(spent) {
+ t.Errorf("addr %v expenditure mismatch: have %d, want %d", addr, pool.spent[addr], spent)
+ }
+ }
+ // Verify that pool storage size is correct
+ var stored uint64
+ for _, txs := range pool.index {
+ for _, tx := range txs {
+ stored += uint64(tx.size)
+ }
+ }
+ if pool.stored != stored {
+ t.Errorf("pool storage mismatch: have %d, want %d", pool.stored, stored)
+ }
+ // Verify the price heap internals
+ verifyHeapInternals(t, pool.evict)
+}
+
+// Tests that transactions can be loaded from disk on startup and that they are
+// correctly discarded if invalid.
+//
+// - 1. A transaction that cannot be decoded must be dropped
+// - 2. A transaction that cannot be recovered (bad signature) must be dropped
+// - 3. All transactions after a nonce gap must be dropped
+// - 4. All transactions after an underpriced one (including it) must be dropped
+func TestOpenDrops(t *testing.T) {
+ log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
+
+ // Create a temporary folder for the persistent backend
+ storage, _ := os.MkdirTemp("", "blobpool-")
+ defer os.RemoveAll(storage)
+
+ os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
+ store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
+
+ // Insert a malformed transaction to verify that decoding errors (or format
+ // changes) are handled gracefully (case 1)
+ malformed, _ := store.Put([]byte("this is a badly encoded transaction"))
+
+ // Insert a transaction with a bad signature to verify that stale junk after
+ // potential hard-forks can get evicted (case 2)
+ tx := types.NewTx(&types.BlobTx{
+ ChainID: uint256.MustFromBig(testChainConfig.ChainID),
+ GasTipCap: new(uint256.Int),
+ GasFeeCap: new(uint256.Int),
+ Gas: 0,
+ Value: new(uint256.Int),
+ Data: nil,
+ BlobFeeCap: new(uint256.Int),
+ V: new(uint256.Int),
+ R: new(uint256.Int),
+ S: new(uint256.Int),
+ })
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+ badsig, _ := store.Put(blob)
+
+ // Insert a sequence of transactions with a nonce gap in between to verify
+ // that anything gapped will get evicted (case 3)
+ var (
+ gapper, _ = crypto.GenerateKey()
+
+ valids = make(map[uint64]struct{})
+ gapped = make(map[uint64]struct{})
+ )
+ for _, nonce := range []uint64{0, 1, 3, 4, 6, 7} { // first gap at #2, another at #5
+ tx := makeTx(nonce, 1, 1, 1, gapper)
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+
+ id, _ := store.Put(blob)
+ if nonce < 2 {
+ valids[id] = struct{}{}
+ } else {
+ gapped[id] = struct{}{}
+ }
+ }
+ // Insert a sequence of transactions with a gapped starting nonce to veirfy
+ // that the entire set will get dropped.
+ var (
+ dangler, _ = crypto.GenerateKey()
+ dangling = make(map[uint64]struct{})
+ )
+ for _, nonce := range []uint64{1, 2, 3} { // first gap at #0, all set dangling
+ tx := makeTx(nonce, 1, 1, 1, dangler)
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+
+ id, _ := store.Put(blob)
+ dangling[id] = struct{}{}
+ }
+ // Insert a sequence of transactions with already passed nonces to veirfy
+ // that the entire set will get dropped.
+ var (
+ filler, _ = crypto.GenerateKey()
+ filled = make(map[uint64]struct{})
+ )
+ for _, nonce := range []uint64{0, 1, 2} { // account nonce at 3, all set filled
+ tx := makeTx(nonce, 1, 1, 1, filler)
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+
+ id, _ := store.Put(blob)
+ filled[id] = struct{}{}
+ }
+ // Insert a sequence of transactions with partially passed nonces to veirfy
+ // that the included part of the set will get dropped
+ var (
+ overlapper, _ = crypto.GenerateKey()
+ overlapped = make(map[uint64]struct{})
+ )
+ for _, nonce := range []uint64{0, 1, 2, 3} { // account nonce at 2, half filled
+ tx := makeTx(nonce, 1, 1, 1, overlapper)
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+
+ id, _ := store.Put(blob)
+ if nonce >= 2 {
+ valids[id] = struct{}{}
+ } else {
+ overlapped[id] = struct{}{}
+ }
+ }
+ // Insert a sequence of transactions with an underpriced in between to verify
+ // that it and anything newly gapped will get evicted (case 4)
+ var (
+ pricer, _ = crypto.GenerateKey()
+ outpriced = make(map[uint64]struct{})
+ )
+ for i := 0; i < 5; i++ { // make #2 underpriced
+ var tx *types.Transaction
+ if i == 2 {
+ tx = makeTx(uint64(i), 0, 0, 0, pricer)
+ } else {
+ tx = makeTx(uint64(i), 1, 1, 1, pricer)
+ }
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+
+ id, _ := store.Put(blob)
+ if i < 2 {
+ valids[id] = struct{}{}
+ } else {
+ outpriced[id] = struct{}{}
+ }
+ }
+ // Insert a sequence of transactions fully overdrafted to verify that the
+ // entire set will get invalidated.
+ var (
+ exceeder, _ = crypto.GenerateKey()
+ exceeded = make(map[uint64]struct{})
+ )
+ for _, nonce := range []uint64{0, 1, 2} { // nonce 0 overdrafts the account
+ var tx *types.Transaction
+ if nonce == 0 {
+ tx = makeTx(nonce, 1, 100, 1, exceeder)
+ } else {
+ tx = makeTx(nonce, 1, 1, 1, exceeder)
+ }
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+
+ id, _ := store.Put(blob)
+ exceeded[id] = struct{}{}
+ }
+ // Insert a sequence of transactions partially overdrafted to verify that part
+ // of the set will get invalidated.
+ var (
+ overdrafter, _ = crypto.GenerateKey()
+ overdrafted = make(map[uint64]struct{})
+ )
+ for _, nonce := range []uint64{0, 1, 2} { // nonce 1 overdrafts the account
+ var tx *types.Transaction
+ if nonce == 1 {
+ tx = makeTx(nonce, 1, 100, 1, overdrafter)
+ } else {
+ tx = makeTx(nonce, 1, 1, 1, overdrafter)
+ }
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+
+ id, _ := store.Put(blob)
+ if nonce < 1 {
+ valids[id] = struct{}{}
+ } else {
+ overdrafted[id] = struct{}{}
+ }
+ }
+ store.Close()
+
+ // Create a blob pool out of the pre-seeded data
+ statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
+ statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), big.NewInt(1000000))
+ statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), big.NewInt(1000000))
+ statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), big.NewInt(1000000))
+ statedb.SetNonce(crypto.PubkeyToAddress(filler.PublicKey), 3)
+ statedb.AddBalance(crypto.PubkeyToAddress(overlapper.PublicKey), big.NewInt(1000000))
+ statedb.SetNonce(crypto.PubkeyToAddress(overlapper.PublicKey), 2)
+ statedb.AddBalance(crypto.PubkeyToAddress(pricer.PublicKey), big.NewInt(1000000))
+ statedb.AddBalance(crypto.PubkeyToAddress(exceeder.PublicKey), big.NewInt(1000000))
+ statedb.AddBalance(crypto.PubkeyToAddress(overdrafter.PublicKey), big.NewInt(1000000))
+ statedb.Commit(true)
+
+ chain := &testBlockChain{
+ config: testChainConfig,
+ basefee: uint256.NewInt(params.InitialBaseFee),
+ blobfee: uint256.NewInt(params.BlobTxMinDataGasprice),
+ statedb: statedb,
+ }
+ pool := New(Config{Datadir: storage}, chain)
+ if err := pool.Init(big.NewInt(1), chain.CurrentBlock()); err != nil {
+ t.Fatalf("failed to create blob pool: %v", err)
+ }
+ defer pool.Close()
+
+ // Verify that the malformed (case 1), badly signed (case 2) and gapped (case
+ // 3) txs have been deleted from the pool
+ alive := make(map[uint64]struct{})
+ for _, txs := range pool.index {
+ for _, tx := range txs {
+ switch tx.id {
+ case malformed:
+ t.Errorf("malformed RLP transaction remained in storage")
+ case badsig:
+ t.Errorf("invalidly signed transaction remained in storage")
+ default:
+ if _, ok := dangling[tx.id]; ok {
+ t.Errorf("dangling transaction remained in storage: %d", tx.id)
+ } else if _, ok := filled[tx.id]; ok {
+ t.Errorf("filled transaction remained in storage: %d", tx.id)
+ } else if _, ok := overlapped[tx.id]; ok {
+ t.Errorf("overlapped transaction remained in storage: %d", tx.id)
+ } else if _, ok := gapped[tx.id]; ok {
+ t.Errorf("gapped transaction remained in storage: %d", tx.id)
+ } else if _, ok := exceeded[tx.id]; ok {
+ t.Errorf("fully overdrafted transaction remained in storage: %d", tx.id)
+ } else if _, ok := overdrafted[tx.id]; ok {
+ t.Errorf("partially overdrafted transaction remained in storage: %d", tx.id)
+ } else {
+ alive[tx.id] = struct{}{}
+ }
+ }
+ }
+ }
+ // Verify that the rest of the transactions remained alive
+ if len(alive) != len(valids) {
+ t.Errorf("valid transaction count mismatch: have %d, want %d", len(alive), len(valids))
+ }
+ for id := range alive {
+ if _, ok := valids[id]; !ok {
+ t.Errorf("extra transaction %d", id)
+ }
+ }
+ for id := range valids {
+ if _, ok := alive[id]; !ok {
+ t.Errorf("missing transaction %d", id)
+ }
+ }
+ // Verify all the calculated pool internals. Interestingly, this is **not**
+ // a duplication of the above checks, this actually validates the verifier
+ // using the above already hard coded checks.
+ //
+ // Do not remove this, nor alter the above to be generic.
+ verifyPoolInternals(t, pool)
+}
+
+// Tests that transactions loaded from disk are indexed corrently.
+//
+// - 1. Transactions must be groupped by sender, sorted by nonce
+// - 2. Eviction thresholds are calculated correctly for the sequences
+// - 3. Balance usage of an account is totals across all transactions
+func TestOpenIndex(t *testing.T) {
+ log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
+
+ // Create a temporary folder for the persistent backend
+ storage, _ := os.MkdirTemp("", "blobpool-")
+ defer os.RemoveAll(storage)
+
+ os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
+ store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
+
+ // Insert a sequence of transactions with varying price points to check that
+ // the cumulative minimumw will be maintained.
+ var (
+ key, _ = crypto.GenerateKey()
+ addr = crypto.PubkeyToAddress(key.PublicKey)
+
+ txExecTipCaps = []uint64{10, 25, 5, 7, 1, 100}
+ txExecFeeCaps = []uint64{100, 90, 200, 10, 80, 300}
+ txBlobFeeCaps = []uint64{55, 66, 77, 33, 22, 11}
+
+ //basefeeJumps = []float64{39.098, 38.204, 44.983, 19.549, 37.204, 48.426} // log 1.125 (exec fee cap)
+ //blobfeeJumps = []float64{34.023, 35.570, 36.879, 29.686, 26.243, 20.358} // log 1.125 (blob fee cap)
+
+ evictExecTipCaps = []uint64{10, 10, 5, 5, 1, 1}
+ evictExecFeeJumps = []float64{39.098, 38.204, 38.204, 19.549, 19.549, 19.549} // min(log 1.125 (exec fee cap))
+ evictBlobFeeJumps = []float64{34.023, 34.023, 34.023, 29.686, 26.243, 20.358} // min(log 1.125 (blob fee cap))
+
+ totalSpent = uint256.NewInt(21000*(100+90+200+10+80+300) + blobSize*(55+66+77+33+22+11) + 100*6) // 21000 gas x price + 128KB x blobprice + value
+ )
+ for _, i := range []int{5, 3, 4, 2, 0, 1} { // Randomize the tx insertion order to force sorting on load
+ tx := makeTx(uint64(i), txExecTipCaps[i], txExecFeeCaps[i], txBlobFeeCaps[i], key)
+ blob, _ := rlp.EncodeToBytes(&blobTx{Tx: tx})
+ store.Put(blob)
+ }
+ store.Close()
+
+ // Create a blob pool out of the pre-seeded data
+ statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
+ statedb.AddBalance(addr, big.NewInt(1_000_000_000))
+ statedb.Commit(true)
+
+ chain := &testBlockChain{
+ config: testChainConfig,
+ basefee: uint256.NewInt(params.InitialBaseFee),
+ blobfee: uint256.NewInt(params.BlobTxMinDataGasprice),
+ statedb: statedb,
+ }
+ pool := New(Config{Datadir: storage}, chain)
+ if err := pool.Init(big.NewInt(1), chain.CurrentBlock()); err != nil {
+ t.Fatalf("failed to create blob pool: %v", err)
+ }
+ defer pool.Close()
+
+ // Verify that the transactions have been sorted by nonce (case 1)
+ for i := 0; i < len(pool.index[addr]); i++ {
+ if pool.index[addr][i].nonce != uint64(i) {
+ t.Errorf("tx %d nonce mismatch: have %d, want %d", i, pool.index[addr][i].nonce, uint64(i))
+ }
+ }
+ // Verify that the cumulative fee minimums have been correctly calculated (case 2)
+ for i, cap := range evictExecTipCaps {
+ if !pool.index[addr][i].evictionExecTip.Eq(uint256.NewInt(cap)) {
+ t.Errorf("eviction tip cap %d mismatch: have %d, want %d", i, pool.index[addr][i].evictionExecTip, cap)
+ }
+ }
+ for i, jumps := range evictExecFeeJumps {
+ if math.Abs(pool.index[addr][i].evictionExecFeeJumps-jumps) > 0.001 {
+ t.Errorf("eviction fee cap jumps %d mismatch: have %f, want %f", i, pool.index[addr][i].evictionExecFeeJumps, jumps)
+ }
+ }
+ for i, jumps := range evictBlobFeeJumps {
+ if math.Abs(pool.index[addr][i].evictionBlobFeeJumps-jumps) > 0.001 {
+ t.Errorf("eviction blob fee cap jumps %d mismatch: have %f, want %f", i, pool.index[addr][i].evictionBlobFeeJumps, jumps)
+ }
+ }
+ // Verify that the balance usage has been correctly calculated (case 3)
+ if !pool.spent[addr].Eq(totalSpent) {
+ t.Errorf("expenditure mismatch: have %d, want %d", pool.spent[addr], totalSpent)
+ }
+ // Verify all the calculated pool internals. Interestingly, this is **not**
+ // a duplication of the above checks, this actually validates the verifier
+ // using the above already hard coded checks.
+ //
+ // Do not remove this, nor alter the above to be generic.
+ verifyPoolInternals(t, pool)
+}
+
+// Tests that after indexing all the loaded transactions from disk, a price heap
+// is correctly constructed based on the head basefee and blobfee.
+func TestOpenHeap(t *testing.T) {
+ log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
+
+ // Create a temporary folder for the persistent backend
+ storage, _ := os.MkdirTemp("", "blobpool-")
+ defer os.RemoveAll(storage)
+
+ os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
+ store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
+
+ // Insert a few transactions from a few accounts
+ var (
+ key1, _ = crypto.GenerateKey()
+ key2, _ = crypto.GenerateKey()
+ key3, _ = crypto.GenerateKey()
+
+ addr1 = crypto.PubkeyToAddress(key1.PublicKey)
+ addr2 = crypto.PubkeyToAddress(key2.PublicKey)
+ addr3 = crypto.PubkeyToAddress(key3.PublicKey)
+
+ tx1 = makeTx(0, 1, 1000, 100, key1)
+ tx2 = makeTx(0, 1, 800, 70, key2)
+ tx3 = makeTx(0, 1, 1500, 110, key3)
+
+ blob1, _ = rlp.EncodeToBytes(&blobTx{Tx: tx1})
+ blob2, _ = rlp.EncodeToBytes(&blobTx{Tx: tx2})
+ blob3, _ = rlp.EncodeToBytes(&blobTx{Tx: tx3})
+
+ heapOrder = []common.Address{addr2, addr1, addr3}
+ heapIndex = map[common.Address]int{addr2: 0, addr1: 1, addr3: 2}
+ )
+ store.Put(blob1)
+ store.Put(blob2)
+ store.Put(blob3)
+ store.Close()
+
+ // Create a blob pool out of the pre-seeded data
+ statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
+ statedb.AddBalance(addr1, big.NewInt(1_000_000_000))
+ statedb.AddBalance(addr2, big.NewInt(1_000_000_000))
+ statedb.AddBalance(addr3, big.NewInt(1_000_000_000))
+ statedb.Commit(true)
+
+ chain := &testBlockChain{
+ config: testChainConfig,
+ basefee: uint256.NewInt(1050),
+ blobfee: uint256.NewInt(105),
+ statedb: statedb,
+ }
+ pool := New(Config{Datadir: storage}, chain)
+ if err := pool.Init(big.NewInt(1), chain.CurrentBlock()); err != nil {
+ t.Fatalf("failed to create blob pool: %v", err)
+ }
+ defer pool.Close()
+
+ // Verify that the heap's internal state matches the expectations
+ for i, addr := range pool.evict.addrs {
+ if addr != heapOrder[i] {
+ t.Errorf("slot %d mismatch: have %v, want %v", i, addr, heapOrder[i])
+ }
+ }
+ for addr, i := range pool.evict.index {
+ if i != heapIndex[addr] {
+ t.Errorf("index for %v mismatch: have %d, want %d", addr, i, heapIndex[addr])
+ }
+ }
+ // Verify all the calculated pool internals. Interestingly, this is **not**
+ // a duplication of the above checks, this actually validates the verifier
+ // using the above already hard coded checks.
+ //
+ // Do not remove this, nor alter the above to be generic.
+ verifyPoolInternals(t, pool)
+}
+
+// Tests that after the pool's previous state is loaded back, any transactions
+// over the new storage cap will get dropped.
+func TestOpenCap(t *testing.T) {
+ log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
+
+ // Create a temporary folder for the persistent backend
+ storage, _ := os.MkdirTemp("", "blobpool-")
+ defer os.RemoveAll(storage)
+
+ os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
+ store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
+
+ // Insert a few transactions from a few accounts
+ var (
+ key1, _ = crypto.GenerateKey()
+ key2, _ = crypto.GenerateKey()
+ key3, _ = crypto.GenerateKey()
+
+ addr1 = crypto.PubkeyToAddress(key1.PublicKey)
+ addr2 = crypto.PubkeyToAddress(key2.PublicKey)
+ addr3 = crypto.PubkeyToAddress(key3.PublicKey)
+
+ tx1 = makeTx(0, 1, 1000, 100, key1)
+ tx2 = makeTx(0, 1, 800, 70, key2)
+ tx3 = makeTx(0, 1, 1500, 110, key3)
+
+ blob1, _ = rlp.EncodeToBytes(&blobTx{Tx: tx1, Blobs: []kzg4844.Blob{emptyBlob}, Commits: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}})
+ blob2, _ = rlp.EncodeToBytes(&blobTx{Tx: tx2, Blobs: []kzg4844.Blob{emptyBlob}, Commits: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}})
+ blob3, _ = rlp.EncodeToBytes(&blobTx{Tx: tx3, Blobs: []kzg4844.Blob{emptyBlob}, Commits: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}})
+
+ keep = []common.Address{addr1, addr3}
+ drop = []common.Address{addr2}
+ size = uint64(2 * (txAvgSize + blobSize))
+ )
+ store.Put(blob1)
+ store.Put(blob2)
+ store.Put(blob3)
+ store.Close()
+
+ // Verify pool capping twice: first by reducing the data cap, then restarting
+ // with a high cap to ensure everything was persisted previously
+ for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} {
+ // Create a blob pool out of the pre-seeded data, but cap it to 2 blob transaction
+ statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
+ statedb.AddBalance(addr1, big.NewInt(1_000_000_000))
+ statedb.AddBalance(addr2, big.NewInt(1_000_000_000))
+ statedb.AddBalance(addr3, big.NewInt(1_000_000_000))
+ statedb.Commit(true)
+
+ chain := &testBlockChain{
+ config: testChainConfig,
+ basefee: uint256.NewInt(1050),
+ blobfee: uint256.NewInt(105),
+ statedb: statedb,
+ }
+ pool := New(Config{Datadir: storage, Datacap: datacap}, chain)
+ if err := pool.Init(big.NewInt(1), chain.CurrentBlock()); err != nil {
+ t.Fatalf("failed to create blob pool: %v", err)
+ }
+ // Verify that enough transactions have been dropped to get the pool's size
+ // under the requested limit
+ if len(pool.index) != len(keep) {
+ t.Errorf("tracked account count mismatch: have %d, want %d", len(pool.index), len(keep))
+ }
+ for _, addr := range keep {
+ if _, ok := pool.index[addr]; !ok {
+ t.Errorf("expected account %v missing from pool", addr)
+ }
+ }
+ for _, addr := range drop {
+ if _, ok := pool.index[addr]; ok {
+ t.Errorf("unexpected account %v present in pool", addr)
+ }
+ }
+ if pool.stored != size {
+ t.Errorf("pool stored size mismatch: have %v, want %v", pool.stored, size)
+ }
+ // Verify all the calculated pool internals. Interestingly, this is **not**
+ // a duplication of the above checks, this actually validates the verifier
+ // using the above already hard coded checks.
+ //
+ // Do not remove this, nor alter the above to be generic.
+ verifyPoolInternals(t, pool)
+
+ pool.Close()
+ }
+}
+
+// Tests that adding transaction will correctly store it in the persistent store
+// and update all the indices.
+//
+// Note, this tests mostly checks the pool transaction shuffling logic or things
+// specific to the blob pool. It does not do an exhaustive transaction validity
+// check.
+func TestAdd(t *testing.T) {
+ log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
+
+ // seed is a helper tumpe to seed an initial state db and pool
+ type seed struct {
+ balance uint64
+ nonce uint64
+ txs []*types.BlobTx
+ }
+
+ // addtx is a helper sender/tx tuple to represent a new tx addition
+ type addtx struct {
+ from string
+ tx *types.BlobTx
+ err error
+ }
+
+ tests := []struct {
+ seeds map[string]seed
+ adds []addtx
+ }{
+ // Transactions from new accounts should be accepted if their initial
+ // nonce matches the expected one from the statedb. Higher or lower must
+ // be rejected.
+ {
+ seeds: map[string]seed{
+ "alice": {balance: 21100 + blobSize},
+ "bob": {balance: 21100 + blobSize, nonce: 1},
+ "claire": {balance: 21100 + blobSize},
+ "dave": {balance: 21100 + blobSize, nonce: 1},
+ },
+ adds: []addtx{
+ { // New account, no previous txs: accept nonce 0
+ from: "alice",
+ tx: makeUnsignedTx(0, 1, 1, 1),
+ err: nil,
+ },
+ { // Old account, 1 tx in chain, 0 pending: accept nonce 1
+ from: "bob",
+ tx: makeUnsignedTx(1, 1, 1, 1),
+ err: nil,
+ },
+ { // New account, no previous txs: reject nonce 1
+ from: "claire",
+ tx: makeUnsignedTx(1, 1, 1, 1),
+ err: core.ErrNonceTooHigh,
+ },
+ { // Old account, 1 tx in chain, 0 pending: reject nonce 0
+ from: "dave",
+ tx: makeUnsignedTx(0, 1, 1, 1),
+ err: core.ErrNonceTooLow,
+ },
+ { // Old account, 1 tx in chain, 0 pending: reject nonce 2
+ from: "dave",
+ tx: makeUnsignedTx(2, 1, 1, 1),
+ err: core.ErrNonceTooHigh,
+ },
+ },
+ },
+ // Transactions from already pooled accounts should only be accepted if
+ // the nonces are contiguous (ignore prices for now, will check later)
+ {
+ seeds: map[string]seed{
+ "alice": {
+ balance: 1000000,
+ txs: []*types.BlobTx{
+ makeUnsignedTx(0, 1, 1, 1),
+ },
+ },
+ "bob": {
+ balance: 1000000,
+ nonce: 1,
+ txs: []*types.BlobTx{
+ makeUnsignedTx(1, 1, 1, 1),
+ },
+ },
+ },
+ adds: []addtx{
+ { // New account, 1 tx pending: reject replacement nonce 0 (ignore price for now)
+ from: "alice",
+ tx: makeUnsignedTx(0, 1, 1, 1),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // New account, 1 tx pending: accept nonce 1
+ from: "alice",
+ tx: makeUnsignedTx(1, 1, 1, 1),
+ err: nil,
+ },
+ { // New account, 2 txs pending: reject nonce 3
+ from: "alice",
+ tx: makeUnsignedTx(3, 1, 1, 1),
+ err: core.ErrNonceTooHigh,
+ },
+ { // New account, 2 txs pending: accept nonce 2
+ from: "alice",
+ tx: makeUnsignedTx(2, 1, 1, 1),
+ err: nil,
+ },
+ { // New account, 3 txs pending: accept nonce 3 now
+ from: "alice",
+ tx: makeUnsignedTx(3, 1, 1, 1),
+ err: nil,
+ },
+ { // Old account, 1 tx in chain, 1 tx pending: reject replacement nonce 1 (ignore price for now)
+ from: "bob",
+ tx: makeUnsignedTx(1, 1, 1, 1),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // Old account, 1 tx in chain, 1 tx pending: accept nonce 2 (ignore price for now)
+ from: "bob",
+ tx: makeUnsignedTx(2, 1, 1, 1),
+ err: nil,
+ },
+ },
+ },
+ // Transactions should only be accepted into the pool if the cumulative
+ // expenditure doesn't overflow the account balance
+ {
+ seeds: map[string]seed{
+ "alice": {balance: 63299 + 3*blobSize}, // 3 tx - 1 wei
+ },
+ adds: []addtx{
+ { // New account, no previous txs: accept nonce 0 with 21100 wei spend
+ from: "alice",
+ tx: makeUnsignedTx(0, 1, 1, 1),
+ err: nil,
+ },
+ { // New account, 1 pooled tx with 21100 wei spent: accept nonce 1 with 21100 wei spend
+ from: "alice",
+ tx: makeUnsignedTx(1, 1, 1, 1),
+ err: nil,
+ },
+ { // New account, 2 pooled tx with 42200 wei spent: reject nonce 2 with 21100 wei spend (1 wei overflow)
+ from: "alice",
+ tx: makeUnsignedTx(2, 1, 1, 1),
+ err: core.ErrInsufficientFunds,
+ },
+ },
+ },
+ // Previously existing transactions should be allowed to be replaced iff
+ // the new cumulative expenditure can be covered by the account and the
+ // prices are bumped all around (no percentage check here).
+ {
+ seeds: map[string]seed{
+ "alice": {balance: 2*100 + 5*21000 + 3*blobSize},
+ },
+ adds: []addtx{
+ { // New account, no previous txs: reject nonce 0 with 341172 wei spend
+ from: "alice",
+ tx: makeUnsignedTx(0, 1, 20, 1),
+ err: core.ErrInsufficientFunds,
+ },
+ { // New account, no previous txs: accept nonce 0 with 173172 wei spend
+ from: "alice",
+ tx: makeUnsignedTx(0, 1, 2, 1),
+ err: nil,
+ },
+ { // New account, 1 pooled tx with 173172 wei spent: accept nonce 1 with 152172 wei spend
+ from: "alice",
+ tx: makeUnsignedTx(1, 1, 1, 1),
+ err: nil,
+ },
+ { // New account, 2 pooled tx with 325344 wei spent: reject nonce 0 with 599684 wei spend (173072 extra) (would overflow balance at nonce 1)
+ from: "alice",
+ tx: makeUnsignedTx(0, 2, 5, 2),
+ err: core.ErrInsufficientFunds,
+ },
+ { // New account, 2 pooled tx with 325344 wei spent: reject nonce 0 with no-gastip-bump
+ from: "alice",
+ tx: makeUnsignedTx(0, 1, 3, 2),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // New account, 2 pooled tx with 325344 wei spent: reject nonce 0 with no-gascap-bump
+ from: "alice",
+ tx: makeUnsignedTx(0, 2, 2, 2),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // New account, 2 pooled tx with 325344 wei spent: reject nonce 0 with no-blobcap-bump
+ from: "alice",
+ tx: makeUnsignedTx(0, 2, 4, 1),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // New account, 2 pooled tx with 325344 wei spent: accept nonce 0 with 84100 wei spend (42000 extra)
+ from: "alice",
+ tx: makeUnsignedTx(0, 2, 4, 2),
+ err: nil,
+ },
+ },
+ },
+ // Previously existing transactions should be allowed to be replaced iff
+ // the new prices are bumped by a sufficient amount.
+ {
+ seeds: map[string]seed{
+ "alice": {balance: 100 + 8*21000 + 4*blobSize},
+ },
+ adds: []addtx{
+ { // New account, no previous txs: accept nonce 0
+ from: "alice",
+ tx: makeUnsignedTx(0, 2, 4, 2),
+ err: nil,
+ },
+ { // New account, 1 pooled tx: reject nonce 0 with low-gastip-bump
+ from: "alice",
+ tx: makeUnsignedTx(0, 3, 8, 4),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // New account, 1 pooled tx: reject nonce 0 with low-gascap-bump
+ from: "alice",
+ tx: makeUnsignedTx(0, 4, 6, 4),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // New account, 1 pooled tx: reject nonce 0 with low-blobcap-bump
+ from: "alice",
+ tx: makeUnsignedTx(0, 4, 8, 3),
+ err: txpool.ErrReplaceUnderpriced,
+ },
+ { // New account, 1 pooled tx: accept nonce 0 with all-bumps
+ from: "alice",
+ tx: makeUnsignedTx(0, 4, 8, 4),
+ err: nil,
+ },
+ },
+ },
+ }
+ for i, tt := range tests {
+ // Create a temporary folder for the persistent backend
+ storage, _ := os.MkdirTemp("", "blobpool-")
+ defer os.RemoveAll(storage) // late defer, still ok
+
+ os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700)
+ store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(), nil)
+
+ // Insert the seed transactions for the pool startup
+ var (
+ keys = make(map[string]*ecdsa.PrivateKey)
+ addrs = make(map[string]common.Address)
+ )
+ statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
+ for acc, seed := range tt.seeds {
+ // Generate a new random key/address for the seed account
+ keys[acc], _ = crypto.GenerateKey()
+ addrs[acc] = crypto.PubkeyToAddress(keys[acc].PublicKey)
+
+ // Seed the state database with this acocunt
+ statedb.AddBalance(addrs[acc], new(big.Int).SetUint64(seed.balance))
+ statedb.SetNonce(addrs[acc], seed.nonce)
+
+ // Sign the seed transactions and store them in the data store
+ for _, tx := range seed.txs {
+ var (
+ signed, _ = types.SignNewTx(keys[acc], types.LatestSigner(testChainConfig), tx)
+ blob, _ = rlp.EncodeToBytes(&blobTx{Tx: signed, Blobs: []kzg4844.Blob{emptyBlob}, Commits: []kzg4844.Commitment{emptyBlobCommit}, Proofs: []kzg4844.Proof{emptyBlobProof}})
+ )
+ store.Put(blob)
+ }
+ }
+ statedb.Commit(true)
+ store.Close()
+
+ // Create a blob pool out of the pre-seeded dats
+ chain := &testBlockChain{
+ config: testChainConfig,
+ basefee: uint256.NewInt(1050),
+ blobfee: uint256.NewInt(105),
+ statedb: statedb,
+ }
+ pool := New(Config{Datadir: storage}, chain)
+ if err := pool.Init(big.NewInt(1), chain.CurrentBlock()); err != nil {
+ t.Fatalf("test %d: failed to create blob pool: %v", i, err)
+ }
+ verifyPoolInternals(t, pool)
+
+ // Add each transaction one by one, verifying the pool internals in between
+ for j, add := range tt.adds {
+ signed, _ := types.SignNewTx(keys[add.from], types.LatestSigner(testChainConfig), add.tx)
+ if err := pool.add(signed, []kzg4844.Blob{emptyBlob}, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}); !errors.Is(err, add.err) {
+ t.Errorf("test %d, tx %d: adding transaction error mismatch: have %v, want %v", i, j, err, add.err)
+ }
+ verifyPoolInternals(t, pool)
+ }
+ // Verify the pool internals and close down the test
+ verifyPoolInternals(t, pool)
+ pool.Close()
+ }
+}
diff --git a/core/txpool/blobpool/config.go b/core/txpool/blobpool/config.go
new file mode 100644
index 000000000000..90f256e723f6
--- /dev/null
+++ b/core/txpool/blobpool/config.go
@@ -0,0 +1,50 @@
+// Copyright 2022 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "github.com/ethereum/go-ethereum/log"
+)
+
+// Config are the configuration parameters of the blob transaction pool.
+type Config struct {
+ Datadir string // Data directory containing the currently executable blobs
+ Datacap uint64 // Soft-cap of database storage (hard cap is larger due to overhead)
+ PriceBump uint64 // Minimum price bump percentage to replace an already existing nonce
+}
+
+// DefaultConfig contains the default configurations for the transaction pool.
+var DefaultConfig = Config{
+ Datadir: "blobpool",
+ Datacap: 10 * 1024 * 1024 * 1024,
+ PriceBump: 100, // either have patience or be agressive, no mushy ground
+}
+
+// sanitize checks the provided user configurations and changes anything that's
+// unreasonable or unworkable.
+func (config *Config) sanitize() Config {
+ conf := *config
+ if conf.Datacap < 1 {
+ log.Warn("Sanitizing invalid blobpool storage cap", "provided", conf.Datacap, "updated", DefaultConfig.Datacap)
+ conf.Datacap = DefaultConfig.Datacap
+ }
+ if conf.PriceBump < 1 {
+ log.Warn("Sanitizing invalid blobpool price bump", "provided", conf.PriceBump, "updated", DefaultConfig.PriceBump)
+ conf.PriceBump = DefaultConfig.PriceBump
+ }
+ return conf
+}
diff --git a/core/txpool/blobpool/evictheap.go b/core/txpool/blobpool/evictheap.go
new file mode 100644
index 000000000000..10a602c2addd
--- /dev/null
+++ b/core/txpool/blobpool/evictheap.go
@@ -0,0 +1,135 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "container/heap"
+ "math"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/holiman/uint256"
+)
+
+// evictHeap is a helper data structure to keep track of the cheapest bottleneck
+// transaction from each account to determine which account to evict from.
+//
+// The heap internally tracks a slice of cheapest transactions from each account
+// and a mapping from addresses to indices for direct removals/udates.
+//
+// The goal of the heap is to decide which account has the worst bottleneck to
+// evict transactions from.
+type evictHeap struct {
+ metas *map[common.Address][]*blobTxMeta // Pointer to the blob pool's index for price retrievals
+
+ basefeeJumps float64 // Pre-calculated absolute dynamic fee jumps for the base fee
+ blobfeeJumps float64 // Pre-calculated absolute dynamic fee jumps for the blob fee
+
+ addrs []common.Address // Heap of addresses to retrieve the cheapest out of
+ index map[common.Address]int // Indices into the heap for replacements
+}
+
+// newPriceHeap creates a new heap of cheapets accounts in the blob pool to evict
+// from in case of over saturation.
+func newPriceHeap(basefee *uint256.Int, blobfee *uint256.Int, index *map[common.Address][]*blobTxMeta) *evictHeap {
+ heap := &evictHeap{
+ metas: index,
+ index: make(map[common.Address]int),
+ }
+ for addr := range *index {
+ heap.index[addr] = len(heap.addrs)
+ heap.addrs = append(heap.addrs, addr)
+ }
+ heap.reinit(basefee, blobfee, true)
+ return heap
+}
+
+// reinit updates the pre-calculated dynamic fee jumps in the price heap and runs
+// the sorting algorithm from scratch on the entire heap.
+func (h *evictHeap) reinit(basefee *uint256.Int, blobfee *uint256.Int, force bool) {
+ // If the update is mostly the same as the old, don't sort pointlessly
+ basefeeJumps := dynamicFeeJumps(basefee)
+ blobfeeJumps := dynamicFeeJumps(blobfee)
+
+ if !force && math.Abs(h.basefeeJumps-basefeeJumps) < 0.01 && math.Abs(h.blobfeeJumps-blobfeeJumps) < 0.01 { // TODO(karalabe): 0.01 enough, maybe should be smaller? Maybe this optimization is moot?
+ return
+ }
+ // One or both of the dynamic fees jumped, resort the pool
+ h.basefeeJumps = basefeeJumps
+ h.blobfeeJumps = blobfeeJumps
+
+ heap.Init(h)
+}
+
+// Len implements sort.Interface as part of heap.Interface, returning the number
+// of accounts in the pool which can be considered for eviction.
+func (h *evictHeap) Len() int {
+ return len(h.addrs)
+}
+
+// Less implements sort.Interface as part of heap.Interface, returning which of
+// the two requested accounts has a cheaper bottleneck.
+func (h *evictHeap) Less(i, j int) bool {
+ txsI := (*(h.metas))[h.addrs[i]]
+ txsJ := (*(h.metas))[h.addrs[j]]
+
+ lastI := txsI[len(txsI)-1]
+ lastJ := txsJ[len(txsJ)-1]
+
+ prioI := evictionPriority(h.basefeeJumps, lastI.evictionExecFeeJumps, h.blobfeeJumps, lastI.evictionBlobFeeJumps)
+ if prioI > 0 {
+ prioI = 0
+ }
+ prioJ := evictionPriority(h.basefeeJumps, lastJ.evictionExecFeeJumps, h.blobfeeJumps, lastJ.evictionBlobFeeJumps)
+ if prioJ > 0 {
+ prioJ = 0
+ }
+ if prioI == prioJ {
+ return lastI.evictionExecTip.Lt(lastJ.evictionExecTip)
+ }
+ return prioI < prioJ
+}
+
+// Swap implements sort.Interface as part of heap.Interface, maintaining both the
+// order of the accounts according to the heap, and the account->item slot mapping
+// for replacements.
+func (h *evictHeap) Swap(i, j int) {
+ h.index[h.addrs[i]], h.index[h.addrs[j]] = h.index[h.addrs[j]], h.index[h.addrs[i]]
+ h.addrs[i], h.addrs[j] = h.addrs[j], h.addrs[i]
+}
+
+// Push implements heap.Interface, appending an item to the end of the account
+// ordering as well as the address to item slot mapping.
+func (h *evictHeap) Push(x any) {
+ h.index[x.(common.Address)] = len(h.addrs)
+ h.addrs = append(h.addrs, x.(common.Address))
+}
+
+// Pop implements heap.Interface, removing and returning the last element of the
+// heap.
+//
+// Note, use `heap.Pop`, not `priceheap.Pop`. This method is used by Go's heap,
+// to provide the functionality, it does not embed it.
+func (h *evictHeap) Pop() any {
+ // Remove the last element from the heap
+ size := len(h.addrs)
+ addr := h.addrs[size-1]
+ h.addrs = h.addrs[:size-1]
+
+ // Unindex the removed element and return
+ delete(h.index, addr)
+ return addr
+}
diff --git a/core/txpool/blobpool/evictheap_test.go b/core/txpool/blobpool/evictheap_test.go
new file mode 100644
index 000000000000..b20e1ca3db75
--- /dev/null
+++ b/core/txpool/blobpool/evictheap_test.go
@@ -0,0 +1,318 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "container/heap"
+ "math/rand"
+ "testing"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/params"
+ "github.com/holiman/uint256"
+)
+
+// verifyHeapInternals verifies that all accounts present in the index are also
+// present in the heap and internals are consistent across various indices.
+func verifyHeapInternals(t *testing.T, evict *evictHeap) {
+ t.Helper()
+
+ // Ensure that all accounts are present in the heap and no extras
+ seen := make(map[common.Address]struct{})
+ for i, addr := range evict.addrs {
+ seen[addr] = struct{}{}
+ if _, ok := (*evict.metas)[addr]; !ok {
+ t.Errorf("heap contains unexpected address at slot %d: %v", i, addr)
+ }
+ }
+ for addr := range *evict.metas {
+ if _, ok := seen[addr]; !ok {
+ t.Errorf("heap is missing required address %v", addr)
+ }
+ }
+ if len(evict.addrs) != len(*evict.metas) {
+ t.Errorf("heap size %d mismatches metadata size %d", len(evict.addrs), len(*evict.metas))
+ }
+ // Ensure that all accounts are present in the heap order index and no extras
+ have := make([]common.Address, len(evict.index))
+ for addr, i := range evict.index {
+ have[i] = addr
+ }
+ if len(have) != len(evict.addrs) {
+ t.Errorf("heap index size %d mismatches heap size %d", len(have), len(evict.addrs))
+ }
+ for i := 0; i < len(have) && i < len(evict.addrs); i++ {
+ if have[i] != evict.addrs[i] {
+ t.Errorf("heap index for slot %d mismatches: have %v, want %v", i, have[i], evict.addrs[i])
+ }
+ }
+}
+
+// Tests that the price heap can correcty sort its set of transactions based on
+// an input base- and blob fee.
+func TestPriceHeapSorting(t *testing.T) {
+ tests := []struct {
+ execTips []uint64
+ execFees []uint64
+ blobFees []uint64
+
+ basefee uint64
+ blobfee uint64
+
+ order []int
+ }{
+ // If everthing is above the basefee and blobfee, order by miner tip
+ {
+ execTips: []uint64{1, 0, 2},
+ execFees: []uint64{1, 2, 3},
+ blobFees: []uint64{3, 2, 1},
+ basefee: 0,
+ blobfee: 0,
+ order: []int{1, 0, 2},
+ },
+ // If only basefees are used (blob fee matches with network), return the
+ // ones the furthest below the current basefee, splitting same ones with
+ // the tip. Anything above the basefee should be split by tip.
+ {
+ execTips: []uint64{100, 50, 100, 50, 1, 2, 3},
+ execFees: []uint64{1000, 1000, 500, 500, 2000, 2000, 2000},
+ blobFees: []uint64{0, 0, 0, 0, 0, 0, 0},
+ basefee: 1999,
+ blobfee: 0,
+ order: []int{3, 2, 1, 0, 4, 5, 6},
+ },
+ // If only blobfees are used (base fee matches with network), return the
+ // ones the furthest below the current blobfee, splitting same ones with
+ // the tip. Anything above the blobfee should be split by tip.
+ {
+ execTips: []uint64{100, 50, 100, 50, 1, 2, 3},
+ execFees: []uint64{0, 0, 0, 0, 0, 0, 0},
+ blobFees: []uint64{1000, 1000, 500, 500, 2000, 2000, 2000},
+ basefee: 0,
+ blobfee: 1999,
+ order: []int{3, 2, 1, 0, 4, 5, 6},
+ },
+ // If both basefee and blobfee is specified, sort by the larger distance
+ // of the two from the current network conditions, splitting same (loglog)
+ // ones via teh tip.
+ //
+ // Basefee: 1000
+ // Blobfee: 100
+ //
+ // Tx #0: (800, 80) - 2 jumps below both => priority -1
+ // Tx #1: (630, 63) - 4 jumps below both => priority -2
+ // Tx #2: (800, 63) - 2 jumps below basefee, 4 jumps below blobfee => priority -2 (blob penalty dominates)
+ // Tx #3: (630, 80) - 4 jumps below basefee, 2 jumps below blobfee => priority -2 (base penalty dominates)
+ //
+ // Txs 1, 2, 3 share the same priority, split via tip, prefer 0 as the best
+ {
+ execTips: []uint64{1, 2, 3, 4},
+ execFees: []uint64{800, 630, 800, 630},
+ blobFees: []uint64{80, 63, 63, 80},
+ basefee: 1000,
+ blobfee: 100,
+ order: []int{1, 2, 3, 0},
+ },
+ }
+ for i, tt := range tests {
+ // Create an index of the transactions
+ index := make(map[common.Address][]*blobTxMeta)
+ for j := byte(0); j < byte(len(tt.execTips)); j++ {
+ addr := common.Address{j}
+
+ var (
+ execTip = uint256.NewInt(tt.execTips[j])
+ execFee = uint256.NewInt(tt.execFees[j])
+ blobFee = uint256.NewInt(tt.blobFees[j])
+
+ basefeeJumps = dynamicFeeJumps(execFee)
+ blobfeeJumps = dynamicFeeJumps(blobFee)
+ )
+ index[addr] = []*blobTxMeta{{
+ id: uint64(j),
+ size: 128 * 1024,
+ nonce: 0,
+ execTipCap: execTip,
+ execFeeCap: execFee,
+ blobFeeCap: blobFee,
+ basefeeJumps: basefeeJumps,
+ blobfeeJumps: blobfeeJumps,
+ evictionExecTip: execTip,
+ evictionExecFeeJumps: basefeeJumps,
+ evictionBlobFeeJumps: blobfeeJumps,
+ }}
+ }
+ // Create a price heap and check the pop order
+ priceheap := newPriceHeap(uint256.NewInt(tt.basefee), uint256.NewInt(tt.blobfee), &index)
+ verifyHeapInternals(t, priceheap)
+
+ for j := 0; j < len(tt.order); j++ {
+ if next := heap.Pop(priceheap); int(next.(common.Address)[0]) != tt.order[j] {
+ t.Errorf("test %d, item %d: order mismatch: have %d, want %d", i, j, next.(common.Address)[0], tt.order[j])
+ } else {
+ delete(index, next.(common.Address)) // remove to simulate a correct pool for the test
+ }
+ verifyHeapInternals(t, priceheap)
+ }
+ }
+}
+
+// Benchmarks reheaping the entire set of accounts in the blob pool.
+func BenchmarkPriceHeapReinit1MB(b *testing.B) { benchmarkPriceHeapReinit(b, 1024*1024) }
+func BenchmarkPriceHeapReinit10MB(b *testing.B) { benchmarkPriceHeapReinit(b, 10*1024*1024) }
+func BenchmarkPriceHeapReinit100MB(b *testing.B) { benchmarkPriceHeapReinit(b, 100*1024*1024) }
+func BenchmarkPriceHeapReinit1GB(b *testing.B) { benchmarkPriceHeapReinit(b, 1024*1024*1024) }
+func BenchmarkPriceHeapReinit10GB(b *testing.B) { benchmarkPriceHeapReinit(b, 10*1024*1024*1024) }
+func BenchmarkPriceHeapReinit25GB(b *testing.B) { benchmarkPriceHeapReinit(b, 25*1024*1024*1024) }
+func BenchmarkPriceHeapReinit50GB(b *testing.B) { benchmarkPriceHeapReinit(b, 50*1024*1024*1024) }
+func BenchmarkPriceHeapReinit100GB(b *testing.B) { benchmarkPriceHeapReinit(b, 100*1024*1024*1024) }
+
+func benchmarkPriceHeapReinit(b *testing.B, datacap uint64) {
+ // Calculate how many unique transactions we can fit into the provided disk
+ // data cap
+ blobs := datacap / (params.BlobTxBytesPerFieldElement * params.BlobTxFieldElementsPerBlob)
+
+ // Create a random set of transactions with random fees. Use a separate account
+ // for each transaction to make it worse case.
+ index := make(map[common.Address][]*blobTxMeta)
+ for i := 0; i < int(blobs); i++ {
+ var addr common.Address
+ rand.Read(addr[:])
+
+ var (
+ execTip = uint256.NewInt(rand.Uint64())
+ execFee = uint256.NewInt(rand.Uint64())
+ blobFee = uint256.NewInt(rand.Uint64())
+
+ basefeeJumps = dynamicFeeJumps(execFee)
+ blobfeeJumps = dynamicFeeJumps(blobFee)
+ )
+ index[addr] = []*blobTxMeta{{
+ id: uint64(i),
+ size: 128 * 1024,
+ nonce: 0,
+ execTipCap: execTip,
+ execFeeCap: execFee,
+ blobFeeCap: blobFee,
+ basefeeJumps: basefeeJumps,
+ blobfeeJumps: blobfeeJumps,
+ evictionExecTip: execTip,
+ evictionExecFeeJumps: basefeeJumps,
+ evictionBlobFeeJumps: blobfeeJumps,
+ }}
+ }
+ // Create a price heap and reinit it over and over
+ heap := newPriceHeap(uint256.NewInt(rand.Uint64()), uint256.NewInt(rand.Uint64()), &index)
+
+ basefees := make([]*uint256.Int, b.N)
+ blobfees := make([]*uint256.Int, b.N)
+ for i := 0; i < b.N; i++ {
+ basefees[i] = uint256.NewInt(rand.Uint64())
+ blobfees[i] = uint256.NewInt(rand.Uint64())
+ }
+ b.ResetTimer()
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ heap.reinit(basefees[i], blobfees[i], true)
+ }
+}
+
+// Benchmarks overflowing the heap over and over (add and then drop).
+func BenchmarkPriceHeapOverflow1MB(b *testing.B) { benchmarkPriceHeapOverflow(b, 1024*1024) }
+func BenchmarkPriceHeapOverflow10MB(b *testing.B) { benchmarkPriceHeapOverflow(b, 10*1024*1024) }
+func BenchmarkPriceHeapOverflow100MB(b *testing.B) { benchmarkPriceHeapOverflow(b, 100*1024*1024) }
+func BenchmarkPriceHeapOverflow1GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 1024*1024*1024) }
+func BenchmarkPriceHeapOverflow10GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 10*1024*1024*1024) }
+func BenchmarkPriceHeapOverflow25GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 25*1024*1024*1024) }
+func BenchmarkPriceHeapOverflow50GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 50*1024*1024*1024) }
+func BenchmarkPriceHeapOverflow100GB(b *testing.B) { benchmarkPriceHeapOverflow(b, 100*1024*1024*1024) }
+
+func benchmarkPriceHeapOverflow(b *testing.B, datacap uint64) {
+ // Calculate how many unique transactions we can fit into the provided disk
+ // data cap
+ blobs := datacap / (params.BlobTxBytesPerFieldElement * params.BlobTxFieldElementsPerBlob)
+
+ // Create a random set of transactions with random fees. Use a separate account
+ // for each transaction to make it worse case.
+ index := make(map[common.Address][]*blobTxMeta)
+ for i := 0; i < int(blobs); i++ {
+ var addr common.Address
+ rand.Read(addr[:])
+
+ var (
+ execTip = uint256.NewInt(rand.Uint64())
+ execFee = uint256.NewInt(rand.Uint64())
+ blobFee = uint256.NewInt(rand.Uint64())
+
+ basefeeJumps = dynamicFeeJumps(execFee)
+ blobfeeJumps = dynamicFeeJumps(blobFee)
+ )
+ index[addr] = []*blobTxMeta{{
+ id: uint64(i),
+ size: 128 * 1024,
+ nonce: 0,
+ execTipCap: execTip,
+ execFeeCap: execFee,
+ blobFeeCap: blobFee,
+ basefeeJumps: basefeeJumps,
+ blobfeeJumps: blobfeeJumps,
+ evictionExecTip: execTip,
+ evictionExecFeeJumps: basefeeJumps,
+ evictionBlobFeeJumps: blobfeeJumps,
+ }}
+ }
+ // Create a price heap and overflow it over and over
+ evict := newPriceHeap(uint256.NewInt(rand.Uint64()), uint256.NewInt(rand.Uint64()), &index)
+ var (
+ addrs = make([]common.Address, b.N)
+ metas = make([]*blobTxMeta, b.N)
+ )
+ for i := 0; i < b.N; i++ {
+ rand.Read(addrs[i][:])
+
+ var (
+ execTip = uint256.NewInt(rand.Uint64())
+ execFee = uint256.NewInt(rand.Uint64())
+ blobFee = uint256.NewInt(rand.Uint64())
+
+ basefeeJumps = dynamicFeeJumps(execFee)
+ blobfeeJumps = dynamicFeeJumps(blobFee)
+ )
+ metas[i] = &blobTxMeta{
+ id: uint64(int(blobs) + i),
+ size: 128 * 1024,
+ nonce: 0,
+ execTipCap: execTip,
+ execFeeCap: execFee,
+ blobFeeCap: blobFee,
+ basefeeJumps: basefeeJumps,
+ blobfeeJumps: blobfeeJumps,
+ evictionExecTip: execTip,
+ evictionExecFeeJumps: basefeeJumps,
+ evictionBlobFeeJumps: blobfeeJumps,
+ }
+ }
+ b.ResetTimer()
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ index[addrs[i]] = []*blobTxMeta{metas[i]}
+ heap.Push(evict, addrs[i])
+
+ drop := heap.Pop(evict)
+ delete(index, drop.(common.Address))
+ }
+}
diff --git a/core/txpool/blobpool/interface.go b/core/txpool/blobpool/interface.go
new file mode 100644
index 000000000000..6f296a54bd63
--- /dev/null
+++ b/core/txpool/blobpool/interface.go
@@ -0,0 +1,44 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/params"
+)
+
+// BlockChain defines the minimal set of methods needed to back a blob pool with
+// a chain. Exists to allow mocking the live chain out of tests.
+type BlockChain interface {
+ // Config retrieves the chain's fork configuration.
+ Config() *params.ChainConfig
+
+ // CurrentBlock returns the current head of the chain.
+ CurrentBlock() *types.Header
+
+ // CurrentFinalBlock returns the current block below which blobs should not
+ // be maintained anymore for reorg purposes.
+ CurrentFinalBlock() *types.Header
+
+ // GetBlock retrieves a specific block, used during pool resets.
+ GetBlock(hash common.Hash, number uint64) *types.Block
+
+ // StateAt returns a state database for a given root hash (generally the head).
+ StateAt(root common.Hash) (*state.StateDB, error)
+}
diff --git a/core/txpool/blobpool/limbo.go b/core/txpool/blobpool/limbo.go
new file mode 100644
index 000000000000..d20a9d4e7406
--- /dev/null
+++ b/core/txpool/blobpool/limbo.go
@@ -0,0 +1,267 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "errors"
+ "os"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
+ "github.com/ethereum/go-ethereum/log"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/holiman/billy"
+)
+
+// limboBlob is a wrapper around an opaque blobset that also contains the tx hash
+// to which it belongs as well as the block number in which it was included for
+// finality eviction.
+type limboBlob struct {
+ Owner common.Hash // Owner transaction's hash to support resurrecting reorged txs
+ Block uint64 // Block in which the blob transaction was included
+
+ Blobs []kzg4844.Blob // The opaque blobs originally part of the transaction
+ Commits []kzg4844.Commitment // The commitments for the original blobs
+ Proofs []kzg4844.Proof // The proofs verifying the commitments
+}
+
+type limboBlobMeta struct {
+ id uint64 // Storage ID in the limbo's persistent store
+ block uint64 // Block in which the blob transaction was included
+}
+
+// limbo is a light, indexed database to temporarily store recently included
+// blobs until they are finalized. The purpose is to support small reorgs, which
+// would require pulling back up old blobs (which aren't part of the chain).
+//
+// TODO(karalabe): Currently updating the inclusion block of a blob needs a full db rewrite. Can we do without?
+type limbo struct {
+ store billy.Database // Persistent data store for limboed blobs
+
+ index map[common.Hash]uint64 // Mappings from tx hashes to datastore ids
+ groups map[uint64]map[uint64]common.Hash // Set of txs included in past blocks
+}
+
+// newLimbo opens and indexes a set of limboed blob transactions.
+func newLimbo(datadir string) (*limbo, error) {
+ l := &limbo{
+ index: make(map[common.Hash]uint64),
+ groups: make(map[uint64]map[uint64]common.Hash),
+ }
+ // Index all limboed blobs on disk and delete anything inprocessable
+ var fails []uint64
+ index := func(id uint64, size uint32, data []byte) {
+ if l.parseBlob(id, data) != nil {
+ fails = append(fails, id)
+ }
+ }
+ if err := os.MkdirAll(datadir, 0700); err != nil {
+ return nil, err
+ }
+ store, err := billy.Open(billy.Options{Path: datadir}, newSlotter(), index)
+ if err != nil {
+ return nil, err
+ }
+ l.store = store
+
+ if len(fails) > 0 {
+ log.Warn("Dropping invalidated limboed blobs", "ids", fails)
+ for _, id := range fails {
+ if err := l.store.Delete(id); err != nil {
+ l.Close()
+ return nil, err
+ }
+ }
+ }
+ return l, nil
+}
+
+// Close closes down the underlying persistent store.
+func (l *limbo) Close() error {
+ return l.store.Close()
+}
+
+// parseBlob is a callback method on limbo creation that gets called for each
+// limboed blob on disk to create the in-memory metadata index.
+func (l *limbo) parseBlob(id uint64, data []byte) error {
+ item := new(limboBlob)
+ if err := rlp.DecodeBytes(data, item); err != nil {
+ // This path is impossible unless the disk data representation changes
+ // across restarts. For that ever unprobable case, recover gracefully
+ // by ignoring this data entry.
+ log.Error("Failed to decode blob limbo entry", "id", id, "err", err)
+ return err
+ }
+ if _, ok := l.index[item.Owner]; ok {
+ // This path is impossible, unless due to a programming error a blob gets
+ // inserted into the limbo which was already part of if. Recover gracefully
+ // by ignoring this data entry.
+ log.Error("Dropping duplicate blob limbo entry", "owner", item.Owner, "id", id)
+ return errors.New("duplicate blob")
+ }
+ l.index[item.Owner] = id
+
+ if _, ok := l.groups[item.Block]; !ok {
+ l.groups[item.Block] = make(map[uint64]common.Hash)
+ }
+ l.groups[item.Block][id] = item.Owner
+
+ return nil
+}
+
+// finalize evicts all blobs belonging to a recently finalized block or older.
+func (l *limbo) finalize(final *types.Header) {
+ // Just in case there's no final block yet (network not yet merged, weird
+ // restart, sethead, etc), fail gracefully.
+ if final == nil {
+ log.Error("Nil finalized block cannot evict old blobs")
+ return
+ }
+ for block, ids := range l.groups {
+ if block > final.Number.Uint64() {
+ continue
+ }
+ for id, owner := range ids {
+ if err := l.store.Delete(id); err != nil {
+ log.Error("Failed to drop finalized blob", "block", block, "id", id, "err", err)
+ }
+ delete(l.index, owner)
+ }
+ delete(l.groups, block)
+ }
+}
+
+// push stores a new blob transaction into the limbo, waiting until finality for
+// it to be automatically evicted.
+func (l *limbo) push(tx common.Hash, block uint64, blobs []kzg4844.Blob, commits []kzg4844.Commitment, proofs []kzg4844.Proof) error {
+ // If the blobs are already tracked by the limbo, consider it a programming
+ // error. There's not much to do against it, but be loud.
+ if _, ok := l.index[tx]; ok {
+ log.Error("Limbo cannot push already tracked blobs", "tx", tx)
+ return errors.New("already tracked blob transaction")
+ }
+ if err := l.setAndIndex(tx, block, blobs, commits, proofs); err != nil {
+ log.Error("Failed to set and index liboed blobs", "tx", tx, "err", err)
+ return err
+ }
+ return nil
+}
+
+// pull retrieves a previously pushed set of blobs back from the limbo, removing
+// it at the same time. This method should be used when a previously included blob
+// transaction gets reorged out.
+func (l *limbo) pull(tx common.Hash) ([]kzg4844.Blob, []kzg4844.Commitment, []kzg4844.Proof, error) {
+ // If the blobs are not tracked by the limbo, there's not much to do. This
+ // can happen for example if a blob transaction is mined without pushing it
+ // into the network first.
+ id, ok := l.index[tx]
+ if !ok {
+ log.Trace("Limbo cannot pull non-tracked blobs", "tx", tx)
+ return nil, nil, nil, errors.New("unseen blob transaction")
+ }
+ item, err := l.getAndDrop(id)
+ if err != nil {
+ log.Error("Failed to get and drop limboed blobs", "tx", tx, "id", id, "err", err)
+ return nil, nil, nil, err
+ }
+ return item.Blobs, item.Commits, item.Proofs, nil
+}
+
+// update changes the block number under which a blob transaction is tracked. This
+// method should be used when a reorg changes a transaction's inclusion block.
+//
+// The method may log errors for various unexpcted scenarios but will not return
+// any of it since there's no clear error case. Some errors may be due to coding
+// issues, others caused by signers mining MEV stuff or swapping transactions. In
+// all cases, the pool needs to continue operating.
+func (l *limbo) update(tx common.Hash, block uint64) {
+ // If the blobs are not tracked by the limbo, there's not much to do. This
+ // can happen for example if a blob transaction is mined without pushing it
+ // into the network first.
+ id, ok := l.index[tx]
+ if !ok {
+ log.Trace("Limbo cannot update non-tracked blobs", "tx", tx)
+ return
+ }
+ // If there was no change in the blob's inclusion block, don't mess around
+ // with heavy database operations.
+ if _, ok := l.groups[block][id]; ok {
+ log.Trace("Blob transaction unchanged in limbo", "tx", tx, "block", block)
+ return
+ }
+ // Retrieve the old blobs from the data store and write tehm back with a new
+ // block number. IF anything fails, there's not much to do, go on.
+ item, err := l.getAndDrop(id)
+ if err != nil {
+ log.Error("Failed to get and drop limboed blobs", "tx", tx, "id", id, "err", err)
+ return
+ }
+ if err := l.setAndIndex(tx, block, item.Blobs, item.Commits, item.Proofs); err != nil {
+ log.Error("Failed to set and index limboed blobs", "tx", tx, "err", err)
+ return
+ }
+ log.Trace("Blob transaction updated in limbo", "tx", tx, "old-block", item.Block, "new-block", block)
+}
+
+// getAndDrop retrieves a blob item from the limbo store and deletes it both from
+// the store and indices.
+func (l *limbo) getAndDrop(id uint64) (*limboBlob, error) {
+ data, err := l.store.Get(id)
+ if err != nil {
+ return nil, err
+ }
+ item := new(limboBlob)
+ if err = rlp.DecodeBytes(data, item); err != nil {
+ return nil, err
+ }
+ delete(l.index, item.Owner)
+ delete(l.groups[item.Block], id)
+ if len(l.groups[item.Block]) == 0 {
+ delete(l.groups, item.Block)
+ }
+ if err := l.store.Delete(id); err != nil {
+ return nil, err
+ }
+ return item, nil
+}
+
+// setAndIndex assembles a limbo blob database entry and stores it, also updating
+// the in-memory indices.
+func (l *limbo) setAndIndex(tx common.Hash, block uint64, blobs []kzg4844.Blob, commits []kzg4844.Commitment, proofs []kzg4844.Proof) error {
+ item := &limboBlob{
+ Owner: tx,
+ Block: block,
+ Blobs: blobs,
+ Commits: commits,
+ Proofs: proofs,
+ }
+ data, err := rlp.EncodeToBytes(item)
+ if err != nil {
+ panic(err) // cannot happen runtime, dev error
+ }
+ id, err := l.store.Put(data)
+ if err != nil {
+ return err
+ }
+ l.index[tx] = id
+ if _, ok := l.groups[block]; !ok {
+ l.groups[block] = make(map[uint64]common.Hash)
+ }
+ l.groups[block][id] = tx
+ return nil
+}
diff --git a/core/txpool/blobpool/metrics.go b/core/txpool/blobpool/metrics.go
new file mode 100644
index 000000000000..cb19dc3133bc
--- /dev/null
+++ b/core/txpool/blobpool/metrics.go
@@ -0,0 +1,76 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import "github.com/ethereum/go-ethereum/metrics"
+
+var (
+ // datacapGauge tracks the user's configured capacity for the blob pool. It
+ // is mostly a way to expose/debug issues.
+ datacapGauge = metrics.NewRegisteredGauge("blobpool/datacap", nil)
+
+ // The below metrics track the per-datastore metrics for the primary blob
+ // store and the temporary limbo store.
+ datausedGauge = metrics.NewRegisteredGauge("blobpool/dataused", nil)
+ datarealGauge = metrics.NewRegisteredGauge("blobpool/datareal", nil)
+ slotusedGauge = metrics.NewRegisteredGauge("blobpool/slotused", nil)
+
+ limboDatausedGauge = metrics.NewRegisteredGauge("blobpool/limbo/dataused", nil)
+ limboDatarealGauge = metrics.NewRegisteredGauge("blobpool/limbo/datareal", nil)
+ limboSlotusedGauge = metrics.NewRegisteredGauge("blobpool/limbo/slotused", nil)
+
+ // The below metrics track the per-shelf metrics for the primary blob store
+ // and the temporary limbo store.
+ shelfDatausedGaugeName = "blobpool/shelf-%d/dataused"
+ shelfDatagapsGaugeName = "blobpool/shelf-%d/datagaps"
+ shelfSlotusedGaugeName = "blobpool/shelf-%d/slotused"
+ shelfSlotgapsGaugeName = "blobpool/shelf-%d/slotgaps"
+
+ limboShelfDatausedGaugeName = "blobpool/limbo/shelf-%d/dataused"
+ limboShelfDatagapsGaugeName = "blobpool/limbo/shelf-%d/datagaps"
+ limboShelfSlotusedGaugeName = "blobpool/limbo/shelf-%d/slotused"
+ limboShelfSlotgapsGaugeName = "blobpool/limbo/shelf-%d/slotgaps"
+
+ // The oversized metrics aggregate the shelf stats above the max blob count
+ // limits to track transactions that are just huge, but don't contain blobs.
+ //
+ // There are no oversized data in the limbo, it only contains blobs and some
+ // constant metadata.
+ oversizedDatausedGauge = metrics.NewRegisteredGauge("blobpool/oversized/dataused", nil)
+ oversizedDatagapsGauge = metrics.NewRegisteredGauge("blobpool/oversized/datagaps", nil)
+ oversizedSlotusedGauge = metrics.NewRegisteredGauge("blobpool/oversized/slotused", nil)
+ oversizedSlotgapsGauge = metrics.NewRegisteredGauge("blobpool/oversized/slotgaps", nil)
+
+ // basefeeGauge and blobfeeGauge track the current network 1559 base fee and
+ // 4844 blob fee respectively.
+ basefeeGauge = metrics.NewRegisteredGauge("blobpool/basefee", nil)
+ blobfeeGauge = metrics.NewRegisteredGauge("blobpool/blobfee", nil)
+
+ // pooltipGague is the configurable miner tip to permit a transaction into
+ // the pool.
+ pooltipGague = metrics.NewRegisteredGauge("blobpool/pooltip", nil)
+
+ // addwait/time, resetwait/time and pendwait/time track the rough health of
+ // the pool and wether or not it's capable of keeping up with the load from
+ // the network.
+ addwaitHist = metrics.NewRegisteredHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015))
+ addtimeHist = metrics.NewRegisteredHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015))
+ resetwaitHist = metrics.NewRegisteredHistogram("blobpool/resetwait", nil, metrics.NewExpDecaySample(1028, 0.015))
+ resettimeHist = metrics.NewRegisteredHistogram("blobpool/resettime", nil, metrics.NewExpDecaySample(1028, 0.015))
+ pendwaitHist = metrics.NewRegisteredHistogram("blobpool/pendwait", nil, metrics.NewExpDecaySample(1028, 0.015))
+ pendtimeHist = metrics.NewRegisteredHistogram("blobpool/pendtime", nil, metrics.NewExpDecaySample(1028, 0.015))
+)
diff --git a/core/txpool/blobpool/priority.go b/core/txpool/blobpool/priority.go
new file mode 100644
index 000000000000..c58518aac1b8
--- /dev/null
+++ b/core/txpool/blobpool/priority.go
@@ -0,0 +1,109 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "math"
+ "math/big"
+
+ "github.com/holiman/uint256"
+)
+
+// log2_1_125 is used in the eviction priority calculation.
+var log2_1_125 = math.Log2(1.125)
+
+// evictionPriority calculates the eviction priority based on the algorithm
+// described in the BlobPool docs for a both fee components.
+//
+// This method takes about 8ns on a very recent laptop CPU, recalculating about
+// 125 million transaction priority values per second.
+func evictionPriority(basefeeJumps float64, txBasefeeJumps, blobfeeJumps, txBlobfeeJumps float64) int {
+ var (
+ basefeePriority = evictionPriority1D(basefeeJumps, txBasefeeJumps)
+ blobfeePriority = evictionPriority1D(blobfeeJumps, txBlobfeeJumps)
+ )
+ if basefeePriority < blobfeePriority {
+ return basefeePriority
+ }
+ return blobfeePriority
+}
+
+// evictionPriority1D calculates the eviction priority based on the algorithm
+// described in the BlobPool docs for a single fee component.
+func evictionPriority1D(basefeeJumps float64, txfeeJumps float64) int {
+ jumps := txfeeJumps - basefeeJumps
+ if int(jumps) == 0 {
+ return 0 // can't log2 0
+ }
+ if jumps < 0 {
+ return -intLog2(int(-math.Floor(jumps)))
+ }
+ return intLog2(int(math.Ceil(jumps)))
+}
+
+// dynamicFeeJumps calculates the log1.125(fee), namely the number of fee jumps
+// needed to reach the requested one. We only use it when calculating the jumps
+// between 2 fees, so it doesn't matter from what exact number with returns.
+// it returns the result from (0, 1, 1.125).
+//
+// This method is very expensive, taking about 75ns on a very recent laptop CPU,
+// but the result does not change with the lifetime of a transaction, so it can
+// be cached.
+func dynamicFeeJumps(fee *uint256.Int) float64 {
+ if fee.IsZero() {
+ return 0 // can't log2 zero, should never happen outside tests, but don't choke
+ }
+ n, _ := new(big.Float).SetInt(fee.ToBig()).Float64()
+ return math.Log2(n) / log2_1_125
+}
+
+// intLog2 is a helper to calculate the integral part of a log2 of an unsigned
+// integer. It is a very specific calculation that's not particularly useful in
+// general, but it's what we need here (it's fast).
+func intLog2(n int) int {
+ switch {
+ case n == 0:
+ panic("log2(0) is undefined")
+ case n == 1:
+ return 0
+ case n < 4:
+ return 1
+ case n < 8:
+ return 2
+ case n < 16:
+ return 3
+ case n < 32:
+ return 4
+ case n < 64:
+ return 5
+ case n < 128:
+ return 6
+ case n < 256:
+ return 7
+ case n < 512:
+ return 8
+ case n < 1024:
+ return 9
+ case n < 2048:
+ return 10
+ default:
+ // The input is log1.125(uint256) = log2(uint256) / log2(1.125). At the
+ // most extreme, log2(uint256) will be a bit below 257, and the constant
+ // log2(1.125) ~= 0.17. The larges input thus is ~257 / ~0.17 ~= ~1511.
+ panic("dynamic fee jump diffs cannot reach this")
+ }
+}
diff --git a/core/txpool/blobpool/priority_test.go b/core/txpool/blobpool/priority_test.go
new file mode 100644
index 000000000000..14a9e83b3fe4
--- /dev/null
+++ b/core/txpool/blobpool/priority_test.go
@@ -0,0 +1,88 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import (
+ "math/rand"
+ "testing"
+
+ "github.com/holiman/uint256"
+)
+
+// Tests that the priority fees are calculated correctly as the log2 of the fee
+// jumps needed to go from the base fee to the tx's fee cap.
+func TestPriorityCalculation(t *testing.T) {
+ tests := []struct {
+ basefee uint64
+ txfee uint64
+ result int
+ }{
+ {basefee: 7, txfee: 10, result: 2}, // 3.02 jumps, 4 ceil, 2 log2
+ {basefee: 17_200_000_000, txfee: 17_200_000_000, result: 0}, // 0 jumps, special case 0 log2
+ {basefee: 9_853_941_692, txfee: 11_085_092_510, result: 0}, // 0.99 jumps, 1 ceil, 0 log2
+ {basefee: 11_544_106_391, txfee: 10_356_781_100, result: 0}, // -0.92 jumps, -1 floor, 0 log2
+ {basefee: 17_200_000_000, txfee: 7, result: -7}, // -183.57 jumps, -184 floor, -7 log2
+ {basefee: 7, txfee: 17_200_000_000, result: 7}, // 183.57 jumps, 184 ceil, 7 log2
+ }
+ for i, tt := range tests {
+ var (
+ baseJumps = dynamicFeeJumps(uint256.NewInt(tt.basefee))
+ feeJumps = dynamicFeeJumps(uint256.NewInt(tt.txfee))
+ )
+ if prio := evictionPriority1D(baseJumps, feeJumps); prio != tt.result {
+ t.Errorf("test %d priority mismatch: have %d, want %d", i, prio, tt.result)
+ }
+ }
+}
+
+// Benchmarks how many dynamic fee jump values can be done.
+func BenchmarkDynamicFeeJumpCalculation(b *testing.B) {
+ fees := make([]*uint256.Int, b.N)
+ for i := 0; i < b.N; i++ {
+ fees[i] = uint256.NewInt(rand.Uint64())
+ }
+ b.ResetTimer()
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ dynamicFeeJumps(fees[i])
+ }
+}
+
+// Benchmarks how many priority recalculations can be done.
+func BenchmarkPriorityCalculation(b *testing.B) {
+ // The basefee and blob fee is constant for all transactions across a block,
+ // so we can assume theit absolute jump counts can be pre-computed.
+ basefee := uint256.NewInt(17_200_000_000) // 17.2 Gwei is the 22.03.2023 zero-emission basefee, random number
+ blobfee := uint256.NewInt(123_456_789_000) // Completely random, no idea what this will be
+
+ basefeeJumps := dynamicFeeJumps(basefee)
+ blobfeeJumps := dynamicFeeJumps(blobfee)
+
+ // The transaction's fee cap and blob fee cap are constant across the life
+ // of the transaction, so we can pre-calculate and cache them.
+ txBasefeeJumps := make([]float64, b.N)
+ txBlobfeeJumps := make([]float64, b.N)
+ for i := 0; i < b.N; i++ {
+ txBasefeeJumps[i] = dynamicFeeJumps(uint256.NewInt(rand.Uint64()))
+ txBlobfeeJumps[i] = dynamicFeeJumps(uint256.NewInt(rand.Uint64()))
+ }
+ b.ResetTimer()
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ evictionPriority(basefeeJumps, txBasefeeJumps[i], blobfeeJumps, txBlobfeeJumps[i])
+ }
+}
diff --git a/core/txpool/blobpool/slotter.go b/core/txpool/blobpool/slotter.go
new file mode 100644
index 000000000000..35349c3445cf
--- /dev/null
+++ b/core/txpool/blobpool/slotter.go
@@ -0,0 +1,38 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+// newSlotter creates a helper method for the Billy datastore that returns the
+// individual shelf sizes used to store transactions in.
+//
+// The slotter will create shelves for each possible blob count + some tx metadata
+// wiggle room, up to the max permitted limits.
+//
+// The slotter also creates a shelf for 0-blob transactions. Whilst those are not
+// allowed in the current protocol, having an empty shelf is not a relevant use
+// of resources, but it makes stress testing with junk transactions simpler.
+func newSlotter() func() (uint32, bool) {
+ slotsize := uint32(txAvgSize)
+ slotsize -= uint32(blobSize) // underflows, it's ok, will overflow back in the first return
+
+ return func() (size uint32, done bool) {
+ slotsize += blobSize
+ finished := slotsize > maxBlobsPerTransaction*blobSize+txMaxSize
+
+ return slotsize, finished
+ }
+}
diff --git a/core/txpool/blobpool/slotter_test.go b/core/txpool/blobpool/slotter_test.go
new file mode 100644
index 000000000000..2751a1872541
--- /dev/null
+++ b/core/txpool/blobpool/slotter_test.go
@@ -0,0 +1,58 @@
+// Copyright 2023 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package blobpool
+
+import "testing"
+
+// Tests that the slotter creates the expected database shelves.
+func TestNewSlotter(t *testing.T) {
+ // Generate the database shelve sizes
+ slotter := newSlotter()
+
+ var shelves []uint32
+ for {
+ shelf, done := slotter()
+ shelves = append(shelves, shelf)
+ if done {
+ break
+ }
+ }
+ // Compare the database shelves to the expected ones
+ want := []uint32{
+ 0*blobSize + txAvgSize, // 0 blob + some expected tx infos
+ 1*blobSize + txAvgSize, // 1 blob + some expected tx infos
+ 2*blobSize + txAvgSize, // 2 blob + some expected tx infos (could be fewer blobs and more tx data)
+ 3*blobSize + txAvgSize, // 3 blob + some expected tx infos (could be fewer blobs and more tx data)
+ 4*blobSize + txAvgSize, // 4 blob + some expected tx infos (could be fewer blobs and more tx data)
+ 5*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size
+ 6*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size
+ 7*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size
+ 8*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size
+ 9*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size
+ 10*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size
+ 11*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size
+ 12*blobSize + txAvgSize, // 1-4 blobs + unexpectedly large tx infos >= 4 blobs + max tx metadata size
+ }
+ if len(shelves) != len(want) {
+ t.Errorf("shelves count mismatch: have %d, want %d", len(shelves), len(want))
+ }
+ for i := 0; i < len(shelves) && i < len(want); i++ {
+ if shelves[i] != want[i] {
+ t.Errorf("shelf %d mismatch: have %d, want %d", i, shelves[i], want[i])
+ }
+ }
+}
diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go
index 3525747c72de..ab7ac1cceacf 100644
--- a/core/txpool/legacypool/legacypool.go
+++ b/core/txpool/legacypool/legacypool.go
@@ -508,11 +508,11 @@ func (pool *LegacyPool) ContentFrom(addr common.Address) ([]*types.Transaction,
// The enforceTips parameter can be used to do an extra filtering on the pending
// transactions and only return those whose **effective** tip is large enough in
// the next pending execution environment.
-func (pool *LegacyPool) Pending(enforceTips bool) map[common.Address][]*types.Transaction {
+func (pool *LegacyPool) Pending(enforceTips bool) map[common.Address][]*txpool.LazyTransaction {
pool.mu.Lock()
defer pool.mu.Unlock()
- pending := make(map[common.Address][]*types.Transaction, len(pool.pending))
+ pending := make(map[common.Address][]*txpool.LazyTransaction, len(pool.pending))
for addr, list := range pool.pending {
txs := list.Flatten()
@@ -526,7 +526,18 @@ func (pool *LegacyPool) Pending(enforceTips bool) map[common.Address][]*types.Tr
}
}
if len(txs) > 0 {
- pending[addr] = txs
+ lazies := make([]*txpool.LazyTransaction, len(txs))
+ for i := 0; i < len(txs); i++ {
+ lazies[i] = &txpool.LazyTransaction{
+ Pool: pool,
+ Hash: txs[i].Hash(),
+ Tx: &txpool.Transaction{Tx: txs[i]},
+ Time: txs[i].Time(),
+ GasFeeCap: txs[i].GasFeeCap(),
+ GasTipCap: txs[i].GasTipCap(),
+ }
+ }
+ pending[addr] = lazies
}
}
return pending
@@ -1305,7 +1316,13 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) {
return
}
}
- reinject = types.TxDifference(discarded, included)
+ lost := make([]*types.Transaction, 0, len(discarded))
+ for _, tx := range types.TxDifference(discarded, included) {
+ if pool.Filter(tx) {
+ lost = append(lost, tx)
+ }
+ }
+ reinject = lost
}
}
}
diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go
index 835f0de97a3b..576e9e89ceeb 100644
--- a/core/txpool/subpool.go
+++ b/core/txpool/subpool.go
@@ -18,6 +18,7 @@ package txpool
import (
"math/big"
+ "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
@@ -36,6 +37,28 @@ type Transaction struct {
BlobTxProofs []kzg4844.Proof // Proofs needed by the blob pool
}
+// LazyTransaction contains a small subset of the transaction properties that is
+// enough for the miner and other APIs to handle large batches of transactions;
+// and supports pulling up the entire transaction when really needed.
+type LazyTransaction struct {
+ Pool SubPool // Transaction subpool to pull the real transaction up
+ Hash common.Hash // Transaction hash to pull up if needed
+ Tx *Transaction // Transaction if already resolved
+
+ Time time.Time // Time when the transaction was first seen
+ GasFeeCap *big.Int // Maximum fee per gas the transaction may consume
+ GasTipCap *big.Int // Maximum miner tip per gas the transaction can pay
+}
+
+// Resolve retrieves the full transaction belonging to a lazy handle if it is still
+// maintained by the transaction pool.
+func (ltx *LazyTransaction) Resolve() *Transaction {
+ if ltx.Tx == nil {
+ ltx.Tx = ltx.Pool.Get(ltx.Hash)
+ }
+ return ltx.Tx
+}
+
// SubPool represents a specialized transaction pool that lives on its own (e.g.
// blob pool). Since independent of how many specialized pools we have, they do
// need to be updated in lockstep and assemble into one coherent view for block
@@ -81,7 +104,7 @@ type SubPool interface {
// Pending retrieves all currently processable transactions, grouped by origin
// account and sorted by nonce.
- Pending(enforceTips bool) map[common.Address][]*types.Transaction
+ Pending(enforceTips bool) map[common.Address][]*LazyTransaction
// SubscribeTransactions subscribes to new transaction events.
SubscribeTransactions(ch chan<- core.NewTxsEvent) event.Subscription
diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go
index f2c94563bc4f..d3834b471802 100644
--- a/core/txpool/txpool.go
+++ b/core/txpool/txpool.go
@@ -17,7 +17,6 @@
package txpool
import (
- "errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
@@ -94,7 +93,7 @@ func (p *TxPool) Close() error {
for _, subpool := range p.subpools {
errs = append(errs, subpool.Close())
}
- return errors.Join(errs...)
+ return errs[0] // TODO fix properly
}
// loop is the transaction pool's main event loop, waiting for and reacting to
@@ -235,8 +234,8 @@ func (p *TxPool) Add(txs []*Transaction, local bool, sync bool) []error {
// Pending retrieves all currently processable transactions, grouped by origin
// account and sorted by nonce.
-func (p *TxPool) Pending(enforceTips bool) map[common.Address][]*types.Transaction {
- txs := make(map[common.Address][]*types.Transaction)
+func (p *TxPool) Pending(enforceTips bool) map[common.Address][]*LazyTransaction {
+ txs := make(map[common.Address][]*LazyTransaction)
for _, subpool := range p.subpools {
for addr, set := range subpool.Pending(enforceTips) {
txs[addr] = set
diff --git a/core/types/block.go b/core/types/block.go
index e1f1feb7a2ec..e444bfd24850 100644
--- a/core/types/block.go
+++ b/core/types/block.go
@@ -85,11 +85,11 @@ type Header struct {
// WithdrawalsHash was added by EIP-4895 and is ignored in legacy headers.
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
- // ExcessDataGas was added by EIP-4844 and is ignored in legacy headers.
- ExcessDataGas *uint64 `json:"excessDataGas" rlp:"optional"`
-
// DataGasUsed was added by EIP-4844 and is ignored in legacy headers.
DataGasUsed *uint64 `json:"dataGasUsed" rlp:"optional"`
+
+ // ExcessDataGas was added by EIP-4844 and is ignored in legacy headers.
+ ExcessDataGas *uint64 `json:"excessDataGas" rlp:"optional"`
}
// field type overrides for gencodec
@@ -102,8 +102,8 @@ type headerMarshaling struct {
Extra hexutil.Bytes
BaseFee *hexutil.Big
Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON
- ExcessDataGas *hexutil.Uint64
DataGasUsed *hexutil.Uint64
+ ExcessDataGas *hexutil.Uint64
}
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
@@ -284,6 +284,14 @@ func CopyHeader(h *Header) *Header {
cpy.WithdrawalsHash = new(common.Hash)
*cpy.WithdrawalsHash = *h.WithdrawalsHash
}
+ if h.ExcessDataGas != nil {
+ excessDataGas := *h.ExcessDataGas
+ cpy.ExcessDataGas = &excessDataGas
+ }
+ if h.DataGasUsed != nil {
+ dataGasUsed := *h.DataGasUsed
+ cpy.DataGasUsed = &dataGasUsed
+ }
return &cpy
}
diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go
index fe246d54ecd8..57f580acf9de 100644
--- a/core/types/gen_header_json.go
+++ b/core/types/gen_header_json.go
@@ -33,8 +33,8 @@ func (h Header) MarshalJSON() ([]byte, error) {
Nonce BlockNonce `json:"nonce"`
BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
- ExcessDataGas *hexutil.Uint64 `json:"excessDataGas" rlp:"optional"`
DataGasUsed *hexutil.Uint64 `json:"dataGasUsed" rlp:"optional"`
+ ExcessDataGas *hexutil.Uint64 `json:"excessDataGas" rlp:"optional"`
Hash common.Hash `json:"hash"`
}
var enc Header
@@ -55,8 +55,8 @@ func (h Header) MarshalJSON() ([]byte, error) {
enc.Nonce = h.Nonce
enc.BaseFee = (*hexutil.Big)(h.BaseFee)
enc.WithdrawalsHash = h.WithdrawalsHash
- enc.ExcessDataGas = (*hexutil.Uint64)(h.ExcessDataGas)
enc.DataGasUsed = (*hexutil.Uint64)(h.DataGasUsed)
+ enc.ExcessDataGas = (*hexutil.Uint64)(h.ExcessDataGas)
enc.Hash = h.Hash()
return json.Marshal(&enc)
}
@@ -81,8 +81,8 @@ func (h *Header) UnmarshalJSON(input []byte) error {
Nonce *BlockNonce `json:"nonce"`
BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"`
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
- ExcessDataGas *hexutil.Uint64 `json:"excessDataGas" rlp:"optional"`
DataGasUsed *hexutil.Uint64 `json:"dataGasUsed" rlp:"optional"`
+ ExcessDataGas *hexutil.Uint64 `json:"excessDataGas" rlp:"optional"`
}
var dec Header
if err := json.Unmarshal(input, &dec); err != nil {
@@ -151,11 +151,11 @@ func (h *Header) UnmarshalJSON(input []byte) error {
if dec.WithdrawalsHash != nil {
h.WithdrawalsHash = dec.WithdrawalsHash
}
- if dec.ExcessDataGas != nil {
- h.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
- }
if dec.DataGasUsed != nil {
h.DataGasUsed = (*uint64)(dec.DataGasUsed)
}
+ if dec.ExcessDataGas != nil {
+ h.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
+ }
return nil
}
diff --git a/core/types/gen_header_rlp.go b/core/types/gen_header_rlp.go
index f488931f1fb0..be63b0270839 100644
--- a/core/types/gen_header_rlp.go
+++ b/core/types/gen_header_rlp.go
@@ -42,8 +42,8 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
w.WriteBytes(obj.Nonce[:])
_tmp1 := obj.BaseFee != nil
_tmp2 := obj.WithdrawalsHash != nil
- _tmp3 := obj.ExcessDataGas != nil
- _tmp4 := obj.DataGasUsed != nil
+ _tmp3 := obj.DataGasUsed != nil
+ _tmp4 := obj.ExcessDataGas != nil
if _tmp1 || _tmp2 || _tmp3 || _tmp4 {
if obj.BaseFee == nil {
w.Write(rlp.EmptyString)
@@ -62,17 +62,17 @@ func (obj *Header) EncodeRLP(_w io.Writer) error {
}
}
if _tmp3 || _tmp4 {
- if obj.ExcessDataGas == nil {
+ if obj.DataGasUsed == nil {
w.Write([]byte{0x80})
} else {
- w.WriteUint64((*obj.ExcessDataGas))
+ w.WriteUint64((*obj.DataGasUsed))
}
}
if _tmp4 {
- if obj.DataGasUsed == nil {
+ if obj.ExcessDataGas == nil {
w.Write([]byte{0x80})
} else {
- w.WriteUint64((*obj.DataGasUsed))
+ w.WriteUint64((*obj.ExcessDataGas))
}
}
w.ListEnd(_tmp0)
diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go
index d83be1447744..1ad79c485373 100644
--- a/core/types/gen_receipt_json.go
+++ b/core/types/gen_receipt_json.go
@@ -16,19 +16,21 @@ var _ = (*receiptMarshaling)(nil)
// MarshalJSON marshals as JSON.
func (r Receipt) MarshalJSON() ([]byte, error) {
type Receipt struct {
- Type hexutil.Uint64 `json:"type,omitempty"`
- PostState hexutil.Bytes `json:"root"`
- Status hexutil.Uint64 `json:"status"`
- CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"`
- Bloom Bloom `json:"logsBloom" gencodec:"required"`
- Logs []*Log `json:"logs" gencodec:"required"`
- TxHash common.Hash `json:"transactionHash" gencodec:"required"`
- ContractAddress common.Address `json:"contractAddress"`
- GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
- EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"`
- BlockHash common.Hash `json:"blockHash,omitempty"`
- BlockNumber *hexutil.Big `json:"blockNumber,omitempty"`
- TransactionIndex hexutil.Uint `json:"transactionIndex"`
+ Type hexutil.Uint64 `json:"type,omitempty"`
+ PostState hexutil.Bytes `json:"root"`
+ Status hexutil.Uint64 `json:"status"`
+ CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"`
+ Bloom Bloom `json:"logsBloom" gencodec:"required"`
+ Logs []*Log `json:"logs" gencodec:"required"`
+ TxHash common.Hash `json:"transactionHash" gencodec:"required"`
+ ContractAddress common.Address `json:"contractAddress"`
+ GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
+ DataGasUsed *hexutil.Uint64 `json:"dataGasUsed"`
+ EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"`
+ DataGasPrice *hexutil.Uint64 `json:"dataGasPrice"`
+ BlockHash common.Hash `json:"blockHash,omitempty"`
+ BlockNumber *hexutil.Big `json:"blockNumber,omitempty"`
+ TransactionIndex hexutil.Uint `json:"transactionIndex"`
}
var enc Receipt
enc.Type = hexutil.Uint64(r.Type)
@@ -40,7 +42,9 @@ func (r Receipt) MarshalJSON() ([]byte, error) {
enc.TxHash = r.TxHash
enc.ContractAddress = r.ContractAddress
enc.GasUsed = hexutil.Uint64(r.GasUsed)
+ enc.DataGasUsed = (*hexutil.Uint64)(r.DataGasUsed)
enc.EffectiveGasPrice = (*hexutil.Big)(r.EffectiveGasPrice)
+ enc.DataGasPrice = (*hexutil.Uint64)(r.DataGasPrice)
enc.BlockHash = r.BlockHash
enc.BlockNumber = (*hexutil.Big)(r.BlockNumber)
enc.TransactionIndex = hexutil.Uint(r.TransactionIndex)
@@ -59,7 +63,9 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
TxHash *common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress *common.Address `json:"contractAddress"`
GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"`
+ DataGasUsed *hexutil.Uint64 `json:"dataGasUsed"`
EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"`
+ DataGasPrice *hexutil.Uint64 `json:"dataGasPrice"`
BlockHash *common.Hash `json:"blockHash,omitempty"`
BlockNumber *hexutil.Big `json:"blockNumber,omitempty"`
TransactionIndex *hexutil.Uint `json:"transactionIndex"`
@@ -100,9 +106,15 @@ func (r *Receipt) UnmarshalJSON(input []byte) error {
return errors.New("missing required field 'gasUsed' for Receipt")
}
r.GasUsed = uint64(*dec.GasUsed)
+ if dec.DataGasUsed != nil {
+ r.DataGasUsed = (*uint64)(dec.DataGasUsed)
+ }
if dec.EffectiveGasPrice != nil {
r.EffectiveGasPrice = (*big.Int)(dec.EffectiveGasPrice)
}
+ if dec.DataGasPrice != nil {
+ r.DataGasPrice = (*uint64)(dec.DataGasPrice)
+ }
if dec.BlockHash != nil {
r.BlockHash = *dec.BlockHash
}
diff --git a/core/types/receipt.go b/core/types/receipt.go
index 6b4b8972450f..3be97bc56e2a 100644
--- a/core/types/receipt.go
+++ b/core/types/receipt.go
@@ -62,7 +62,9 @@ type Receipt struct {
TxHash common.Hash `json:"transactionHash" gencodec:"required"`
ContractAddress common.Address `json:"contractAddress"`
GasUsed uint64 `json:"gasUsed" gencodec:"required"`
+ DataGasUsed *uint64 `json:"dataGasUsed"`
EffectiveGasPrice *big.Int `json:"effectiveGasPrice"` // required, but tag omitted for backwards compatibility
+ DataGasPrice *uint64 `json:"dataGasPrice"`
// Inclusion information: These fields provide information about the inclusion of the
// transaction corresponding to this receipt.
@@ -77,7 +79,9 @@ type receiptMarshaling struct {
Status hexutil.Uint64
CumulativeGasUsed hexutil.Uint64
GasUsed hexutil.Uint64
+ DataGasUsed *hexutil.Uint64
EffectiveGasPrice *hexutil.Big
+ DataGasPrice *hexutil.Uint64
BlockNumber *hexutil.Big
TransactionIndex hexutil.Uint
}
@@ -341,6 +345,9 @@ func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, nu
rs[i].ContractAddress = common.Address{}
}
+ dataGasUsed := uint64(len(txs[i].BlobHashes()) * params.BlobTxDataGasPerBlob)
+ rs[i].DataGasUsed = &dataGasUsed
+
// The used gas can be calculated based on previous r
if i == 0 {
rs[i].GasUsed = rs[i].CumulativeGasUsed
diff --git a/core/types/transaction.go b/core/types/transaction.go
index 579fc00d1043..91a20d32a793 100644
--- a/core/types/transaction.go
+++ b/core/types/transaction.go
@@ -18,7 +18,6 @@ package types
import (
"bytes"
- "container/heap"
"errors"
"io"
"math/big"
@@ -394,6 +393,19 @@ func (tx *Transaction) BlobGasFeeCapIntCmp(other *big.Int) int {
return tx.inner.blobGasFeeCap().Cmp(other)
}
+// SetTime sets the decoding time of a transaction. This is used by tests to set
+// arbitrary times and by persistent transaction pools when loading old txs from
+// disk.
+func (tx *Transaction) SetTime(t time.Time) {
+ tx.time = t
+}
+
+// Time returns the time when the transaction was first seen on the network. It
+// is a heuristic to prefer mining older txs vs new all other things equal.
+func (tx *Transaction) Time() time.Time {
+ return tx.time
+}
+
// Hash returns the transaction hash.
func (tx *Transaction) Hash() common.Hash {
if hash := tx.hash.Load(); hash != nil {
@@ -502,123 +514,6 @@ func (s TxByNonce) Len() int { return len(s) }
func (s TxByNonce) Less(i, j int) bool { return s[i].Nonce() < s[j].Nonce() }
func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-// TxWithMinerFee wraps a transaction with its gas price or effective miner gasTipCap
-type TxWithMinerFee struct {
- tx *Transaction
- minerFee *big.Int
-}
-
-// NewTxWithMinerFee creates a wrapped transaction, calculating the effective
-// miner gasTipCap if a base fee is provided.
-// Returns error in case of a negative effective miner gasTipCap.
-func NewTxWithMinerFee(tx *Transaction, baseFee *big.Int) (*TxWithMinerFee, error) {
- minerFee, err := tx.EffectiveGasTip(baseFee)
- if err != nil {
- return nil, err
- }
- return &TxWithMinerFee{
- tx: tx,
- minerFee: minerFee,
- }, nil
-}
-
-// TxByPriceAndTime implements both the sort and the heap interface, making it useful
-// for all at once sorting as well as individually adding and removing elements.
-type TxByPriceAndTime []*TxWithMinerFee
-
-func (s TxByPriceAndTime) Len() int { return len(s) }
-func (s TxByPriceAndTime) Less(i, j int) bool {
- // If the prices are equal, use the time the transaction was first seen for
- // deterministic sorting
- cmp := s[i].minerFee.Cmp(s[j].minerFee)
- if cmp == 0 {
- return s[i].tx.time.Before(s[j].tx.time)
- }
- return cmp > 0
-}
-func (s TxByPriceAndTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-func (s *TxByPriceAndTime) Push(x interface{}) {
- *s = append(*s, x.(*TxWithMinerFee))
-}
-
-func (s *TxByPriceAndTime) Pop() interface{} {
- old := *s
- n := len(old)
- x := old[n-1]
- old[n-1] = nil
- *s = old[0 : n-1]
- return x
-}
-
-// TransactionsByPriceAndNonce represents a set of transactions that can return
-// transactions in a profit-maximizing sorted order, while supporting removing
-// entire batches of transactions for non-executable accounts.
-type TransactionsByPriceAndNonce struct {
- txs map[common.Address][]*Transaction // Per account nonce-sorted list of transactions
- heads TxByPriceAndTime // Next transaction for each unique account (price heap)
- signer Signer // Signer for the set of transactions
- baseFee *big.Int // Current base fee
-}
-
-// NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
-// price sorted transactions in a nonce-honouring way.
-//
-// Note, the input map is reowned so the caller should not interact any more with
-// if after providing it to the constructor.
-func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address][]*Transaction, baseFee *big.Int) *TransactionsByPriceAndNonce {
- // Initialize a price and received time based heap with the head transactions
- heads := make(TxByPriceAndTime, 0, len(txs))
- for from, accTxs := range txs {
- acc, _ := Sender(signer, accTxs[0])
- wrapped, err := NewTxWithMinerFee(accTxs[0], baseFee)
- // Remove transaction if sender doesn't match from, or if wrapping fails.
- if acc != from || err != nil {
- delete(txs, from)
- continue
- }
- heads = append(heads, wrapped)
- txs[from] = accTxs[1:]
- }
- heap.Init(&heads)
-
- // Assemble and return the transaction set
- return &TransactionsByPriceAndNonce{
- txs: txs,
- heads: heads,
- signer: signer,
- baseFee: baseFee,
- }
-}
-
-// Peek returns the next transaction by price.
-func (t *TransactionsByPriceAndNonce) Peek() *Transaction {
- if len(t.heads) == 0 {
- return nil
- }
- return t.heads[0].tx
-}
-
-// Shift replaces the current best head with the next one from the same account.
-func (t *TransactionsByPriceAndNonce) Shift() {
- acc, _ := Sender(t.signer, t.heads[0].tx)
- if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
- if wrapped, err := NewTxWithMinerFee(txs[0], t.baseFee); err == nil {
- t.heads[0], t.txs[acc] = wrapped, txs[1:]
- heap.Fix(&t.heads, 0)
- return
- }
- }
- heap.Pop(&t.heads)
-}
-
-// Pop removes the best transaction, *not* replacing it with the next one from
-// the same account. This should be used when a transaction cannot be executed
-// and hence all subsequent ones should be discarded from the same account.
-func (t *TransactionsByPriceAndNonce) Pop() {
- heap.Pop(&t.heads)
-}
-
// copyAddressPtr copies an address.
func copyAddressPtr(a *common.Address) *common.Address {
if a == nil {
diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go
index dbe77fa6036a..a984a9c70952 100644
--- a/core/types/transaction_test.go
+++ b/core/types/transaction_test.go
@@ -23,10 +23,8 @@ import (
"errors"
"fmt"
"math/big"
- "math/rand"
"reflect"
"testing"
- "time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
@@ -259,152 +257,6 @@ func TestRecipientNormal(t *testing.T) {
}
}
-func TestTransactionPriceNonceSortLegacy(t *testing.T) {
- testTransactionPriceNonceSort(t, nil)
-}
-
-func TestTransactionPriceNonceSort1559(t *testing.T) {
- testTransactionPriceNonceSort(t, big.NewInt(0))
- testTransactionPriceNonceSort(t, big.NewInt(5))
- testTransactionPriceNonceSort(t, big.NewInt(50))
-}
-
-// Tests that transactions can be correctly sorted according to their price in
-// decreasing order, but at the same time with increasing nonces when issued by
-// the same account.
-func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
- // Generate a batch of accounts to start with
- keys := make([]*ecdsa.PrivateKey, 25)
- for i := 0; i < len(keys); i++ {
- keys[i], _ = crypto.GenerateKey()
- }
- signer := LatestSignerForChainID(common.Big1)
-
- // Generate a batch of transactions with overlapping values, but shifted nonces
- groups := map[common.Address][]*Transaction{}
- expectedCount := 0
- for start, key := range keys {
- addr := crypto.PubkeyToAddress(key.PublicKey)
- count := 25
- for i := 0; i < 25; i++ {
- var tx *Transaction
- gasFeeCap := rand.Intn(50)
- if baseFee == nil {
- tx = NewTx(&LegacyTx{
- Nonce: uint64(start + i),
- To: &common.Address{},
- Value: big.NewInt(100),
- Gas: 100,
- GasPrice: big.NewInt(int64(gasFeeCap)),
- Data: nil,
- })
- } else {
- tx = NewTx(&DynamicFeeTx{
- Nonce: uint64(start + i),
- To: &common.Address{},
- Value: big.NewInt(100),
- Gas: 100,
- GasFeeCap: big.NewInt(int64(gasFeeCap)),
- GasTipCap: big.NewInt(int64(rand.Intn(gasFeeCap + 1))),
- Data: nil,
- })
- if count == 25 && int64(gasFeeCap) < baseFee.Int64() {
- count = i
- }
- }
- tx, err := SignTx(tx, signer, key)
- if err != nil {
- t.Fatalf("failed to sign tx: %s", err)
- }
- groups[addr] = append(groups[addr], tx)
- }
- expectedCount += count
- }
- // Sort the transactions and cross check the nonce ordering
- txset := NewTransactionsByPriceAndNonce(signer, groups, baseFee)
-
- txs := Transactions{}
- for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
- txs = append(txs, tx)
- txset.Shift()
- }
- if len(txs) != expectedCount {
- t.Errorf("expected %d transactions, found %d", expectedCount, len(txs))
- }
- for i, txi := range txs {
- fromi, _ := Sender(signer, txi)
-
- // Make sure the nonce order is valid
- for j, txj := range txs[i+1:] {
- fromj, _ := Sender(signer, txj)
- if fromi == fromj && txi.Nonce() > txj.Nonce() {
- t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce())
- }
- }
- // If the next tx has different from account, the price must be lower than the current one
- if i+1 < len(txs) {
- next := txs[i+1]
- fromNext, _ := Sender(signer, next)
- tip, err := txi.EffectiveGasTip(baseFee)
- nextTip, nextErr := next.EffectiveGasTip(baseFee)
- if err != nil || nextErr != nil {
- t.Errorf("error calculating effective tip")
- }
- if fromi != fromNext && tip.Cmp(nextTip) < 0 {
- t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice())
- }
- }
- }
-}
-
-// Tests that if multiple transactions have the same price, the ones seen earlier
-// are prioritized to avoid network spam attacks aiming for a specific ordering.
-func TestTransactionTimeSort(t *testing.T) {
- // Generate a batch of accounts to start with
- keys := make([]*ecdsa.PrivateKey, 5)
- for i := 0; i < len(keys); i++ {
- keys[i], _ = crypto.GenerateKey()
- }
- signer := HomesteadSigner{}
-
- // Generate a batch of transactions with overlapping prices, but different creation times
- groups := map[common.Address][]*Transaction{}
- for start, key := range keys {
- addr := crypto.PubkeyToAddress(key.PublicKey)
-
- tx, _ := SignTx(NewTransaction(0, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key)
- tx.time = time.Unix(0, int64(len(keys)-start))
-
- groups[addr] = append(groups[addr], tx)
- }
- // Sort the transactions and cross check the nonce ordering
- txset := NewTransactionsByPriceAndNonce(signer, groups, nil)
-
- txs := Transactions{}
- for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
- txs = append(txs, tx)
- txset.Shift()
- }
- if len(txs) != len(keys) {
- t.Errorf("expected %d transactions, found %d", len(keys), len(txs))
- }
- for i, txi := range txs {
- fromi, _ := Sender(signer, txi)
- if i+1 < len(txs) {
- next := txs[i+1]
- fromNext, _ := Sender(signer, next)
-
- if txi.GasPrice().Cmp(next.GasPrice()) < 0 {
- t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice())
- }
- // Make sure time order is ascending if the txs have the same gas price
- if txi.GasPrice().Cmp(next.GasPrice()) == 0 && txi.time.After(next.time) {
- t.Errorf("invalid received time ordering: tx #%d (A=%x T=%v) > tx #%d (A=%x T=%v)", i, fromi[:4], txi.time, i+1, fromNext[:4], next.time)
- }
- }
- }
-}
-
// TestTransactionCoding tests serializing/de-serializing to/from rlp and JSON.
func TestTransactionCoding(t *testing.T) {
key, err := crypto.GenerateKey()
diff --git a/core/types/tx_blob_with_blob.go b/core/types/tx_blob_with_blob.go
new file mode 100644
index 000000000000..0af91ff4017a
--- /dev/null
+++ b/core/types/tx_blob_with_blob.go
@@ -0,0 +1,19 @@
+package types
+
+import "github.com/ethereum/go-ethereum/crypto/kzg4844"
+
+type BlobTxWithBlobs struct {
+ BlobTx *BlobTx
+ Blobs []kzg4844.Blob
+ Commitments []kzg4844.Commitment
+ Proofs []kzg4844.Proof
+}
+
+func NewBlobTxWithBlobs(tx *Transaction, blobs []kzg4844.Blob, commitments []kzg4844.Commitment, proofs []kzg4844.Proof) *BlobTxWithBlobs {
+ return &BlobTxWithBlobs{
+ BlobTx: tx.inner.(*BlobTx),
+ Blobs: blobs,
+ Commitments: commitments,
+ Proofs: proofs,
+ }
+}
diff --git a/core/types/types_test.go b/core/types/types_test.go
index 1fb386d5deef..1e557be5a6eb 100644
--- a/core/types/types_test.go
+++ b/core/types/types_test.go
@@ -17,12 +17,14 @@
package types
import (
+ "bytes"
"math/big"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
+ "github.com/holiman/uint256"
)
type devnull struct{ len int }
@@ -43,7 +45,7 @@ func BenchmarkDecodeRLP(b *testing.B) {
func benchRLP(b *testing.B, encode bool) {
key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
to := common.HexToAddress("0x00000000000000000000000000000000deadbeef")
- signer := NewLondonSigner(big.NewInt(1337))
+ signer := NewCancunSigner(big.NewInt(1337))
for _, tc := range []struct {
name string
obj interface{}
@@ -121,6 +123,19 @@ func benchRLP(b *testing.B, encode bool) {
GasFeeCap: big.NewInt(500),
}),
},
+ {
+ "blob-transaction",
+ MustSignNewTx(key, signer,
+ &BlobTx{
+ Nonce: 1,
+ Gas: 1000000,
+ To: to,
+ Value: uint256.NewInt(1),
+ GasTipCap: uint256.NewInt(500),
+ GasFeeCap: uint256.NewInt(500),
+ ChainID: uint256.NewInt(1337),
+ }),
+ },
} {
if encode {
b.Run(tc.name, func(b *testing.B) {
@@ -146,3 +161,43 @@ func benchRLP(b *testing.B, encode bool) {
}
}
}
+
+func TestEncodeDecodeBlobTx(t *testing.T) {
+ key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
+ to := common.HexToAddress("0x00000000000000000000000000000000deadbeef")
+ signer := NewCancunSigner(big.NewInt(1337))
+ tx := MustSignNewTx(key, signer,
+ &BlobTx{
+ Nonce: 1,
+ Gas: 1000000,
+ To: to,
+ Value: uint256.NewInt(1),
+ GasTipCap: uint256.NewInt(500),
+ GasFeeCap: uint256.NewInt(500),
+ ChainID: uint256.NewInt(1337),
+ })
+ data, err := rlp.EncodeToBytes(tx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := rlp.DecodeBytes(data, tx); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestDecodeBlobTx(t *testing.T) {
+ //0x03
+ encoded := "0xfa0200fdf88f0780843b9aca008506fc23ac00830186a09400000000000000000000000000000000000001008080c001e1a0010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c44401401a0840650aa8f74d2b07f40067dc33b715078d73422f01da17abdbd11e02bbdfda9a04b2260f6022bf53eadb337b3e59514936f7317d872defb891a708ee279bdca90fa020004ba0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f1b0c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f1b0c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+
+ var tx BlobTxWithBlobs
+ if err := rlp.DecodeBytes(common.FromHex(encoded), &tx); err != nil {
+ t.Fatal(err)
+ }
+ res, err := rlp.EncodeToBytes(tx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !bytes.Equal(res, common.FromHex(encoded)) {
+ panic("encoded not equal")
+ }
+}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 36336d8cbd4c..0d6ef5c10b43 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -77,6 +77,8 @@ type BlockContext struct {
Difficulty *big.Int // Provides information for DIFFICULTY
BaseFee *big.Int // Provides information for BASEFEE
Random *common.Hash // Provides information for PREVRANDAO
+
+ ExcessDataGas *uint64 // ExcessDataGas field in the header, needed to compute the data
}
// TxContext provides the EVM with information about a transaction.
diff --git a/core/vm/testdata/precompiles/pointEvaluation.json b/core/vm/testdata/precompiles/pointEvaluation.json
index 2fee5baf2424..dd06f7343052 100644
--- a/core/vm/testdata/precompiles/pointEvaluation.json
+++ b/core/vm/testdata/precompiles/pointEvaluation.json
@@ -1,6 +1,6 @@
[
{
- "Input": "013c03613f6fc558fb7e61e75602241ed9a2f04e36d8670aadd286e71b5ca9cc420000000000000000000000000000000000000000000000000000000000000031e5a2356cbc2ef6a733eae8d54bf48719ae3d990017ca787c419c7d369f8e3c83fac17c3f237fc51f90e2c660eb202a438bc2025baded5cd193c1a018c5885bc9281ba704d5566082e851235c7be763b2a99adff965e0a121ee972ebc472d02944a74f5c6243e14052e105124b70bf65faf85ad3a494325e269fad097842cba",
+ "Input": "01d18459b334ffe8e2226eef1db874fda6db2bdd9357268b39220af2d59464fb564c0a11a0f704f4fc3e8acfe0f8245f0ad1347b378fbf96e206da11a5d3630624d25032e67a7e6a4910df5834b8fe70e6bcfeeac0352434196bdf4b2485d5a1978a0d595c823c05947b1156175e72634a377808384256e9921ebf72181890be2d6b58d4a73a880541d1656875654806942307f266e636553e94006d11423f2688945ff3bdf515859eba1005c1a7708d620a94d91a1c0c285f9584e75ec2f82a",
"Expected": "000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",
"Name": "pointEvaluation1",
"Gas": 50000,
diff --git a/eth/api_backend.go b/eth/api_backend.go
index 02d1946e8e42..0a21856a0ad9 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethdb"
@@ -297,11 +298,19 @@ func (b *EthAPIBackend) SendTx(ctx context.Context, signedTx *types.Transaction)
return b.eth.txPool.Add([]*txpool.Transaction{&txpool.Transaction{Tx: signedTx}}, true, false)[0]
}
+func (b *EthAPIBackend) SendBlobTx(ctx context.Context, signedTx *types.Transaction, blobTxBlobs []kzg4844.Blob, blobTxCommits []kzg4844.Commitment, blobTxProofs []kzg4844.Proof) error {
+ return b.eth.txPool.Add([]*txpool.Transaction{&txpool.Transaction{Tx: signedTx, BlobTxBlobs: blobTxBlobs, BlobTxCommits: blobTxCommits, BlobTxProofs: blobTxProofs}}, true, false)[0]
+}
+
func (b *EthAPIBackend) GetPoolTransactions() (types.Transactions, error) {
pending := b.eth.txPool.Pending(false)
var txs types.Transactions
for _, batch := range pending {
- txs = append(txs, batch...)
+ for _, lazy := range batch {
+ if tx := lazy.Resolve(); tx != nil {
+ txs = append(txs, tx.Tx)
+ }
+ }
}
return txs, nil
}
diff --git a/eth/backend.go b/eth/backend.go
index 8d6977205e2c..dd295b9f2084 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -35,6 +35,7 @@ import (
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state/pruner"
"github.com/ethereum/go-ethereum/core/txpool"
+ "github.com/ethereum/go-ethereum/core/txpool/blobpool"
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
@@ -205,12 +206,17 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
}
eth.bloomIndexer.Start(eth.blockchain)
+ if config.BlobPool.Datadir != "" {
+ config.BlobPool.Datadir = stack.ResolvePath(config.BlobPool.Datadir)
+ }
+ blobPool := blobpool.New(config.BlobPool, eth.blockchain)
+
if config.TxPool.Journal != "" {
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
}
legacyPool := legacypool.New(config.TxPool, eth.blockchain)
- eth.txPool, err = txpool.New(new(big.Int).SetUint64(config.TxPool.PriceLimit), eth.blockchain, []txpool.SubPool{legacyPool})
+ eth.txPool, err = txpool.New(new(big.Int).SetUint64(config.TxPool.PriceLimit), eth.blockchain, []txpool.SubPool{legacyPool, blobPool})
if err != nil {
return nil, err
}
diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go
index 456bd7741327..05118883c922 100644
--- a/eth/catalyst/api.go
+++ b/eth/catalyst/api.go
@@ -81,8 +81,10 @@ var caps = []string{
"engine_exchangeTransitionConfigurationV1",
"engine_getPayloadV1",
"engine_getPayloadV2",
+ "engine_getPayloadV3",
"engine_newPayloadV1",
"engine_newPayloadV2",
+ "engine_newPayloadV3",
"engine_getPayloadBodiesByHashV1",
"engine_getPayloadBodiesByRangeV1",
}
@@ -405,6 +407,11 @@ func (api *ConsensusAPI) GetPayloadV2(payloadID engine.PayloadID) (*engine.Execu
return api.getPayload(payloadID)
}
+// GetPayloadV2 returns a cached payload by id.
+func (api *ConsensusAPI) GetPayloadV3(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
+ return api.getPayload(payloadID) // TODO (MariusVanDerWijden) return blobs once miner allows it
+}
+
func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) {
log.Trace("Engine API request received", "method", "GetPayload", "id", payloadID)
data := api.localBlocks.get(payloadID)
@@ -419,7 +426,7 @@ func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.Payl
if params.Withdrawals != nil {
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("withdrawals not supported in V1"))
}
- return api.newPayload(params)
+ return api.newPayload(params, nil)
}
// NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
@@ -431,10 +438,26 @@ func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.Payl
} else if params.Withdrawals != nil {
return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(errors.New("non-nil withdrawals pre-shanghai"))
}
- return api.newPayload(params)
+ return api.newPayload(params, nil)
+}
+
+// NewPayloadV3 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
+func (api *ConsensusAPI) NewPayloadV3(params engine.ExecutableData, versionedHashes *[]common.Hash) (engine.PayloadStatusV1, error) {
+ if api.eth.BlockChain().Config().IsCancun(new(big.Int).SetUint64(params.Number), params.Timestamp) {
+ if params.ExcessDataGas == nil {
+ return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("nil excessDataGas post-cancun"))
+ }
+ } else if params.ExcessDataGas != nil {
+ return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("non-nil excessDataGas pre-cancun"))
+ }
+ var hashes []common.Hash
+ if versionedHashes != nil {
+ hashes = *versionedHashes
+ }
+ return api.newPayload(params, hashes)
}
-func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
+func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashes []common.Hash) (engine.PayloadStatusV1, error) {
// The locking here is, strictly, not required. Without these locks, this can happen:
//
// 1. NewPayload( execdata-N ) is invoked from the CL. It goes all the way down to
@@ -452,9 +475,9 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData) (engine.Payloa
defer api.newPayloadLock.Unlock()
log.Trace("Engine API request received", "method", "NewPayload", "number", params.Number, "hash", params.BlockHash)
- block, err := engine.ExecutableDataToBlock(params)
+ block, err := engine.ExecutableDataToBlock(params, versionedHashes)
if err != nil {
- log.Debug("Invalid NewPayload params", "params", params, "error", err)
+ log.Warn("Invalid NewPayload params", "params", params, "error", err)
return engine.PayloadStatusV1{Status: engine.INVALID}, nil
}
// Stash away the last update to warn the user if the beacon client goes offline
diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go
index 254a510ab40f..05ad3def48ae 100644
--- a/eth/catalyst/api_test.go
+++ b/eth/catalyst/api_test.go
@@ -38,6 +38,7 @@ import (
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/ethconfig"
@@ -322,7 +323,7 @@ func TestEth2NewBlock(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create the executable data %v", err)
}
- block, err := engine.ExecutableDataToBlock(*execData)
+ block, err := engine.ExecutableDataToBlock(*execData, nil)
if err != nil {
t.Fatalf("Failed to convert executable data to block %v", err)
}
@@ -364,7 +365,7 @@ func TestEth2NewBlock(t *testing.T) {
if err != nil {
t.Fatalf("Failed to create the executable data %v", err)
}
- block, err := engine.ExecutableDataToBlock(*execData)
+ block, err := engine.ExecutableDataToBlock(*execData, nil)
if err != nil {
t.Fatalf("Failed to convert executable data to block %v", err)
}
@@ -996,7 +997,7 @@ func TestSimultaneousNewBlock(t *testing.T) {
t.Fatal(testErr)
}
}
- block, err := engine.ExecutableDataToBlock(*execData)
+ block, err := engine.ExecutableDataToBlock(*execData, nil)
if err != nil {
t.Fatalf("Failed to convert executable data to block %v", err)
}
@@ -1519,3 +1520,38 @@ func equalBody(a *types.Body, b *engine.ExecutionPayloadBodyV1) bool {
}
return reflect.DeepEqual(a.Withdrawals, b.Withdrawals)
}
+
+func TestBlockToPayloadWithBlobs(t *testing.T) {
+ header := types.Header{}
+ var txs []*types.Transaction
+
+ inner := types.BlobTx{
+ BlobHashes: make([]common.Hash, 1),
+ }
+
+ txs = append(txs, types.NewTx(&inner))
+
+ blobs := make([]kzg4844.Blob, 1)
+ commitments := make([]kzg4844.Commitment, 1)
+ proofs := make([]kzg4844.Proof, 1)
+
+ block := types.NewBlock(&header, txs, nil, nil, trie.NewStackTrie(nil))
+ envelope := engine.BlockToExecutableData(block, nil, blobs, commitments, proofs)
+ var want int
+ for _, tx := range txs {
+ want += len(tx.BlobHashes())
+ }
+ if got := len(envelope.BlobsBundle.Commitments); got != want {
+ t.Fatalf("invalid number of commitments: got %v, want %v", got, want)
+ }
+ if got := len(envelope.BlobsBundle.Proofs); got != want {
+ t.Fatalf("invalid number of proofs: got %v, want %v", got, want)
+ }
+ if got := len(envelope.BlobsBundle.Blobs); got != want {
+ t.Fatalf("invalid number of blobs: got %v, want %v", got, want)
+ }
+ _, err := engine.ExecutableDataToBlock(*envelope.ExecutionPayload, make([]common.Hash, 1))
+ if err != nil {
+ t.Error(err)
+ }
+}
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index 432ec8ffbb70..457c3cad3809 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -27,6 +27,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/txpool/blobpool"
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/gasprice"
@@ -72,6 +73,7 @@ var Defaults = Config{
FilterLogCacheSize: 32,
Miner: miner.DefaultConfig,
TxPool: legacypool.DefaultConfig,
+ BlobPool: blobpool.DefaultConfig,
RPCGasCap: 50000000,
RPCEVMTimeout: 5 * time.Second,
GPO: FullNodeGPO,
@@ -139,7 +141,8 @@ type Config struct {
Miner miner.Config
// Transaction pool options
- TxPool legacypool.Config
+ TxPool legacypool.Config
+ BlobPool blobpool.Config
// Gas Price Oracle options
GPO gasprice.Config
diff --git a/eth/handler.go b/eth/handler.go
index 46113fbc2ffc..a8d9d8cb89f8 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -67,7 +67,7 @@ type txPool interface {
// Pending should return pending transactions.
// The slice should be modifiable by the caller.
- Pending(enforceTips bool) map[common.Address][]*types.Transaction
+ Pending(enforceTips bool) map[common.Address][]*txpool.LazyTransaction
// SubscribeNewTxsEvent should return an event subscription of
// NewTxsEvent and send events to the given channel.
diff --git a/eth/handler_test.go b/eth/handler_test.go
index 2f776e874b3d..7451e17012a0 100644
--- a/eth/handler_test.go
+++ b/eth/handler_test.go
@@ -101,7 +101,7 @@ func (p *testTxPool) Add(txs []*txpool.Transaction, local bool, sync bool) []err
}
// Pending returns all the transactions known to the pool
-func (p *testTxPool) Pending(enforceTips bool) map[common.Address][]*types.Transaction {
+func (p *testTxPool) Pending(enforceTips bool) map[common.Address][]*txpool.LazyTransaction {
p.lock.RLock()
defer p.lock.RUnlock()
@@ -113,7 +113,19 @@ func (p *testTxPool) Pending(enforceTips bool) map[common.Address][]*types.Trans
for _, batch := range batches {
sort.Sort(types.TxByNonce(batch))
}
- return batches
+ pending := make(map[common.Address][]*txpool.LazyTransaction)
+ for addr, batch := range batches {
+ for _, tx := range batch {
+ pending[addr] = append(pending[addr], &txpool.LazyTransaction{
+ Hash: tx.Hash(),
+ Tx: &txpool.Transaction{Tx: tx},
+ Time: tx.Time(),
+ GasFeeCap: tx.GasFeeCap(),
+ GasTipCap: tx.GasTipCap(),
+ })
+ }
+ }
+ return pending
}
// SubscribeNewTxsEvent should return an event subscription of NewTxsEvent and
diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go
index f9fbf72b7b1c..b47a6cba4f62 100644
--- a/eth/protocols/eth/handlers.go
+++ b/eth/protocols/eth/handlers.go
@@ -497,8 +497,13 @@ func answerGetPooledTransactions(backend Backend, query GetPooledTransactionsPac
if tx == nil {
continue
}
+ var toEncode interface{}
+ toEncode = tx.Tx
+ if tx.Tx.Type() == types.BlobTxType {
+ toEncode = types.NewBlobTxWithBlobs(tx.Tx, tx.BlobTxBlobs, tx.BlobTxCommits, tx.BlobTxProofs)
+ }
// If known, encode and queue for response packet
- if encoded, err := rlp.EncodeToBytes(tx.Tx); err != nil {
+ if encoded, err := rlp.EncodeToBytes(toEncode); err != nil {
log.Error("Failed to encode transaction", "err", err)
} else {
hashes = append(hashes, hash)
diff --git a/eth/sync.go b/eth/sync.go
index ace1071143b5..087041fdb8d0 100644
--- a/eth/sync.go
+++ b/eth/sync.go
@@ -23,7 +23,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/downloader"
"github.com/ethereum/go-ethereum/eth/protocols/eth"
"github.com/ethereum/go-ethereum/log"
@@ -36,27 +35,15 @@ const (
// syncTransactions starts sending all currently pending transactions to the given peer.
func (h *handler) syncTransactions(p *eth.Peer) {
- // Assemble the set of transaction to broadcast or announce to the remote
- // peer. Fun fact, this is quite an expensive operation as it needs to sort
- // the transactions if the sorting is not cached yet. However, with a random
- // order, insertions could overflow the non-executable queues and get dropped.
- //
- // TODO(karalabe): Figure out if we could get away with random order somehow
- var txs types.Transactions
- pending := h.txpool.Pending(false)
- for _, batch := range pending {
- txs = append(txs, batch...)
+ var hashes []common.Hash
+ for _, batch := range h.txpool.Pending(false) {
+ for _, tx := range batch {
+ hashes = append(hashes, tx.Hash)
+ }
}
- if len(txs) == 0 {
+ if len(hashes) == 0 {
return
}
- // The eth/65 protocol introduces proper transaction announcements, so instead
- // of dripping transactions across multiple peers, just send the entire list as
- // an announcement and let the remote side decide what they need (likely nothing).
- hashes := make([]common.Hash, len(txs))
- for i, tx := range txs {
- hashes[i] = tx.Hash()
- }
p.AsyncSendPooledTransactionHashes(hashes)
}
diff --git a/go.mod b/go.mod
index 1cd835798f36..9e2259484110 100644
--- a/go.mod
+++ b/go.mod
@@ -9,12 +9,12 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.1.1
github.com/aws/aws-sdk-go-v2/credentials v1.1.1
github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1
- github.com/btcsuite/btcd/btcec/v2 v2.2.0
+ github.com/btcsuite/btcd/btcec/v2 v2.3.2
github.com/cespare/cp v0.1.0
github.com/cloudflare/cloudflare-go v0.14.0
github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811
github.com/consensys/gnark-crypto v0.10.0
- github.com/crate-crypto/go-kzg-4844 v0.2.0
+ github.com/crate-crypto/go-kzg-4844 v0.3.0
github.com/davecgh/go-spew v1.1.1
github.com/deckarep/golang-set/v2 v2.1.0
github.com/docker/docker v1.6.2
@@ -36,6 +36,7 @@ require (
github.com/gorilla/websocket v1.4.2
github.com/graph-gophers/graphql-go v1.3.0
github.com/hashicorp/go-bexpr v0.1.10
+ github.com/holiman/billy v0.0.0-20230616073924-97ff6efa2b93
github.com/holiman/bloomfilter/v2 v2.0.3
github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c
github.com/huin/goupnp v1.0.3
@@ -59,7 +60,7 @@ require (
github.com/supranational/blst v0.3.11-0.20230406105308-e9dfc5ee724b
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
github.com/tyler-smith/go-bip39 v1.1.0
- github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa
+ github.com/urfave/cli/v2 v2.24.1
golang.org/x/crypto v0.9.0
golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc
golang.org/x/sync v0.2.0
@@ -91,7 +92,7 @@ require (
github.com/consensys/bavard v0.1.13 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7 // indirect
- github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
+ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/dlclark/regexp2 v1.7.0 // indirect
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect
diff --git a/go.sum b/go.sum
index eb819cd68e9e..a545a350dd5e 100644
--- a/go.sum
+++ b/go.sum
@@ -7,7 +7,7 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSu
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0 h1:Px2UA+2RvSSvv+RvJNuUB6n7rs5Wsel4dXLe90Um2n4=
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
+github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8=
@@ -45,8 +45,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo=
github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
-github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
-github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU=
+github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U=
+github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
@@ -88,6 +88,8 @@ github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7 h1:6IrxszG5G+O
github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI=
github.com/crate-crypto/go-kzg-4844 v0.2.0 h1:UVuHOE+5tIWrim4zf/Xaa43+MIsDCPyW76QhUpiMGj4=
github.com/crate-crypto/go-kzg-4844 v0.2.0/go.mod h1:SBP7ikXEgDnUPONgm33HtuDZEDtWa3L4QtN1ocJSEQ4=
+github.com/crate-crypto/go-kzg-4844 v0.3.0 h1:UBlWE0CgyFqqzTI+IFyCzA7A3Zw4iip6uzRv5NIXG0A=
+github.com/crate-crypto/go-kzg-4844 v0.3.0/go.mod h1:SBP7ikXEgDnUPONgm33HtuDZEDtWa3L4QtN1ocJSEQ4=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -96,9 +98,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI=
github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
-github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
-github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
-github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4=
+github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc=
github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M=
github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU=
github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw=
@@ -114,8 +115,6 @@ github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5O
github.com/docker/docker v1.6.2 h1:HlFGsy+9/xrgMmhmN+NGhCc5SHGJ7I+kHosRR1xc/aI=
github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
-github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 h1:kgvzE5wLsLa7XKfV85VZl40QXaMCaeFtHpPwJ8fhotY=
-github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs=
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 h1:+3HCtB74++ClLy8GgjUQYeC8R4ILzVcIe8+5edAJJnE=
github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
@@ -235,6 +234,8 @@ github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpx
github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/holiman/billy v0.0.0-20230616073924-97ff6efa2b93 h1:OEhkkDN9VRUu0ALWB0xM5v4nOwyCCuGYM7f8UouUORw=
+github.com/holiman/billy v0.0.0-20230616073924-97ff6efa2b93/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc=
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8=
@@ -440,8 +441,8 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
-github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q=
-github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
+github.com/urfave/cli/v2 v2.24.1 h1:/QYYr7g0EhwXEML8jO+8OYt5trPnLHS0p3mrgExJ5NU=
+github.com/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
diff --git a/graphql/graphql.go b/graphql/graphql.go
index e1c716f318d3..ab58a0564681 100644
--- a/graphql/graphql.go
+++ b/graphql/graphql.go
@@ -1292,10 +1292,13 @@ func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Has
func (r *Resolver) SendRawTransaction(ctx context.Context, args struct{ Data hexutil.Bytes }) (common.Hash, error) {
tx := new(types.Transaction)
if err := tx.UnmarshalBinary(args.Data); err != nil {
+ var outer types.BlobTxWithBlobs
+ if innerErr := rlp.DecodeBytes(args.Data, &outer); innerErr == nil {
+ return ethapi.SubmitTransaction(ctx, r.backend, types.NewTx(outer.BlobTx), outer.Blobs, outer.Commitments, outer.Proofs)
+ }
return common.Hash{}, err
}
- hash, err := ethapi.SubmitTransaction(ctx, r.backend, tx)
- return hash, err
+ return ethapi.SubmitTransaction(ctx, r.backend, tx, nil, nil, nil)
}
// FilterCriteria encapsulates the arguments to `logs` on the root resolver object.
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 80756b64b80d..fdaf302fe868 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -40,6 +40,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/p2p"
@@ -467,7 +468,7 @@ func (s *PersonalAccountAPI) SendTransaction(ctx context.Context, args Transacti
log.Warn("Failed transaction send attempt", "from", args.from(), "to", args.To, "value", args.Value.ToInt(), "err", err)
return common.Hash{}, err
}
- return SubmitTransaction(ctx, s.b, signed)
+ return SubmitTransaction(ctx, s.b, signed, nil, nil, nil)
}
// SignTransaction will create a transaction from the given arguments and
@@ -1275,6 +1276,14 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
result["withdrawalsRoot"] = head.WithdrawalsHash
}
+ if head.DataGasUsed != nil {
+ result["dataGasUsed"] = hexutil.Uint64(*head.DataGasUsed)
+ }
+
+ if head.ExcessDataGas != nil {
+ result["excessDataGas"] = hexutil.Uint64(*head.ExcessDataGas)
+ }
+
return result
}
@@ -1333,25 +1342,27 @@ func (s *BlockChainAPI) rpcMarshalBlock(ctx context.Context, b *types.Block, inc
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
type RPCTransaction struct {
- BlockHash *common.Hash `json:"blockHash"`
- BlockNumber *hexutil.Big `json:"blockNumber"`
- From common.Address `json:"from"`
- Gas hexutil.Uint64 `json:"gas"`
- GasPrice *hexutil.Big `json:"gasPrice"`
- GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
- GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
- Hash common.Hash `json:"hash"`
- Input hexutil.Bytes `json:"input"`
- Nonce hexutil.Uint64 `json:"nonce"`
- To *common.Address `json:"to"`
- TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
- Value *hexutil.Big `json:"value"`
- Type hexutil.Uint64 `json:"type"`
- Accesses *types.AccessList `json:"accessList,omitempty"`
- ChainID *hexutil.Big `json:"chainId,omitempty"`
- V *hexutil.Big `json:"v"`
- R *hexutil.Big `json:"r"`
- S *hexutil.Big `json:"s"`
+ BlockHash *common.Hash `json:"blockHash"`
+ BlockNumber *hexutil.Big `json:"blockNumber"`
+ From common.Address `json:"from"`
+ Gas hexutil.Uint64 `json:"gas"`
+ GasPrice *hexutil.Big `json:"gasPrice"`
+ GasFeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
+ GasTipCap *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
+ MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas,omitempty"`
+ Hash common.Hash `json:"hash"`
+ Input hexutil.Bytes `json:"input"`
+ Nonce hexutil.Uint64 `json:"nonce"`
+ To *common.Address `json:"to"`
+ TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
+ Value *hexutil.Big `json:"value"`
+ Type hexutil.Uint64 `json:"type"`
+ Accesses *types.AccessList `json:"accessList,omitempty"`
+ ChainID *hexutil.Big `json:"chainId,omitempty"`
+ BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
+ V *hexutil.Big `json:"v"`
+ R *hexutil.Big `json:"r"`
+ S *hexutil.Big `json:"s"`
}
// newRPCTransaction returns a transaction that will serialize to the RPC
@@ -1403,6 +1414,22 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
} else {
result.GasPrice = (*hexutil.Big)(tx.GasFeeCap())
}
+ case types.BlobTxType:
+ al := tx.AccessList()
+ result.Accesses = &al
+ result.ChainID = (*hexutil.Big)(tx.ChainId())
+ result.GasFeeCap = (*hexutil.Big)(tx.GasFeeCap())
+ result.GasTipCap = (*hexutil.Big)(tx.GasTipCap())
+ // if the transaction has been mined, compute the effective gas price
+ if baseFee != nil && blockHash != (common.Hash{}) {
+ // price = min(tip, gasFeeCap - baseFee) + baseFee
+ price := math.BigMin(new(big.Int).Add(tx.GasTipCap(), baseFee), tx.GasFeeCap())
+ result.GasPrice = (*hexutil.Big)(price)
+ } else {
+ result.GasPrice = (*hexutil.Big)(tx.GasFeeCap())
+ }
+ result.MaxFeePerDataGas = (*hexutil.Big)(tx.BlobGasFeeCap())
+ result.BlobVersionedHashes = tx.BlobHashes()
}
return result
}
@@ -1727,7 +1754,7 @@ func (s *TransactionAPI) sign(addr common.Address, tx *types.Transaction) (*type
}
// SubmitTransaction is a helper function that submits tx to txPool and logs a message.
-func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) {
+func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction, blobTxBlobs []kzg4844.Blob, blobTxCommits []kzg4844.Commitment, blobTxProofs []kzg4844.Proof) (common.Hash, error) {
// If the transaction fee cap is already specified, ensure the
// fee of the given transaction is _reasonable_.
if err := checkTxFee(tx.GasPrice(), tx.Gas(), b.RPCTxFeeCap()); err != nil {
@@ -1737,9 +1764,16 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c
// Ensure only eip155 signed transactions are submitted if EIP155Required is set.
return common.Hash{}, errors.New("only replay-protected (EIP-155) transactions allowed over RPC")
}
- if err := b.SendTx(ctx, tx); err != nil {
- return common.Hash{}, err
+ if tx.Type() == types.BlobTxType {
+ if err := b.SendBlobTx(ctx, tx, blobTxBlobs, blobTxCommits, blobTxProofs); err != nil {
+ return common.Hash{}, err
+ }
+ } else {
+ if err := b.SendTx(ctx, tx); err != nil {
+ return common.Hash{}, err
+ }
}
+
// Print a log with full tx details for manual investigations and interventions
head := b.CurrentBlock()
signer := types.MakeSigner(b.ChainConfig(), head.Number, head.Time)
@@ -1786,7 +1820,7 @@ func (s *TransactionAPI) SendTransaction(ctx context.Context, args TransactionAr
if err != nil {
return common.Hash{}, err
}
- return SubmitTransaction(ctx, s.b, signed)
+ return SubmitTransaction(ctx, s.b, signed, nil, nil, nil)
}
// FillTransaction fills the defaults (nonce, gas, gasPrice or 1559 fields)
@@ -1810,10 +1844,20 @@ func (s *TransactionAPI) FillTransaction(ctx context.Context, args TransactionAr
// The sender is responsible for signing the transaction and using the correct nonce.
func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) {
tx := new(types.Transaction)
+ if len(input) < 1 {
+ return common.Hash{}, errors.New("input to short")
+ }
+ if input[0] == types.BlobTxType {
+ var outer types.BlobTxWithBlobs
+ if err := rlp.DecodeBytes(input[1:], &outer); err != nil {
+ return common.Hash{}, err
+ }
+ return SubmitTransaction(ctx, s.b, types.NewTx(outer.BlobTx), outer.Blobs, outer.Commitments, outer.Proofs)
+ }
if err := tx.UnmarshalBinary(input); err != nil {
return common.Hash{}, err
}
- return SubmitTransaction(ctx, s.b, tx)
+ return SubmitTransaction(ctx, s.b, tx, nil, nil, nil)
}
// Sign calculates an ECDSA signature for:
diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go
index 7c503dc39103..7b12e0ef2a98 100644
--- a/internal/ethapi/api_test.go
+++ b/internal/ethapi/api_test.go
@@ -42,6 +42,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
@@ -357,6 +358,9 @@ func (b testBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) even
func (b testBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error {
panic("implement me")
}
+func (b testBackend) SendBlobTx(ctx context.Context, signedTx *types.Transaction, blobTxBlobs []kzg4844.Blob, blobTxCommits []kzg4844.Commitment, blobTxProofs []kzg4844.Proof) error {
+ panic("implement me")
+}
func (b testBackend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
panic("implement me")
}
diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go
index 458fb811edae..213ec637f09c 100644
--- a/internal/ethapi/backend.go
+++ b/internal/ethapi/backend.go
@@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
@@ -75,6 +76,8 @@ type Backend interface {
// Transaction pool API
SendTx(ctx context.Context, signedTx *types.Transaction) error
+ SendBlobTx(ctx context.Context, signedTx *types.Transaction, blobTxBlobs []kzg4844.Blob, blobTxCommits []kzg4844.Commitment, blobTxProofs []kzg4844.Proof) error
+
GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
GetPoolTransactions() (types.Transactions, error)
GetPoolTransaction(txHash common.Hash) *types.Transaction
diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go
index 9161d5e681f2..267a33617ae1 100644
--- a/internal/ethapi/transaction_args_test.go
+++ b/internal/ethapi/transaction_args_test.go
@@ -34,6 +34,7 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
@@ -316,6 +317,9 @@ func (b *backendMock) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) eve
return nil
}
func (b *backendMock) SendTx(ctx context.Context, signedTx *types.Transaction) error { return nil }
+func (b *backendMock) SendBlobTx(ctx context.Context, signedTx *types.Transaction, blobTxBlobs []kzg4844.Blob, blobTxCommits []kzg4844.Commitment, blobTxProofs []kzg4844.Proof) error {
+ return nil
+}
func (b *backendMock) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
return nil, [32]byte{}, 0, 0, nil
}
diff --git a/les/api_backend.go b/les/api_backend.go
index dee3e3bfd93c..468320b8c8be 100644
--- a/les/api_backend.go
+++ b/les/api_backend.go
@@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/eth/gasprice"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/ethdb"
@@ -200,6 +201,10 @@ func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction)
return b.eth.txPool.Add(ctx, signedTx)
}
+func (b *LesApiBackend) SendBlobTx(ctx context.Context, signedTx *types.Transaction, blobTxBlobs []kzg4844.Blob, blobTxCommits []kzg4844.Commitment, blobTxProofs []kzg4844.Proof) error {
+ return errors.New("blob transactions not implemented on LES")
+}
+
func (b *LesApiBackend) RemoveTx(txHash common.Hash) {
b.eth.txPool.RemoveTx(txHash)
}
diff --git a/les/catalyst/api.go b/les/catalyst/api.go
index 30b41101dbc1..794cc08e9a8d 100644
--- a/les/catalyst/api.go
+++ b/les/catalyst/api.go
@@ -106,7 +106,7 @@ func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.Execu
// ExecutePayloadV1 creates an Eth1 block, inserts it in the chain, and returns the status of the chain.
func (api *ConsensusAPI) ExecutePayloadV1(params engine.ExecutableData) (engine.PayloadStatusV1, error) {
- block, err := engine.ExecutableDataToBlock(params)
+ block, err := engine.ExecutableDataToBlock(params, nil)
if err != nil {
return api.invalid(), err
}
diff --git a/miner/ordering.go b/miner/ordering.go
new file mode 100644
index 000000000000..4c3055f0d317
--- /dev/null
+++ b/miner/ordering.go
@@ -0,0 +1,147 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package miner
+
+import (
+ "container/heap"
+ "math/big"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/math"
+ "github.com/ethereum/go-ethereum/core/txpool"
+ "github.com/ethereum/go-ethereum/core/types"
+)
+
+// txWithMinerFee wraps a transaction with its gas price or effective miner gasTipCap
+type txWithMinerFee struct {
+ tx *txpool.LazyTransaction
+ from common.Address
+ fees *big.Int
+}
+
+// newTxWithMinerFee creates a wrapped transaction, calculating the effective
+// miner gasTipCap if a base fee is provided.
+// Returns error in case of a negative effective miner gasTipCap.
+func newTxWithMinerFee(tx *txpool.LazyTransaction, from common.Address, baseFee *big.Int) (*txWithMinerFee, error) {
+ tip := new(big.Int).Set(tx.GasTipCap)
+ if baseFee != nil {
+ if tx.GasFeeCap.Cmp(baseFee) < 0 {
+ return nil, types.ErrGasFeeCapTooLow
+ }
+ tip = math.BigMin(tx.GasTipCap, new(big.Int).Sub(tx.GasFeeCap, baseFee))
+ }
+ return &txWithMinerFee{
+ tx: tx,
+ from: from,
+ fees: tip,
+ }, nil
+}
+
+// txByPriceAndTime implements both the sort and the heap interface, making it useful
+// for all at once sorting as well as individually adding and removing elements.
+type txByPriceAndTime []*txWithMinerFee
+
+func (s txByPriceAndTime) Len() int { return len(s) }
+func (s txByPriceAndTime) Less(i, j int) bool {
+ // If the prices are equal, use the time the transaction was first seen for
+ // deterministic sorting
+ cmp := s[i].fees.Cmp(s[j].fees)
+ if cmp == 0 {
+ return s[i].tx.Time.Before(s[j].tx.Time)
+ }
+ return cmp > 0
+}
+func (s txByPriceAndTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func (s *txByPriceAndTime) Push(x interface{}) {
+ *s = append(*s, x.(*txWithMinerFee))
+}
+
+func (s *txByPriceAndTime) Pop() interface{} {
+ old := *s
+ n := len(old)
+ x := old[n-1]
+ old[n-1] = nil
+ *s = old[0 : n-1]
+ return x
+}
+
+// transactionsByPriceAndNonce represents a set of transactions that can return
+// transactions in a profit-maximizing sorted order, while supporting removing
+// entire batches of transactions for non-executable accounts.
+type transactionsByPriceAndNonce struct {
+ txs map[common.Address][]*txpool.LazyTransaction // Per account nonce-sorted list of transactions
+ heads txByPriceAndTime // Next transaction for each unique account (price heap)
+ signer types.Signer // Signer for the set of transactions
+ baseFee *big.Int // Current base fee
+}
+
+// newTransactionsByPriceAndNonce creates a transaction set that can retrieve
+// price sorted transactions in a nonce-honouring way.
+//
+// Note, the input map is reowned so the caller should not interact any more with
+// if after providing it to the constructor.
+func newTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address][]*txpool.LazyTransaction, baseFee *big.Int) *transactionsByPriceAndNonce {
+ // Initialize a price and received time based heap with the head transactions
+ heads := make(txByPriceAndTime, 0, len(txs))
+ for from, accTxs := range txs {
+ wrapped, err := newTxWithMinerFee(accTxs[0], from, baseFee)
+ if err != nil {
+ delete(txs, from)
+ continue
+ }
+ heads = append(heads, wrapped)
+ txs[from] = accTxs[1:]
+ }
+ heap.Init(&heads)
+
+ // Assemble and return the transaction set
+ return &transactionsByPriceAndNonce{
+ txs: txs,
+ heads: heads,
+ signer: signer,
+ baseFee: baseFee,
+ }
+}
+
+// Peek returns the next transaction by price.
+func (t *transactionsByPriceAndNonce) Peek() *txpool.LazyTransaction {
+ if len(t.heads) == 0 {
+ return nil
+ }
+ return t.heads[0].tx
+}
+
+// Shift replaces the current best head with the next one from the same account.
+func (t *transactionsByPriceAndNonce) Shift() {
+ acc := t.heads[0].from
+ if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
+ if wrapped, err := newTxWithMinerFee(txs[0], acc, t.baseFee); err == nil {
+ t.heads[0], t.txs[acc] = wrapped, txs[1:]
+ heap.Fix(&t.heads, 0)
+ return
+ }
+ }
+ heap.Pop(&t.heads)
+}
+
+// Pop removes the best transaction, *not* replacing it with the next one from
+// the same account. This should be used when a transaction cannot be executed
+// and hence all subsequent ones should be discarded from the same account.
+func (t *transactionsByPriceAndNonce) Pop() {
+ heap.Pop(&t.heads)
+}
diff --git a/miner/ordering_test.go b/miner/ordering_test.go
new file mode 100644
index 000000000000..589633e0b8dd
--- /dev/null
+++ b/miner/ordering_test.go
@@ -0,0 +1,188 @@
+// Copyright 2014 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package miner
+
+import (
+ "crypto/ecdsa"
+ "math/big"
+ "math/rand"
+ "testing"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/txpool"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+func TestTransactionPriceNonceSortLegacy(t *testing.T) {
+ testTransactionPriceNonceSort(t, nil)
+}
+
+func TestTransactionPriceNonceSort1559(t *testing.T) {
+ testTransactionPriceNonceSort(t, big.NewInt(0))
+ testTransactionPriceNonceSort(t, big.NewInt(5))
+ testTransactionPriceNonceSort(t, big.NewInt(50))
+}
+
+// Tests that transactions can be correctly sorted according to their price in
+// decreasing order, but at the same time with increasing nonces when issued by
+// the same account.
+func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
+ // Generate a batch of accounts to start with
+ keys := make([]*ecdsa.PrivateKey, 25)
+ for i := 0; i < len(keys); i++ {
+ keys[i], _ = crypto.GenerateKey()
+ }
+ signer := types.LatestSignerForChainID(common.Big1)
+
+ // Generate a batch of transactions with overlapping values, but shifted nonces
+ groups := map[common.Address][]*txpool.LazyTransaction{}
+ expectedCount := 0
+ for start, key := range keys {
+ addr := crypto.PubkeyToAddress(key.PublicKey)
+ count := 25
+ for i := 0; i < 25; i++ {
+ var tx *types.Transaction
+ gasFeeCap := rand.Intn(50)
+ if baseFee == nil {
+ tx = types.NewTx(&types.LegacyTx{
+ Nonce: uint64(start + i),
+ To: &common.Address{},
+ Value: big.NewInt(100),
+ Gas: 100,
+ GasPrice: big.NewInt(int64(gasFeeCap)),
+ Data: nil,
+ })
+ } else {
+ tx = types.NewTx(&types.DynamicFeeTx{
+ Nonce: uint64(start + i),
+ To: &common.Address{},
+ Value: big.NewInt(100),
+ Gas: 100,
+ GasFeeCap: big.NewInt(int64(gasFeeCap)),
+ GasTipCap: big.NewInt(int64(rand.Intn(gasFeeCap + 1))),
+ Data: nil,
+ })
+ if count == 25 && int64(gasFeeCap) < baseFee.Int64() {
+ count = i
+ }
+ }
+ tx, err := types.SignTx(tx, signer, key)
+ if err != nil {
+ t.Fatalf("failed to sign tx: %s", err)
+ }
+ groups[addr] = append(groups[addr], &txpool.LazyTransaction{
+ Hash: tx.Hash(),
+ Tx: &txpool.Transaction{Tx: tx},
+ Time: tx.Time(),
+ GasFeeCap: tx.GasFeeCap(),
+ GasTipCap: tx.GasTipCap(),
+ })
+ }
+ expectedCount += count
+ }
+ // Sort the transactions and cross check the nonce ordering
+ txset := newTransactionsByPriceAndNonce(signer, groups, baseFee)
+
+ txs := types.Transactions{}
+ for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
+ txs = append(txs, tx.Tx.Tx)
+ txset.Shift()
+ }
+ if len(txs) != expectedCount {
+ t.Errorf("expected %d transactions, found %d", expectedCount, len(txs))
+ }
+ for i, txi := range txs {
+ fromi, _ := types.Sender(signer, txi)
+
+ // Make sure the nonce order is valid
+ for j, txj := range txs[i+1:] {
+ fromj, _ := types.Sender(signer, txj)
+ if fromi == fromj && txi.Nonce() > txj.Nonce() {
+ t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce())
+ }
+ }
+ // If the next tx has different from account, the price must be lower than the current one
+ if i+1 < len(txs) {
+ next := txs[i+1]
+ fromNext, _ := types.Sender(signer, next)
+ tip, err := txi.EffectiveGasTip(baseFee)
+ nextTip, nextErr := next.EffectiveGasTip(baseFee)
+ if err != nil || nextErr != nil {
+ t.Errorf("error calculating effective tip: %v, %v", err, nextErr)
+ }
+ if fromi != fromNext && tip.Cmp(nextTip) < 0 {
+ t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice())
+ }
+ }
+ }
+}
+
+// Tests that if multiple transactions have the same price, the ones seen earlier
+// are prioritized to avoid network spam attacks aiming for a specific ordering.
+func TestTransactionTimeSort(t *testing.T) {
+ // Generate a batch of accounts to start with
+ keys := make([]*ecdsa.PrivateKey, 5)
+ for i := 0; i < len(keys); i++ {
+ keys[i], _ = crypto.GenerateKey()
+ }
+ signer := types.HomesteadSigner{}
+
+ // Generate a batch of transactions with overlapping prices, but different creation times
+ groups := map[common.Address][]*txpool.LazyTransaction{}
+ for start, key := range keys {
+ addr := crypto.PubkeyToAddress(key.PublicKey)
+
+ tx, _ := types.SignTx(types.NewTransaction(0, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key)
+ tx.SetTime(time.Unix(0, int64(len(keys)-start)))
+
+ groups[addr] = append(groups[addr], &txpool.LazyTransaction{
+ Hash: tx.Hash(),
+ Tx: &txpool.Transaction{Tx: tx},
+ Time: tx.Time(),
+ GasFeeCap: tx.GasFeeCap(),
+ GasTipCap: tx.GasTipCap(),
+ })
+ }
+ // Sort the transactions and cross check the nonce ordering
+ txset := newTransactionsByPriceAndNonce(signer, groups, nil)
+
+ txs := types.Transactions{}
+ for tx := txset.Peek(); tx != nil; tx = txset.Peek() {
+ txs = append(txs, tx.Tx.Tx)
+ txset.Shift()
+ }
+ if len(txs) != len(keys) {
+ t.Errorf("expected %d transactions, found %d", len(keys), len(txs))
+ }
+ for i, txi := range txs {
+ fromi, _ := types.Sender(signer, txi)
+ if i+1 < len(txs) {
+ next := txs[i+1]
+ fromNext, _ := types.Sender(signer, next)
+
+ if txi.GasPrice().Cmp(next.GasPrice()) < 0 {
+ t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice())
+ }
+ // Make sure time order is ascending if the txs have the same gas price
+ if txi.GasPrice().Cmp(next.GasPrice()) == 0 && txi.Time().After(next.Time()) {
+ t.Errorf("invalid received time ordering: tx #%d (A=%x T=%v) > tx #%d (A=%x T=%v)", i, fromi[:4], txi.Time(), i+1, fromNext[:4], next.Time())
+ }
+ }
+ }
+}
diff --git a/miner/payload_building.go b/miner/payload_building.go
index 819937ba3263..d2777374c291 100644
--- a/miner/payload_building.go
+++ b/miner/payload_building.go
@@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/beacon/engine"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
@@ -62,13 +63,16 @@ func (args *BuildPayloadArgs) Id() engine.PayloadID {
// the revenue. Therefore, the empty-block here is always available and full-block
// will be set/updated afterwards.
type Payload struct {
- id engine.PayloadID
- empty *types.Block
- full *types.Block
- fullFees *big.Int
- stop chan struct{}
- lock sync.Mutex
- cond *sync.Cond
+ id engine.PayloadID
+ empty *types.Block
+ full *types.Block
+ blobs []kzg4844.Blob
+ commitments []kzg4844.Commitment
+ proofs []kzg4844.Proof
+ fullFees *big.Int
+ stop chan struct{}
+ lock sync.Mutex
+ cond *sync.Cond
}
// newPayload initializes the payload object.
@@ -84,7 +88,7 @@ func newPayload(empty *types.Block, id engine.PayloadID) *Payload {
}
// update updates the full-block with latest built version.
-func (payload *Payload) update(block *types.Block, fees *big.Int, elapsed time.Duration) {
+func (payload *Payload) update(block *types.Block, fees *big.Int, blobs []kzg4844.Blob, commits []kzg4844.Commitment, proofs []kzg4844.Proof, elapsed time.Duration) {
payload.lock.Lock()
defer payload.lock.Unlock()
@@ -99,6 +103,9 @@ func (payload *Payload) update(block *types.Block, fees *big.Int, elapsed time.D
if payload.full == nil || fees.Cmp(payload.fullFees) > 0 {
payload.full = block
payload.fullFees = fees
+ payload.blobs = blobs
+ payload.commitments = commits
+ payload.proofs = proofs
feesInEther := new(big.Float).Quo(new(big.Float).SetInt(fees), big.NewFloat(params.Ether))
log.Info("Updated payload", "id", payload.id, "number", block.NumberU64(), "hash", block.Hash(),
@@ -120,9 +127,9 @@ func (payload *Payload) Resolve() *engine.ExecutionPayloadEnvelope {
close(payload.stop)
}
if payload.full != nil {
- return engine.BlockToExecutableData(payload.full, payload.fullFees)
+ return engine.BlockToExecutableData(payload.full, payload.fullFees, payload.blobs, payload.commitments, payload.proofs)
}
- return engine.BlockToExecutableData(payload.empty, big.NewInt(0))
+ return engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil, nil, nil)
}
// ResolveEmpty is basically identical to Resolve, but it expects empty block only.
@@ -131,7 +138,7 @@ func (payload *Payload) ResolveEmpty() *engine.ExecutionPayloadEnvelope {
payload.lock.Lock()
defer payload.lock.Unlock()
- return engine.BlockToExecutableData(payload.empty, big.NewInt(0))
+ return engine.BlockToExecutableData(payload.empty, big.NewInt(0), nil, nil, nil)
}
// ResolveFull is basically identical to Resolve, but it expects full block only.
@@ -148,7 +155,7 @@ func (payload *Payload) ResolveFull() *engine.ExecutionPayloadEnvelope {
}
payload.cond.Wait()
}
- return engine.BlockToExecutableData(payload.full, payload.fullFees)
+ return engine.BlockToExecutableData(payload.full, payload.fullFees, payload.blobs, payload.commitments, payload.proofs)
}
// buildPayload builds the payload according to the provided parameters.
@@ -156,7 +163,7 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) {
// Build the initial version with no transaction included. It should be fast
// enough to run. The empty payload can at least make sure there is something
// to deliver for not missing slot.
- empty, _, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, args.Withdrawals, true)
+ empty, _, _, _, _, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, args.Withdrawals, true)
if err != nil {
return nil, err
}
@@ -180,9 +187,9 @@ func (w *worker) buildPayload(args *BuildPayloadArgs) (*Payload, error) {
select {
case <-timer.C:
start := time.Now()
- block, fees, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, args.Withdrawals, false)
+ block, fees, blobs, commits, proofs, err := w.getSealingBlock(args.Parent, args.Timestamp, args.FeeRecipient, args.Random, args.Withdrawals, false)
if err == nil {
- payload.update(block, fees, time.Since(start))
+ payload.update(block, fees, blobs, commits, proofs, time.Since(start))
}
timer.Reset(w.recommit)
case <-payload.stop:
diff --git a/miner/worker.go b/miner/worker.go
index fb30142aa6ea..6e0423102c25 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -29,7 +29,9 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
+ "github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
@@ -85,9 +87,12 @@ type environment struct {
gasPool *core.GasPool // available gas used to pack transactions
coinbase common.Address
- header *types.Header
- txs []*types.Transaction
- receipts []*types.Receipt
+ header *types.Header
+ txs []*types.Transaction
+ receipts []*types.Receipt
+ blobs []kzg4844.Blob
+ commitments []kzg4844.Commitment
+ proofs []kzg4844.Proof
}
// copy creates a deep copy of environment.
@@ -106,6 +111,15 @@ func (env *environment) copy() *environment {
}
cpy.txs = make([]*types.Transaction, len(env.txs))
copy(cpy.txs, env.txs)
+
+ cpy.blobs = make([]kzg4844.Blob, len(env.blobs))
+ copy(cpy.blobs, env.blobs)
+
+ cpy.commitments = make([]kzg4844.Commitment, len(env.commitments))
+ copy(cpy.commitments, env.commitments)
+
+ cpy.proofs = make([]kzg4844.Proof, len(env.proofs))
+ copy(cpy.proofs, env.proofs)
return cpy
}
@@ -145,6 +159,10 @@ type newPayloadResult struct {
err error
block *types.Block
fees *big.Int
+
+ blobs []kzg4844.Blob
+ commitments []kzg4844.Commitment
+ proofs []kzg4844.Proof
}
// getWorkReq represents a request for getting a new sealing work with provided parameters.
@@ -515,11 +533,14 @@ func (w *worker) mainLoop() {
w.commitWork(req.interrupt, req.timestamp)
case req := <-w.getWorkCh:
- block, fees, err := w.generateWork(req.params)
+ block, fees, blobs, commits, proofs, err := w.generateWork(req.params)
req.result <- &newPayloadResult{
- err: err,
- block: block,
- fees: fees,
+ err: err,
+ block: block,
+ fees: fees,
+ blobs: blobs,
+ commitments: commits,
+ proofs: proofs,
}
case ev := <-w.txsCh:
@@ -533,12 +554,18 @@ func (w *worker) mainLoop() {
if gp := w.current.gasPool; gp != nil && gp.Gas() < params.TxGas {
continue
}
- txs := make(map[common.Address][]*types.Transaction, len(ev.Txs))
+ txs := make(map[common.Address][]*txpool.LazyTransaction, len(ev.Txs))
for _, tx := range ev.Txs {
acc, _ := types.Sender(w.current.signer, tx)
- txs[acc] = append(txs[acc], tx)
+ txs[acc] = append(txs[acc], &txpool.LazyTransaction{
+ Hash: tx.Hash(),
+ Tx: &txpool.Transaction{Tx: tx},
+ Time: tx.Time(),
+ GasFeeCap: tx.GasFeeCap(),
+ GasTipCap: tx.GasTipCap(),
+ })
}
- txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs, w.current.header.BaseFee)
+ txset := newTransactionsByPriceAndNonce(w.current.signer, txs, w.current.header.BaseFee)
tcount := w.current.tcount
w.commitTransactions(w.current, txset, nil)
@@ -727,24 +754,34 @@ func (w *worker) updateSnapshot(env *environment) {
w.snapshotState = env.state.Copy()
}
-func (w *worker) commitTransaction(env *environment, tx *types.Transaction) ([]*types.Log, error) {
+func (w *worker) commitTransaction(env *environment, tx *txpool.Transaction) ([]*types.Log, error) {
var (
snap = env.state.Snapshot()
gp = env.gasPool.Gas()
)
- receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, env.gasPool, env.state, env.header, tx, &env.header.GasUsed, *w.chain.GetVMConfig())
+ // TODO (MariusVanDerWijden): Move this check
+ if (len(env.blobs)+len(tx.Tx.BlobHashes()))*params.BlobTxDataGasPerBlob > params.BlobTxMaxDataGasPerBlock {
+ return nil, errors.New("max data blobs reached")
+ }
+ receipt, err := core.ApplyTransaction(w.chainConfig, w.chain, &env.coinbase, env.gasPool, env.state, env.header, tx.Tx, &env.header.GasUsed, *w.chain.GetVMConfig())
if err != nil {
env.state.RevertToSnapshot(snap)
env.gasPool.SetGas(gp)
return nil, err
}
- env.txs = append(env.txs, tx)
+ env.txs = append(env.txs, tx.Tx)
env.receipts = append(env.receipts, receipt)
+ if tx.Tx.Type() == types.BlobTxType {
+ env.blobs = append(env.blobs, tx.BlobTxBlobs...)
+ env.commitments = append(env.commitments, tx.BlobTxCommits...)
+ env.proofs = append(env.proofs, tx.BlobTxProofs...)
+ }
+
return receipt.Logs, nil
}
-func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByPriceAndNonce, interrupt *atomic.Int32) error {
+func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAndNonce, interrupt *atomic.Int32) error {
gasLimit := env.header.GasLimit
if env.gasPool == nil {
env.gasPool = new(core.GasPool).AddGas(gasLimit)
@@ -764,30 +801,37 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
break
}
// Retrieve the next transaction and abort if all done.
- tx := txs.Peek()
- if tx == nil {
+ ltx := txs.Peek()
+ if ltx == nil {
break
}
+ tx := ltx.Resolve()
+ if tx == nil {
+ log.Warn("Ignoring evicted transaction")
+
+ txs.Pop()
+ continue
+ }
// Error may be ignored here. The error has already been checked
// during transaction acceptance is the transaction pool.
- from, _ := types.Sender(env.signer, tx)
+ from, _ := types.Sender(env.signer, tx.Tx)
// Check whether the tx is replay protected. If we're not in the EIP155 hf
// phase, start ignoring the sender until we do.
- if tx.Protected() && !w.chainConfig.IsEIP155(env.header.Number) {
- log.Trace("Ignoring reply protected transaction", "hash", tx.Hash(), "eip155", w.chainConfig.EIP155Block)
+ if tx.Tx.Protected() && !w.chainConfig.IsEIP155(env.header.Number) {
+ log.Trace("Ignoring reply protected transaction", "hash", tx.Tx.Hash(), "eip155", w.chainConfig.EIP155Block)
txs.Pop()
continue
}
// Start executing the transaction
- env.state.SetTxContext(tx.Hash(), env.tcount)
+ env.state.SetTxContext(tx.Tx.Hash(), env.tcount)
logs, err := w.commitTransaction(env, tx)
switch {
case errors.Is(err, core.ErrNonceTooLow):
// New head notification data race between the transaction pool and miner, shift
- log.Trace("Skipping transaction with low nonce", "sender", from, "nonce", tx.Nonce())
+ log.Trace("Skipping transaction with low nonce", "sender", from, "nonce", tx.Tx.Nonce())
txs.Shift()
case errors.Is(err, nil):
@@ -799,7 +843,7 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP
default:
// Transaction is regarded as invalid, drop all consecutive transactions from
// the same sender because of `nonce-too-high` clause.
- log.Debug("Transaction failed, account skipped", "hash", tx.Hash(), "err", err)
+ log.Debug("Transaction failed, account skipped", "hash", tx.Tx.Hash(), "err", err)
txs.Pop()
}
}
@@ -881,6 +925,16 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil)
}
}
+ if w.chainConfig.IsCancun(header.Number, header.Time) {
+ var excessData uint64
+ if w.chainConfig.IsCancun(parent.Number, parent.Time) {
+ excessData = misc.CalcExcessDataGas(*parent.ExcessDataGas, *parent.DataGasUsed)
+ } else {
+ // For the first post-fork block, both parent.data_gas_used and parent.excess_data_gas are evaluated as 0
+ excessData = misc.CalcExcessDataGas(0, 0)
+ }
+ header.ExcessDataGas = &excessData
+ }
// Run the consensus preparation with the default or customized consensus engine.
if err := w.engine.Prepare(w.chain, header); err != nil {
log.Error("Failed to prepare header for sealing", "err", err)
@@ -904,27 +958,25 @@ func (w *worker) fillTransactions(interrupt *atomic.Int32, env *environment) err
// Split the pending transactions into locals and remotes
// Fill the block with all available pending transactions.
pending := w.eth.TxPool().Pending(true)
- /*blobtxs := w.eth.BlobPool().Pending(
- uint256.MustFromBig(env.header.BaseFee),
- uint256.MustFromBig(misc.CalcBlobFee(*env.header.ExcessDataGas)),
- )
- log.Trace("Side-effect log, much wow", "blobs", len(blobtxs))*/
- localTxs, remoteTxs := make(map[common.Address][]*types.Transaction), pending
+ localTxs, remoteTxs := make(map[common.Address][]*txpool.LazyTransaction), pending
for _, account := range w.eth.TxPool().Locals() {
- if txs := remoteTxs[account]; len(txs) > 0 {
- delete(remoteTxs, account)
- localTxs[account] = txs
+ if txs := pending[account]; len(txs) > 0 {
+ delete(pending, account)
+ for _, tx := range txs {
+ localTxs[account] = append(localTxs[account], tx)
+ }
}
}
+
if len(localTxs) > 0 {
- txs := types.NewTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
+ txs := newTransactionsByPriceAndNonce(env.signer, localTxs, env.header.BaseFee)
if err := w.commitTransactions(env, txs, interrupt); err != nil {
return err
}
}
if len(remoteTxs) > 0 {
- txs := types.NewTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
+ txs := newTransactionsByPriceAndNonce(env.signer, remoteTxs, env.header.BaseFee)
if err := w.commitTransactions(env, txs, interrupt); err != nil {
return err
}
@@ -933,10 +985,10 @@ func (w *worker) fillTransactions(interrupt *atomic.Int32, env *environment) err
}
// generateWork generates a sealing block based on the given parameters.
-func (w *worker) generateWork(params *generateParams) (*types.Block, *big.Int, error) {
+func (w *worker) generateWork(params *generateParams) (*types.Block, *big.Int, []kzg4844.Blob, []kzg4844.Commitment, []kzg4844.Proof, error) {
work, err := w.prepareWork(params)
if err != nil {
- return nil, nil, err
+ return nil, nil, nil, nil, nil, err
}
defer work.discard()
@@ -954,9 +1006,9 @@ func (w *worker) generateWork(params *generateParams) (*types.Block, *big.Int, e
}
block, err := w.engine.FinalizeAndAssemble(w.chain, work.header, work.state, work.txs, nil, work.receipts, params.withdrawals)
if err != nil {
- return nil, nil, err
+ return nil, nil, nil, nil, nil, err
}
- return block, totalFees(block, work.receipts), nil
+ return block, totalFees(block, work.receipts), work.blobs, work.commitments, work.proofs, nil
}
// commitWork generates several new sealing tasks based on the parent block
@@ -1065,7 +1117,7 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti
// getSealingBlock generates the sealing block based on the given parameters.
// The generation result will be passed back via the given channel no matter
// the generation itself succeeds or not.
-func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase common.Address, random common.Hash, withdrawals types.Withdrawals, noTxs bool) (*types.Block, *big.Int, error) {
+func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase common.Address, random common.Hash, withdrawals types.Withdrawals, noTxs bool) (*types.Block, *big.Int, []kzg4844.Blob, []kzg4844.Commitment, []kzg4844.Proof, error) {
req := &getWorkReq{
params: &generateParams{
timestamp: timestamp,
@@ -1082,11 +1134,11 @@ func (w *worker) getSealingBlock(parent common.Hash, timestamp uint64, coinbase
case w.getWorkCh <- req:
result := <-req.result
if result.err != nil {
- return nil, nil, result.err
+ return nil, nil, nil, nil, nil, result.err
}
- return result.block, result.fees, nil
+ return result.block, result.fees, result.blobs, result.commitments, result.proofs, nil
case <-w.exitCh:
- return nil, nil, errors.New("miner closed")
+ return nil, nil, nil, nil, nil, errors.New("miner closed")
}
}
diff --git a/miner/worker_test.go b/miner/worker_test.go
index 80557d99bfcf..a28cf353aceb 100644
--- a/miner/worker_test.go
+++ b/miner/worker_test.go
@@ -452,7 +452,7 @@ func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine co
// This API should work even when the automatic sealing is not enabled
for _, c := range cases {
- block, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, nil, false)
+ block, _, _, _, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, nil, false)
if c.expectErr {
if err == nil {
t.Error("Expect error but get nil")
@@ -468,7 +468,7 @@ func testGetSealingWork(t *testing.T, chainConfig *params.ChainConfig, engine co
// This API should work even when the automatic sealing is enabled
w.start()
for _, c := range cases {
- block, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, nil, false)
+ block, _, _, _, _, err := w.getSealingBlock(c.parent, timestamp, c.coinbase, c.random, nil, false)
if c.expectErr {
if err == nil {
t.Error("Expect error but get nil")
diff --git a/params/protocol_params.go b/params/protocol_params.go
index 9a0b8115b13c..4e72d169dba3 100644
--- a/params/protocol_params.go
+++ b/params/protocol_params.go
@@ -160,15 +160,15 @@ const (
RefundQuotient uint64 = 2
RefundQuotientEIP3529 uint64 = 5
- BlobTxBytesPerFieldElement = 32 // Size in bytes of a field element
- BlobTxFieldElementsPerBlob = 4096 // Number of field elements stored in a single data blob
- BlobTxHashVersion = 0x01 // Version byte of the commitment hash
- BlobTxMaxDataGasPerBlock = 1 << 19 // Maximum consumable data gas for data blobs per block
- BlobTxTargetDataGasPerBlock = 1 << 18 // Target consumable data gas for data blobs per block (for 1559-like pricing)
- BlobTxDataGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
- BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs
- BlobTxDataGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for data gas price
- BlobTxPointEvaluationPrecompileGas = 50000 // Gas price for the point evaluation precompile.
+ BlobTxBytesPerFieldElement = 32 // Size in bytes of a field element
+ BlobTxFieldElementsPerBlob = 4096 // Number of field elements stored in a single data blob
+ BlobTxHashVersion = 0x01 // Version byte of the commitment hash
+ BlobTxDataGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
+ BlobTxMaxDataGasPerBlock = 6 * BlobTxDataGasPerBlob // Maximum consumable data gas for data blobs per block
+ BlobTxTargetDataGasPerBlock = 3 * BlobTxDataGasPerBlob // Target consumable data gas for data blobs per block (for 1559-like pricing)
+ BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs
+ BlobTxDataGaspriceUpdateFraction = 3338477 // Controls the maximum rate of change for data gas price
+ BlobTxPointEvaluationPrecompileGas = 50000 // Gas price for the point evaluation precompile.
)
// Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations
diff --git a/tests/block_test_util.go b/tests/block_test_util.go
index d3e525a387e3..8ea67b94ea56 100644
--- a/tests/block_test_util.go
+++ b/tests/block_test_util.go
@@ -88,6 +88,8 @@ type btHeader struct {
Timestamp uint64
BaseFeePerGas *big.Int
WithdrawalsRoot *common.Hash
+ DataGasUsed *uint64
+ ExcessDataGas *uint64
}
type btHeaderMarshaling struct {
@@ -98,6 +100,8 @@ type btHeaderMarshaling struct {
GasUsed math.HexOrDecimal64
Timestamp math.HexOrDecimal64
BaseFeePerGas *math.HexOrDecimal256
+ DataGasUsed *math.HexOrDecimal64
+ ExcessDataGas *math.HexOrDecimal64
}
func (t *BlockTest) Run(snapshotter bool, tracer vm.EVMLogger) error {
@@ -158,18 +162,20 @@ func (t *BlockTest) Run(snapshotter bool, tracer vm.EVMLogger) error {
func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
return &core.Genesis{
- Config: config,
- Nonce: t.json.Genesis.Nonce.Uint64(),
- Timestamp: t.json.Genesis.Timestamp,
- ParentHash: t.json.Genesis.ParentHash,
- ExtraData: t.json.Genesis.ExtraData,
- GasLimit: t.json.Genesis.GasLimit,
- GasUsed: t.json.Genesis.GasUsed,
- Difficulty: t.json.Genesis.Difficulty,
- Mixhash: t.json.Genesis.MixHash,
- Coinbase: t.json.Genesis.Coinbase,
- Alloc: t.json.Pre,
- BaseFee: t.json.Genesis.BaseFeePerGas,
+ Config: config,
+ Nonce: t.json.Genesis.Nonce.Uint64(),
+ Timestamp: t.json.Genesis.Timestamp,
+ ParentHash: t.json.Genesis.ParentHash,
+ ExtraData: t.json.Genesis.ExtraData,
+ GasLimit: t.json.Genesis.GasLimit,
+ GasUsed: t.json.Genesis.GasUsed,
+ Difficulty: t.json.Genesis.Difficulty,
+ Mixhash: t.json.Genesis.MixHash,
+ Coinbase: t.json.Genesis.Coinbase,
+ Alloc: t.json.Pre,
+ BaseFee: t.json.Genesis.BaseFeePerGas,
+ DataGasUsed: t.json.Genesis.DataGasUsed,
+ ExcessDataGas: t.json.Genesis.ExcessDataGas,
}
}
@@ -278,6 +284,12 @@ func validateHeader(h *btHeader, h2 *types.Header) error {
if !reflect.DeepEqual(h.WithdrawalsRoot, h2.WithdrawalsHash) {
return fmt.Errorf("withdrawalsRoot: want: %v have: %v", h.WithdrawalsRoot, h2.WithdrawalsHash)
}
+ if !reflect.DeepEqual(h.DataGasUsed, h2.DataGasUsed) {
+ return fmt.Errorf("dataGasUsed: want: %v have: %v", h.DataGasUsed, h2.DataGasUsed)
+ }
+ if !reflect.DeepEqual(h.ExcessDataGas, h2.ExcessDataGas) {
+ return fmt.Errorf("excessDataGas: want: %v have: %v", h.ExcessDataGas, h2.ExcessDataGas)
+ }
return nil
}
diff --git a/tests/gen_btheader.go b/tests/gen_btheader.go
index 985ea692d751..40d80e335509 100644
--- a/tests/gen_btheader.go
+++ b/tests/gen_btheader.go
@@ -35,6 +35,8 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
Timestamp math.HexOrDecimal64
BaseFeePerGas *math.HexOrDecimal256
WithdrawalsRoot *common.Hash
+ DataGasUsed *math.HexOrDecimal64
+ ExcessDataGas *math.HexOrDecimal64
}
var enc btHeader
enc.Bloom = b.Bloom
@@ -55,6 +57,8 @@ func (b btHeader) MarshalJSON() ([]byte, error) {
enc.Timestamp = math.HexOrDecimal64(b.Timestamp)
enc.BaseFeePerGas = (*math.HexOrDecimal256)(b.BaseFeePerGas)
enc.WithdrawalsRoot = b.WithdrawalsRoot
+ enc.DataGasUsed = (*math.HexOrDecimal64)(b.DataGasUsed)
+ enc.ExcessDataGas = (*math.HexOrDecimal64)(b.ExcessDataGas)
return json.Marshal(&enc)
}
@@ -79,6 +83,8 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
Timestamp *math.HexOrDecimal64
BaseFeePerGas *math.HexOrDecimal256
WithdrawalsRoot *common.Hash
+ DataGasUsed *math.HexOrDecimal64
+ ExcessDataGas *math.HexOrDecimal64
}
var dec btHeader
if err := json.Unmarshal(input, &dec); err != nil {
@@ -138,5 +144,11 @@ func (b *btHeader) UnmarshalJSON(input []byte) error {
if dec.WithdrawalsRoot != nil {
b.WithdrawalsRoot = dec.WithdrawalsRoot
}
+ if dec.DataGasUsed != nil {
+ b.DataGasUsed = (*uint64)(dec.DataGasUsed)
+ }
+ if dec.ExcessDataGas != nil {
+ b.ExcessDataGas = (*uint64)(dec.ExcessDataGas)
+ }
return nil
}
diff --git a/tests/init.go b/tests/init.go
index 869f1bfcdd67..99b7e4d33310 100644
--- a/tests/init.go
+++ b/tests/init.go
@@ -299,6 +299,44 @@ var Forks = map[string]*params.ChainConfig{
TerminalTotalDifficulty: big.NewInt(0),
ShanghaiTime: u64(15_000),
},
+ "Cancun": {
+ ChainID: big.NewInt(1),
+ HomesteadBlock: big.NewInt(0),
+ EIP150Block: big.NewInt(0),
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: big.NewInt(0),
+ MuirGlacierBlock: big.NewInt(0),
+ BerlinBlock: big.NewInt(0),
+ LondonBlock: big.NewInt(0),
+ ArrowGlacierBlock: big.NewInt(0),
+ MergeNetsplitBlock: big.NewInt(0),
+ TerminalTotalDifficulty: big.NewInt(0),
+ ShanghaiTime: u64(0),
+ CancunTime: u64(0),
+ },
+ "ShanghaiToCancunAtTime15k": {
+ ChainID: big.NewInt(1),
+ HomesteadBlock: big.NewInt(0),
+ EIP150Block: big.NewInt(0),
+ EIP155Block: big.NewInt(0),
+ EIP158Block: big.NewInt(0),
+ ByzantiumBlock: big.NewInt(0),
+ ConstantinopleBlock: big.NewInt(0),
+ PetersburgBlock: big.NewInt(0),
+ IstanbulBlock: big.NewInt(0),
+ MuirGlacierBlock: big.NewInt(0),
+ BerlinBlock: big.NewInt(0),
+ LondonBlock: big.NewInt(0),
+ ArrowGlacierBlock: big.NewInt(0),
+ MergeNetsplitBlock: big.NewInt(0),
+ TerminalTotalDifficulty: big.NewInt(0),
+ ShanghaiTime: u64(0),
+ CancunTime: u64(15_000),
+ },
}
// AvailableForks returns the set of defined fork names