|
|
@@ -17,6 +17,7 @@
|
|
|
package eth
|
|
|
|
|
|
import (
|
|
|
+ "fmt"
|
|
|
"math"
|
|
|
"math/big"
|
|
|
"math/rand"
|
|
|
@@ -466,14 +467,17 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
|
|
|
}
|
|
|
// Create a DAO aware protocol manager
|
|
|
var (
|
|
|
- evmux = new(event.TypeMux)
|
|
|
- pow = ethash.NewFaker()
|
|
|
- db = ethdb.NewMemDatabase()
|
|
|
- config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
|
|
- gspec = &core.Genesis{Config: config}
|
|
|
- genesis = gspec.MustCommit(db)
|
|
|
- blockchain, _ = core.NewBlockChain(db, nil, config, pow, vm.Config{}, nil)
|
|
|
+ evmux = new(event.TypeMux)
|
|
|
+ pow = ethash.NewFaker()
|
|
|
+ db = ethdb.NewMemDatabase()
|
|
|
+ config = ¶ms.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
|
|
|
+ gspec = &core.Genesis{Config: config}
|
|
|
+ genesis = gspec.MustCommit(db)
|
|
|
)
|
|
|
+ blockchain, err := core.NewBlockChain(db, nil, config, pow, vm.Config{}, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create new blockchain: %v", err)
|
|
|
+ }
|
|
|
pm, err := NewProtocolManager(config, downloader.FullSync, DefaultConfig.NetworkId, evmux, new(testTxPool), pow, blockchain, db)
|
|
|
if err != nil {
|
|
|
t.Fatalf("failed to start test protocol manager: %v", err)
|
|
|
@@ -520,3 +524,90 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+func TestBroadcastBlock(t *testing.T) {
|
|
|
+ var tests = []struct {
|
|
|
+ totalPeers int
|
|
|
+ broadcastExpected int
|
|
|
+ }{
|
|
|
+ {1, 1},
|
|
|
+ {2, 2},
|
|
|
+ {3, 3},
|
|
|
+ {4, 4},
|
|
|
+ {5, 4},
|
|
|
+ {9, 4},
|
|
|
+ {12, 4},
|
|
|
+ {16, 4},
|
|
|
+ {26, 5},
|
|
|
+ {100, 10},
|
|
|
+ }
|
|
|
+ for _, test := range tests {
|
|
|
+ testBroadcastBlock(t, test.totalPeers, test.broadcastExpected)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func testBroadcastBlock(t *testing.T, totalPeers, broadcastExpected int) {
|
|
|
+ var (
|
|
|
+ evmux = new(event.TypeMux)
|
|
|
+ pow = ethash.NewFaker()
|
|
|
+ db = ethdb.NewMemDatabase()
|
|
|
+ config = ¶ms.ChainConfig{}
|
|
|
+ gspec = &core.Genesis{Config: config}
|
|
|
+ genesis = gspec.MustCommit(db)
|
|
|
+ )
|
|
|
+ blockchain, err := core.NewBlockChain(db, nil, config, pow, vm.Config{}, nil)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to create new blockchain: %v", err)
|
|
|
+ }
|
|
|
+ pm, err := NewProtocolManager(config, downloader.FullSync, DefaultConfig.NetworkId, evmux, new(testTxPool), pow, blockchain, db)
|
|
|
+ if err != nil {
|
|
|
+ t.Fatalf("failed to start test protocol manager: %v", err)
|
|
|
+ }
|
|
|
+ pm.Start(1000)
|
|
|
+ defer pm.Stop()
|
|
|
+ var peers []*testPeer
|
|
|
+ for i := 0; i < totalPeers; i++ {
|
|
|
+ peer, _ := newTestPeer(fmt.Sprintf("peer %d", i), eth63, pm, true)
|
|
|
+ defer peer.close()
|
|
|
+ peers = append(peers, peer)
|
|
|
+ }
|
|
|
+ chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 1, func(i int, gen *core.BlockGen) {})
|
|
|
+ pm.BroadcastBlock(chain[0], true /*propagate*/)
|
|
|
+
|
|
|
+ errCh := make(chan error, totalPeers)
|
|
|
+ doneCh := make(chan struct{}, totalPeers)
|
|
|
+ for _, peer := range peers {
|
|
|
+ go func(p *testPeer) {
|
|
|
+ if err := p2p.ExpectMsg(p.app, NewBlockMsg, &newBlockData{Block: chain[0], TD: big.NewInt(131136)}); err != nil {
|
|
|
+ errCh <- err
|
|
|
+ } else {
|
|
|
+ doneCh <- struct{}{}
|
|
|
+ }
|
|
|
+ }(peer)
|
|
|
+ }
|
|
|
+ timeoutCh := time.NewTimer(time.Millisecond * 100).C
|
|
|
+ var receivedCount int
|
|
|
+outer:
|
|
|
+ for {
|
|
|
+ select {
|
|
|
+ case err = <-errCh:
|
|
|
+ break outer
|
|
|
+ case <-doneCh:
|
|
|
+ receivedCount++
|
|
|
+ if receivedCount == totalPeers {
|
|
|
+ break outer
|
|
|
+ }
|
|
|
+ case <-timeoutCh:
|
|
|
+ break outer
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for _, peer := range peers {
|
|
|
+ peer.app.Close()
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ t.Errorf("error matching block by peer: %v", err)
|
|
|
+ }
|
|
|
+ if receivedCount != broadcastExpected {
|
|
|
+ t.Errorf("block broadcast to %d peers, expected %d", receivedCount, broadcastExpected)
|
|
|
+ }
|
|
|
+}
|