mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
core: add TestReorgSideEvent test and side chain event subscription back
This commit is contained in:
parent
a6c89c1cff
commit
253faa5bc1
2 changed files with 93 additions and 0 deletions
|
|
@ -484,6 +484,11 @@ func (bc *BlockChain) SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Su
|
||||||
return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
|
return bc.scope.Track(bc.chainHeadFeed.Subscribe(ch))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubscribeChainSideEvent registers a subscription of ChainSideEvent.
|
||||||
|
func (bc *BlockChain) SubscribeChainSideEvent(ch chan<- ChainSideEvent) event.Subscription {
|
||||||
|
return bc.scope.Track(bc.chainSideFeed.Subscribe(ch))
|
||||||
|
}
|
||||||
|
|
||||||
// SubscribeLogsEvent registers a subscription of []*types.Log.
|
// SubscribeLogsEvent registers a subscription of []*types.Log.
|
||||||
func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
|
func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
|
||||||
return bc.scope.Track(bc.logsFeed.Subscribe(ch))
|
return bc.scope.Track(bc.logsFeed.Subscribe(ch))
|
||||||
|
|
|
||||||
|
|
@ -1512,6 +1512,94 @@ func checkLogEvents(t *testing.T, logsCh <-chan []*types.Log, rmLogsCh <-chan Re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReorgSideEvent(t *testing.T) {
|
||||||
|
testReorgSideEvent(t, rawdb.HashScheme)
|
||||||
|
testReorgSideEvent(t, rawdb.PathScheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testReorgSideEvent(t *testing.T, scheme string) {
|
||||||
|
var (
|
||||||
|
key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||||
|
addr1 = crypto.PubkeyToAddress(key1.PublicKey)
|
||||||
|
gspec = &Genesis{
|
||||||
|
Config: params.TestChainConfig,
|
||||||
|
Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(10000000000000000)}},
|
||||||
|
}
|
||||||
|
signer = types.LatestSigner(gspec.Config)
|
||||||
|
)
|
||||||
|
blockchain, _ := NewBlockChain(rawdb.NewMemoryDatabase(), DefaultCacheConfigWithScheme(scheme), gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
|
||||||
|
defer blockchain.Stop()
|
||||||
|
|
||||||
|
_, chain, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 3, func(i int, gen *BlockGen) {})
|
||||||
|
if _, err := blockchain.InsertChain(chain); err != nil {
|
||||||
|
t.Fatalf("failed to insert chain: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, replacementBlocks, _ := GenerateChainWithGenesis(gspec, ethash.NewFaker(), 4, func(i int, gen *BlockGen) {
|
||||||
|
tx, err := types.SignTx(types.NewContractCreation(gen.TxNonce(addr1), new(big.Int), 1000000, gen.header.BaseFee, nil), signer, key1)
|
||||||
|
|
||||||
|
if i == 2 {
|
||||||
|
gen.OffsetTime(-9)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create tx: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
gen.AddTx(tx)
|
||||||
|
})
|
||||||
|
chainSideCh := make(chan ChainSideEvent, 64)
|
||||||
|
blockchain.SubscribeChainSideEvent(chainSideCh)
|
||||||
|
|
||||||
|
if _, err := blockchain.InsertChain(replacementBlocks); err != nil {
|
||||||
|
t.Fatalf("failed to insert chain: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// first two block of the secondary chain are for a brief moment considered
|
||||||
|
// side chains because up to that point the first one is considered the
|
||||||
|
// heavier chain.
|
||||||
|
expectedSideHashes := map[common.Hash]bool{
|
||||||
|
replacementBlocks[0].Hash(): true,
|
||||||
|
replacementBlocks[1].Hash(): true,
|
||||||
|
chain[0].Hash(): true,
|
||||||
|
chain[1].Hash(): true,
|
||||||
|
chain[2].Hash(): true,
|
||||||
|
}
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
const timeoutDura = 10 * time.Second
|
||||||
|
timeout := time.NewTimer(timeoutDura)
|
||||||
|
done:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case ev := <-chainSideCh:
|
||||||
|
block := ev.Block
|
||||||
|
if _, ok := expectedSideHashes[block.Hash()]; !ok {
|
||||||
|
t.Errorf("%d: didn't expect %x to be in side chain", i, block.Hash())
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
|
||||||
|
if i == len(expectedSideHashes) {
|
||||||
|
timeout.Stop()
|
||||||
|
|
||||||
|
break done
|
||||||
|
}
|
||||||
|
timeout.Reset(timeoutDura)
|
||||||
|
|
||||||
|
case <-timeout.C:
|
||||||
|
t.Fatal("Timeout. Possibly not all blocks were triggered for sideevent")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure no more events are fired
|
||||||
|
select {
|
||||||
|
case e := <-chainSideCh:
|
||||||
|
t.Errorf("unexpected event fired: %v", e)
|
||||||
|
case <-time.After(250 * time.Millisecond):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Tests if the canonical block can be fetched from the database during chain insertion.
|
// Tests if the canonical block can be fetched from the database during chain insertion.
|
||||||
func TestCanonicalBlockRetrieval(t *testing.T) {
|
func TestCanonicalBlockRetrieval(t *testing.T) {
|
||||||
testCanonicalBlockRetrieval(t, rawdb.HashScheme)
|
testCanonicalBlockRetrieval(t, rawdb.HashScheme)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue