Skip to content

Commit

Permalink
Fix test (stratisproject#3291)
Browse files Browse the repository at this point in the history
  • Loading branch information
fassadlr authored and fshutdown committed Mar 1, 2019
1 parent 376dcbe commit ddda2b8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 66 deletions.
14 changes: 12 additions & 2 deletions src/Stratis.Bitcoin.IntegrationTests.Common/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using NBitcoin;
Expand Down Expand Up @@ -184,6 +185,11 @@ public static void TriggerSync(CoreNode node)
connectedPeer.Behavior<ConsensusManagerBehavior>().ResyncAsync().GetAwaiter().GetResult();
}

/// <summary>
/// Determines whether or not the node has any connections.
/// </summary>
/// <param name="node">The node to check.</param>
/// <returns>Returns <c>true</c> if the node does not have any connected peers.</returns>
public static bool IsNodeConnected(CoreNode node)
{
return node.FullNode.ConnectionManager.ConnectedPeers.Any();
Expand Down Expand Up @@ -428,7 +434,7 @@ public static void Connect(CoreNode thisNode, CoreNode connectToNode)
}

/// <summary>
/// This connect method will only retry the connection if an RPC exception occurred.
/// This connect method will only retry the connection if an WebException occurred.
/// <para>
/// In cases where we expect the node to disconnect, this should be used.
/// </para>
Expand All @@ -446,10 +452,14 @@ public static void ConnectNoCheck(CoreNode thisNode, CoreNode connectToNode)
thisNode.CreateRPCClient().AddNode(connectToNode.Endpoint, true);
return true;
}
catch (Exception)
catch (WebException)
{
return false;
}
catch (Exception)
{
return true;
}
}, retryDelayInMiliseconds: 500, cancellationToken: cancellation.Token);
}

Expand Down
90 changes: 26 additions & 64 deletions src/Stratis.Bitcoin.IntegrationTests/NodeSyncTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.IO;
using System.Linq;
using NBitcoin;
using NBitcoin.BouncyCastle.Math;
using Stratis.Bitcoin.Connection;
using Stratis.Bitcoin.IntegrationTests.Common;
using Stratis.Bitcoin.IntegrationTests.Common.EnvironmentMockUpHelpers;
Expand All @@ -23,45 +22,14 @@ public NodeSyncTests()
this.posNetwork = new StratisRegTest();
}

private class StratisRegTestMaxReorg : StratisRegTest
public class StratisRegTestMaxReorg : StratisRegTest
{
public StratisRegTestMaxReorg()
{
this.Consensus = new NBitcoin.Consensus(
consensusFactory: base.Consensus.ConsensusFactory,
consensusOptions: base.Consensus.Options,
coinType: 105,
hashGenesisBlock: base.GenesisHash,
subsidyHalvingInterval: 210000,
majorityEnforceBlockUpgrade: 750,
majorityRejectBlockOutdated: 950,
majorityWindow: 1000,
buriedDeployments: base.Consensus.BuriedDeployments,
bip9Deployments: base.Consensus.BIP9Deployments,
bip34Hash: new uint256("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"),
ruleChangeActivationThreshold: 1916, // 95% of 2016
minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
maxReorgLength: 10,
defaultAssumeValid: null, // turn off assumevalid for regtest.
maxMoney: long.MaxValue,
coinbaseMaturity: 10,
premineHeight: 2,
premineReward: Money.Coins(98000000),
proofOfWorkReward: Money.Coins(4),
powTargetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
powTargetSpacing: TimeSpan.FromSeconds(10 * 60),
powAllowMinDifficultyBlocks: true,
posNoRetargeting: true,
powNoRetargeting: true,
powLimit: base.Consensus.PowLimit,
minimumChainWork: null,
isProofOfStake: true,
lastPowBlock: 12500,
proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
proofOfStakeReward: Money.COIN);

this.Name = Guid.NewGuid().ToString();

Type consensusType = typeof(NBitcoin.Consensus);
consensusType.GetProperty("MaxReorgLength").SetValue(this.Consensus, (uint)10);
}
}

Expand Down Expand Up @@ -152,55 +120,49 @@ public void Pow_CanCoreSyncFromStratis()
}

