public void WhenRefreshWhitelist_AndInactivePeersInWhitelist_ThenWhitelistDoesNotContainInactivePeers()
        {
            // Arrange.
            Mock <IDateTimeProvider> mockDateTimeProvider = new Mock <IDateTimeProvider>();

            Mock <ILogger>        mockLogger        = new Mock <ILogger>();
            Mock <ILoggerFactory> mockLoggerFactory = new Mock <ILoggerFactory>();

            mockLoggerFactory.Setup(l => l.CreateLogger(It.IsAny <string>())).Returns(mockLogger.Object);
            ILoggerFactory loggerFactory = mockLoggerFactory.Object;

            mockDateTimeProvider.Setup(d => d.GetTimeOffset()).Returns(new DateTimeOffset(new DateTime(2017, 8, 30, 1, 2, 3))).Verifiable();
            IDateTimeProvider dateTimeProvider = mockDateTimeProvider.Object;

            int inactiveTimePeriod = 3000;

            IPAddress      activeIpAddressOne      = IPAddress.Parse("::ffff:192.168.0.1");
            NetworkAddress activeNetworkAddressOne = new NetworkAddress(activeIpAddressOne, 80);

            IPAddress      activeIpAddressTwo      = IPAddress.Parse("::ffff:192.168.0.2");
            NetworkAddress activeNetworkAddressTwo = new NetworkAddress(activeIpAddressTwo, 80);

            IPAddress      activeIpAddressThree      = IPAddress.Parse("::ffff:192.168.0.3");
            NetworkAddress activeNetworkAddressThree = new NetworkAddress(activeIpAddressThree, 80);

            IPAddress      activeIpAddressFour      = IPAddress.Parse("::ffff:192.168.0.4");
            NetworkAddress activeNetworkAddressFour = new NetworkAddress(activeIpAddressFour, 80);

            List <Tuple <NetworkAddress, DateTimeOffset> > activeTestDataSet = new List <Tuple <NetworkAddress, DateTimeOffset> >()
            {
                new Tuple <NetworkAddress, DateTimeOffset> (activeNetworkAddressOne, dateTimeProvider.GetTimeOffset().AddSeconds(-inactiveTimePeriod).AddSeconds(10)),
                new Tuple <NetworkAddress, DateTimeOffset>(activeNetworkAddressTwo, dateTimeProvider.GetTimeOffset().AddSeconds(-inactiveTimePeriod).AddSeconds(20)),
                new Tuple <NetworkAddress, DateTimeOffset>(activeNetworkAddressThree, dateTimeProvider.GetTimeOffset().AddSeconds(-inactiveTimePeriod).AddSeconds(30)),
                new Tuple <NetworkAddress, DateTimeOffset>(activeNetworkAddressFour, dateTimeProvider.GetTimeOffset().AddSeconds(-inactiveTimePeriod).AddSeconds(40))
            };

            IPAddress      inactiveIpAddressOne      = IPAddress.Parse("::ffff:192.168.100.1");
            NetworkAddress inactiveNetworkAddressOne = new NetworkAddress(inactiveIpAddressOne, 80);

            IPAddress      inactiveIpAddressTwo      = IPAddress.Parse("::ffff:192.168.100.2");
            NetworkAddress inactiveNetworkAddressTwo = new NetworkAddress(inactiveIpAddressTwo, 80);

            IPAddress      inactiveIpAddressThree      = IPAddress.Parse("::ffff:192.168.100.3");
            NetworkAddress inactiveNetworkAddressThree = new NetworkAddress(inactiveIpAddressThree, 80);

            List <Tuple <NetworkAddress, DateTimeOffset> > inactiveTestDataSet = new List <Tuple <NetworkAddress, DateTimeOffset> >()
            {
                new Tuple <NetworkAddress, DateTimeOffset> (inactiveNetworkAddressOne, dateTimeProvider.GetTimeOffset().AddSeconds(-inactiveTimePeriod).AddSeconds(-10)),
                new Tuple <NetworkAddress, DateTimeOffset>(inactiveNetworkAddressTwo, dateTimeProvider.GetTimeOffset().AddSeconds(-inactiveTimePeriod).AddSeconds(-20)),
                new Tuple <NetworkAddress, DateTimeOffset>(inactiveNetworkAddressThree, dateTimeProvider.GetTimeOffset().AddSeconds(-inactiveTimePeriod).AddSeconds(-30))
            };

            IPeerAddressManager peerAddressManager = this.CreateTestPeerAddressManager(activeTestDataSet.Concat(inactiveTestDataSet).ToList());

            IMasterFile       spiedMasterFile = null;
            Mock <IDnsServer> mockDnsServer   = new Mock <IDnsServer>();

            mockDnsServer.Setup(d => d.SwapMasterfile(It.IsAny <IMasterFile>()))
            .Callback <IMasterFile>(m =>
            {
                spiedMasterFile = m;
            })
            .Verifiable();

            NodeSettings nodeSettings = NodeSettings.Default();
            DnsSettings  dnsSettings  = new Mock <DnsSettings>().Object;

            dnsSettings.DnsPeerBlacklistThresholdInSeconds = inactiveTimePeriod;
            dnsSettings.DnsHostName = "stratis.test.com";
            ConnectionManagerSettings connectionSettings = new ConnectionManagerSettings();

            connectionSettings.Load(nodeSettings);

            WhitelistManager whitelistManager = new WhitelistManager(dateTimeProvider, loggerFactory, peerAddressManager, mockDnsServer.Object, connectionSettings, dnsSettings);

            // Act.
            whitelistManager.RefreshWhitelist();

            // Assert.
            spiedMasterFile.Should().NotBeNull();

            Question question = new Question(new Domain(dnsSettings.DnsHostName), RecordType.AAAA);
            IList <IResourceRecord> resourceRecords = spiedMasterFile.Get(question);

            resourceRecords.Should().NotBeNullOrEmpty();

            IList <IPAddressResourceRecord> ipAddressResourceRecords = resourceRecords.OfType <IPAddressResourceRecord>().ToList();

            ipAddressResourceRecords.Should().HaveSameCount(activeTestDataSet);

            foreach (Tuple <NetworkAddress, DateTimeOffset> testData in activeTestDataSet)
            {
                ipAddressResourceRecords.SingleOrDefault(i => i.IPAddress.Equals(testData.Item1.Endpoint.Address)).Should().NotBeNull("the ip address is active and should be in DNS");
            }

            foreach (Tuple <NetworkAddress, DateTimeOffset> testData in inactiveTestDataSet)
            {
                ipAddressResourceRecords.SingleOrDefault(i => i.IPAddress.Equals(testData.Item1.Endpoint.Address)).Should().BeNull("the ip address is inactive and should not be returned from DNS");
            }
        }
예제 #2
0
        public void BuildTransactionNoChangeAdressesLeftCreatesNewChangeAddress()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var wallet          = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
            var accountKeys     = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            var spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            var destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            var chain = new ConcurrentChain(wallet.Network.GetGenesis().Header);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address);
            var addressTransaction = address.Transactions.First();

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
            .Returns(new FeeRate(20000));

            var walletManager = new WalletManager(this.LoggerFactory.Object, Network.Main, chain, NodeSettings.Default(), dataFolder,
                                                  walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default);
            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, chain, walletManager, walletFeePolicy.Object, Network.Main);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            var context           = CreateContext(walletReference, "password", destinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0);
            var transactionResult = walletTransactionHandler.BuildTransaction(context);

            var result = new Transaction(transactionResult.ToHex());
            var expectedChangeAddressKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "1/0");

            Assert.Single(result.Inputs);
            Assert.Equal(addressTransaction.Id, result.Inputs[0].PrevOut.Hash);

            Assert.Equal(2, result.Outputs.Count);
            var output = result.Outputs[0];

            Assert.Equal((addressTransaction.Amount - context.TransactionFee - 7500), output.Value);
            Assert.Equal(expectedChangeAddressKeys.Address.ScriptPubKey, output.ScriptPubKey);

            output = result.Outputs[1];
            Assert.Equal(7500, output.Value);
            Assert.Equal(destinationKeys.PubKey.ScriptPubKey, output.ScriptPubKey);

            Assert.Equal(addressTransaction.Amount - context.TransactionFee, result.TotalOut);
            Assert.NotNull(transactionResult.GetHash());
            Assert.Equal(result.GetHash(), transactionResult.GetHash());
        }
예제 #3
0
        public void Given_AnInvalidAccountIsUsed_When_GetMaximumSpendableAmountIsCalled_Then_AnExceptionIsThrown()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var walletManager = new WalletManager(this.LoggerFactory.Object, Network.Main, new Mock <ConcurrentChain>().Object, NodeSettings.Default(),
                                                  dataFolder, new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default);

            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, It.IsAny <ConcurrentChain>(), walletManager, It.IsAny <WalletFeePolicy>(), Network.Main);

            var wallet = WalletTestsHelpers.CreateWallet("wallet1");

            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    WalletTestsHelpers.CreateAccount("account 1")
                }
            });
            walletManager.Wallets.Add(wallet);

            Exception ex = Assert.Throws <WalletException>(() => walletTransactionHandler.GetMaximumSpendableAmount(new WalletAccountReference("wallet1", "noaccount"), FeeType.Low, true));

            Assert.NotNull(ex);
            Assert.NotNull(ex.Message);
            Assert.NotEqual(string.Empty, ex.Message);
            Assert.IsType <WalletException>(ex);
        }
