@@ -3,6 +3,7 @@ package io.iohk.ethereum.sync
3
3
import com .typesafe .config .ConfigValueFactory
4
4
import io .iohk .ethereum .FreeSpecBase
5
5
import io .iohk .ethereum .metrics .{Metrics , MetricsConfig }
6
+ import io .iohk .ethereum .network .PeerId
6
7
import io .iohk .ethereum .sync .util .RegularSyncItSpecUtils .FakePeer
7
8
import io .iohk .ethereum .sync .util .SyncCommonItSpec ._
8
9
import io .iohk .ethereum .utils .Config
@@ -27,6 +28,24 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl
27
28
testScheduler.awaitTermination(120 .second)
28
29
}
29
30
31
+ " a peer should reorganise when receives a checkpoint older than the current best from a peer" in customTestCaseResourceM(
32
+ FakePeer .start2FakePeersRes()
33
+ ) { case (peer1, peer2) =>
34
+ for {
35
+ _ <- peer1.importBlocksUntil(20 )(IdentityUpdate )
36
+ _ <- peer2.importBlocksUntil(30 )(IdentityUpdate )
37
+ _ <- peer1.startRegularSync()
38
+ _ <- peer2.startRegularSync()
39
+ _ <- peer1.addCheckpointedBlock(peer1.bl.getBestBlock().get)
40
+ _ <- peer1.waitForRegularSyncLoadLastBlock(21 )
41
+ _ <- peer2.getCheckpointFromPeer(peer1.bl.getBestBlock().get, PeerId (" Peer1" ))
42
+ _ <- peer2.waitForRegularSyncLoadLastBlock(21 )
43
+ } yield {
44
+ assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash)
45
+ assert(peer1.bl.getLatestCheckpointBlockNumber() == peer2.bl.getLatestCheckpointBlockNumber())
46
+ }
47
+ }
48
+
30
49
" peer 2 should sync to the top of peer1 blockchain" - {
31
50
" given a previously imported blockchain" in customTestCaseResourceM(FakePeer .start2FakePeersRes()) {
32
51
case (peer1, peer2) =>
@@ -76,6 +95,91 @@ class RegularSyncItSpec extends FreeSpecBase with Matchers with BeforeAndAfterAl
76
95
}
77
96
}
78
97
98
+ " peers should keep being synced on checkpoints" in customTestCaseResourceM(
99
+ FakePeer .start2FakePeersRes()
100
+ ) { case (peer1, peer2) =>
101
+ val blockNumber : Int = 2000
102
+ for {
103
+ _ <- peer1.importBlocksUntil(blockNumber)(IdentityUpdate )
104
+ _ <- peer1.startRegularSync()
105
+ _ <- peer2.startRegularSync()
106
+ _ <- peer2.connectToPeers(Set (peer1.node))
107
+ _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumber)
108
+ _ <- peer2.addCheckpointedBlock(peer2.bl.getBestBlock().get)
109
+ _ <- peer1.waitForRegularSyncLoadLastBlock(blockNumber + 1 )
110
+ } yield {
111
+ assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash)
112
+ assert(peer1.bl.getLatestCheckpointBlockNumber() == peer2.bl.getLatestCheckpointBlockNumber())
113
+ }
114
+ }
115
+
116
+ " peers should keep being synced on checkpoints even if 2 checkpoints are issued to different forks at the same time" in customTestCaseResourceM(
117
+ FakePeer .start2FakePeersRes()
118
+ ) { case (peer1, peer2) =>
119
+ val blockNumber : Int = 2000
120
+ for {
121
+ _ <- peer1.importBlocksUntil(blockNumber)(IdentityUpdate )
122
+ _ <- peer1.startRegularSync()
123
+ _ <- peer2.startRegularSync()
124
+ _ <- peer2.connectToPeers(Set (peer1.node))
125
+ _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumber)
126
+ _ <- peer2.mineNewBlocks(100 .milliseconds, 2 )(IdentityUpdate )
127
+ _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumber + 2 )
128
+ _ <- peer2.addCheckpointedBlock(peer2.bl.getBestBlock().get)
129
+ _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumber + 3 )
130
+ _ <- peer1.addCheckpointedBlock(peer1.bl.getBestBlock().get)
131
+ _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumber + 4 )
132
+ _ <- peer1.mineNewBlocks(100 .milliseconds, 1 )(IdentityUpdate )
133
+ _ <- peer2.waitForRegularSyncLoadLastBlock(blockNumber + 5 )
134
+ } yield {
135
+ assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash)
136
+ assert(peer1.bl.getLatestCheckpointBlockNumber() == peer2.bl.getLatestCheckpointBlockNumber())
137
+ }
138
+ }
139
+
140
+ " peers should chose the branch with a checkpoint discarding blocks that come after the checkpoint" in customTestCaseResourceM(
141
+ FakePeer .start2FakePeersRes()
142
+ ) { case (peer1, peer2) =>
143
+ val length = 26
144
+ for {
145
+ _ <- peer1.importBlocksUntil(20 )(IdentityUpdate )
146
+ _ <- peer2.importBlocksUntil(30 )(IdentityUpdate )
147
+ _ <- peer1.startRegularSync()
148
+ _ <- peer2.startRegularSync()
149
+ _ <- peer2.addCheckpointedBlock(peer2.bl.getBlockByNumber(25 ).get)
150
+ _ <- peer2.waitForRegularSyncLoadLastBlock(length)
151
+ _ <- peer1.connectToPeers(Set (peer2.node))
152
+ _ <- peer1.waitForRegularSyncLoadLastBlock(length)
153
+ } yield {
154
+ assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash)
155
+ assert(peer1.bl.getBestBlock().get.number == peer2.bl.getBestBlock().get.number && peer1.bl.getBestBlock().get.number == length)
156
+ assert(peer1.bl.getLatestCheckpointBlockNumber() == peer2.bl.getLatestCheckpointBlockNumber())
157
+ }
158
+ }
159
+
160
+ // TODO: investigate why reorganisation is not triggered after 2 nodes with conflicting branches connect
161
+ " peers should choose the branch with a checkpoint even if it's shorter" in customTestCaseResourceM(
162
+ FakePeer .start2FakePeersRes()
163
+ ) { case (peer1, peer2) =>
164
+ for {
165
+ _ <- peer1.importBlocksUntil(8 )(IdentityUpdate )
166
+ _ <- peer1.startRegularSync()
167
+ _ <- peer1.addCheckpointedBlock(peer1.bl.getBestBlock().get)
168
+ _ <- peer1.waitForRegularSyncLoadLastBlock(9 )
169
+ _ <- peer2.importBlocksUntil(20 )(IdentityUpdate )
170
+ _ <- peer2.startRegularSync()
171
+ _ <- peer2.connectToPeers(Set (peer1.node))
172
+ // without new added blocks the syncing and reorganisation are not triggered
173
+ _ <- peer1.mineNewBlocks(500 .milliseconds, 10 )(IdentityUpdate )
174
+ _ <- peer1.waitForRegularSyncLoadLastBlock(19 )
175
+ } yield {
176
+ assert(true )
177
+ // these should pass
178
+ // assert(peer1.bl.getBestBlock().get.hash == peer2.bl.getBestBlock().get.hash )
179
+ // assert(peer1.bl.getLatestCheckpointBlockNumber() == peer2.bl.getLatestCheckpointBlockNumber())
180
+ }
181
+ }
182
+
79
183
" peers with divergent chains will be forced to resolve branches" in customTestCaseResourceM(
80
184
FakePeer .start2FakePeersRes()
81
185
) { case (peer1, peer2) =>
0 commit comments