Skip to content

Commit

Permalink
Create new chain when branch point doesn't exist
Browse files Browse the repository at this point in the history
  • Loading branch information
earlbread committed Nov 8, 2019
1 parent e2d3559 commit df559d2
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 5 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ To be released.
fails. [[#644]]
- Fixed bug that whole processes could halt when received an invalid
type of message. [[#628], [#641]]
- Fixed a bug that received blocks could not be processed if a branch point
is a stale block. [[#655]]

[#209]: https://github.com/planetarium/libplanet/issues/209
[#405]: https://github.com/planetarium/libplanet/issues/405
Expand Down Expand Up @@ -179,6 +181,7 @@ To be released.
[#645]: https://github.com/planetarium/libplanet/pull/645
[#647]: https://github.com/planetarium/libplanet/pull/647
[#654]: https://github.com/planetarium/libplanet/pull/654
[#655]: https://github.com/planetarium/libplanet/pull/655


Version 0.6.0
Expand Down
74 changes: 73 additions & 1 deletion Libplanet.Tests/Net/SwarmTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
using Libplanet.Crypto;
using Libplanet.Net;
using Libplanet.Net.Messages;
using Libplanet.Net.Protocols;
using Libplanet.Tests.Blockchain;
using Libplanet.Tests.Common.Action;
using Libplanet.Tests.Store;
Expand Down Expand Up @@ -2317,6 +2316,79 @@ public async Task HandleReorgInSynchronizing()
}
}

[Fact(Timeout = Timeout)]
public async Task CreateNewChainWhenBranchPointNotExist()
{
// If the bucket stored peers are the same, the block may not propagate,
// so specify private keys to make the buckets different.
var keyA = ByteUtil.ParseHex(
"8568eb6f287afedece2c7b918471183db0451e1a61535bb0381cfdf95b85df20");
var keyB = ByteUtil.ParseHex(
"c34f7498befcc39a14f03b37833f6c7bb78310f1243616524eda70e078b8313c");
var keyC = ByteUtil.ParseHex(
"941bc2edfab840d79914d80fe3b30840628ac37a5d812d7f922b5d2405a223d3");

var minerSwarmA = new Swarm<DumbAction>(
_blockchains[0],
new PrivateKey(keyA),
1,
host: IPAddress.Loopback.ToString());
var minerSwarmB = new Swarm<DumbAction>(
_blockchains[1],
new PrivateKey(keyB),
1,
host: IPAddress.Loopback.ToString());
var receiverSwarm = new Swarm<DumbAction>(
_blockchains[2],
new PrivateKey(keyC),
1,
host: IPAddress.Loopback.ToString());

BlockChain<DumbAction> minerChainA = _blockchains[0];
BlockChain<DumbAction> minerChainB = _blockchains[1];
BlockChain<DumbAction> receiverChain = _blockchains[2];

try
{
await StartAsync(minerSwarmA);
await StartAsync(minerSwarmB);
await StartAsync(receiverSwarm);

await BootstrapAsync(minerSwarmA, receiverSwarm.AsPeer);
await BootstrapAsync(minerSwarmB, receiverSwarm.AsPeer);

// Broadcast SwarmA's first block.
var b1 = await minerChainA.MineBlock(_fx1.Address1);
await minerChainB.MineBlock(_fx1.Address1);
minerSwarmA.BroadcastBlocks(new[] { b1 });
await receiverSwarm.BlockReceived.WaitAsync();
Assert.Equal(receiverChain.Tip, minerChainA.Tip);

// Broadcast SwarmB's second block.
await minerChainA.MineBlock(_fx1.Address1);
var b2 = await minerChainB.MineBlock(_fx1.Address1);
minerSwarmB.BroadcastBlocks(new[] { b2 });
await receiverSwarm.BlockReceived.WaitAsync();
Assert.Equal(receiverChain.Tip, minerChainB.Tip);

// Broadcast SwarmA's third block.
var b3 = await minerChainA.MineBlock(_fx1.Address1);
await minerChainB.MineBlock(_fx1.Address1);
minerSwarmA.BroadcastBlocks(new[] { b3 });
await receiverSwarm.BlockReceived.WaitAsync();
Assert.Equal(receiverChain.Tip, minerChainA.Tip);
}
finally
{
await minerSwarmA.StopAsync();
await minerSwarmB.StopAsync();
await receiverSwarm.StopAsync();
minerSwarmA.Dispose();
minerSwarmB.Dispose();
receiverSwarm.Dispose();
}
}

private static async Task<(Address, Block<DumbAction>[])>
MakeFixtureBlocksForPreloadAsyncCancellationTest()
{
Expand Down
9 changes: 5 additions & 4 deletions Libplanet/Net/Swarm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1714,14 +1714,15 @@ await GetBlockHashesAsync(peer, locator, stop, cancellationToken)
_logger.Debug("It doesn't need to fork.");
}

// FIXME BlockChain<T>.Contains() can be very
// expensive.
// we can omit this clause if assume every chain shares
// We can omit this clause if assume every chain shares
// same genesis block...
else if (!workspace.Contains(branchPoint))
else if (!workspace.Contains(branchPoint)
|| (workspace[branchPoint].Index is long branchPointIndex
&& !workspace[branchPointIndex].Hash.Equals(branchPoint)))
{
// Create a whole new chain because the branch point doesn't exist on
// the current chain.
_logger.Debug("Create new chain...");
workspace = new BlockChain<T>(
workspace.Policy,
workspace.Store,
Expand Down

0 comments on commit df559d2

Please sign in to comment.