1717package eth
1818
1919import (
20+ "bytes"
21+ "math/big"
22+ "strings"
2023 "sync/atomic"
2124 "testing"
2225 "time"
2326
2427 "github.com/XinFinOrg/XDPoSChain/eth/downloader"
28+ "github.com/XinFinOrg/XDPoSChain/log"
2529 "github.com/XinFinOrg/XDPoSChain/p2p"
2630 "github.com/XinFinOrg/XDPoSChain/p2p/enode"
2731)
@@ -31,6 +35,66 @@ func TestFastSyncDisabling100(t *testing.T) { testFastSyncDisabling(t, xdc100) }
3135func TestFastSyncDisabling164 (t * testing.T ) { testFastSyncDisabling (t , xdc164 ) }
3236func TestFastSyncDisabling165 (t * testing.T ) { testFastSyncDisabling (t , xdc165 ) }
3337
38+ // Tests that the periodic sync status logger reports progress whenever the node
39+ // is behind the best peer's head, even when the downloader is idle (i.e. the
40+ // node is following new blocks through the block fetcher / BFT announcements).
41+ func TestSyncStatusLogger (t * testing.T ) {
42+ pm , _ := newTestProtocolManagerMust (t , downloader .FullSync , 0 , nil , nil )
43+ defer pm .Stop ()
44+
45+ // Capture the warn-level logs emitted by the sync status logger.
46+ var logBuf bytes.Buffer
47+ prevLog := log .Root ()
48+ glog := log .NewGlogHandler (log .NewTerminalHandlerWithLevel (& logBuf , log .LevelTrace , false ))
49+ glog .Verbosity (log .LevelTrace )
50+ log .SetDefault (log .NewLogger (glog ))
51+ defer log .SetDefault (prevLog )
52+
53+ // Register a peer that we can move ahead of / behind our own chain head.
54+ app , net := p2p .MsgPipe ()
55+ defer app .Close ()
56+ peer := pm .newPeer (xdc100 , p2p .NewPeer (enode.ID {1 }, "sync-status-peer" , nil ), net , pm .txpool .Get )
57+ if err := pm .peers .Register (peer ); err != nil {
58+ t .Fatalf ("failed to register peer: %v" , err )
59+ }
60+ defer pm .peers .Unregister (peer .id )
61+
62+ current := pm .blockchain .CurrentBlock ()
63+ localTD := pm .blockchain .GetTd (current .Hash (), current .Number .Uint64 ())
64+
65+ // setHead moves the peer's advertised head to the given total difficulty.
66+ // The handshake (which normally initialises these fields) is skipped here,
67+ // so set the peer's head state directly.
68+ setHead := func (td * big.Int ) {
69+ peer .lock .Lock ()
70+ defer peer .lock .Unlock ()
71+ peer .head = current .Hash ()
72+ peer .td = new (big.Int ).Set (td )
73+ }
74+
75+ // A peer ahead of us must trigger a sync status report...
76+ setHead (new (big.Int ).Add (localTD , big .NewInt (1 )))
77+ pm .reportSyncStatus ()
78+ if got := strings .Count (logBuf .String (), "Block synchronisation in progress" ); got != 1 {
79+ t .Fatalf ("expected a sync status log when behind the best peer, got %d, log: %q" , got , logBuf .String ())
80+ }
81+ // ...while a peer at or behind us must not.
82+ logBuf .Reset ()
83+ setHead (localTD )
84+ pm .reportSyncStatus ()
85+ if got := strings .Count (logBuf .String (), "Block synchronisation in progress" ); got != 0 {
86+ t .Fatalf ("expected no sync status log when at the best peer's head, got %d, log: %q" , got , logBuf .String ())
87+ }
88+ // The progress fields must be populated with the local chain state.
89+ logBuf .Reset ()
90+ setHead (new (big.Int ).Add (localTD , big .NewInt (1 )))
91+ pm .reportSyncStatus ()
92+ logLine := logBuf .String ()
93+ if ! strings .Contains (logLine , "current=" ) || ! strings .Contains (logLine , "peers=1" ) {
94+ t .Fatalf ("expected populated progress fields, got %q" , logLine )
95+ }
96+ }
97+
3498// Tests that fast sync gets disabled as soon as a real block is successfully
3599// imported into the blockchain.
36100func testFastSyncDisabling (t * testing.T , protocol int ) {
0 commit comments