예제 #4
0
        public void VerifyCheckpoints_StratisMainnet()
        {
            var verifyableCheckpoints = new Dictionary <int, CheckpointInfo>
            {
                { 0, new CheckpointInfo(new uint256("0x0000066e91e46e5a264d42c89e1204963b2ee6be230b443e9159020539d972af"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
                { 2, new CheckpointInfo(new uint256("0xbca5936f638181e74a5f1e9999c95b0ce77da48c2688399e72bcc53a00c61eff"), new uint256("0x7d61c139a471821caa6b7635a4636e90afcfe5e195040aecbc1ad7d24924db1e")) }, // Premine
                { 50, new CheckpointInfo(new uint256("0x0353b43f4ce80bf24578e7c0141d90d7962fb3a4b4b4e5a17925ca95e943b816"), new uint256("0x7c2af3b10d13f9d2bc6063baaf7f0860d90d870c994378144f9bf85d0d555061")) },
                { 100, new CheckpointInfo(new uint256("0x688468a8aa48cd1c2197e42e7d8acd42760b7e2ac4bcab9d18ac149a673e16f6"), new uint256("0xcf2b1e9e76aaa3d96f255783eb2d907bf6ccb9c1deeb3617149278f0e4a1ab1b")) },
                { 150, new CheckpointInfo(new uint256("0xe4ae9663519abec15e28f68bdb2cb89a739aee22f53d1573048d69141db6ee5d"), new uint256("0xa6c17173e958dc716cc0892ce33dad8bc327963d78a16c436264ceae43d584ce")) },
                { 127500, new CheckpointInfo(new uint256("0x4773ca7512489df22de03aa03938412fab5b46154b05df004b97bcbeaa184078"), new uint256("0x619743c02ebaff06b90fcc5c60c52dba8aa3fdb6ba3800aae697cbb3c5483f17")) },
                { 128943, new CheckpointInfo(new uint256("0x36bcaa27a53d3adf22b2064150a297adb02ac39c24263a5ceb73856832d49679"), new uint256("0xa3a6fd04e41fcaae411a3990aaabcf5e086d2d06c72c849182b27b4de8c2c42a")) },
                { 136601, new CheckpointInfo(new uint256("0xf5c5210c55ff1ef9c04715420a82728e1647f3473e31dc478b3745a97b4a6d10"), new uint256("0x42058fabe21f7b118a9e358eaf9ef574dadefd024244899e71f2f6d618161e16")) }, // Hardfork to V2 - Drifting Bug Fix
                { 170000, new CheckpointInfo(new uint256("0x22b10952e0cf7e85bfc81c38f1490708f195bff34d2951d193cc20e9ca1fc9d5"), new uint256("0xa4942a6c99cba397cf2b18e4b912930fe1e64a7413c3d97c5a926c2af9073091")) },
                { 200000, new CheckpointInfo(new uint256("0x2391dd493be5d0ff0ef57c3b08c73eefeecc2701b80f983054bb262f7a146989"), new uint256("0x253152d129e82c30c584197deb6833502eff3ec2f30014008f75842d7bb48453")) },
                { 250000, new CheckpointInfo(new uint256("0x681c70fab7c1527246138f0cf937f0eb013838b929fbe9a831af02a60fc4bf55"), new uint256("0x24eed95e00c90618aa9d137d2ee273267285c444c9cde62a25a3e880c98a3685")) },
                { 300000, new CheckpointInfo(new uint256("0xd10ca8c2f065a49ae566c7c9d7a2030f4b8b7f71e4c6fc6b2a02509f94cdcd44"), new uint256("0x39c4dd765b49652935524248b4de4ccb604df086d0723bcd81faf5d1c2489304")) },
                { 350000, new CheckpointInfo(new uint256("0xe2b76d1a068c4342f91db7b89b66e0f2146d3a4706c21f3a262737bb7339253a"), new uint256("0xd1dd94985eaaa028c893687a7ddf89143dcf0176918f958c2d01f33d64910399")) },
                { 390000, new CheckpointInfo(new uint256("0x4682737abc2a3257fdf4c3c119deb09cbac75981969e2ffa998b4f76b7c657bb"), new uint256("0xd84b204ee94499ff65262328a428851fb4f4d2741e928cdd088fdf1deb5413b8")) },
                { 394000, new CheckpointInfo(new uint256("0x42857fa2bc15d45cdcaae83411f755b95985da1cb464ee23f6d40936df523e9f"), new uint256("0x2314b336906a2ed2a39cbdf6fc0622530709c62dbb3a3729de17154fc9d1a7c4")) },
                { 400000, new CheckpointInfo(new uint256("0x4938d5cf450b4e2d9072558971223555055aa3987b634a8bb2e97f95d1a3c501"), new uint256("0x1756c127f0ac7029cf095a6c3ed9b7d206d0e36744d8b3cef306002f9f901a31")) },
                { 450000, new CheckpointInfo(new uint256("0x7699e07ac18c25ac042deb6b985e2decfd6034cb6361de2152a2d704ef785bac"), new uint256("0xa140a86a03c4f852d8a651f6386a02a0262e7bbf841ede8b54541c011c51ba0e")) },
                { 500000, new CheckpointInfo(new uint256("0x558700d99239e64017d10910466719fe1edc6f863bd3de254b89ba828818ea47"), new uint256("0x6a0b7dab4a7aa9ea2477cddffe5a976c9423454835054a39c19d37613002638f")) },
                { 550000, new CheckpointInfo(new uint256("0x83d074957f509772b1fbbfaeb7bdc52932c540d54e205b92a7d4e92f68957eb4"), new uint256("0x012b63ad7d50606f2cafb1a7806ea90f4981c56b5407725aeeff34e3c584433c")) },
                { 600000, new CheckpointInfo(new uint256("0xcd05c75c0c47060d78508095c0766452f80e2defb6a4641ac603742a2ccf2207"), new uint256("0x1f25507e09b199a71d5879811376856e5fb3da1da3d522204c017eec3b6c4dad")) },
                { 650000, new CheckpointInfo(new uint256("0xa2814a439b33662f43bdbc8ab089d368524975bb53a08326395e57456cba8d39"), new uint256("0x192a2ef70e2280cf05aa5655f496a109b2445d0ddda62531e9bce9aaced1fe54")) },
                { 700000, new CheckpointInfo(new uint256("0x782b2506bb67bb448ff56aa946f7aad6b63a6b27d8c5818725a56b568f25b9ce"), new uint256("0xf23dc64b130d80790a83a86913f619afaeef10e1fd24e4b42af9387ec935edd6")) },
                { 750000, new CheckpointInfo(new uint256("0x4db98bd41a2f9ee845cc89ac03109686f615f4d0dcd81e0488005c1616fa692c"), new uint256("0x9f620af75bc27a0e4b503deaf7f052ba112a49bb74fb6446350642bc2ac9d93b")) },
                { 800000, new CheckpointInfo(new uint256("0x161da1d97d35d6897dbdae110617bb839805f8b02d33ac23d227a87cacbfac78"), new uint256("0xe95049a313345f26bfa90094ceb6400f43359fc43fc5f1471918d98bc4ab3bac")) },
                { 850000, new CheckpointInfo(new uint256("0xc3a249b01795b22858aa00fd0973471fcd769a14f4f9cf0abe6651ac3e6ade19"), new uint256("0x5de8766ed4cfcc3ce9d74f38196596c6f91b9ff62cbd20abbfa991dca54d2bd4")) }
            };

            var checkpoints = new Checkpoints(KnownNetworks.StratisMain, new ConsensusSettings(NodeSettings.Default(KnownNetworks.StratisTest))
            {
                UseCheckpoints = true
            });

            VerifyCheckpoints(checkpoints, verifyableCheckpoints);
        }
예제 #5
0
        public void GetLastCheckPointHeight_BitcoinRegTestNet_DoesNotLoadCheckpoints()
        {
            var checkpoints = new Checkpoints(KnownNetworks.RegTest, new ConsensusSettings(NodeSettings.Default(KnownNetworks.StratisTest))
            {
                UseCheckpoints = true
            });

            int result = checkpoints.GetLastCheckpointHeight();

            Assert.Equal(0, result);
        }
        private static MempoolManager CreateTestMempool(NodeSettings settings, out TxMempool txMemPool)
        {
            IDateTimeProvider dateTimeProvider = DateTimeProvider.Default;

            txMemPool = new TxMempool(new FeeRate(1000), dateTimeProvider, new BlockPolicyEstimator(new FeeRate(1000), NodeSettings.Default(), new LoggerFactory()), new LoggerFactory());
            var mempoolLock        = new MempoolAsyncLock();
            var coins              = new InMemoryCoinView(settings.Network.GenesisHash);
            var chain              = new ConcurrentChain(Network.Main.GetGenesis().Header);
            var mempoolPersistence = new MempoolPersistence(settings, new LoggerFactory());

            NBitcoin.Network.Main.Consensus.Options = new PosConsensusOptions();
            var consensusValidator = new PowConsensusValidator(NBitcoin.Network.Main);
            var mempoolValidator   = new MempoolValidator(txMemPool, mempoolLock, consensusValidator, dateTimeProvider, settings, chain, coins, new LoggerFactory());
            var mempoolOrphans     = new MempoolOrphans(mempoolLock, txMemPool, chain, new Bitcoin.Signals.Signals(), mempoolValidator, consensusValidator, coins, dateTimeProvider, settings, new LoggerFactory());

            return(new MempoolManager(mempoolLock, txMemPool, mempoolValidator, mempoolOrphans, dateTimeProvider, settings, mempoolPersistence, new LoggerFactory()));
        }
예제 #7
0
        public void GetCheckPoint_CheckpointExists_PoSChain_ReturnsCheckpoint()
        {
            var checkpoints = new Checkpoints(KnownNetworks.StratisMain, new ConsensusSettings(NodeSettings.Default(KnownNetworks.StratisTest))
            {
                UseCheckpoints = true
            });

            CheckpointInfo result = checkpoints.GetCheckpoint(2);

            Assert.Equal(new uint256("0xbca5936f638181e74a5f1e9999c95b0ce77da48c2688399e72bcc53a00c61eff"), result.Hash);
            Assert.Equal(new uint256("0x7d61c139a471821caa6b7635a4636e90afcfe5e195040aecbc1ad7d24924db1e"), result.StakeModifierV2);
        }
예제 #8
0
        public void Given_GetMaximumSpendableAmountIsCalled_When_ThereAreNoTransactions_Then_MaxAmountReturnsAsZero()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, new ConcurrentChain(this.Network), NodeSettings.Default(), new Mock <WalletSettings>().Object,
                                                  dataFolder, new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);

            var       walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny <WalletFeePolicy>(), this.Network, this.standardTransactionPolicy);
            HdAccount account         = WalletTestsHelpers.CreateAccount("account 1");
            HdAddress accountAddress1 = WalletTestsHelpers.CreateAddress();
            HdAddress accountAddress2 = WalletTestsHelpers.CreateAddress();

            account.ExternalAddresses.Add(accountAddress1);
            account.InternalAddresses.Add(accountAddress2);

            Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1");

            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    account
                }
            });

            walletManager.Wallets.Add(wallet);

            (Money max, Money fee)result = walletTransactionHandler.GetMaximumSpendableAmount(new WalletAccountReference("wallet1", "account 1"), FeeType.Low, true);
            Assert.Equal(Money.Zero, result.max);
            Assert.Equal(Money.Zero, result.fee);
        }