[Fact]
[Trait("Unstable", "True")]
public void Pos_Given_NodesAreSynced_When_ABigReorgHappens_Then_TheReorgIsIgnored()
{
using (NodeBuilder builder = NodeBuilder.Create(this))
{
var stratisRegTestMaxReorg = new StratisRegTestMaxReorg();
CoreNode stratisMiner = builder.CreateStratisPosNode(stratisRegTestMaxReorg, nameof(stratisMiner)).WithDummyWallet().Start();
CoreNode stratisSyncer = builder.CreateStratisPosNode(stratisRegTestMaxReorg, nameof(stratisSyncer)).Start();
CoreNode stratisReorg = builder.CreateStratisPosNode(stratisRegTestMaxReorg, nameof(stratisReorg)).WithDummyWallet().Start();

TestHelper.MineBlocks(stratisMiner, 1);
CoreNode miner = builder.CreateStratisPosNode(stratisRegTestMaxReorg, nameof(miner)).WithDummyWallet().Start();
CoreNode syncer = builder.CreateStratisPosNode(stratisRegTestMaxReorg, nameof(syncer)).Start();
CoreNode reorg = builder.CreateStratisPosNode(stratisRegTestMaxReorg, nameof(reorg)).WithDummyWallet().Start();

// Wait for block repo for block sync to work
TestHelper.ConnectAndSync(stratisMiner, stratisReorg);
TestHelper.ConnectAndSync(stratisMiner, stratisSyncer);
TestHelper.MineBlocks(miner, 1);

// Create a reorg by mining on two different chains
TestHelper.Disconnect(stratisMiner, stratisReorg);
TestHelper.Disconnect(stratisMiner, stratisSyncer);
// Sync miner with syncer and reorg
TestHelper.ConnectAndSync(miner, reorg);
TestHelper.ConnectAndSync(miner, syncer);

TestHelper.MineBlocks(stratisMiner, 11);
TestHelper.MineBlocks(stratisReorg, 12);
// Create a reorg by mining on two different chains
TestHelper.Disconnect(miner, reorg);
TestHelper.Disconnect(miner, syncer);
TestHelper.MineBlocks(miner, 11);
TestHelper.MineBlocks(reorg, 12);

// Make sure the nodes are actually on different chains.
Assert.NotEqual(stratisMiner.FullNode.Chain.GetBlock(2).HashBlock, stratisReorg.FullNode.Chain.GetBlock(2).HashBlock);
Assert.NotEqual(miner.FullNode.Chain.GetBlock(2).HashBlock, reorg.FullNode.Chain.GetBlock(2).HashBlock);

TestHelper.ConnectAndSync(stratisSyncer, stratisMiner);
TestHelper.ConnectAndSync(miner, syncer);

// The hash before the reorg node is connected.
uint256 hashBeforeReorg = stratisMiner.FullNode.Chain.Tip.HashBlock;
uint256 hashBeforeReorg = miner.FullNode.Chain.Tip.HashBlock;

// Connect the reorg chain
TestHelper.Connect(stratisMiner, stratisReorg);
TestHelper.Connect(stratisSyncer, stratisReorg);

// Trigger nodes to sync
TestHelper.TriggerSync(stratisMiner);
TestHelper.TriggerSync(stratisReorg);
TestHelper.TriggerSync(stratisSyncer);
TestHelper.ConnectNoCheck(miner, reorg);
TestHelper.ConnectNoCheck(syncer, reorg);

// Wait for the synced chain to get headers updated.
TestHelper.WaitLoop(() => !stratisReorg.FullNode.ConnectionManager.ConnectedPeers.Any());
TestHelper.WaitLoop(() => !TestHelper.IsNodeConnected(reorg));

TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisMiner, stratisSyncer));
TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReorg, stratisMiner) == false);
TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReorg, stratisSyncer) == false);
TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(miner, syncer));
TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(reorg, miner) == false);
TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(reorg, syncer) == false);

// Check that a reorg did not happen.
Assert.Equal(hashBeforeReorg, stratisSyncer.FullNode.Chain.Tip.HashBlock);
Assert.Equal(hashBeforeReorg, syncer.FullNode.Chain.Tip.HashBlock);
}
}

Expand Down

0 comments on commit ddda2b8

Please sign in to comment.