github.com/aergoio/aergo@v1.3.1/syncer/syncerservice_test.go (about)

     1  package syncer
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/aergoio/aergo/chain"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/aergoio/aergo/message"
    10  	"github.com/stretchr/testify/assert"
    11  )
    12  
    13  func TestSyncer_sync1000(t *testing.T) {
    14  	remoteChainLen := 1002
    15  	localChainLen := 10
    16  	targetNo := uint64(1000)
    17  
    18  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
    19  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:1], localChainLen-1)
    20  
    21  	remoteChains := []*chain.StubBlockChain{remoteChain}
    22  	peers := makeStubPeerSet(remoteChains)
    23  
    24  	testCfg := *SyncerCfg
    25  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: 0}
    26  
    27  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
    28  	syncer.start()
    29  
    30  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: 1000}
    31  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
    32  
    33  	syncer.waitStop()
    34  
    35  	assert.Equal(t, int(targetNo), syncer.localChain.Best, "sync failed")
    36  }
    37  
    38  func TestSyncer_sync10000(t *testing.T) {
    39  	remoteChainLen := 10002
    40  	localChainLen := 10000
    41  	targetNo := uint64(10000)
    42  	ancestorNo := 100
    43  
    44  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
    45  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:ancestorNo+1], localChainLen-(ancestorNo+1))
    46  
    47  	remoteChains := []*chain.StubBlockChain{remoteChain}
    48  	peers := makeStubPeerSet(remoteChains)
    49  
    50  	testCfg := *SyncerCfg
    51  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: ancestorNo}
    52  
    53  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
    54  	syncer.start()
    55  
    56  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: targetNo}
    57  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
    58  
    59  	syncer.waitStop()
    60  
    61  	assert.Equal(t, int(targetNo), syncer.localChain.Best, "sync failed")
    62  }
    63  
    64  func TestSyncer_sync_multiPeer(t *testing.T) {
    65  	remoteChainLen := 1002
    66  	localChainLen := 10
    67  	targetNo := uint64(1000)
    68  
    69  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
    70  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:1], localChainLen-1)
    71  
    72  	remoteChains := []*chain.StubBlockChain{remoteChain, remoteChain, remoteChain, remoteChain}
    73  	peers := makeStubPeerSet(remoteChains)
    74  
    75  	testCfg := *SyncerCfg
    76  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: 0}
    77  
    78  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
    79  	syncer.start()
    80  
    81  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: 1000}
    82  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
    83  
    84  	syncer.waitStop()
    85  
    86  	//check if all peers is used
    87  	for i, peer := range peers {
    88  		assert.True(t, peer.blockFetched, fmt.Sprintf("%d is not used", i))
    89  	}
    90  
    91  	assert.Equal(t, int(targetNo), syncer.localChain.Best, "sync failed")
    92  }
    93  
    94  //case : peer1 is slow (timeout)
    95  func TestSyncer_sync_slowPeer(t *testing.T) {
    96  	remoteChainLen := 1002
    97  	localChainLen := 10
    98  	targetNo := uint64(1000)
    99  
   100  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
   101  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:1], localChainLen-1)
   102  
   103  	remoteChains := []*chain.StubBlockChain{remoteChain, remoteChain, remoteChain, remoteChain}
   104  	peers := makeStubPeerSet(remoteChains)
   105  
   106  	testCfg := *SyncerCfg
   107  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: 0}
   108  	testCfg.debugContext.logBadPeers = make(map[int]bool)
   109  	testCfg.fetchTimeOut = time.Millisecond * 500
   110  	expBadPeer := 1
   111  	peers[expBadPeer].timeDelaySec = time.Second * 1
   112  
   113  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
   114  	syncer.start()
   115  
   116  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: 1000}
   117  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
   118  
   119  	syncer.waitStop()
   120  
   121  	//check if all peers is used
   122  	for i, peer := range peers {
   123  		assert.True(t, peer.blockFetched, fmt.Sprintf("%d is not used", i))
   124  	}
   125  
   126  	//check bad peer
   127  	assert.True(t, testCfg.debugContext.logBadPeers[expBadPeer], "check bad peer")
   128  
   129  	assert.Equal(t, int(targetNo), syncer.localChain.Best, "sync failed")
   130  }
   131  
   132  func TestSyncer_sync_allPeerBad(t *testing.T) {
   133  	remoteChainLen := 1002
   134  	localChainLen := 10
   135  	targetNo := uint64(1000)
   136  
   137  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
   138  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:1], localChainLen-1)
   139  
   140  	remoteChains := []*chain.StubBlockChain{remoteChain, remoteChain, remoteChain, remoteChain}
   141  	peers := makeStubPeerSet(remoteChains)
   142  
   143  	testCfg := *SyncerCfg
   144  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: 0}
   145  	testCfg.debugContext.logBadPeers = make(map[int]bool)
   146  
   147  	testCfg.fetchTimeOut = time.Millisecond * 500
   148  	peers[0].timeDelaySec = time.Second * 1
   149  	peers[1].timeDelaySec = time.Second * 1
   150  	peers[2].timeDelaySec = time.Second * 1
   151  	peers[3].timeDelaySec = time.Second * 1
   152  
   153  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
   154  	syncer.start()
   155  
   156  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: 1000}
   157  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
   158  
   159  	syncer.waitStop()
   160  
   161  	//check if all peers is used
   162  	for i, peer := range peers {
   163  		assert.True(t, peer.blockFetched, fmt.Sprintf("%d is not used", i))
   164  	}
   165  
   166  	for _, peerNo := range []int{0, 1, 2, 3} {
   167  		assert.True(t, testCfg.debugContext.logBadPeers[peerNo], "check bad peer")
   168  	}
   169  
   170  	assert.NotEqual(t, int(targetNo), syncer.localChain.Best, "sync must fail")
   171  }
   172  
   173  func TestSyncerAllPeerBadByResponseError(t *testing.T) {
   174  	remoteChainLen := 1002
   175  	localChainLen := 10
   176  	targetNo := uint64(1000)
   177  
   178  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
   179  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:1], localChainLen-1)
   180  
   181  	remoteChains := []*chain.StubBlockChain{remoteChain}
   182  	peers := makeStubPeerSet(remoteChains)
   183  
   184  	testCfg := *SyncerCfg
   185  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: 0}
   186  	testCfg.debugContext.logBadPeers = make(map[int]bool)
   187  
   188  	testCfg.fetchTimeOut = time.Millisecond * 500
   189  
   190  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
   191  
   192  	peers[0].HookGetBlockChunkRsp = func(msgReq *message.GetBlockChunks) {
   193  		rsp := &message.GetBlockChunksRsp{Seq: msgReq.Seq, ToWhom: msgReq.ToWhom, Blocks: nil, Err: message.RemotePeerFailError}
   194  		syncer.stubRequester.TellTo(message.SyncerSvc, rsp)
   195  	}
   196  
   197  	syncer.start()
   198  
   199  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: 1000}
   200  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
   201  
   202  	syncer.waitStop()
   203  
   204  	//check if all peers is used
   205  	for i, peer := range peers {
   206  		assert.True(t, peer.blockFetched, fmt.Sprintf("%d is not used", i))
   207  	}
   208  
   209  	for _, peerNo := range []int{0} {
   210  		assert.True(t, testCfg.debugContext.logBadPeers[peerNo], "check bad peer")
   211  	}
   212  
   213  	assert.NotEqual(t, int(targetNo), syncer.localChain.Best, "sync must fail")
   214  }
   215  
   216  func TestSyncerAlreadySynched(t *testing.T) {
   217  	//When sync is already done before finder runs
   218  	remoteChainLen := 1010
   219  	//localChainLen := 999
   220  	targetNo := uint64(1000)
   221  
   222  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
   223  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:1000], 0)
   224  
   225  	remoteChains := []*chain.StubBlockChain{remoteChain}
   226  	peers := makeStubPeerSet(remoteChains)
   227  
   228  	testCfg := *SyncerCfg
   229  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: 0, expErrResult: ErrAlreadySyncDone}
   230  
   231  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
   232  	syncer.getAnchorsHookFn = func(stubSyncer *StubSyncer) {
   233  		stubSyncer.localChain.AddBlock(remoteChain.Blocks[1000])
   234  		stubSyncer.localChain.AddBlock(remoteChain.Blocks[1001])
   235  		stubSyncer.localChain.AddBlock(remoteChain.Blocks[1002])
   236  	}
   237  	syncer.start()
   238  
   239  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: targetNo}
   240  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
   241  
   242  	syncer.waitStop()
   243  
   244  	assert.Equal(t, 1002, syncer.localChain.Best, "sync failed")
   245  }
   246  
   247  func TestSyncer_invalid_seq_getancestor(t *testing.T) {
   248  	remoteChainLen := 1002
   249  	localChainLen := 10
   250  	targetNo := uint64(1000)
   251  
   252  	remoteChain := chain.InitStubBlockChain(nil, remoteChainLen)
   253  	localChain := chain.InitStubBlockChain(remoteChain.Blocks[0:1], localChainLen-1)
   254  
   255  	remoteChains := []*chain.StubBlockChain{remoteChain}
   256  	peers := makeStubPeerSet(remoteChains)
   257  
   258  	testCfg := *SyncerCfg
   259  	testCfg.debugContext = &SyncerDebug{t: t, expAncestor: 0}
   260  
   261  	syncer := NewTestSyncer(t, localChain, remoteChain, peers, &testCfg)
   262  	// set prev sequence
   263  	syncer.realSyncer.Seq = 99
   264  	syncer.getSyncAncestorHookFn = func(stubSyncer *StubSyncer, msg *message.GetSyncAncestor) {
   265  		// send prev sequence
   266  		newMsg := &message.GetSyncAncestor{Seq: 98, ToWhom: msg.ToWhom, Hashes: msg.Hashes}
   267  		syncer.SendGetSyncAncestorRsp(newMsg)
   268  
   269  		newMsg = &message.GetSyncAncestor{Seq: 99, ToWhom: msg.ToWhom, Hashes: msg.Hashes}
   270  		syncer.SendGetSyncAncestorRsp(newMsg)
   271  	}
   272  
   273  	syncer.start()
   274  
   275  	syncReq := &message.SyncStart{PeerID: targetPeerID, TargetNo: 1000}
   276  	syncer.stubRequester.TellTo(message.SyncerSvc, syncReq)
   277  
   278  	syncer.waitStop()
   279  
   280  	assert.Equal(t, int(targetNo), syncer.localChain.Best, "sync failed")
   281  }