예제 #9
0
        public void BuildTransactionFeeTooLowThrowsWalletException()
        {
            Assert.Throws <WalletException>(() =>
            {
                var walletFeePolicy = new Mock <IWalletFeePolicy>();
                walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
                .Returns(new FeeRate(0));

                Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
                (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
                (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
                (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");
                (PubKey PubKey, BitcoinPubKeyAddress Address)changeKeys      = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "1/0");

                var address = new HdAddress
                {
                    Index        = 0,
                    HdPath       = $"m/44'/0'/0'/0/0",
                    Address      = spendingKeys.Address.ToString(),
                    Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                    ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                    Transactions = new List <TransactionData>()
                };

                var chain = new ConcurrentChain(wallet.Network);
                WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address);

                wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
                {
                    Index             = 0,
                    Name              = "account1",
                    HdPath            = "m/44'/0'/0'",
                    ExtendedPubKey    = accountKeys.ExtPubKey,
                    ExternalAddresses = new List <HdAddress> {
                        address
                    },
                    InternalAddresses = new List <HdAddress>
                    {
                        new HdAddress {
                            Index        = 0,
                            HdPath       = $"m/44'/0'/0'/1/0",
                            Address      = changeKeys.Address.ToString(),
                            Pubkey       = changeKeys.PubKey.ScriptPubKey,
                            ScriptPubKey = changeKeys.Address.ScriptPubKey,
                            Transactions = new List <TransactionData>()
                        }
                    }
                });

                string dataDir    = "TestData/WalletTransactionHandlerTest/BuildTransactionFeeTooLowThrowsWalletException";
                var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, chain, NodeSettings.Default(), new Mock <WalletSettings>().Object,
                                                      new DataFolder(new NodeSettings(args: new string[] { $"-datadir={dataDir}" }).DataDir), walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);
                var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy);

                walletManager.Wallets.Add(wallet);

                var walletReference = new WalletAccountReference
                {
                    AccountName = "account1",
                    WalletName  = "myWallet1"
                };

                walletTransactionHandler.BuildTransaction(CreateContext(this.Network, walletReference, "password", destinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0));
            });
        }
예제 #10
0
        public void BuildTransactionNoSpendableTransactionsThrowsWalletException()
        {
            Assert.Throws <WalletException>(() =>
            {
                Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
                wallet.AccountsRoot.ElementAt(0).Accounts.Add(
                    new HdAccount
                {
                    Name = "account1",
                    ExternalAddresses = new List <HdAddress>(),
                    InternalAddresses = new List <HdAddress>()
                });

                BlockHeader blockHeader = this.Network.Consensus.ConsensusFactory.CreateBlockHeader();
                var chain = new ConcurrentChain(this.Network, new ChainedHeader(blockHeader, blockHeader.GetHash(), 1));

                string dataDir    = "TestData/WalletTransactionHandlerTest/BuildTransactionNoSpendableTransactionsThrowsWalletException";
                var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, chain, NodeSettings.Default(), new Mock <WalletSettings>().Object,
                                                      new DataFolder(new NodeSettings(args: new string[] { $"-datadir={dataDir}" }).DataDir), new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default, new ScriptAddressReader());
                var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, new Mock <IWalletFeePolicy>().Object, this.Network, new StandardTransactionPolicy(this.Network));

                walletManager.Wallets.Add(wallet);

                var walletReference = new WalletAccountReference
                {
                    AccountName = "account1",
                    WalletName  = "myWallet1"
                };

                walletTransactionHandler.BuildTransaction(CreateContext(this.Network, walletReference, "password", new Script(), new Money(500), FeeType.Medium, 2));
            });
        }
예제 #11
0
        public void Given_GetMaximumSpendableAmountIsCalled_When_ThereAreNoConfirmedSpendableFound_Then_MaxAmountReturnsAsTheSumOfUnconfirmedTxs()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations())).Returns(new FeeRate(20000));

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, new ConcurrentChain(this.Network), NodeSettings.Default(), new Mock <WalletSettings>().Object,
                                                  dataFolder, new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);

            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy);

            HdAccount account = WalletTestsHelpers.CreateAccount("account 1");

            HdAddress accountAddress1 = WalletTestsHelpers.CreateAddress();

            accountAddress1.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(15000), null, null, null, new Key().ScriptPubKey));
            accountAddress1.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(2), new Money(10000), null, null, null, new Key().ScriptPubKey));

            HdAddress accountAddress2 = WalletTestsHelpers.CreateAddress();

            accountAddress2.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(3), new Money(20000), null, null, null, new Key().ScriptPubKey));
            accountAddress2.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(4), new Money(120000), null, null, null, new Key().ScriptPubKey));

            account.ExternalAddresses.Add(accountAddress1);
            account.InternalAddresses.Add(accountAddress2);

            Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1");

            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    account
                }
            });

            walletManager.Wallets.Add(wallet);

            (Money max, Money fee)result = walletTransactionHandler.GetMaximumSpendableAmount(new WalletAccountReference("wallet1", "account 1"), FeeType.Low, true);
            Assert.Equal(new Money(165000), result.max + result.fee);
        }
예제 #12
0
                 WalletAccountReference walletReference) SetupWallet()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");

            (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            var chain = new ConcurrentChain(wallet.Network);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address);
            TransactionData addressTransaction = address.Transactions.First();

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
            .Returns(new FeeRate(20000));

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, chain, NodeSettings.Default(),
                                                  new Mock <WalletSettings>().Object, dataFolder,
                                                  walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);
            var walletTransactionHandler =
                new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            return(wallet, accountKeys, destinationKeys, addressTransaction, walletTransactionHandler, walletReference);
        }
예제 #13
0
 /// <summary>
 /// Initializes an instance of the object from the default configuration.
 /// </summary>
 public MempoolSettings() : this(NodeSettings.Default())
 {
 }
        public void Given_GetMaximumSpendableAmountIsCalledForConfirmedTransactions_When_ThereAreNoConfirmedSpendableFound_Then_MaxAmountReturnsAsZero()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var walletManager = new WalletManager(this.LoggerFactory.Object, Network.Main, new ConcurrentChain(Network.Main), NodeSettings.Default(), new Mock <WalletSettings>().Object,
                                                  dataFolder, new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default);

            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny <WalletFeePolicy>(), Network.Main);

            HdAccount account = WalletTestsHelpers.CreateAccount("account 1");

            HdAddress accountAddress1 = WalletTestsHelpers.CreateAddress();

            accountAddress1.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(15000), null));
            accountAddress1.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(2), new Money(10000), null));

            HdAddress accountAddress2 = WalletTestsHelpers.CreateAddress();

            accountAddress2.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(3), new Money(20000), null));
            accountAddress2.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(4), new Money(120000), null));

            account.ExternalAddresses.Add(accountAddress1);
            account.InternalAddresses.Add(accountAddress2);

            Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1");

            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    account
                }
            });

            walletManager.Wallets.Add(wallet);

            (Money max, Money fee)result = walletTransactionHandler.GetMaximumSpendableAmount(new WalletAccountReference("wallet1", "account 1"), FeeType.Low, false);
            Assert.Equal(Money.Zero, result.max);
            Assert.Equal(Money.Zero, result.fee);
        }
