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 }