38db9bf4e2
* ci: temp enable blobtx branch ci run; * Switch ON blobpool & ensure Cancun hardfork can occur (#2223) * feat: support blob storage & miscs; (#2229) * chainconfig: use cancun fork for BSC; * feat: fill WithdrawalsHash when BSC enable cancun fork; * rawdb: support to CRUD blobs; * freezer: support to freeze block blobs; * blockchain: add blob cache & blob query helper; * freezer: refactor addition table logic, add uts; * blobexpiry: add more extra expiry time, and logs; * parlia: implement IsDataAvailable function; * blob: refactor blob transfer logic; * blob: support config blob extra reserve; * blockchian: support to import block with blob & blobGasFee; (#2260) * blob: implement min&max gas price logic; * blockchian: support import side chain; * blobpool: reject the banned address; * blockchain: add chasing head for DA check; * params: update blob related config; * blockchain: opt data available checking performance; * params: modify blob related params; * gasprice: support BEP-336 blob gas price calculate; * blobTx: mining + brodcasting (#2253) * blobtx mining pass (#2282) * Sidecar fetching changes for 4844 (#2283) * ci: temp enable blobtx branch ci run; * Switch ON blobpool & ensure Cancun hardfork can occur (#2223) * feat: support blob storage & miscs; (#2229) * chainconfig: use cancun fork for BSC; feat: fill WithdrawalsHash when BSC enable cancun fork; * rawdb: support to CRUD blobs; * freezer: support to freeze block blobs; * blockchain: add blob cache & blob query helper; * freezer: refactor addition table logic, add uts; * blobexpiry: add more extra expiry time, and logs; * parlia: implement IsDataAvailable function; * blob: refactor blob transfer logic; * blob: support config blob extra reserve; * blockchian: support to import block with blob & blobGasFee; (#2260) * blob: implement min&max gas price logic; * blockchian: support import side chain; * blobpool: reject the banned address; * blockchain: add chasing head for DA check; * params: update blob related config; * blockchain: opt data available checking performance; * params: modify blob related params; * gasprice: support BEP-336 blob gas price calculate; * fix failed check for WithdrawalsHash (#2276) * eth: include sidecars in fitering of body * core: refactor sidecars name * eth: sidecars type refactor * core: remove extra from bad merge * eth: fix handlenewblock test after merge * Implement eth_getBlobSidecars && eth_getBlobSidecarByTxHash (#2286) * execution: add blob gas fee reward to system; * syncing: support blob syncing & DA checking; * naming: rename blobs to sidecars; * fix the semantics of WithXXX (#2293) * config: reduce sidecar cache to 1024 and rename (#2297) * fix: Withdrawals turn into empty from nil when BlockBody has Sidecars (#2301) * internal/api_test: add test case for eth_getBlobSidecars && eth_getBlobSidecarByTxHash (#2300) * consensus/misc: rollback CalcBlobFee (#2306) * flags: add new flags to override blobs' params; * freezer: fix blob ancient save error; * blobsidecar: add new sidecar struct with metadata; (#2315) * core/rawdb: optimize write block with sidecars (#2318) * core: more check for validity of sidecars * mev: add TxIndex for mev bid (#2325) * remove useless Config() (#2326) * fix WithSidecars (#2327) * fix: fix mined block sidecar issue; (#2328) * fix WithSidecars (#2329) --------- Co-authored-by: GalaIO <GalaIO@users.noreply.github.com> Co-authored-by: buddho <galaxystroller@gmail.com> Co-authored-by: Satyajit Das <emailtovamos@gmail.com> Co-authored-by: Eric <45141191+zlacfzy@users.noreply.github.com> Co-authored-by: zzzckck <152148891+zzzckck@users.noreply.github.com>
351 lines
10 KiB
Go
351 lines
10 KiB
Go
package core
|
|
|
|
import (
|
|
"math/big"
|
|
"testing"
|
|
|
|
"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/params"
|
|
"github.com/holiman/uint256"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var (
|
|
emptyBlob = kzg4844.Blob{}
|
|
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
|
|
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
|
|
)
|
|
|
|
func TestIsDataAvailable(t *testing.T) {
|
|
hr := NewMockDAHeaderReader(params.ParliaTestChainConfig)
|
|
tests := []struct {
|
|
block *types.Block
|
|
chasingHead uint64
|
|
withSidecar bool
|
|
err bool
|
|
}{
|
|
{
|
|
block: types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
chasingHead: 1,
|
|
withSidecar: true,
|
|
err: false,
|
|
},
|
|
{
|
|
block: types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), nil),
|
|
}, nil),
|
|
chasingHead: 1,
|
|
withSidecar: true,
|
|
err: false,
|
|
},
|
|
{
|
|
block: types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
chasingHead: 1,
|
|
withSidecar: false,
|
|
err: true,
|
|
},
|
|
{
|
|
block: types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
chasingHead: 1,
|
|
withSidecar: true,
|
|
err: false,
|
|
},
|
|
|
|
{
|
|
block: types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob, emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit, emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof, emptyBlobProof, emptyBlobProof},
|
|
}),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob, emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit, emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof, emptyBlobProof, emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
chasingHead: params.MinBlocksForBlobRequests + 1,
|
|
withSidecar: true,
|
|
err: true,
|
|
},
|
|
{
|
|
block: types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(0),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
chasingHead: params.MinBlocksForBlobRequests + 1,
|
|
withSidecar: false,
|
|
err: true,
|
|
},
|
|
}
|
|
|
|
for i, item := range tests {
|
|
if item.withSidecar {
|
|
item.block = item.block.WithSidecars(collectBlobsFromTxs(item.block.Header(), item.block.Transactions()))
|
|
}
|
|
hr.setChasingHead(item.chasingHead)
|
|
err := IsDataAvailable(hr, item.block)
|
|
if item.err {
|
|
require.Error(t, err, i)
|
|
t.Log(err)
|
|
continue
|
|
}
|
|
require.NoError(t, err, i)
|
|
}
|
|
}
|
|
|
|
func TestCheckDataAvailableInBatch(t *testing.T) {
|
|
hr := NewMockDAHeaderReader(params.ParliaTestChainConfig)
|
|
tests := []struct {
|
|
chain types.Blocks
|
|
err bool
|
|
index int
|
|
}{
|
|
{
|
|
chain: types.Blocks{
|
|
types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(2),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
},
|
|
err: false,
|
|
},
|
|
{
|
|
chain: types.Blocks{
|
|
types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(2),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(3),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
},
|
|
err: true,
|
|
index: 1,
|
|
},
|
|
{
|
|
chain: types.Blocks{
|
|
types.NewBlockWithHeader(&types.Header{
|
|
Number: big.NewInt(1),
|
|
}).WithBody(types.Transactions{
|
|
createMockDATx(hr.Config(), nil),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob, emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit, emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof, emptyBlobProof, emptyBlobProof},
|
|
}),
|
|
createMockDATx(hr.Config(), &types.BlobTxSidecar{
|
|
Blobs: []kzg4844.Blob{emptyBlob, emptyBlob, emptyBlob, emptyBlob},
|
|
Commitments: []kzg4844.Commitment{emptyBlobCommit, emptyBlobCommit, emptyBlobCommit, emptyBlobCommit},
|
|
Proofs: []kzg4844.Proof{emptyBlobProof, emptyBlobProof, emptyBlobProof, emptyBlobProof},
|
|
}),
|
|
}, nil),
|
|
},
|
|
err: true,
|
|
index: 0,
|
|
},
|
|
}
|
|
|
|
for i, item := range tests {
|
|
for j, block := range item.chain {
|
|
item.chain[j] = block.WithSidecars(collectBlobsFromTxs(block.Header(), block.Transactions()))
|
|
}
|
|
index, err := CheckDataAvailableInBatch(hr, item.chain)
|
|
if item.err {
|
|
t.Log(index, err)
|
|
require.Error(t, err, i)
|
|
require.Equal(t, item.index, index, i)
|
|
continue
|
|
}
|
|
require.NoError(t, err, i)
|
|
}
|
|
}
|
|
|
|
func collectBlobsFromTxs(header *types.Header, txs types.Transactions) types.BlobSidecars {
|
|
sidecars := make(types.BlobSidecars, 0, len(txs))
|
|
for i, tx := range txs {
|
|
sidecar := types.NewBlobSidecarFromTx(tx)
|
|
if sidecar == nil {
|
|
continue
|
|
}
|
|
sidecar.TxIndex = uint64(i)
|
|
sidecar.TxHash = tx.Hash()
|
|
sidecar.BlockNumber = header.Number
|
|
sidecar.BlockHash = header.Hash()
|
|
sidecars = append(sidecars, sidecar)
|
|
}
|
|
return sidecars
|
|
}
|
|
|
|
type mockDAHeaderReader struct {
|
|
config *params.ChainConfig
|
|
chasingHead uint64
|
|
}
|
|
|
|
func NewMockDAHeaderReader(config *params.ChainConfig) *mockDAHeaderReader {
|
|
return &mockDAHeaderReader{
|
|
config: config,
|
|
chasingHead: 0,
|
|
}
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) setChasingHead(h uint64) {
|
|
r.chasingHead = h
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) Config() *params.ChainConfig {
|
|
return r.config
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) CurrentHeader() *types.Header {
|
|
return &types.Header{
|
|
Number: new(big.Int).SetUint64(r.chasingHead),
|
|
}
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) ChasingHead() *types.Header {
|
|
return &types.Header{
|
|
Number: new(big.Int).SetUint64(r.chasingHead),
|
|
}
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) GenesisHeader() *types.Header {
|
|
panic("not supported")
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) GetHeader(hash common.Hash, number uint64) *types.Header {
|
|
panic("not supported")
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) GetHeaderByNumber(number uint64) *types.Header {
|
|
panic("not supported")
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) GetHeaderByHash(hash common.Hash) *types.Header {
|
|
panic("not supported")
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) GetTd(hash common.Hash, number uint64) *big.Int {
|
|
panic("not supported")
|
|
}
|
|
|
|
func (r *mockDAHeaderReader) GetHighestVerifiedHeader() *types.Header {
|
|
panic("not supported")
|
|
}
|
|
|
|
func createMockDATx(config *params.ChainConfig, sidecar *types.BlobTxSidecar) *types.Transaction {
|
|
if sidecar == nil {
|
|
tx := &types.DynamicFeeTx{
|
|
ChainID: config.ChainID,
|
|
Nonce: 0,
|
|
GasTipCap: big.NewInt(22),
|
|
GasFeeCap: big.NewInt(5),
|
|
Gas: 25000,
|
|
To: &common.Address{0x03, 0x04, 0x05},
|
|
Value: big.NewInt(99),
|
|
Data: make([]byte, 50),
|
|
}
|
|
return types.NewTx(tx)
|
|
}
|
|
tx := &types.BlobTx{
|
|
ChainID: uint256.MustFromBig(config.ChainID),
|
|
Nonce: 5,
|
|
GasTipCap: uint256.NewInt(22),
|
|
GasFeeCap: uint256.NewInt(5),
|
|
Gas: 25000,
|
|
To: common.Address{0x03, 0x04, 0x05},
|
|
Value: uint256.NewInt(99),
|
|
Data: make([]byte, 50),
|
|
BlobFeeCap: uint256.NewInt(15),
|
|
BlobHashes: sidecar.BlobHashes(),
|
|
Sidecar: sidecar,
|
|
}
|
|
return types.NewTx(tx)
|
|
}
|