예제 #15
0
        public void MempoolAncestorIndexingTest()
        {
            var settings = NodeSettings.Default();
            var pool     = new TxMempool(DateTimeProvider.Default, new BlockPolicyEstimator(new MempoolSettings(settings), settings.LoggerFactory, settings), settings.LoggerFactory, settings);
            var entry    = new TestMemPoolEntryHelper();

            /* 3rd highest fee */
            Transaction tx1 = new Transaction();

            tx1.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx1.GetHash(), entry.Fee(new Money(10000L)).Priority(10.0).FromTx(tx1));

            /* highest fee */
            Transaction tx2 = new Transaction();

            tx2.AddOutput(new TxOut(new Money(2 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx2.GetHash(), entry.Fee(new Money(20000L)).Priority(9.0).FromTx(tx2));
            var tx2Size = tx2.GetVirtualSize();

            /* lowest fee */
            Transaction tx3 = new Transaction();

            tx3.AddOutput(new TxOut(new Money(5 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx3.GetHash(), entry.Fee(new Money(0L)).Priority(100.0).FromTx(tx3));

            /* 2nd highest fee */
            Transaction tx4 = new Transaction();

            tx4.AddOutput(new TxOut(new Money(6 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx4.GetHash(), entry.Fee(new Money(15000L)).Priority(1.0).FromTx(tx4));

            /* equal fee rate to tx1, but newer */
            Transaction tx5 = new Transaction();

            tx5.AddOutput(new TxOut(new Money(11 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx5.GetHash(), entry.Fee(new Money(10000L)).Priority(1.0).FromTx(tx5));

            // assert size
            Assert.Equal(5, pool.Size);

            List <string> sortedOrder = new List <string>(5);

            sortedOrder.Insert(0, tx2.GetHash().ToString()); // 20000
            sortedOrder.Insert(1, tx4.GetHash().ToString()); // 15000

            // tx1 and tx5 are both 10000
            // Ties are broken by hash, not timestamp, so determine which
            // hash comes first.
            if (tx1.GetHash() < tx5.GetHash())
            {
                sortedOrder.Insert(2, tx1.GetHash().ToString());
                sortedOrder.Insert(3, tx5.GetHash().ToString());
            }
            else
            {
                sortedOrder.Insert(2, tx5.GetHash().ToString());
                sortedOrder.Insert(3, tx1.GetHash().ToString());
            }
            sortedOrder.Insert(4, tx3.GetHash().ToString()); // 0
            this.CheckSort(pool, pool.MapTx.AncestorScore.ToList(), sortedOrder);

            /* low fee parent with high fee child */
            /* tx6 (0) -> tx7 (high) */
            Transaction tx6 = new Transaction();

            tx6.AddOutput(new TxOut(new Money(20 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx6.GetHash(), entry.Fee(new Money(0L)).FromTx(tx6));
            var tx6Size = tx6.GetVirtualSize();

            Assert.Equal(6, pool.Size);
            // Ties are broken by hash
            if (tx3.GetHash() < tx6.GetHash())
            {
                sortedOrder.Add(tx6.GetHash().ToString());
            }
            else
            {
                sortedOrder.Insert(sortedOrder.Count - 1, tx6.GetHash().ToString());
            }
            this.CheckSort(pool, pool.MapTx.AncestorScore.ToList(), sortedOrder);

            Transaction tx7 = new Transaction();

            tx7.AddInput(new TxIn(new OutPoint(tx6.GetHash(), 0), new Script(OpcodeType.OP_11)));
            tx7.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            var   tx7Size = tx7.GetVirtualSize();
            Money fee     = (20000 / tx2Size) * (tx7Size + tx6Size) - 1;

            pool.AddUnchecked(tx7.GetHash(), entry.Fee(fee).FromTx(tx7));
            Assert.Equal(7, pool.Size);
            sortedOrder.Insert(1, tx7.GetHash().ToString());
            this.CheckSort(pool, pool.MapTx.AncestorScore.ToList(), sortedOrder);

            /* after tx6 is mined, tx7 should move up in the sort */
            List <Transaction> vtx = new List <Transaction>(new[] { tx6 });

            pool.RemoveForBlock(vtx, 1);

            sortedOrder.RemoveAt(1);
            // Ties are broken by hash
            if (tx3.GetHash() < tx6.GetHash())
            {
                sortedOrder.Remove(sortedOrder.Last());
            }
            else
            {
                sortedOrder.RemoveAt(sortedOrder.Count - 2);
            }
            sortedOrder.Insert(0, tx7.GetHash().ToString());
            this.CheckSort(pool, pool.MapTx.AncestorScore.ToList(), sortedOrder);
        }
예제 #16
0
 public static PowBlockDefinition AssemblerForTest(TestContext testContext)
 {
     return(new PowBlockDefinition(testContext.consensus, testContext.DateTimeProvider, new LoggerFactory(), testContext.mempool, testContext.mempoolLock, new MinerSettings(NodeSettings.Default(testContext.network)), testContext.network, testContext.ConsensusRules, new NodeDeployments(testContext.network, testContext.ChainIndexer)));
 }
예제 #17
0
        public void MempoolSizeLimitTest()
        {
            var settings    = NodeSettings.Default();
            var dateTimeSet = new DateTimeProviderSet();
            var pool        = new TxMempool(dateTimeSet, new BlockPolicyEstimator(new MempoolSettings(settings), settings.LoggerFactory, settings), settings.LoggerFactory, settings);
            var entry       = new TestMemPoolEntryHelper();

            entry.Priority(10.0);

            Transaction tx1 = new Transaction();

            tx1.AddInput(new TxIn(new Script(OpcodeType.OP_1)));
            tx1.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_1, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx1.GetHash(), entry.Fee(10000L).FromTx(tx1, pool));

            Transaction tx2 = new Transaction();

            tx2.AddInput(new TxIn(new Script(OpcodeType.OP_2)));
            tx2.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_2, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx2.GetHash(), entry.Fee(5000L).FromTx(tx2, pool));

            pool.TrimToSize(pool.DynamicMemoryUsage()); // should do nothing
            Assert.True(pool.Exists(tx1.GetHash()));
            Assert.True(pool.Exists(tx2.GetHash()));

            pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); // should remove the lower-feerate transaction
            Assert.True(pool.Exists(tx1.GetHash()));
            Assert.True(!pool.Exists(tx2.GetHash()));

            pool.AddUnchecked(tx2.GetHash(), entry.FromTx(tx2, pool));
            Transaction tx3 = new Transaction();

            tx3.AddInput(new TxIn(new OutPoint(tx2.GetHash(), 0), new Script(OpcodeType.OP_2)));
            tx3.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_3, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx3.GetHash(), entry.Fee(20000L).FromTx(tx3, pool));

            pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); // tx3 should pay for tx2 (CPFP)
            Assert.True(!pool.Exists(tx1.GetHash()));
            Assert.True(pool.Exists(tx2.GetHash()));
            Assert.True(pool.Exists(tx3.GetHash()));

            pool.TrimToSize(tx1.GetVirtualSize()); // mempool is limited to tx1's size in memory usage, so nothing fits
            Assert.True(!pool.Exists(tx1.GetHash()));
            Assert.True(!pool.Exists(tx2.GetHash()));
            Assert.True(!pool.Exists(tx3.GetHash()));

            FeeRate maxFeeRateRemoved = new FeeRate(25000, tx3.GetVirtualSize() + tx2.GetVirtualSize());

            Assert.Equal(pool.GetMinFee(1).FeePerK, maxFeeRateRemoved.FeePerK + 1000);

            Transaction tx4 = new Transaction();

            tx4.AddInput(new TxIn(new Script(OpcodeType.OP_4)));
            tx4.AddInput(new TxIn(new Script(OpcodeType.OP_4)));
            tx4.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_4, OpcodeType.OP_EQUAL)));
            tx4.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_4, OpcodeType.OP_EQUAL)));

            Transaction tx5 = new Transaction();

            tx5.AddInput(new TxIn(new OutPoint(tx4.GetHash(), 0), new Script(OpcodeType.OP_4)));
            tx5.AddInput(new TxIn(new Script(OpcodeType.OP_5)));
            tx5.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_5, OpcodeType.OP_EQUAL)));
            tx5.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_5, OpcodeType.OP_EQUAL)));

            Transaction tx6 = new Transaction();

            tx6.AddInput(new TxIn(new OutPoint(tx4.GetHash(), 0), new Script(OpcodeType.OP_4)));
            tx6.AddInput(new TxIn(new Script(OpcodeType.OP_6)));
            tx6.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_6, OpcodeType.OP_EQUAL)));
            tx6.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_6, OpcodeType.OP_EQUAL)));

            Transaction tx7 = new Transaction();

            tx7.AddInput(new TxIn(new OutPoint(tx5.GetHash(), 0), new Script(OpcodeType.OP_5)));
            tx7.AddInput(new TxIn(new OutPoint(tx6.GetHash(), 0), new Script(OpcodeType.OP_6)));
            tx7.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_7, OpcodeType.OP_EQUAL)));
            tx7.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_7, OpcodeType.OP_EQUAL)));

            pool.AddUnchecked(tx4.GetHash(), entry.Fee(7000L).FromTx(tx4, pool));
            pool.AddUnchecked(tx5.GetHash(), entry.Fee(1000L).FromTx(tx5, pool));
            pool.AddUnchecked(tx6.GetHash(), entry.Fee(1100L).FromTx(tx6, pool));
            pool.AddUnchecked(tx7.GetHash(), entry.Fee(9000L).FromTx(tx7, pool));

            // we only require this remove, at max, 2 txn, because its not clear what we're really optimizing for aside from that
            pool.TrimToSize(pool.DynamicMemoryUsage() - 1);
            Assert.True(pool.Exists(tx4.GetHash()));
            Assert.True(pool.Exists(tx6.GetHash()));
            Assert.True(!pool.Exists(tx7.GetHash()));

            if (!pool.Exists(tx5.GetHash()))
            {
                pool.AddUnchecked(tx5.GetHash(), entry.Fee(1000L).FromTx(tx5, pool));
            }
            pool.AddUnchecked(tx7.GetHash(), entry.Fee(9000L).FromTx(tx7, pool));

            pool.TrimToSize(pool.DynamicMemoryUsage() / 2); // should maximize mempool size by only removing 5/7
            Assert.True(pool.Exists(tx4.GetHash()));
            Assert.True(!pool.Exists(tx5.GetHash()));
            Assert.True(pool.Exists(tx6.GetHash()));
            Assert.True(!pool.Exists(tx7.GetHash()));

            pool.AddUnchecked(tx5.GetHash(), entry.Fee(1000L).FromTx(tx5, pool));
            pool.AddUnchecked(tx7.GetHash(), entry.Fee(9000L).FromTx(tx7, pool));

            List <Transaction> vtx = new List <Transaction>();

            dateTimeSet.time = 42 + TxMempool.RollingFeeHalflife;
            Assert.Equal(pool.GetMinFee(1).FeePerK.Satoshi, maxFeeRateRemoved.FeePerK.Satoshi + 1000);
            // ... we should keep the same min fee until we get a block
            pool.RemoveForBlock(vtx, 1);
            dateTimeSet.time = 42 + 2 * +TxMempool.RollingFeeHalflife;
            Assert.Equal(pool.GetMinFee(1).FeePerK.Satoshi, (maxFeeRateRemoved.FeePerK.Satoshi + 1000) / 2);
            // ... then feerate should drop 1/2 each halflife

            dateTimeSet.time = 42 + 2 * TxMempool.RollingFeeHalflife + TxMempool.RollingFeeHalflife / 2;
            Assert.Equal(pool.GetMinFee(pool.DynamicMemoryUsage() * 5 / 2).FeePerK.Satoshi, (maxFeeRateRemoved.FeePerK.Satoshi + 1000) / 4);
            // ... with a 1/2 halflife when mempool is < 1/2 its target size

            dateTimeSet.time = 42 + 2 * TxMempool.RollingFeeHalflife + TxMempool.RollingFeeHalflife / 2 + TxMempool.RollingFeeHalflife / 4;
            Assert.Equal(pool.GetMinFee(pool.DynamicMemoryUsage() * 9 / 2).FeePerK.Satoshi, (maxFeeRateRemoved.FeePerK.Satoshi + 1000) / 8);
            // ... with a 1/4 halflife when mempool is < 1/4 its target size

            dateTimeSet.time = 42 + 7 * TxMempool.RollingFeeHalflife + TxMempool.RollingFeeHalflife / 2 + TxMempool.RollingFeeHalflife / 4;
            Assert.Equal(1000, pool.GetMinFee(1).FeePerK.Satoshi);
            // ... but feerate should never drop below 1000

            dateTimeSet.time = 42 + 8 * TxMempool.RollingFeeHalflife + TxMempool.RollingFeeHalflife / 2 + TxMempool.RollingFeeHalflife / 4;
            Assert.Equal(0, pool.GetMinFee(1).FeePerK);
            // ... unless it has gone all the way to 0 (after getting past 1000/2)
        }
        public void EnsureTimestampIsNotTooNew()
        {
            long     timestamp = new DateTimeProvider().GetUtcNow().ToUnixTimestamp() / this.consensusOptions.TargetSpacingSeconds * this.consensusOptions.TargetSpacingSeconds;
            DateTime time      = DateTimeOffset.FromUnixTimeSeconds(timestamp).DateTime;

            // Pretend we receive the next block right on its timestamp
            var provider = new Mock <IDateTimeProvider>();

            provider.Setup(x => x.GetAdjustedTime()).Returns(time + TimeSpan.FromSeconds(this.consensusOptions.TargetSpacingSeconds));

            this.rulesEngine = new PoAConsensusRuleEngine(this.network, this.loggerFactory, provider.Object, this.ChainIndexer, new NodeDeployments(this.network, this.ChainIndexer),
                                                          this.consensusSettings, new Checkpoints(this.network, this.consensusSettings), new Mock <ICoinView>().Object, new ChainState(), new InvalidBlockHashStore(provider.Object),
                                                          new NodeStats(provider.Object, NodeSettings.Default(this.network), new Mock <IVersionProvider>().Object), this.slotsManager, this.poaHeaderValidator, this.votingManager, this.federationManager, this.asyncProvider,
                                                          new ConsensusRulesContainer(), null);

            this.timeChecksRule.Parent = this.rulesEngine;
            this.timeChecksRule.Initialize();

            var validationContext = new ValidationContext()
            {
                ChainedHeaderToValidate = this.currentHeader
            };
            var ruleContext = new RuleContext(validationContext, time);

            ChainedHeader prevHeader = this.currentHeader.Previous;

            prevHeader.Header.BlockTime = time;

            // There is no "valid future offset" as the time is restricted to be accurate within 1 target spacing.
            this.currentHeader.Header.BlockTime = prevHeader.Header.BlockTime + TimeSpan.FromSeconds(this.consensusOptions.TargetSpacingSeconds);
            this.timeChecksRule.Run(ruleContext);

            // Send a block too far into the future, more than a targetspacing away
            this.currentHeader.Header.BlockTime = this.currentHeader.Header.BlockTime + TimeSpan.FromSeconds(this.consensusOptions.TargetSpacingSeconds);
            Assert.Throws <ConsensusErrorException>(() => this.timeChecksRule.Run(ruleContext));

            try
            {
                this.timeChecksRule.Run(ruleContext);
            }
            catch (ConsensusErrorException exception)
            {
                Assert.Equal(ConsensusErrors.TimeTooNew, exception.ConsensusError);
            }
        }
