core: add basic chain history support in GenerateChain (#28428)
This change improves GenerateChain to support internal chain history access (ChainReader) for the consensus engine and EVM. GenerateChain takes a `parent` block and the number of blocks to create. With my changes, the consensus engine and EVM can now access blocks from `parent` up to the block currently being generated. This is required to make the BLOCKHASH instruction work, and also needed to create real clique chains. Clique uses chain history to figure out if the current signer is in-turn, for example. I've also added some more accessors to BlockGen. These are helpful when creating transactions: - g.Signer returns a signer instance for the current block - g.Difficulty returns the current block difficulty - g.Gas returns the remaining gas amount Another fix in this commit concerns the receipts returned by GenerateChain. The receipts now have properly derived fields (BlockHash, etc.) and should generally match what would be returned by the RPC API.
This commit is contained in:
parent
447945e438
commit
bc42e88415
@ -84,7 +84,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
|
|||||||
toaddr := common.Address{}
|
toaddr := common.Address{}
|
||||||
data := make([]byte, nbytes)
|
data := make([]byte, nbytes)
|
||||||
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
|
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
|
||||||
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), gen.header.Time)
|
signer := gen.Signer()
|
||||||
gasPrice := big.NewInt(0)
|
gasPrice := big.NewInt(0)
|
||||||
if gen.header.BaseFee != nil {
|
if gen.header.BaseFee != nil {
|
||||||
gasPrice = gen.header.BaseFee
|
gasPrice = gen.header.BaseFee
|
||||||
@ -128,7 +128,7 @@ func genTxRing(naccounts int) func(int, *BlockGen) {
|
|||||||
if gen.header.BaseFee != nil {
|
if gen.header.BaseFee != nil {
|
||||||
gasPrice = gen.header.BaseFee
|
gasPrice = gen.header.BaseFee
|
||||||
}
|
}
|
||||||
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)), gen.header.Time)
|
signer := gen.Signer()
|
||||||
for {
|
for {
|
||||||
gas -= params.TxGas
|
gas -= params.TxGas
|
||||||
if gas < params.TxGas {
|
if gas < params.TxGas {
|
||||||
|
@ -38,8 +38,8 @@ import (
|
|||||||
// See GenerateChain for a detailed explanation.
|
// See GenerateChain for a detailed explanation.
|
||||||
type BlockGen struct {
|
type BlockGen struct {
|
||||||
i int
|
i int
|
||||||
|
cm *chainMaker
|
||||||
parent *types.Block
|
parent *types.Block
|
||||||
chain []*types.Block
|
|
||||||
header *types.Header
|
header *types.Header
|
||||||
statedb *state.StateDB
|
statedb *state.StateDB
|
||||||
|
|
||||||
@ -49,7 +49,6 @@ type BlockGen struct {
|
|||||||
uncles []*types.Header
|
uncles []*types.Header
|
||||||
withdrawals []*types.Withdrawal
|
withdrawals []*types.Withdrawal
|
||||||
|
|
||||||
config *params.ChainConfig
|
|
||||||
engine consensus.Engine
|
engine consensus.Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +87,18 @@ func (b *BlockGen) SetPoS() {
|
|||||||
b.header.Difficulty = new(big.Int)
|
b.header.Difficulty = new(big.Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Difficulty returns the currently calculated difficulty of the block.
|
||||||
|
func (b *BlockGen) Difficulty() *big.Int {
|
||||||
|
return new(big.Int).Set(b.header.Difficulty)
|
||||||
|
}
|
||||||
|
|
||||||
// SetParentBeaconRoot sets the parent beacon root field of the generated
|
// SetParentBeaconRoot sets the parent beacon root field of the generated
|
||||||
// block.
|
// block.
|
||||||
func (b *BlockGen) SetParentBeaconRoot(root common.Hash) {
|
func (b *BlockGen) SetParentBeaconRoot(root common.Hash) {
|
||||||
b.header.ParentBeaconRoot = &root
|
b.header.ParentBeaconRoot = &root
|
||||||
var (
|
var (
|
||||||
blockContext = NewEVMBlockContext(b.header, nil, &b.header.Coinbase)
|
blockContext = NewEVMBlockContext(b.header, b.cm, &b.header.Coinbase)
|
||||||
vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.config, vm.Config{})
|
vmenv = vm.NewEVM(blockContext, vm.TxContext{}, b.statedb, b.cm.config, vm.Config{})
|
||||||
)
|
)
|
||||||
ProcessBeaconBlockRoot(root, vmenv, b.statedb)
|
ProcessBeaconBlockRoot(root, vmenv, b.statedb)
|
||||||
}
|
}
|
||||||
@ -111,7 +115,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
|
|||||||
b.SetCoinbase(common.Address{})
|
b.SetCoinbase(common.Address{})
|
||||||
}
|
}
|
||||||
b.statedb.SetTxContext(tx.Hash(), len(b.txs))
|
b.statedb.SetTxContext(tx.Hash(), len(b.txs))
|
||||||
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig)
|
receipt, err := ApplyTransaction(b.cm.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vmConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -125,11 +129,11 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
|
|||||||
// AddTx adds a transaction to the generated block. If no coinbase has
|
// AddTx adds a transaction to the generated block. If no coinbase has
|
||||||
// been set, the block's coinbase is set to the zero address.
|
// been set, the block's coinbase is set to the zero address.
|
||||||
//
|
//
|
||||||
// AddTx panics if the transaction cannot be executed. In addition to
|
// AddTx panics if the transaction cannot be executed. In addition to the protocol-imposed
|
||||||
// the protocol-imposed limitations (gas limit, etc.), there are some
|
// limitations (gas limit, etc.), there are some further limitations on the content of
|
||||||
// further limitations on the content of transactions that can be
|
// transactions that can be added. Notably, contract code relying on the BLOCKHASH
|
||||||
// added. Notably, contract code relying on the BLOCKHASH instruction
|
// instruction will panic during execution if it attempts to access a block number outside
|
||||||
// will panic during execution.
|
// of the range created by GenerateChain.
|
||||||
func (b *BlockGen) AddTx(tx *types.Transaction) {
|
func (b *BlockGen) AddTx(tx *types.Transaction) {
|
||||||
b.addTx(nil, vm.Config{}, tx)
|
b.addTx(nil, vm.Config{}, tx)
|
||||||
}
|
}
|
||||||
@ -137,11 +141,10 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
|
|||||||
// AddTxWithChain adds a transaction to the generated block. If no coinbase has
|
// AddTxWithChain adds a transaction to the generated block. If no coinbase has
|
||||||
// been set, the block's coinbase is set to the zero address.
|
// been set, the block's coinbase is set to the zero address.
|
||||||
//
|
//
|
||||||
// AddTxWithChain panics if the transaction cannot be executed. In addition to
|
// AddTxWithChain panics if the transaction cannot be executed. In addition to the
|
||||||
// the protocol-imposed limitations (gas limit, etc.), there are some
|
// protocol-imposed limitations (gas limit, etc.), there are some further limitations on
|
||||||
// further limitations on the content of transactions that can be
|
// the content of transactions that can be added. If contract code relies on the BLOCKHASH
|
||||||
// added. If contract code relies on the BLOCKHASH instruction,
|
// instruction, the block in chain will be returned.
|
||||||
// the block in chain will be returned.
|
|
||||||
func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
|
func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
|
||||||
b.addTx(bc, vm.Config{}, tx)
|
b.addTx(bc, vm.Config{}, tx)
|
||||||
}
|
}
|
||||||
@ -158,8 +161,7 @@ func (b *BlockGen) GetBalance(addr common.Address) *big.Int {
|
|||||||
return b.statedb.GetBalance(addr)
|
return b.statedb.GetBalance(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddUncheckedTx forcefully adds a transaction to the block without any
|
// AddUncheckedTx forcefully adds a transaction to the block without any validation.
|
||||||
// validation.
|
|
||||||
//
|
//
|
||||||
// AddUncheckedTx will cause consensus failures when used during real
|
// AddUncheckedTx will cause consensus failures when used during real
|
||||||
// chain processing. This is best used in conjunction with raw block insertion.
|
// chain processing. This is best used in conjunction with raw block insertion.
|
||||||
@ -182,6 +184,16 @@ func (b *BlockGen) BaseFee() *big.Int {
|
|||||||
return new(big.Int).Set(b.header.BaseFee)
|
return new(big.Int).Set(b.header.BaseFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gas returns the amount of gas left in the current block.
|
||||||
|
func (b *BlockGen) Gas() uint64 {
|
||||||
|
return b.header.GasLimit - b.header.GasUsed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signer returns a valid signer instance for the current block.
|
||||||
|
func (b *BlockGen) Signer() types.Signer {
|
||||||
|
return types.MakeSigner(b.cm.config, b.header.Number, b.header.Time)
|
||||||
|
}
|
||||||
|
|
||||||
// AddUncheckedReceipt forcefully adds a receipts to the block without a
|
// AddUncheckedReceipt forcefully adds a receipts to the block without a
|
||||||
// backing transaction.
|
// backing transaction.
|
||||||
//
|
//
|
||||||
@ -207,20 +219,19 @@ func (b *BlockGen) AddUncle(h *types.Header) {
|
|||||||
|
|
||||||
var parent *types.Header
|
var parent *types.Header
|
||||||
for i := b.i - 1; i >= 0; i-- {
|
for i := b.i - 1; i >= 0; i-- {
|
||||||
if b.chain[i].Hash() == h.ParentHash {
|
if b.cm.chain[i].Hash() == h.ParentHash {
|
||||||
parent = b.chain[i].Header()
|
parent = b.cm.chain[i].Header()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chainreader := &fakeChainReader{config: b.config}
|
h.Difficulty = b.engine.CalcDifficulty(b.cm, b.header.Time, parent)
|
||||||
h.Difficulty = b.engine.CalcDifficulty(chainreader, b.header.Time, parent)
|
|
||||||
|
|
||||||
// The gas limit and price should be derived from the parent
|
// The gas limit and price should be derived from the parent
|
||||||
h.GasLimit = parent.GasLimit
|
h.GasLimit = parent.GasLimit
|
||||||
if b.config.IsLondon(h.Number) {
|
if b.cm.config.IsLondon(h.Number) {
|
||||||
h.BaseFee = eip1559.CalcBaseFee(b.config, parent)
|
h.BaseFee = eip1559.CalcBaseFee(b.cm.config, parent)
|
||||||
if !b.config.IsLondon(parent.Number) {
|
if !b.cm.config.IsLondon(parent.Number) {
|
||||||
parentGasLimit := parent.GasLimit * b.config.ElasticityMultiplier()
|
parentGasLimit := parent.GasLimit * b.cm.config.ElasticityMultiplier()
|
||||||
h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
|
h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,12 +253,12 @@ func (b *BlockGen) nextWithdrawalIndex() uint64 {
|
|||||||
return b.withdrawals[len(b.withdrawals)-1].Index + 1
|
return b.withdrawals[len(b.withdrawals)-1].Index + 1
|
||||||
}
|
}
|
||||||
for i := b.i - 1; i >= 0; i-- {
|
for i := b.i - 1; i >= 0; i-- {
|
||||||
if wd := b.chain[i].Withdrawals(); len(wd) != 0 {
|
if wd := b.cm.chain[i].Withdrawals(); len(wd) != 0 {
|
||||||
return wd[len(wd)-1].Index + 1
|
return wd[len(wd)-1].Index + 1
|
||||||
}
|
}
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
// Correctly set the index if no parent had withdrawals.
|
// Correctly set the index if no parent had withdrawals.
|
||||||
if wd := b.parent.Withdrawals(); len(wd) != 0 {
|
if wd := b.cm.bottom.Withdrawals(); len(wd) != 0 {
|
||||||
return wd[len(wd)-1].Index + 1
|
return wd[len(wd)-1].Index + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,9 +274,9 @@ func (b *BlockGen) PrevBlock(index int) *types.Block {
|
|||||||
panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i))
|
panic(fmt.Errorf("block index %d out of range (%d,%d)", index, -1, b.i))
|
||||||
}
|
}
|
||||||
if index == -1 {
|
if index == -1 {
|
||||||
return b.parent
|
return b.cm.bottom
|
||||||
}
|
}
|
||||||
return b.chain[index]
|
return b.cm.chain[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
// OffsetTime modifies the time instance of a block, implicitly changing its
|
// OffsetTime modifies the time instance of a block, implicitly changing its
|
||||||
@ -273,11 +284,10 @@ func (b *BlockGen) PrevBlock(index int) *types.Block {
|
|||||||
// tied to chain length directly.
|
// tied to chain length directly.
|
||||||
func (b *BlockGen) OffsetTime(seconds int64) {
|
func (b *BlockGen) OffsetTime(seconds int64) {
|
||||||
b.header.Time += uint64(seconds)
|
b.header.Time += uint64(seconds)
|
||||||
if b.header.Time <= b.parent.Header().Time {
|
if b.header.Time <= b.cm.bottom.Header().Time {
|
||||||
panic("block time out of range")
|
panic("block time out of range")
|
||||||
}
|
}
|
||||||
chainreader := &fakeChainReader{config: b.config}
|
b.header.Difficulty = b.engine.CalcDifficulty(b.cm, b.header.Time, b.parent.Header())
|
||||||
b.header.Difficulty = b.engine.CalcDifficulty(chainreader, b.header.Time, b.parent.Header())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateChain creates a chain of n blocks. The first block's
|
// GenerateChain creates a chain of n blocks. The first block's
|
||||||
@ -296,11 +306,14 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||||||
if config == nil {
|
if config == nil {
|
||||||
config = params.TestChainConfig
|
config = params.TestChainConfig
|
||||||
}
|
}
|
||||||
blocks, receipts := make(types.Blocks, n), make([]types.Receipts, n)
|
if engine == nil {
|
||||||
chainreader := &fakeChainReader{config: config}
|
panic("nil consensus engine")
|
||||||
|
}
|
||||||
|
cm := newChainMaker(parent, config, engine)
|
||||||
|
|
||||||
genblock := func(i int, parent *types.Block, triedb *trie.Database, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
genblock := func(i int, parent *types.Block, triedb *trie.Database, statedb *state.StateDB) (*types.Block, types.Receipts) {
|
||||||
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
|
b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine}
|
||||||
b.header = makeHeader(chainreader, parent, statedb, b.engine)
|
b.header = cm.makeHeader(parent, statedb, b.engine)
|
||||||
|
|
||||||
// Set the difficulty for clique block. The chain maker doesn't have access
|
// Set the difficulty for clique block. The chain maker doesn't have access
|
||||||
// to a chain, so the difficulty will be left unset (nil). Set it here to the
|
// to a chain, so the difficulty will be left unset (nil). Set it here to the
|
||||||
@ -330,8 +343,8 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||||||
if gen != nil {
|
if gen != nil {
|
||||||
gen(i, b)
|
gen(i, b)
|
||||||
}
|
}
|
||||||
if b.engine != nil {
|
|
||||||
block, err := b.engine.FinalizeAndAssemble(chainreader, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals)
|
block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, b.txs, b.uncles, b.receipts, b.withdrawals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -346,8 +359,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||||||
}
|
}
|
||||||
return block, b.receipts
|
return block, b.receipts
|
||||||
}
|
}
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
// Forcibly use hash-based state scheme for retaining all nodes in disk.
|
// Forcibly use hash-based state scheme for retaining all nodes in disk.
|
||||||
triedb := trie.NewDatabase(db, trie.HashDefaults)
|
triedb := trie.NewDatabase(db, trie.HashDefaults)
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
@ -357,12 +369,36 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
block, receipt := genblock(i, parent, triedb, statedb)
|
block, receipts := genblock(i, parent, triedb, statedb)
|
||||||
blocks[i] = block
|
|
||||||
receipts[i] = receipt
|
// Post-process the receipts.
|
||||||
|
// Here we assign the final block hash and other info into the receipt.
|
||||||
|
// In order for DeriveFields to work, the transaction and receipt lists need to be
|
||||||
|
// of equal length. If AddUncheckedTx or AddUncheckedReceipt are used, there will be
|
||||||
|
// extra ones, so we just trim the lists here.
|
||||||
|
receiptsCount := len(receipts)
|
||||||
|
txs := block.Transactions()
|
||||||
|
if len(receipts) > len(txs) {
|
||||||
|
receipts = receipts[:len(txs)]
|
||||||
|
} else if len(receipts) < len(txs) {
|
||||||
|
txs = txs[:len(receipts)]
|
||||||
|
}
|
||||||
|
var blobGasPrice *big.Int
|
||||||
|
if block.ExcessBlobGas() != nil {
|
||||||
|
blobGasPrice = eip4844.CalcBlobFee(*block.ExcessBlobGas())
|
||||||
|
}
|
||||||
|
if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-expand to ensure all receipts are returned.
|
||||||
|
receipts = receipts[:receiptsCount]
|
||||||
|
|
||||||
|
// Advance the chain.
|
||||||
|
cm.add(block, receipts)
|
||||||
parent = block
|
parent = block
|
||||||
}
|
}
|
||||||
return blocks, receipts
|
return cm.chain, cm.receipts
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateChainWithGenesis is a wrapper of GenerateChain which will initialize
|
// GenerateChainWithGenesis is a wrapper of GenerateChain which will initialize
|
||||||
@ -380,35 +416,26 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int,
|
|||||||
return db, blocks, receipts
|
return db, blocks, receipts
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
|
func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
|
||||||
var time uint64
|
time := parent.Time() + 10 // block time is fixed at 10 seconds
|
||||||
if parent.Time() == 0 {
|
|
||||||
time = 10
|
|
||||||
} else {
|
|
||||||
time = parent.Time() + 10 // block time is fixed at 10 seconds
|
|
||||||
}
|
|
||||||
header := &types.Header{
|
header := &types.Header{
|
||||||
Root: state.IntermediateRoot(chain.Config().IsEIP158(parent.Number())),
|
Root: state.IntermediateRoot(cm.config.IsEIP158(parent.Number())),
|
||||||
ParentHash: parent.Hash(),
|
ParentHash: parent.Hash(),
|
||||||
Coinbase: parent.Coinbase(),
|
Coinbase: parent.Coinbase(),
|
||||||
Difficulty: engine.CalcDifficulty(chain, time, &types.Header{
|
Difficulty: engine.CalcDifficulty(cm, time, parent.Header()),
|
||||||
Number: parent.Number(),
|
|
||||||
Time: time - 10,
|
|
||||||
Difficulty: parent.Difficulty(),
|
|
||||||
UncleHash: parent.UncleHash(),
|
|
||||||
}),
|
|
||||||
GasLimit: parent.GasLimit(),
|
GasLimit: parent.GasLimit(),
|
||||||
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
||||||
Time: time,
|
Time: time,
|
||||||
}
|
}
|
||||||
if chain.Config().IsLondon(header.Number) {
|
|
||||||
header.BaseFee = eip1559.CalcBaseFee(chain.Config(), parent.Header())
|
if cm.config.IsLondon(header.Number) {
|
||||||
if !chain.Config().IsLondon(parent.Number()) {
|
header.BaseFee = eip1559.CalcBaseFee(cm.config, parent.Header())
|
||||||
parentGasLimit := parent.GasLimit() * chain.Config().ElasticityMultiplier()
|
if !cm.config.IsLondon(parent.Number()) {
|
||||||
|
parentGasLimit := parent.GasLimit() * cm.config.ElasticityMultiplier()
|
||||||
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
|
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if chain.Config().IsCancun(header.Number, header.Time) {
|
if cm.config.IsCancun(header.Number, header.Time) {
|
||||||
var (
|
var (
|
||||||
parentExcessBlobGas uint64
|
parentExcessBlobGas uint64
|
||||||
parentBlobGasUsed uint64
|
parentBlobGasUsed uint64
|
||||||
@ -461,18 +488,86 @@ func makeBlockChainWithGenesis(genesis *Genesis, n int, engine consensus.Engine,
|
|||||||
return db, blocks
|
return db, blocks
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeChainReader struct {
|
// chainMaker contains the state of chain generation.
|
||||||
|
type chainMaker struct {
|
||||||
|
bottom *types.Block
|
||||||
|
engine consensus.Engine
|
||||||
config *params.ChainConfig
|
config *params.ChainConfig
|
||||||
|
chain []*types.Block
|
||||||
|
chainByHash map[common.Hash]*types.Block
|
||||||
|
receipts []types.Receipts
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config returns the chain configuration.
|
func newChainMaker(bottom *types.Block, config *params.ChainConfig, engine consensus.Engine) *chainMaker {
|
||||||
func (cr *fakeChainReader) Config() *params.ChainConfig {
|
return &chainMaker{
|
||||||
return cr.config
|
bottom: bottom,
|
||||||
|
config: config,
|
||||||
|
engine: engine,
|
||||||
|
chainByHash: make(map[common.Hash]*types.Block),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *fakeChainReader) CurrentHeader() *types.Header { return nil }
|
func (cm *chainMaker) add(b *types.Block, r []*types.Receipt) {
|
||||||
func (cr *fakeChainReader) GetHeaderByNumber(number uint64) *types.Header { return nil }
|
cm.chain = append(cm.chain, b)
|
||||||
func (cr *fakeChainReader) GetHeaderByHash(hash common.Hash) *types.Header { return nil }
|
cm.chainByHash[b.Hash()] = b
|
||||||
func (cr *fakeChainReader) GetHeader(hash common.Hash, number uint64) *types.Header { return nil }
|
cm.receipts = append(cm.receipts, r)
|
||||||
func (cr *fakeChainReader) GetBlock(hash common.Hash, number uint64) *types.Block { return nil }
|
}
|
||||||
func (cr *fakeChainReader) GetTd(hash common.Hash, number uint64) *big.Int { return nil }
|
|
||||||
|
func (cm *chainMaker) blockByNumber(number uint64) *types.Block {
|
||||||
|
if number == cm.bottom.NumberU64() {
|
||||||
|
return cm.bottom
|
||||||
|
}
|
||||||
|
cur := cm.CurrentHeader().Number.Uint64()
|
||||||
|
lowest := cm.bottom.NumberU64() + 1
|
||||||
|
if number < lowest || number > cur {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return cm.chain[number-lowest]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainReader/ChainContext implementation
|
||||||
|
|
||||||
|
// Config returns the chain configuration (for consensus.ChainReader).
|
||||||
|
func (cm *chainMaker) Config() *params.ChainConfig {
|
||||||
|
return cm.config
|
||||||
|
}
|
||||||
|
|
||||||
|
// Engine returns the consensus engine (for ChainContext).
|
||||||
|
func (cm *chainMaker) Engine() consensus.Engine {
|
||||||
|
return cm.engine
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *chainMaker) CurrentHeader() *types.Header {
|
||||||
|
if len(cm.chain) == 0 {
|
||||||
|
return cm.bottom.Header()
|
||||||
|
}
|
||||||
|
return cm.chain[len(cm.chain)-1].Header()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *chainMaker) GetHeaderByNumber(number uint64) *types.Header {
|
||||||
|
b := cm.blockByNumber(number)
|
||||||
|
if b == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return b.Header()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *chainMaker) GetHeaderByHash(hash common.Hash) *types.Header {
|
||||||
|
b := cm.chainByHash[hash]
|
||||||
|
if b == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return b.Header()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *chainMaker) GetHeader(hash common.Hash, number uint64) *types.Header {
|
||||||
|
return cm.GetHeaderByNumber(number)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *chainMaker) GetBlock(hash common.Hash, number uint64) *types.Block {
|
||||||
|
return cm.blockByNumber(number)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cm *chainMaker) GetTd(hash common.Hash, number uint64) *big.Int {
|
||||||
|
return nil // not supported
|
||||||
|
}
|
||||||
|
@ -19,8 +19,10 @@ package core
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus/beacon"
|
"github.com/ethereum/go-ethereum/consensus/beacon"
|
||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
@ -53,7 +55,6 @@ func TestGeneratePOSChain(t *testing.T) {
|
|||||||
GasLimit: 5_000_000,
|
GasLimit: 5_000_000,
|
||||||
}
|
}
|
||||||
gendb = rawdb.NewMemoryDatabase()
|
gendb = rawdb.NewMemoryDatabase()
|
||||||
signer = types.LatestSigner(gspec.Config)
|
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -82,10 +83,20 @@ func TestGeneratePOSChain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
genesis := gspec.MustCommit(gendb, trie.NewDatabase(gendb, trie.HashDefaults))
|
genesis := gspec.MustCommit(gendb, trie.NewDatabase(gendb, trie.HashDefaults))
|
||||||
|
|
||||||
chain, _ := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), gendb, 4, func(i int, gen *BlockGen) {
|
genchain, genreceipts := GenerateChain(gspec.Config, genesis, beacon.NewFaker(), gendb, 4, func(i int, gen *BlockGen) {
|
||||||
gen.SetParentBeaconRoot(common.Hash{byte(i + 1)})
|
gen.SetParentBeaconRoot(common.Hash{byte(i + 1)})
|
||||||
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(address), address, big.NewInt(1000), params.TxGas, new(big.Int).Add(gen.BaseFee(), common.Big1), nil), signer, key)
|
|
||||||
|
// Add value transfer tx.
|
||||||
|
tx := types.MustSignNewTx(key, gen.Signer(), &types.LegacyTx{
|
||||||
|
Nonce: gen.TxNonce(address),
|
||||||
|
To: &address,
|
||||||
|
Value: big.NewInt(1000),
|
||||||
|
Gas: params.TxGas,
|
||||||
|
GasPrice: new(big.Int).Add(gen.BaseFee(), common.Big1),
|
||||||
|
})
|
||||||
gen.AddTx(tx)
|
gen.AddTx(tx)
|
||||||
|
|
||||||
|
// Add withdrawals.
|
||||||
if i == 1 {
|
if i == 1 {
|
||||||
gen.AddWithdrawal(&types.Withdrawal{
|
gen.AddWithdrawal(&types.Withdrawal{
|
||||||
Validator: 42,
|
Validator: 42,
|
||||||
@ -116,20 +127,39 @@ func TestGeneratePOSChain(t *testing.T) {
|
|||||||
blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil, nil)
|
blockchain, _ := NewBlockChain(db, nil, gspec, nil, beacon.NewFaker(), vm.Config{}, nil, nil)
|
||||||
defer blockchain.Stop()
|
defer blockchain.Stop()
|
||||||
|
|
||||||
if i, err := blockchain.InsertChain(chain); err != nil {
|
if i, err := blockchain.InsertChain(genchain); err != nil {
|
||||||
fmt.Printf("insert error (block %d): %v\n", chain[i].NumberU64(), err)
|
t.Fatalf("insert error (block %d): %v\n", genchain[i].NumberU64(), err)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// enforce that withdrawal indexes are monotonically increasing from 0
|
// enforce that withdrawal indexes are monotonically increasing from 0
|
||||||
var (
|
var (
|
||||||
withdrawalIndex uint64
|
withdrawalIndex uint64
|
||||||
head = blockchain.CurrentBlock().Number.Uint64()
|
|
||||||
)
|
)
|
||||||
for i := 0; i < int(head); i++ {
|
for i := range genchain {
|
||||||
block := blockchain.GetBlockByNumber(uint64(i))
|
blocknum := genchain[i].NumberU64()
|
||||||
|
block := blockchain.GetBlockByNumber(blocknum)
|
||||||
if block == nil {
|
if block == nil {
|
||||||
t.Fatalf("block %d not found", i)
|
t.Fatalf("block %d not found", blocknum)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify receipts.
|
||||||
|
genBlockReceipts := genreceipts[i]
|
||||||
|
for _, r := range genBlockReceipts {
|
||||||
|
if r.BlockNumber.Cmp(block.Number()) != 0 {
|
||||||
|
t.Errorf("receipt has wrong block number %d, want %d", r.BlockNumber, block.Number())
|
||||||
|
}
|
||||||
|
if r.BlockHash != block.Hash() {
|
||||||
|
t.Errorf("receipt has wrong block hash %v, want %v", r.BlockHash, block.Hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
// patch up empty logs list to make DeepEqual below work
|
||||||
|
if r.Logs == nil {
|
||||||
|
r.Logs = []*types.Log{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blockchainReceipts := blockchain.GetReceiptsByHash(block.Hash())
|
||||||
|
if !reflect.DeepEqual(genBlockReceipts, blockchainReceipts) {
|
||||||
|
t.Fatalf("receipts mismatch\ngenerated: %s\nblockchain: %s", spew.Sdump(genBlockReceipts), spew.Sdump(blockchainReceipts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify withdrawals.
|
// Verify withdrawals.
|
||||||
@ -144,7 +174,7 @@ func TestGeneratePOSChain(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify parent beacon root.
|
// Verify parent beacon root.
|
||||||
want := common.Hash{byte(i)}
|
want := common.Hash{byte(blocknum)}
|
||||||
if got := block.BeaconRoot(); *got != want {
|
if got := block.BeaconRoot(); *got != want {
|
||||||
t.Fatalf("block %d, wrong parent beacon root: got %s, want %s", i, got, want)
|
t.Fatalf("block %d, wrong parent beacon root: got %s, want %s", i, got, want)
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,8 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||||||
}
|
}
|
||||||
// Create a new context to be used in the EVM environment
|
// Create a new context to be used in the EVM environment
|
||||||
blockContext := NewEVMBlockContext(header, bc, author)
|
blockContext := NewEVMBlockContext(header, bc, author)
|
||||||
vmenv := vm.NewEVM(blockContext, vm.TxContext{BlobHashes: tx.BlobHashes()}, statedb, config, cfg)
|
txContext := NewEVMTxContext(msg)
|
||||||
|
vmenv := vm.NewEVM(blockContext, txContext, statedb, config, cfg)
|
||||||
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
|
return applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx, usedGas, vmenv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +359,8 @@ func TestStateProcessorErrors(t *testing.T) {
|
|||||||
func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block {
|
func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block {
|
||||||
difficulty := big.NewInt(0)
|
difficulty := big.NewInt(0)
|
||||||
if !config.TerminalTotalDifficultyPassed {
|
if !config.TerminalTotalDifficultyPassed {
|
||||||
difficulty = engine.CalcDifficulty(&fakeChainReader{config}, parent.Time()+10, &types.Header{
|
fakeChainReader := newChainMaker(nil, config, engine)
|
||||||
|
difficulty = engine.CalcDifficulty(fakeChainReader, parent.Time()+10, &types.Header{
|
||||||
Number: parent.Number(),
|
Number: parent.Number(),
|
||||||
Time: parent.Time(),
|
Time: parent.Time(),
|
||||||
Difficulty: parent.Difficulty(),
|
Difficulty: parent.Difficulty(),
|
||||||
|
@ -287,53 +287,71 @@ func TestFilters(t *testing.T) {
|
|||||||
{
|
{
|
||||||
f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil),
|
f: sys.NewBlockFilter(chain[2].Hash(), []common.Address{contract}, nil),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}),
|
f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}),
|
f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}),
|
||||||
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}),
|
f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}),
|
f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
|
f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
||||||
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
|
||||||
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil),
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
||||||
err: "safe header not found",
|
err: "safe header not found",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
|
||||||
err: "safe header not found",
|
err: "safe header not found",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil),
|
||||||
err: "safe header not found",
|
err: "safe header not found",
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xc7245899e5817f16fa99cf5ad2d9c1e4b98443a565a673ec9c764640443ef037","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil),
|
||||||
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xc7245899e5817f16fa99cf5ad2d9c1e4b98443a565a673ec9c764640443ef037","logIndex":"0x0","removed":false}]`,
|
want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696335"],"data":"0x","blockNumber":"0x3e9","transactionHash":"0x4110587c1b8d86edc85dce929a34127f1cb8809515a9f177c91c866de3eb0638","transactionIndex":"0x0","blockHash":"0xd5e8d4e4eb51a2a2a6ec20ef68a4c2801240743c8deb77a6a1d118ac3eefb725","logIndex":"0x0","removed":false}]`,
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil),
|
||||||
err: "invalid block range",
|
err: "invalid block range",
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user