예제 #19
0
        public void WhiteListedEndpoint_CanBeMappedAndRoutedTo_OtherNode()
        {
            IPEndPoint endpointA   = null;
            IPEndPoint endpointB   = null;
            IPEndPoint endpointOut = null;

            var connectionManagerSettings = new ConnectionManagerSettings(NodeSettings.Default(this.Network));
            var networkEndpoints          = connectionManagerSettings.Bind.Select(x => x.Endpoint).ToList();

            // IPV4: 127.0.0.1:16178 != 0.0.0.0:16178 (both are considered local endpoints)
            endpointA        = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 16178);
            endpointB        = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 16178);
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            connectionManagerSettings.Port = 16178;
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // IPV6: [::1]:16178 != [::]:16178
            endpointA        = new IPEndPoint(IPAddress.Parse("[::1]"), 16178);
            endpointB        = new IPEndPoint(IPAddress.Parse("[::]"), 16178);
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            connectionManagerSettings.Port = 16178;
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // 127.0.0.1:16178 != 0.0.0.0:44556
            endpointA        = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 16178);
            endpointB        = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 44556);
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            connectionManagerSettings.Port = 44556;
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // 0.0.0.0:16178 == 127.0.0.1:16178
            endpointA        = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 16178);
            endpointB        = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 16178);
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            connectionManagerSettings.Port = 16178;
            Assert.True(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // IPV4: 0.0.0.0:16178 == 127.0.0.2:16178
            endpointA = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 16178);
            endpointB = new IPEndPoint(IPAddress.Parse("127.0.0.2"), 16178);
            connectionManagerSettings.Port = 16178;
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            Assert.True(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // IPV6: [::]:16178 == [::1]:16178
            endpointA = new IPEndPoint(IPAddress.Parse("[::]"), 16178);
            endpointB = new IPEndPoint(IPAddress.Parse("[::1]"), 16178);
            connectionManagerSettings.Port = 16178;
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            Assert.True(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // IPV4: 0.0.0.0:16178 == 127.0.0.2:999
            endpointA        = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 16178);
            endpointB        = new IPEndPoint(IPAddress.Parse("127.0.0.2"), 999);
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            connectionManagerSettings.Port = 999;
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // IPV6: [::]:16178 != [::2]:999
            endpointA = new IPEndPoint(IPAddress.Parse("[::]"), 16178);
            endpointB = new IPEndPoint(IPAddress.Parse("[::2]"), 999);
            connectionManagerSettings.Port = 999;
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // IPV6: [::1] != [fe80::d111:a4c4:ce4:2bc7%21] (Localhost -> Network address).
            endpointA = new IPEndPoint(IPAddress.Parse("[::1]"), 16178);
            endpointB = new IPEndPoint(IPAddress.Parse("[fe80::d111:a4c4:ce4:2bc7%21]"), 16178);
            connectionManagerSettings.Port = 16178;
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // 10.0.0.1:16178 != 192.168.1.1:16178 (Bound to any but whitelisting local).
            endpointA        = new IPEndPoint(IPAddress.Parse("192.168.1.1"), 16178);
            endpointB        = new IPEndPoint(IPAddress.Parse("10.0.0.1"), 16178);
            networkEndpoints = new List <IPEndPoint>()
            {
                endpointB
            };
            connectionManagerSettings.Port = 16178;
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // Using whitebind = 0.0.0.0:16178 and connecting from local or remote IP address on port 16178 should be whitebinded.
            endpointA = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 16178);
            endpointB = new IPEndPoint(IPAddress.Parse("10.0.0.1"), 16178);
            Assert.True(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // Using whitebind = 100.64.1.1:16178 and connecting from local or remote IP address(other than 100.64.1.1) on port 16178 should not be whitebinded.
            endpointA = new IPEndPoint(IPAddress.Parse("100.64.1.1"), 16178);
            endpointB = new IPEndPoint(IPAddress.Parse("100.64.1.2"), 16178);
            Assert.False(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));

            // Using whitebind = 0.0.0.0:16178 and connecting from local or remote IP address on port other than 16178 should be not whitebinded.
            endpointA = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 16178);
            endpointB = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 16179);
            Assert.True(endpointA.CanBeMappedTo(networkEndpoints, out endpointOut));
        }
예제 #20
0
        public void BlockPolicyEstimates()
        {
            var          dateTimeSet = new DateTimeProviderSet();
            NodeSettings settings    = NodeSettings.Default();
            var          mpool       = new TxMempool(DateTimeProvider.Default,
                                                     new BlockPolicyEstimator(new MempoolSettings(settings), settings.LoggerFactory, settings), settings.LoggerFactory, settings);
            var entry    = new TestMemPoolEntryHelper();
            var basefee  = new Money(2000);
            var deltaFee = new Money(100);
            var feeV     = new List <Money>();

            // Populate vectors of increasing fees
            for (int j = 0; j < 10; j++)
            {
                feeV.Add(basefee * (j + 1));
            }

            // Store the hashes of transactions that have been
            // added to the mempool by their associate fee
            // txHashes[j] is populated with transactions either of
            // fee = basefee * (j+1)
            var txHashes = new List <uint256> [10];

            for (int i = 0; i < txHashes.Length; i++)
            {
                txHashes[i] = new List <uint256>();
            }

            // Create a transaction template
            var garbage = new Script(Enumerable.Range(0, 128).Select(i => (byte)1).ToArray());

            var txf = new Transaction();

            txf.AddInput(new TxIn(garbage));
            txf.AddOutput(new TxOut(0L, Script.Empty));
            var baseRate = new FeeRate(basefee, txf.GetVirtualSize());

            // Create a fake block
            var block    = new List <Transaction>();
            int blocknum = 0;
            int answerFound;

            // Loop through 200 blocks
            // At a decay .998 and 4 fee transactions per block
            // This makes the tx count about 1.33 per bucket, above the 1 threshold
            while (blocknum < 200)
            {
                for (int j = 0; j < 10; j++)
                {                                                                        // For each fee
                    for (int k = 0; k < 4; k++)
                    {                                                                    // add 4 fee txs
                        Transaction tx = txf.Clone(false, Network.Main);
                        tx.Inputs[0].PrevOut.N = (uint)(10000 * blocknum + 100 * j + k); // make transaction unique
                        uint256 hash = tx.GetHash();
                        mpool.AddUnchecked(hash, entry.Fee(feeV[j]).Time(dateTimeSet.GetTime()).Priority(0).Height(blocknum).FromTx(tx, mpool));
                        txHashes[j].Add(hash);
                    }
                }
                //Create blocks where higher fee txs are included more often
                for (int h = 0; h <= blocknum % 10; h++)
                {
                    // 10/10 blocks add highest fee transactions
                    // 9/10 blocks add 2nd highest and so on until ...
                    // 1/10 blocks add lowest fee transactions
                    while (txHashes[9 - h].Count > 0)
                    {
                        Transaction ptx = mpool.Get(txHashes[9 - h].Last());
                        if (ptx != null)
                        {
                            block.Add(ptx);
                        }
                        txHashes[9 - h].Remove(txHashes[9 - h].Last());
                    }
                }
                mpool.RemoveForBlock(block, ++blocknum);
                block.Clear();
                if (blocknum == 30)
                {
                    // At this point we should need to combine 5 buckets to get enough data points
                    // So estimateFee(1,2,3) should fail and estimateFee(4) should return somewhere around
                    // 8*baserate.  estimateFee(4) %'s are 100,100,100,100,90 = average 98%
                    Assert.True(mpool.EstimateFee(1) == new FeeRate(0));
                    Assert.True(mpool.EstimateFee(2) == new FeeRate(0));
                    Assert.True(mpool.EstimateFee(3) == new FeeRate(0));
                    Assert.True(mpool.EstimateFee(4).FeePerK < 8 * baseRate.FeePerK + deltaFee);
                    Assert.True(mpool.EstimateFee(4).FeePerK > 8 * baseRate.FeePerK - deltaFee);

                    Assert.True(mpool.EstimateSmartFee(1, out answerFound) == mpool.EstimateFee(4) && answerFound == 4);
                    Assert.True(mpool.EstimateSmartFee(3, out answerFound) == mpool.EstimateFee(4) && answerFound == 4);
                    Assert.True(mpool.EstimateSmartFee(4, out answerFound) == mpool.EstimateFee(4) && answerFound == 4);
                    Assert.True(mpool.EstimateSmartFee(8, out answerFound) == mpool.EstimateFee(8) && answerFound == 8);
                }
            }

            var origFeeEst = new List <Money>();

            // Highest feerate is 10*baseRate and gets in all blocks,
            // second highest feerate is 9*baseRate and gets in 9/10 blocks = 90%,
            // third highest feerate is 8*base rate, and gets in 8/10 blocks = 80%,
            // so estimateFee(1) would return 10*baseRate but is hardcoded to return failure
            // Second highest feerate has 100% chance of being included by 2 blocks,
            // so estimateFee(2) should return 9*baseRate etc...
            for (int i = 1; i < 10; i++)
            {
                origFeeEst.Add(mpool.EstimateFee(i).FeePerK);
                if (i > 2)
                { // Fee estimates should be monotonically decreasing
                    Assert.True(origFeeEst[i - 1] <= origFeeEst[i - 2]);
                }
                int mult = 11 - i;
                if (i > 1)
                {
                    Assert.True(origFeeEst[i - 1] < mult * baseRate.FeePerK + deltaFee);
                    Assert.True(origFeeEst[i - 1] > mult * baseRate.FeePerK - deltaFee);
                }
                else
                {
                    Assert.True(origFeeEst[i - 1] == new FeeRate(0).FeePerK);
                }
            }

            // Mine 50 more blocks with no transactions happening, estimates shouldn't change
            // We haven't decayed the moving average enough so we still have enough data points in every bucket
            while (blocknum < 250)
            {
                mpool.RemoveForBlock(block, ++blocknum);
            }

            Assert.True(mpool.EstimateFee(1) == new FeeRate(0));
            for (int i = 2; i < 10; i++)
            {
                Assert.True(mpool.EstimateFee(i).FeePerK < origFeeEst[i - 1] + deltaFee);
                Assert.True(mpool.EstimateFee(i).FeePerK > origFeeEst[i - 1] - deltaFee);
            }

            // Mine 15 more blocks with lots of transactions happening and not getting mined
            // Estimates should go up
            while (blocknum < 265)
            {
                for (int j = 0; j < 10; j++)
                {     // For each fee multiple
                    for (int k = 0; k < 4; k++)
                    { // add 4 fee txs
                        Transaction tx = txf.Clone(false, Network.Main);
                        tx.Inputs[0].PrevOut.N = (uint)(10000 * blocknum + 100 * j + k);
                        uint256 hash = tx.GetHash();
                        mpool.AddUnchecked(hash, entry.Fee(feeV[j]).Time(dateTimeSet.GetTime()).Priority(0).Height(blocknum).FromTx(tx, mpool));
                        txHashes[j].Add(hash);
                    }
                }
                mpool.RemoveForBlock(block, ++blocknum);
            }

            for (int i = 1; i < 10; i++)
            {
                Assert.True(mpool.EstimateFee(i) == new FeeRate(0) || mpool.EstimateFee(i).FeePerK > origFeeEst[i - 1] - deltaFee);
                Assert.True(mpool.EstimateSmartFee(i, out answerFound).FeePerK > origFeeEst[answerFound - 1] - deltaFee);
            }

            // Mine all those transactions
            // Estimates should still not be below original
            for (int j = 0; j < 10; j++)
            {
                while (txHashes[j].Count > 0)
                {
                    Transaction ptx = mpool.Get(txHashes[j].Last());
                    if (ptx != null)
                    {
                        block.Add(ptx);
                    }
                    txHashes[j].Remove(txHashes[j].Last());
                }
            }
            mpool.RemoveForBlock(block, 265);
            block.Clear();
            Assert.True(mpool.EstimateFee(1) == new FeeRate(0));
            for (int i = 2; i < 10; i++)
            {
                Assert.True(mpool.EstimateFee(i).FeePerK > origFeeEst[i - 1] - deltaFee);
            }

            // Mine 200 more blocks where everything is mined every block
            // Estimates should be below original estimates
            while (blocknum < 465)
            {
                for (int j = 0; j < 10; j++)
                {     // For each fee multiple
                    for (int k = 0; k < 4; k++)
                    { // add 4 fee txs
                        Transaction tx = txf.Clone(false, Network.Main);
                        tx.Inputs[0].PrevOut.N = (uint)(10000 * blocknum + 100 * j + k);
                        uint256 hash = tx.GetHash();
                        mpool.AddUnchecked(hash, entry.Fee(feeV[j]).Time(dateTimeSet.GetTime()).Priority(0).Height(blocknum).FromTx(tx, mpool));
                        Transaction ptx = mpool.Get(hash);
                        if (ptx != null)
                        {
                            block.Add(ptx);
                        }
                    }
                }
                mpool.RemoveForBlock(block, ++blocknum);
                block.Clear();
            }
            Assert.True(mpool.EstimateFee(1) == new FeeRate(0));
            for (int i = 2; i < 10; i++)
            {
                Assert.True(mpool.EstimateFee(i).FeePerK < origFeeEst[i - 1] - deltaFee);
            }

            // Test that if the mempool is limited, estimateSmartFee won't return a value below the mempool min fee
            // and that estimateSmartPriority returns essentially an infinite value
            mpool.AddUnchecked(txf.GetHash(), entry.Fee(feeV[5]).Time(dateTimeSet.GetTime()).Priority(0).Height(blocknum).FromTx(txf, mpool));
            // evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[5]
            mpool.TrimToSize(1);
            Assert.True(mpool.GetMinFee(1).FeePerK > feeV[5]);
            for (int i = 1; i < 10; i++)
            {
                Assert.True(mpool.EstimateSmartFee(i, out answerFound).FeePerK >= mpool.EstimateFee(i).FeePerK);
                Assert.True(mpool.EstimateSmartFee(i, out answerFound).FeePerK >= mpool.GetMinFee(1).FeePerK);
                Assert.True(mpool.EstimateSmartPriority(i, out answerFound) == BlockPolicyEstimator.InfPriority);
            }
        }
예제 #21
0
        public void VerifyCheckpoints_BitcoinTestnet()
        {
            var verifyableCheckpoints = new Dictionary <int, CheckpointInfo>
            {
                { 546, new CheckpointInfo(new uint256("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")) },
                { 1210000, new CheckpointInfo(new uint256("00000000461201277cf8c635fc10d042d6f0a7eaa57f6c9e8c099b9e0dbc46dc")) },
            };

            var checkpoints = new Checkpoints(KnownNetworks.TestNet, new ConsensusSettings(NodeSettings.Default(this.network))
            {
                UseCheckpoints = true
            });

            VerifyCheckpoints(checkpoints, verifyableCheckpoints);
        }
예제 #22
0
 /// <summary>
 /// Initializes an instance of the object from the default node configuration.
 /// </summary>
 public RpcSettings() : this(NodeSettings.Default())
 {
 }
예제 #23
0
        public void VerifyCheckpoints_StratisTestnet()
        {
            var verifyableCheckpoints = new Dictionary <int, CheckpointInfo>
            {
                { 0, new CheckpointInfo(new uint256("0x00000e246d7b73b88c9ab55f2e5e94d9e22d471def3df5ea448f5576b1d156b9"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
                { 2, new CheckpointInfo(new uint256("0x56959b1c8498631fb0ca5fe7bd83319dccdc6ac003dccb3171f39f553ecfa2f2"), new uint256("0x13f4c27ca813aefe2d9018077f8efeb3766796b9144fcc4cd51803bf4376ab02")) },
                { 50000, new CheckpointInfo(new uint256("0xb42c18eacf8fb5ed94eac31943bd364451d88da0fd44cc49616ffea34d530ad4"), new uint256("0x824934ddc5f935e854ac59ae7f5ed25f2d29a7c3914cac851f3eddb4baf96d78")) },
                { 100000, new CheckpointInfo(new uint256("0xf9e2f7561ee4b92d3bde400d251363a0e8924204c326da7f4ad9ccc8863aad79"), new uint256("0xdef8d92d20becc71f662ee1c32252aca129f1bf4744026b116d45d9bfe67e9fb")) },
                { 150000, new CheckpointInfo(new uint256("0x08b7c20a450252ddf9ce41dbeb92ecf54932beac9090dc8250e933ad3a175381"), new uint256("0xf05dad15f733ae0acbd34adc449be9429099dbee5fa9ecd8e524cf28e9153adb")) },
                { 200000, new CheckpointInfo(new uint256("0x8609cc873222a0573615788dc32e377b88bfd6a0015791f627d969ee3a415115"), new uint256("0xfa28c1f20a8162d133607c6a1c8997833befac3efd9076567258a7683ac181fa")) },
                { 250000, new CheckpointInfo(new uint256("0xdd664e15ac679a6f3b96a7176303956661998174a697ad8231f154f1e32ff4a3"), new uint256("0x19fc0fa29418f8b19cbb6557c1c79dfd0eff6779c0eaaec5d245c5cdf3c96d78")) },
                { 300000, new CheckpointInfo(new uint256("0x2409eb5ae72c80d5b37c77903d75a8e742a33843ab633935ce6e5264db962e23"), new uint256("0xf5ec7af55516b8e264ed280e9a5dba0180a4a9d3713351bfea275b18f3f1514e")) },
                { 350000, new CheckpointInfo(new uint256("0x36811041e9060f4b4c26dc20e0850dca5efaabb60618e3456992e9c0b1b2120e"), new uint256("0xbfda55ef0756bcee8485e15527a2b8ca27ca877aa09c88e363ef8d3253cdfd1c")) },
                { 400000, new CheckpointInfo(new uint256("0xb6abcb933d3e3590345ca5d3abb697461093313f8886568ac8ae740d223e56f6"), new uint256("0xfaf5fcebee3ec0df5155393a99da43de18b12e620fef5edb111a791ecbfaa63a")) }
            };

            var checkpoints = new Checkpoints(KnownNetworks.StratisTest, new ConsensusSettings(NodeSettings.Default(KnownNetworks.StratisTest))
            {
                UseCheckpoints = true
            });

            VerifyCheckpoints(checkpoints, verifyableCheckpoints);
        }
 /// <summary>
 /// Makes the full node builder use the default node settings.
 /// </summary>
 /// <param name="builder">Full node builder to change node settings for.</param>
 /// <returns>Interface to allow fluent code.</returns>
 public static IFullNodeBuilder UseDefaultNodeSettings(this IFullNodeBuilder builder)
 {
     return(builder.UseNodeSettings(NodeSettings.Default(builder.Network)));
 }
예제 #25
0
        public void GetLastCheckPointHeight_StratisTestnet_ReturnsLastCheckPointHeight()
        {
            var checkpoints = new Checkpoints(KnownNetworks.StratisTest, new ConsensusSettings(NodeSettings.Default(KnownNetworks.StratisTest))
            {
                UseCheckpoints = true
            });

            int result = checkpoints.GetLastCheckpointHeight();

            Assert.Equal(1150000, result);
        }
예제 #26
0
        public void MempoolIndexingTest()
        {
            var settings = NodeSettings.Default();
            var pool     = new TxMempool(DateTimeProvider.Default, new BlockPolicyEstimator(new MempoolSettings(settings), settings.LoggerFactory, settings), settings.LoggerFactory, settings);
            var entry    = new TestMemPoolEntryHelper();

            /* 3rd highest fee */
            Transaction tx1 = new Transaction();

            tx1.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx1.GetHash(), entry.Fee(new Money(10000L)).Priority(10.0).FromTx(tx1));

            /* highest fee */
            Transaction tx2 = new Transaction();

            tx2.AddOutput(new TxOut(new Money(2 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx2.GetHash(), entry.Fee(new Money(20000L)).Priority(9.0).FromTx(tx2));

            /* lowest fee */
            Transaction tx3 = new Transaction();

            tx3.AddOutput(new TxOut(new Money(5 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx3.GetHash(), entry.Fee(new Money(0L)).Priority(100.0).FromTx(tx3));

            /* 2nd highest fee */
            Transaction tx4 = new Transaction();

            tx4.AddOutput(new TxOut(new Money(6 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx4.GetHash(), entry.Fee(new Money(15000L)).Priority(1.0).FromTx(tx4));

            /* equal fee rate to tx1, but newer */
            Transaction tx5 = new Transaction();

            tx5.AddOutput(new TxOut(new Money(11 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx5.GetHash(), entry.Fee(new Money(10000L)).Priority(10.0).Time(1).FromTx(tx5));

            // assert size
            Assert.Equal(5, pool.Size);

            List <string> sortedOrder = new List <string>(5);

            sortedOrder.Insert(0, tx3.GetHash().ToString()); // 0
            sortedOrder.Insert(1, tx5.GetHash().ToString()); // 10000
            sortedOrder.Insert(2, tx1.GetHash().ToString()); // 10000
            sortedOrder.Insert(3, tx4.GetHash().ToString()); // 15000
            sortedOrder.Insert(4, tx2.GetHash().ToString()); // 20000
            this.CheckSort(pool, pool.MapTx.DescendantScore.ToList(), sortedOrder);

            /* low fee but with high fee child */
            /* tx6 -> tx7 -> tx8, tx9 -> tx10 */
            Transaction tx6 = new Transaction();

            tx6.AddOutput(new TxOut(new Money(20 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx6.GetHash(), entry.Fee(new Money(0L)).FromTx(tx6));

            // assert size
            Assert.Equal(6, pool.Size);

            // Check that at this point, tx6 is sorted low
            sortedOrder.Insert(0, tx6.GetHash().ToString());
            this.CheckSort(pool, pool.MapTx.DescendantScore.ToList(), sortedOrder);

            TxMempool.SetEntries setAncestors = new TxMempool.SetEntries();
            setAncestors.Add(pool.MapTx.TryGet(tx6.GetHash()));
            Transaction tx7 = new Transaction();

            tx7.AddInput(new TxIn(new OutPoint(tx6.GetHash(), 0), new Script(OpcodeType.OP_11)));
            tx7.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            tx7.AddOutput(new TxOut(new Money(1 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));

            TxMempool.SetEntries setAncestorsCalculated = new TxMempool.SetEntries();
            string dummy;

            Assert.True(pool.CalculateMemPoolAncestors(entry.Fee(2000000L).FromTx(tx7), setAncestorsCalculated, 100, 1000000, 1000, 1000000, out dummy));
            Assert.True(setAncestorsCalculated.Equals(setAncestors));

            pool.AddUnchecked(tx7.GetHash(), entry.FromTx(tx7), setAncestors);
            Assert.Equal(7, pool.Size);

            // Now tx6 should be sorted higher (high fee child): tx7, tx6, tx2, ...
            sortedOrder.RemoveAt(0);
            sortedOrder.Add(tx6.GetHash().ToString());
            sortedOrder.Add(tx7.GetHash().ToString());
            this.CheckSort(pool, pool.MapTx.DescendantScore.ToList(), sortedOrder);

            /* low fee child of tx7 */
            Transaction tx8 = new Transaction();

            tx8.AddInput(new TxIn(new OutPoint(tx7.GetHash(), 0), new Script(OpcodeType.OP_11)));
            tx8.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            setAncestors.Add(pool.MapTx.TryGet(tx7.GetHash()));
            pool.AddUnchecked(tx8.GetHash(), entry.Fee(0L).Time(2).FromTx(tx8), setAncestors);

            // Now tx8 should be sorted low, but tx6/tx both high
            sortedOrder.Insert(0, tx8.GetHash().ToString());
            this.CheckSort(pool, pool.MapTx.DescendantScore.ToList(), sortedOrder);

            /* low fee child of tx7 */
            Transaction tx9 = new Transaction();

            tx9.AddInput(new TxIn(new OutPoint(tx7.GetHash(), 1), new Script(OpcodeType.OP_11)));
            tx9.AddOutput(new TxOut(new Money(1 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            pool.AddUnchecked(tx9.GetHash(), entry.Fee(0L).Time(3).FromTx(tx9), setAncestors);

            // tx9 should be sorted low
            Assert.Equal(9, pool.Size);

            sortedOrder.Insert(0, tx9.GetHash().ToString());
            this.CheckSort(pool, pool.MapTx.DescendantScore.ToList(), sortedOrder);

            List <string> snapshotOrder = sortedOrder.ToList();

            setAncestors.Add(pool.MapTx.TryGet(tx8.GetHash()));
            setAncestors.Add(pool.MapTx.TryGet(tx9.GetHash()));
            /* tx10 depends on tx8 and tx9 and has a high fee*/
            Transaction tx10 = new Transaction();

            tx10.AddInput(new TxIn(new OutPoint(tx8.GetHash(), 0), new Script(OpcodeType.OP_11)));
            tx10.AddInput(new TxIn(new OutPoint(tx9.GetHash(), 0), new Script(OpcodeType.OP_11)));
            tx10.AddOutput(new TxOut(new Money(10 * Money.COIN), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));

            setAncestorsCalculated.Clear();
            Assert.True(pool.CalculateMemPoolAncestors(entry.Fee(200000L).Time(4).FromTx(tx10), setAncestorsCalculated, 100, 1000000, 1000, 1000000, out dummy));
            Assert.True(setAncestorsCalculated.Equals(setAncestors));

            pool.AddUnchecked(tx10.GetHash(), entry.FromTx(tx10), setAncestors);

            /**
             *  tx8 and tx9 should both now be sorted higher
             *  Final order after tx10 is added:
             *
             *  tx3 = 0 (1)
             *  tx5 = 10000 (1)
             *  tx1 = 10000 (1)
             *  tx4 = 15000 (1)
             *  tx2 = 20000 (1)
             *  tx9 = 200k (2 txs)
             *  tx8 = 200k (2 txs)
             *  tx10 = 200k (1 tx)
             *  tx6 = 2.2M (5 txs)
             *  tx7 = 2.2M (4 txs)
             */
            sortedOrder.RemoveRange(0, 2); // take out tx9, tx8 from the beginning
            sortedOrder.Insert(5, tx9.GetHash().ToString());
            sortedOrder.Insert(6, tx8.GetHash().ToString());
            sortedOrder.Insert(7, tx10.GetHash().ToString()); // tx10 is just before tx6
            this.CheckSort(pool, pool.MapTx.DescendantScore.ToList(), sortedOrder);

            // there should be 10 transactions in the mempool
            Assert.Equal(10, pool.Size);

            // Now try removing tx10 and verify the sort order returns to normal
            pool.RemoveRecursive(pool.MapTx.TryGet(tx10.GetHash()).Transaction);
            this.CheckSort(pool, pool.MapTx.DescendantScore.ToList(), snapshotOrder);

            pool.RemoveRecursive(pool.MapTx.TryGet(tx9.GetHash()).Transaction);
            pool.RemoveRecursive(pool.MapTx.TryGet(tx8.GetHash()).Transaction);

            /* Now check the sort on the mining score index.
             * Final order should be:
             *
             * tx7 (2M)
             * tx2 (20k)
             * tx4 (15000)
             * tx1/tx5 (10000)
             * tx3/6 (0)
             * (Ties resolved by hash)
             */
            sortedOrder.Clear();
            sortedOrder.Add(tx7.GetHash().ToString());
            sortedOrder.Add(tx2.GetHash().ToString());
            sortedOrder.Add(tx4.GetHash().ToString());
            if (tx1.GetHash() < tx5.GetHash())
            {
                sortedOrder.Add(tx5.GetHash().ToString());
                sortedOrder.Add(tx1.GetHash().ToString());
            }
            else
            {
                sortedOrder.Add(tx1.GetHash().ToString());
                sortedOrder.Add(tx5.GetHash().ToString());
            }
            if (tx3.GetHash() < tx6.GetHash())
            {
                sortedOrder.Add(tx6.GetHash().ToString());
                sortedOrder.Add(tx3.GetHash().ToString());
            }
            else
            {
                sortedOrder.Add(tx3.GetHash().ToString());
                sortedOrder.Add(tx6.GetHash().ToString());
            }
            this.CheckSort(pool, pool.MapTx.MiningScore.ToList(), sortedOrder);
        }
예제 #27
0
        public void FundTransaction_Given__a_wallet_has_enough_inputs__When__adding_inputs_to_an_existing_transaction__Then__the_transaction_is_funded_successfully()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var wallet           = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
            var accountKeys      = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            var spendingKeys     = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            var destinationKeys1 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");
            var destinationKeys2 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/2");
            var destinationKeys3 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/3");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            // wallet with 4 coinbase outputs of 50 = 200 Bitcoin
            var chain = new ConcurrentChain(wallet.Network.GetGenesis().Header);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.Network, chain, address, 4);

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations())).Returns(new FeeRate(20000));
            var overrideFeeRate = new FeeRate(20000);

            var walletManager            = new WalletManager(this.LoggerFactory.Object, Network.Main, chain, NodeSettings.Default(), dataFolder, walletFeePolicy.Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default);
            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, chain, walletManager, walletFeePolicy.Object, Network.Main);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            // create a trx with 3 outputs 50 + 50 + 49 = 149 BTC
            var context = new TransactionBuildContext(walletReference,
                                                      new[]
            {
                new Recipient {
                    Amount = new Money(50, MoneyUnit.BTC), ScriptPubKey = destinationKeys1.PubKey.ScriptPubKey
                },
                new Recipient {
                    Amount = new Money(50, MoneyUnit.BTC), ScriptPubKey = destinationKeys2.PubKey.ScriptPubKey
                },
                new Recipient {
                    Amount = new Money(49, MoneyUnit.BTC), ScriptPubKey = destinationKeys3.PubKey.ScriptPubKey
                }
            }
                                                      .ToList(), "password")
            {
                MinConfirmations = 0,
                FeeType          = FeeType.Low
            };

            var fundTransaction = walletTransactionHandler.BuildTransaction(context);

            Assert.Equal(3, fundTransaction.Inputs.Count);  // 3 inputs
            Assert.Equal(4, fundTransaction.Outputs.Count); // 3 outputs with change

            // remove the change output
            fundTransaction.Outputs.Remove(fundTransaction.Outputs.First(f => f.ScriptPubKey == context.ChangeAddress.ScriptPubKey));
            // remove 2 inputs they will be added back by fund transaction
            fundTransaction.Inputs.RemoveAt(2);
            fundTransaction.Inputs.RemoveAt(1);
            Assert.Single(fundTransaction.Inputs); // 3 inputs

            var fundTransactionClone = fundTransaction.Clone();
            var fundContext          = new TransactionBuildContext(walletReference, new List <Recipient>(), "password")
            {
                MinConfirmations = 0,
                FeeType          = FeeType.Low
            };

            fundContext.OverrideFeeRate = overrideFeeRate;
            walletTransactionHandler.FundTransaction(fundContext, fundTransaction);

            foreach (var input in fundTransactionClone.Inputs) // all original inputs are still in the trx
            {
                Assert.Contains(fundTransaction.Inputs, a => a.PrevOut == input.PrevOut);
            }

            Assert.Equal(3, fundTransaction.Inputs.Count);  // we expect 3 inputs
            Assert.Equal(4, fundTransaction.Outputs.Count); // we expect 4 outputs
            Assert.Equal(new Money(150, MoneyUnit.BTC) - fundContext.TransactionFee, fundTransaction.TotalOut);

            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys1.PubKey.ScriptPubKey);
            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys2.PubKey.ScriptPubKey);
            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys3.PubKey.ScriptPubKey);
        }
예제 #28
0
        public void MempoolRemoveTest()
        {
            TestMemPoolEntryHelper entry = new TestMemPoolEntryHelper();

            // Parent transaction with three children,
            // and three grand-children:
            Transaction txParent = new Transaction();

            txParent.AddInput(new TxIn());
            txParent.Inputs[0].ScriptSig = new Script(OpcodeType.OP_11);

            for (int i = 0; i < 3; i++)
            {
                txParent.AddOutput(new TxOut(new Money(33000L), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            }

            Transaction[] txChild = new Transaction[3];
            for (int i = 0; i < 3; i++)
            {
                txChild[i] = new Transaction();
                txChild[i].AddInput(new TxIn(new OutPoint(txParent, i), new Script(OpcodeType.OP_11)));
                txChild[i].AddOutput(new TxOut(new Money(11000L), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            }

            Transaction[] txGrandChild = new Transaction[3];
            for (int i = 0; i < 3; i++)
            {
                txGrandChild[i] = new Transaction();
                txGrandChild[i].AddInput(new TxIn(new OutPoint(txChild[i], 0), new Script(OpcodeType.OP_11)));
                txGrandChild[i].AddOutput(new TxOut(new Money(11000L), new Script(OpcodeType.OP_11, OpcodeType.OP_EQUAL)));
            }

            var       settings = NodeSettings.Default();
            TxMempool testPool = new TxMempool(DateTimeProvider.Default, new BlockPolicyEstimator(new MempoolSettings(settings), settings.LoggerFactory, settings), settings.LoggerFactory, settings);

            // Nothing in pool, remove should do nothing:
            var poolSize = testPool.Size;

            testPool.RemoveRecursive(txParent);
            Assert.Equal(testPool.Size, poolSize);

            // Just the parent:
            testPool.AddUnchecked(txParent.GetHash(), entry.FromTx(txParent));
            poolSize = testPool.Size;
            testPool.RemoveRecursive(txParent);
            Assert.Equal(testPool.Size, poolSize - 1);

            // Parent, children, grandchildren:
            testPool.AddUnchecked(txParent.GetHash(), entry.FromTx(txParent));
            for (int i = 0; i < 3; i++)
            {
                testPool.AddUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i]));
                testPool.AddUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i]));
            }
            // Remove Child[0], GrandChild[0] should be removed:
            poolSize = testPool.Size;
            testPool.RemoveRecursive(txChild[0]);
            Assert.Equal(testPool.Size, poolSize - 2);
            // ... make sure grandchild and child are gone:
            poolSize = testPool.Size;
            testPool.RemoveRecursive(txGrandChild[0]);
            Assert.Equal(testPool.Size, poolSize);
            poolSize = testPool.Size;
            testPool.RemoveRecursive(txChild[0]);
            Assert.Equal(testPool.Size, poolSize);
            // Remove parent, all children/grandchildren should go:
            poolSize = testPool.Size;
            testPool.RemoveRecursive(txParent);
            Assert.Equal(testPool.Size, poolSize - 5);
            Assert.Equal(0, testPool.Size);

            // Add children and grandchildren, but NOT the parent (simulate the parent being in a block)
            for (int i = 0; i < 3; i++)
            {
                testPool.AddUnchecked(txChild[i].GetHash(), entry.FromTx(txChild[i]));
                testPool.AddUnchecked(txGrandChild[i].GetHash(), entry.FromTx(txGrandChild[i]));
            }
            // Now remove the parent, as might happen if a block-re-org occurs but the parent cannot be
            // put into the mempool (maybe because it is non-standard):
            poolSize = testPool.Size;
            testPool.RemoveRecursive(txParent);
            Assert.Equal(poolSize - 6, testPool.Size);
            Assert.Equal(0, testPool.Size);
        }
예제 #29
0
        public void BuildTransactionNoSpendableTransactionsThrowsWalletException()
        {
            Assert.Throws <WalletException>(() =>
            {
                var wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
                wallet.AccountsRoot.ElementAt(0).Accounts.Add(
                    new HdAccount
                {
                    Name = "account1",
                    ExternalAddresses = new List <HdAddress>(),
                    InternalAddresses = new List <HdAddress>()
                });

                var chain = new Mock <ConcurrentChain>();
                chain.Setup(c => c.Tip).Returns(new ChainedBlock(new BlockHeader(), 1));

                var walletManager = new WalletManager(this.LoggerFactory.Object, Network.Main, chain.Object, NodeSettings.Default(),
                                                      new DataFolder(new NodeSettings {
                    DataDir = "TestData/WalletTransactionHandlerTest/BuildTransactionNoSpendableTransactionsThrowsWalletException"
                }), new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncLoopFactory>().Object, new NodeLifetime(), DateTimeProvider.Default);
                var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, chain.Object, walletManager, new Mock <IWalletFeePolicy>().Object, Network.Main);

                walletManager.Wallets.Add(wallet);

                var walletReference = new WalletAccountReference
                {
                    AccountName = "account1",
                    WalletName  = "myWallet1"
                };

                walletTransactionHandler.BuildTransaction(CreateContext(walletReference, "password", new Script(), new Money(500), FeeType.Medium, 2));
            });
        }
예제 #30
0
 /// <summary>
 /// Initializes an instance of the object from the default configuration.
 /// </summary>
 public WalletSettings() : this(NodeSettings.Default())
 {
 }