Example #1
0
 /// <summary>
 /// Constructs and instance of memory pool behavior.
 /// Constructs a logger instance for memory pool behavior object.
 /// </summary>
 /// <param name="validator">Memory pool validator for validating transactions.</param>
 /// <param name="manager">Memory pool manager for managing the memory pool.</param>
 /// <param name="orphans">Memory pool orphans for managing orphan transactions.</param>
 /// <param name="connectionManager">Connection manager for managing peer connections.</param>
 /// <param name="initialBlockDownloadState">Provider of IBD state.</param>
 /// <param name="signals">Peer notifications available to subscribe to.</param>
 /// <param name="loggerFactory">Logger factory for creating logger.</param>
 public MempoolBehavior(
     IMempoolValidator validator,
     MempoolManager manager,
     MempoolOrphans orphans,
     IConnectionManager connectionManager,
     IInitialBlockDownloadState initialBlockDownloadState,
     Signals.Signals signals,
     ILoggerFactory loggerFactory)
     : this(validator, manager, orphans, connectionManager, initialBlockDownloadState, signals, loggerFactory.CreateLogger(typeof(MempoolBehavior).FullName))
 {
 }
        /// <summary>
        /// Constructs a wallet fee policy.
        /// </summary>
        /// <param name="blockPolicyEstimator">Block policy estimator.</param>
        /// <param name="mempoolValidator">Memory pool validator.</param>
        /// <param name="mempool">Memory pool.</param>
        /// <param name="network">Network node is running on.</param>
        /// <param name="nodeSettings">Settings for the the node.</param>
        public WalletFeePolicy(BlockPolicyEstimator blockPolicyEstimator, IMempoolValidator mempoolValidator, TxMempool mempool, Network network, NodeSettings nodeSettings)
        {
            this.blockPolicyEstimator = blockPolicyEstimator;
            this.mempoolValidator     = mempoolValidator;
            this.mempool = mempool;

            this.minTxFee      = nodeSettings.MinTxFeeRate;
            this.fallbackFee   = nodeSettings.FallbackTxFeeRate;
            this.payTxFee      = new FeeRate(0);
            this.maxTxFee      = new Money(0.1M, MoneyUnit.BTC);
            this.minRelayTxFee = nodeSettings.MinRelayTxFeeRate;
        }
Example #3
0
 public BlocksDisconnectedSignaled(
     ITxMempool mempool,
     IMempoolValidator mempoolValidator,
     MempoolSchedulerLock mempoolLock,
     ILoggerFactory loggerFactory,
     ISignals signals)
 {
     this.mempool          = mempool;
     this.mempoolValidator = mempoolValidator;
     this.mempoolLock      = mempoolLock;
     this.signals          = signals;
     this.logger           = loggerFactory.CreateLogger(this.GetType().FullName);
 }
Example #4
0
        public SignedMultisigTransactionBroadcasterTests()
        {
            this.loggerFactory             = Substitute.For <ILoggerFactory>();
            this.logger                    = Substitute.For <ILogger>();
            this.federationGatewaySettings = Substitute.For <IFederationGatewaySettings>();
            this.loggerFactory.CreateLogger(null).ReturnsForAnyArgs(this.logger);
            this.leaderReceiverSubscription = Substitute.For <IDisposable>();
            this.store = Substitute.For <ICrossChainTransferStore>();
            this.broadcasterManager = Substitute.For <IBroadcasterManager>();
            this.asyncProvider      = Substitute.For <IAsyncProvider>();
            this.nodeLifetime       = Substitute.For <INodeLifetime>();

            this.ibdState = Substitute.For <IInitialBlockDownloadState>();
            this.federationWalletManager = Substitute.For <IFederationWalletManager>();
            this.federationWalletManager.IsFederationWalletActive().Returns(true);

            // Setup MempoolManager.
            this.dateTimeProvider = Substitute.For <IDateTimeProvider>();
            this.nodeSettings     = new NodeSettings(networksSelector: CirrusNetwork.NetworksSelector, protocolVersion: NBitcoin.Protocol.ProtocolVersion.ALT_PROTOCOL_VERSION);

            this.mempoolSettings = new MempoolSettings(this.nodeSettings)
            {
                MempoolExpiry = MempoolValidator.DefaultMempoolExpiry
            };

            this.blockPolicyEstimator = new BlockPolicyEstimator(
                this.mempoolSettings,
                this.loggerFactory,
                this.nodeSettings);

            this.txMempool = new TxMempool(
                this.dateTimeProvider,
                this.blockPolicyEstimator,
                this.loggerFactory,
                this.nodeSettings);

            this.mempoolValidator   = Substitute.For <IMempoolValidator>();
            this.mempoolPersistence = Substitute.For <IMempoolPersistence>();
            this.coinView           = Substitute.For <ICoinView>();

            this.mempoolManager = new MempoolManager(
                new MempoolSchedulerLock(),
                this.txMempool,
                this.mempoolValidator,
                this.dateTimeProvider,
                this.mempoolSettings,
                this.mempoolPersistence,
                this.coinView,
                this.loggerFactory,
                this.nodeSettings.Network);
        }
Example #5
0
        public async void AcceptToMemoryPool_TxAncestorsConflictSpend_ReturnsFalseAsync()
        {
            // TODO: Execute failure cases for CheckAncestors
            // - conflicting spend transaction

            string dataDir = GetTestDirectoryPath(this);

            var miner = new BitcoinSecret(new Key(), Network.RegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(Network.RegTest, miner.PubKey.Hash.ScriptPubKey, dataDir).ConfigureAwait(false);

            IMempoolValidator validator = context.MempoolValidator;
            var bob       = new BitcoinSecret(new Key(), Network.RegTest);
            var txBuilder = new TransactionBuilder(Network.RegTest);

            //Create Coin from first tx on chain
            var coin = new Coin(context.SrcTxs[0].GetHash(), 0, context.SrcTxs[0].TotalOut, PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(miner.PubKey));

            //Send 10 to Bob and return the rest as change to miner
            Transaction originalTx = txBuilder
                                     .AddCoins(coin)
                                     .AddKeys(miner)
                                     .Send(bob, "10.00")
                                     .SendFees("0.001")
                                     .SetChange(miner)
                                     .BuildTransaction(true);
            var state = new MempoolValidationState(false);

            //Mempool should accept it, there's nothing wrong
            Assert.True(await validator.AcceptToMemoryPool(state, originalTx).ConfigureAwait(false), $"Transaction: {nameof(originalTx)} failed mempool validation.");

            //Create second transaction spending the same coin
            Transaction conflictingTx = txBuilder
                                        .AddCoins(coin)
                                        .AddKeys(miner)
                                        .Send(bob, "10.00")
                                        .SendFees("0.001")
                                        .SetChange(miner)
                                        .BuildTransaction(true);

            //Mempool should reject the second transaction
            Assert.False(await validator.AcceptToMemoryPool(state, conflictingTx).ConfigureAwait(false), $"Transaction: {nameof(conflictingTx)} should have failed mempool validation.");

            Directory.Delete(dataDir, true);
        }
 /// <summary>
 /// Constructs an instance of a memory pool manager object.
 /// </summary>
 /// <param name="mempoolLock">A lock for managing asynchronous access to memory pool.</param>
 /// <param name="memPool">Transaction memory pool for managing transactions in the memory pool.</param>
 /// <param name="validator">Memory pool validator for validating transactions.</param>
 /// <param name="orphans">Memory pool orphans for managing orphan transactions.</param>
 /// <param name="dateTimeProvider">Date and time information provider.</param>
 /// <param name="nodeArgs">Settings from the node.</param>
 /// <param name="mempoolPersistence">Memory pool persistence methods for loading and saving from storage.</param>
 /// <param name="loggerFactory">Logger factory for creating instance logger.</param>
 public MempoolManager(
     MempoolAsyncLock mempoolLock,
     TxMempool memPool,
     IMempoolValidator validator,
     MempoolOrphans orphans,
     IDateTimeProvider dateTimeProvider,
     NodeSettings nodeArgs,
     IMempoolPersistence mempoolPersistence,
     ILoggerFactory loggerFactory)
 {
     this.MempoolLock        = mempoolLock;
     this.memPool            = memPool;
     this.DateTimeProvider   = dateTimeProvider;
     this.NodeArgs           = nodeArgs;
     this.Orphans            = orphans;
     this.Validator          = validator;
     this.mempoolPersistence = mempoolPersistence;
     this.mempoolLogger      = loggerFactory.CreateLogger(this.GetType().FullName);
 }
        public async Task AcceptToMemoryPool_WithSegWitValidTxns_IsSuccessfullAsync()
        {
            string dataDir = Path.Combine("TestData", nameof(MempoolValidatorTest), nameof(this.AcceptToMemoryPool_WithSegWitValidTxns_IsSuccessfullAsync));

            Directory.CreateDirectory(dataDir);

            BitcoinSecret     miner   = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(Network.PurpleRegTest, miner.PubKey.ScriptPubKey.WitHash.ScriptPubKey.Hash.ScriptPubKey, dataDir);

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

            BitcoinSecret bob = new BitcoinSecret(new Key(), Network.PurpleRegTest);

            // Fund Bob
            // 50 Coins come from first tx on chain - send bob 42 and change back to miner
            ScriptCoin         witnessCoin    = new ScriptCoin(context.SrcTxs[0].GetHash(), 0, context.SrcTxs[0].TotalOut, miner.PubKey.ScriptPubKey.WitHash.ScriptPubKey.Hash.ScriptPubKey, miner.PubKey.ScriptPubKey);
            TransactionBuilder txBuilder      = new TransactionBuilder();
            Transaction        p2shOverp2wpkh = txBuilder
                                                .AddCoins(witnessCoin)
                                                .AddKeys(miner)
                                                .Send(bob, "42.00")
                                                .SendFees("0.001")
                                                .SetChange(miner)
                                                .BuildTransaction(true);

            Assert.True(txBuilder.Verify(p2shOverp2wpkh)); //check fully signed

            // remove witness data from tx
            Transaction noWitTx = p2shOverp2wpkh.WithOptions(NetworkOptions.None);

            Assert.Equal(p2shOverp2wpkh.GetHash(), noWitTx.GetHash());
            Assert.True(noWitTx.GetSerializedSize() < p2shOverp2wpkh.GetSerializedSize());

            Assert.True(txBuilder.Verify(p2shOverp2wpkh)); //check fully signed
            MempoolValidationState state = new MempoolValidationState(false);

            Assert.True(await validator.AcceptToMemoryPool(state, p2shOverp2wpkh), $"Transaction: {nameof(p2shOverp2wpkh)} failed mempool validation.");

            Directory.Delete(dataDir, true);
        }
Example #8
0
        public async void AcceptToMemoryPool_WithValidP2PKHTxn_IsSuccessfull()
        {
            BitcoinSecret     minerSecret = new BitcoinSecret(new Key(), Network.RegTest);
            ITestChainContext context     = TestChainFactory.Create(Network.RegTest, minerSecret.PubKey.Hash.ScriptPubKey);
            IMempoolValidator validator   = context.MempoolValidator;

            Assert.NotNull(validator);

            BitcoinSecret destSecret = new BitcoinSecret(new Key(), Network.RegTest);
            Transaction   tx         = new Transaction();

            tx.AddInput(new TxIn(new OutPoint(context.SrcTxs[0].GetHash(), 0), PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(minerSecret.PubKey)));
            tx.AddOutput(new TxOut(new Money(Money.CENT * 11), destSecret.PubKeyHash));
            tx.Sign(minerSecret, false);

            MempoolValidationState state = new MempoolValidationState(false);
            bool isSuccess = await validator.AcceptToMemoryPool(state, tx);

            Assert.True(isSuccess, "P2PKH tx not valid.");
        }
        /// <summary>
        /// Constructs an instance of memory pool behavior.
        /// </summary>
        /// <param name="validator">Memory pool validator for validating transactions.</param>
        /// <param name="manager">Memory pool manager for managing the memory pool.</param>
        /// <param name="orphans">Memory pool orphans for managing orphan transactions.</param>
        /// <param name="connectionManager">Connection manager for managing node connections.</param>
        /// <param name="chainState">Current block chain state.</param>
        /// <param name="signals">Node notifications available to subscribe to.</param>
        /// <param name="logger">Instance logger for memory pool behavior.</param>
        public MempoolBehavior(
            IMempoolValidator validator,
            MempoolManager manager,
            MempoolOrphans orphans,
            IConnectionManager connectionManager,
            ChainState chainState,
            Signals.Signals signals,
            ILogger logger)
        {
            this.validator         = validator;
            this.manager           = manager;
            this.orphans           = orphans;
            this.connectionManager = connectionManager;
            this.chainState        = chainState;
            this.signals           = signals;
            this.logger            = logger;

            this.inventoryTxToSend    = new Dictionary <uint256, uint256>();
            this.filterInventoryKnown = new Dictionary <uint256, uint256>();
        }
 /// <summary>
 /// Constructs an instance of a memory pool manager object.
 /// </summary>
 /// <param name="mempoolLock">A lock for managing asynchronous access to memory pool.</param>
 /// <param name="memPool">Transaction memory pool for managing transactions in the memory pool.</param>
 /// <param name="validator">Memory pool validator for validating transactions.</param>
 /// <param name="orphans">Memory pool orphans for managing orphan transactions.</param>
 /// <param name="dateTimeProvider">Date and time information provider.</param>
 /// <param name="nodeArgs">Settings from the node.</param>
 /// <param name="mempoolSettings">Settings for memory pool.</param>
 /// <param name="mempoolPersistence">Memory pool persistence methods for loading and saving from storage.</param>
 /// <param name="loggerFactory">Logger factory for creating instance logger.</param>
 public MempoolManager(
     MempoolSchedulerLock mempoolLock,
     TxMempool memPool,
     IMempoolValidator validator,
     MempoolOrphans orphans,
     IDateTimeProvider dateTimeProvider,
     MempoolSettings mempoolSettings,
     IMempoolPersistence mempoolPersistence,
     CoinView coinView,
     ILoggerFactory loggerFactory)
 {
     this.MempoolLock        = mempoolLock;
     this.memPool            = memPool;
     this.DateTimeProvider   = dateTimeProvider;
     this.mempoolSettings    = mempoolSettings;
     this.Orphans            = orphans;
     this.Validator          = validator;
     this.mempoolPersistence = mempoolPersistence;
     this.coinView           = coinView;
     this.mempoolLogger      = loggerFactory.CreateLogger(this.GetType().FullName);
 }
 /// <summary>
 /// Constructs an instance of a MempoolSignaled object.
 /// Starts the block notification loop to memory pool behaviors for connected nodes.
 /// </summary>
 /// <param name="manager">Memory pool manager injected dependency.</param>
 /// <param name="chain">Concurrent chain injected dependency.</param>
 /// <param name="connection">Connection manager injected dependency.</param>
 /// <param name="nodeLifetime">Node lifetime injected dependency.</param>
 /// <param name="asyncLoopFactory">Asynchronous loop factory injected dependency.</param>
 /// <param name="mempoolLock">The mempool lock.</param>
 /// <param name="memPool">the mempool.</param>
 /// <param name="validator">The mempool validator.</param>
 /// <param name="mempoolOrphans">The mempool orphan list.</param>
 public MempoolSignaled(
     MempoolManager manager,
     ConcurrentChain chain,
     IConnectionManager connection,
     INodeLifetime nodeLifetime,
     IAsyncLoopFactory asyncLoopFactory,
     MempoolSchedulerLock mempoolLock,
     ITxMempool memPool,
     IMempoolValidator validator,
     MempoolOrphans mempoolOrphans)
 {
     this.manager          = manager;
     this.chain            = chain;
     this.connection       = connection;
     this.nodeLifetime     = nodeLifetime;
     this.asyncLoopFactory = asyncLoopFactory;
     this.mempoolLock      = mempoolLock;
     this.memPool          = memPool;
     this.validator        = validator;
     this.mempoolOrphans   = mempoolOrphans;
 }
Example #12
0
 public MempoolManager(
     MempoolSchedulerLock mempoolLock,
     ITxMempool memPool,
     IMempoolValidator validator,
     IDateTimeProvider dateTimeProvider,
     MempoolSettings mempoolSettings,
     IMempoolPersistence mempoolPersistence,
     ICoinView coinView,
     ILoggerFactory loggerFactory,
     Network network)
 {
     this.MempoolLock        = mempoolLock;
     this.memPool            = memPool;
     this.DateTimeProvider   = dateTimeProvider;
     this.mempoolSettings    = mempoolSettings;
     this.Validator          = validator;
     this.mempoolPersistence = mempoolPersistence;
     this.coinView           = coinView;
     this.network            = network;
     this.logger             = loggerFactory.CreateLogger(GetType().FullName);
 }
Example #13
0
        /// <summary>
        /// Constructs an instance of memory pool behavior.
        /// </summary>
        /// <param name="validator">Memory pool validator for validating transactions.</param>
        /// <param name="manager">Memory pool manager for managing the memory pool.</param>
        /// <param name="orphans">Memory pool orphans for managing orphan transactions.</param>
        /// <param name="connectionManager">Connection manager for managing peer connections.</param>
        /// <param name="initialBlockDownloadState">Provider of IBD state.</param>
        /// <param name="signals">Peer notifications available to subscribe to.</param>
        /// <param name="logger">Instance logger for memory pool behavior.</param>
        /// <param name="network">The blockchain network.</param>
        public MempoolBehavior(
            IMempoolValidator validator,
            MempoolManager manager,
            MempoolOrphans orphans,
            IConnectionManager connectionManager,
            IInitialBlockDownloadState initialBlockDownloadState,
            Signals.Signals signals,
            ILogger logger,
            Network network)
        {
            this.validator                 = validator;
            this.manager                   = manager;
            this.orphans                   = orphans;
            this.connectionManager         = connectionManager;
            this.initialBlockDownloadState = initialBlockDownloadState;
            this.signals                   = signals;
            this.logger  = logger;
            this.network = network;

            this.inventoryTxToSend    = new Dictionary <uint256, uint256>();
            this.filterInventoryKnown = new Dictionary <uint256, uint256>();
        }
        public WalletManager(
            ILoggerFactory loggerFactory,
            IConnectionManager connectionManager,
            Network network,
            ConcurrentChain chain,
            NodeSettings settings, DataFolder dataFolder,
            IWalletFeePolicy walletFeePolicy,
            IAsyncLoopFactory asyncLoopFactory,
            INodeLifetime nodeLifetime,
            IMempoolValidator mempoolValidator = null) // mempool does not exist in a light wallet
        {
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(chain, nameof(chain));
            Guard.NotNull(settings, nameof(settings));
            Guard.NotNull(dataFolder, nameof(dataFolder));
            Guard.NotNull(walletFeePolicy, nameof(walletFeePolicy));
            Guard.NotNull(asyncLoopFactory, nameof(asyncLoopFactory));
            Guard.NotNull(nodeLifetime, nameof(nodeLifetime));


            this.logger  = loggerFactory.CreateLogger(this.GetType().FullName);
            this.Wallets = new ConcurrentBag <Wallet>();

            this.connectionManager = connectionManager;
            this.network           = network;
            this.coinType          = (CoinType)network.Consensus.CoinType;
            this.chain             = chain;
            this.settings          = settings;
            this.dataFolder        = dataFolder;
            this.walletFeePolicy   = walletFeePolicy;
            this.mempoolValidator  = mempoolValidator;
            this.asyncLoopFactory  = asyncLoopFactory;
            this.nodeLifetime      = nodeLifetime;

            // register events
            this.TransactionFound += this.OnTransactionFound;
        }
        public async Task AcceptToMemoryPool_WithValidP2PKHTxn_IsSuccessfullAsync()
        {
            string dataDir = GetTestDirectoryPath(this);

            var minerSecret           = new BitcoinSecret(new Key(), KnownNetworks.RegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(KnownNetworks.RegTest, minerSecret.PubKey.Hash.ScriptPubKey, dataDir);

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

            var destSecret = new BitcoinSecret(new Key(), KnownNetworks.RegTest);
            var tx         = new Transaction();

            tx.AddInput(new TxIn(new OutPoint(context.SrcTxs[0].GetHash(), 0), PayToPubkeyHashTemplate.Instance.GenerateScriptPubKey(minerSecret.PubKey)));
            tx.AddOutput(new TxOut(new Money(Money.CENT * 11), destSecret.PubKeyHash));
            tx.Sign(KnownNetworks.RegTest, minerSecret, false);

            var  state     = new MempoolValidationState(false);
            bool isSuccess = await validator.AcceptToMemoryPool(state, tx);

            Assert.True(isSuccess, "P2PKH tx not valid.");
        }
Example #16
0
 /// <summary>
 /// Constructs an instance of a MempoolSignaled object.
 /// Starts the block notification loop to memory pool behaviors for connected nodes.
 /// </summary>
 /// <param name="manager">Memory pool manager injected dependency.</param>
 /// <param name="chainIndexer">Concurrent chain injected dependency.</param>
 /// <param name="connection">Connection manager injected dependency.</param>
 /// <param name="nodeLifetime">Node lifetime injected dependency.</param>
 /// <param name="asyncProvider">Asynchronous loop factory injected dependency.</param>
 /// <param name="mempoolLock">The mempool lock.</param>
 /// <param name="memPool">the mempool.</param>
 /// <param name="validator">The mempool validator.</param>
 /// <param name="mempoolOrphans">The mempool orphan list.</param>
 public MempoolSignaled(
     MempoolManager manager,
     ChainIndexer chainIndexer,
     IConnectionManager connection,
     INodeLifetime nodeLifetime,
     IAsyncProvider asyncProvider,
     MempoolSchedulerLock mempoolLock,
     ITxMempool memPool,
     IMempoolValidator validator,
     MempoolOrphans mempoolOrphans,
     ISignals signals)
 {
     this.manager        = manager;
     this.chainIndexer   = chainIndexer;
     this.connection     = connection;
     this.nodeLifetime   = nodeLifetime;
     this.asyncProvider  = asyncProvider;
     this.mempoolLock    = mempoolLock;
     this.memPool        = memPool;
     this.validator      = validator;
     this.mempoolOrphans = mempoolOrphans;
     this.signals        = signals;
 }
        public MempoolBehavior(
            IMempoolValidator validator,
            MempoolManager mempoolManager,
            MempoolOrphans orphans,
            IConnectionManager connectionManager,
            IInitialBlockDownloadState initialBlockDownloadState,
            Signals.Signals signals,
            ILoggerFactory loggerFactory,
            Network network)
        {
            this.validator                 = validator;
            this.mempoolManager            = mempoolManager;
            this.orphans                   = orphans;
            this.connectionManager         = connectionManager;
            this.initialBlockDownloadState = initialBlockDownloadState;
            this.signals                   = signals;
            this.logger        = loggerFactory.CreateLogger(this.GetType().FullName);
            this.loggerFactory = loggerFactory;
            this.network       = network;

            this.lockObject           = new object();
            this.inventoryTxToSend    = new HashSet <uint256>();
            this.filterInventoryKnown = new HashSet <uint256>();
        }
Example #18
0
        public WalletFeePolicy(BlockPolicyEstimator blockPolicyEstimator, IMempoolValidator mempoolValidator, TxMempool mempool, Network network)
        {
            this.blockPolicyEstimator = blockPolicyEstimator;
            this.mempoolValidator     = mempoolValidator;
            this.mempool = mempool;

            this.minTxFee      = new FeeRate(1000);
            this.fallbackFee   = new FeeRate(20000);
            this.payTxFee      = new FeeRate(0);
            this.maxTxFee      = new Money(0.1M, MoneyUnit.BTC);
            this.minRelayTxFee = MempoolValidator.MinRelayTxFee;

            // this is a very very ugly hack
            // the fee constants should be set at the
            // network level or the consensus options
            if (network.Name.ToLower().Contains("stratis"))
            {
                this.minTxFee      = new FeeRate(10000);
                this.fallbackFee   = new FeeRate(40000);
                this.payTxFee      = new FeeRate(0);
                this.maxTxFee      = new Money(0.1M, MoneyUnit.BTC);
                this.minRelayTxFee = new FeeRate(10000);
            }
        }
        public FullNodeBroadcasterManager(IConnectionManager connectionManager, IMempoolValidator mempoolValidator) : base(connectionManager)
        {
            Guard.NotNull(mempoolValidator, nameof(mempoolValidator));

            this.mempoolValidator = mempoolValidator;
        }
Example #20
0
 /// <summary>
 /// Constructs a memory pool coin view.
 /// </summary>
 /// <param name="inner">The backing coin view.</param>
 /// <param name="memPool">Transaction memory pool for managing transactions in the memory pool.</param>
 /// <param name="mempoolLock">A lock for managing asynchronous access to memory pool.</param>
 /// <param name="mempoolValidator">Memory pool validator for validating transactions.</param>
 public MempoolCoinView(CoinView inner, ITxMempool memPool, SchedulerLock mempoolLock, IMempoolValidator mempoolValidator)
 {
     this.Inner            = inner;
     this.memPool          = memPool;
     this.mempoolLock      = mempoolLock;
     this.mempoolValidator = mempoolValidator;
     this.Set = new UnspentOutputSet();
 }
Example #21
0
        public async Task AcceptToMemoryPool_WithP2SHValidTxns_IsSuccessfullAsync()
        {
            string dataDir = Path.Combine("TestData", nameof(MempoolValidatorTest), nameof(this.AcceptToMemoryPool_WithP2SHValidTxns_IsSuccessfullAsync));

            Directory.CreateDirectory(dataDir);

            BitcoinSecret     miner   = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(Network.PurpleRegTest, miner.PubKey.Hash.ScriptPubKey, dataDir);

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

            BitcoinSecret alice   = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            BitcoinSecret bob     = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            BitcoinSecret satoshi = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            BitcoinSecret nico    = new BitcoinSecret(new Key(), Network.PurpleRegTest);

            // corp needs two out of three of alice, bob, nico
            Script corpMultiSig = PayToMultiSigTemplate
                                  .Instance
                                  .GenerateScriptPubKey(2, new[] { alice.PubKey, bob.PubKey, nico.PubKey });

            // P2SH address for corp multi-sig
            BitcoinScriptAddress corpRedeemAddress = corpMultiSig.GetScriptAddress(Network.PurpleRegTest);

            // Fund corp
            // 50 Coins come from first tx on chain - send corp 42 and change back to miner
            Coin coin = new Coin(context.SrcTxs[0].GetHash(), 0, context.SrcTxs[0].TotalOut, miner.ScriptPubKey);
            TransactionBuilder txBuilder  = new TransactionBuilder();
            Transaction        fundP2shTx = txBuilder
                                            .AddCoins(new List <Coin> {
                coin
            })
                                            .AddKeys(miner)
                                            .Send(corpRedeemAddress, "42.00")
                                            .SendFees("0.001")
                                            .SetChange(miner.GetAddress())
                                            .BuildTransaction(true);

            Assert.True(txBuilder.Verify(fundP2shTx)); //check fully signed
            MempoolValidationState state = new MempoolValidationState(false);

            Assert.True(await validator.AcceptToMemoryPool(state, fundP2shTx), $"Transaction: {nameof(fundP2shTx)} failed mempool validation.");

            // AliceBobNico corp. send 20 to Satoshi
            Coin[] corpCoins = fundP2shTx.Outputs
                               .Where(o => o.ScriptPubKey == corpRedeemAddress.ScriptPubKey)
                               .Select(o => new ScriptCoin(new OutPoint(fundP2shTx.GetHash(), fundP2shTx.Outputs.IndexOf(o)), o, corpMultiSig))
                               .ToArray();

            txBuilder = new TransactionBuilder();
            Transaction p2shSpendTx = txBuilder
                                      .AddCoins(corpCoins)
                                      .AddKeys(alice, bob)
                                      .Send(satoshi.GetAddress(), "20")
                                      .SendFees("0.001")
                                      .SetChange(corpRedeemAddress)
                                      .BuildTransaction(true);

            Assert.True(txBuilder.Verify(p2shSpendTx));

            Assert.True(await validator.AcceptToMemoryPool(state, p2shSpendTx), $"Transaction: {nameof(p2shSpendTx)} failed mempool validation.");

            Directory.Delete(dataDir, true);
        }
Example #22
0
        public async Task AcceptToMemoryPool_WithMultiInOutValidTxns_IsSuccessfullAsync()
        {
            string dataDir = Path.Combine("TestData", nameof(MempoolValidatorTest), nameof(this.AcceptToMemoryPool_WithMultiInOutValidTxns_IsSuccessfullAsync));

            Directory.CreateDirectory(dataDir);

            BitcoinSecret     miner   = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(Network.PurpleRegTest, miner.PubKey.Hash.ScriptPubKey, dataDir);

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

            BitcoinSecret alice   = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            BitcoinSecret bob     = new BitcoinSecret(new Key(), Network.PurpleRegTest);
            BitcoinSecret satoshi = new BitcoinSecret(new Key(), Network.PurpleRegTest);

            // Fund Alice, Bob, Satoshi
            // 50 Coins come from first tx on chain - send satoshi 1, bob 2, Alice 1.5 and change back to miner
            Coin coin = new Coin(context.SrcTxs[0].GetHash(), 0, context.SrcTxs[0].TotalOut, miner.ScriptPubKey);
            TransactionBuilder txBuilder     = new TransactionBuilder();
            Transaction        multiOutputTx = txBuilder
                                               .AddCoins(new List <Coin> {
                coin
            })
                                               .AddKeys(miner)
                                               .Send(satoshi.GetAddress(), "1.00")
                                               .Send(bob.GetAddress(), "2.00")
                                               .Send(alice.GetAddress(), "1.50")
                                               .SendFees("0.001")
                                               .SetChange(miner.GetAddress())
                                               .BuildTransaction(true);

            Assert.True(txBuilder.Verify(multiOutputTx)); //check fully signed
            MempoolValidationState state = new MempoolValidationState(false);

            Assert.True(await validator.AcceptToMemoryPool(state, multiOutputTx), $"Transaction: {nameof(multiOutputTx)} failed mempool validation.");

            // Alice then Bob sends to Satoshi
            Coin[] aliceCoins = multiOutputTx.Outputs
                                .Where(o => o.ScriptPubKey == alice.ScriptPubKey)
                                .Select(o => new Coin(new OutPoint(multiOutputTx.GetHash(), multiOutputTx.Outputs.IndexOf(o)), o))
                                .ToArray();
            Coin[] bobCoins = multiOutputTx.Outputs
                              .Where(o => o.ScriptPubKey == bob.ScriptPubKey)
                              .Select(o => new Coin(new OutPoint(multiOutputTx.GetHash(), multiOutputTx.Outputs.IndexOf(o)), o))
                              .ToArray();

            txBuilder = new TransactionBuilder();
            Transaction multiInputTx = txBuilder
                                       .AddCoins(aliceCoins)
                                       .AddKeys(alice)
                                       .Send(satoshi.GetAddress(), "0.8")
                                       .SetChange(alice.GetAddress())
                                       .SendFees("0.0005")
                                       .Then()
                                       .AddCoins(bobCoins)
                                       .AddKeys(bob)
                                       .Send(satoshi.GetAddress(), "0.2")
                                       .SetChange(bob.GetAddress())
                                       .SendFees("0.0005")
                                       .BuildTransaction(true);

            Assert.True(txBuilder.Verify(multiInputTx)); //check fully signed
            Assert.True(await validator.AcceptToMemoryPool(state, multiInputTx), $"Transaction: {nameof(multiInputTx)} failed mempool validation.");

            Directory.Delete(dataDir, true);
        }
Example #23
0
        public MempoolBroadcastCheck(IMempoolValidator mempoolValidator)
        {
            Guard.NotNull(mempoolValidator, nameof(mempoolValidator));

            this.mempoolValidator = mempoolValidator;
        }
 public FullNodeBroadcasterManager(IConnectionManager connectionManager, IMempoolValidator mempoolValidator) : base()
 {
     this.connectionManager = connectionManager ?? throw new ArgumentNullException(nameof(connectionManager));
     this.mempoolValidator  = mempoolValidator ?? throw new ArgumentNullException(nameof(mempoolValidator));
 }
Example #25
0
        public async Task AcceptToMemoryPool_WithMultiSigValidTxns_IsSuccessfullAsync()
        {
            string dataDir = GetTestDirectoryPath(this);

            var miner = new BitcoinSecret(new Key(), Network.RegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(Network.RegTest, miner.PubKey.Hash.ScriptPubKey, dataDir);

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

            var alice   = new BitcoinSecret(new Key(), Network.RegTest);
            var bob     = new BitcoinSecret(new Key(), Network.RegTest);
            var satoshi = new BitcoinSecret(new Key(), Network.RegTest);
            var nico    = new BitcoinSecret(new Key(), Network.RegTest);

            // corp needs two out of three of alice, bob, nico
            Script corpMultiSig = PayToMultiSigTemplate
                                  .Instance
                                  .GenerateScriptPubKey(2, new[] { alice.PubKey, bob.PubKey, nico.PubKey });

            // Fund corp
            // 50 Coins come from first tx on chain - send corp 42 and change back to miner
            var         coin             = new Coin(context.SrcTxs[0].GetHash(), 0, context.SrcTxs[0].TotalOut, miner.ScriptPubKey);
            var         txBuilder        = new TransactionBuilder(Network.RegTest);
            Transaction sendToMultiSigTx = txBuilder
                                           .AddCoins(new List <Coin> {
                coin
            })
                                           .AddKeys(miner)
                                           .Send(corpMultiSig, "42.00")
                                           .SendFees("0.001")
                                           .SetChange(miner.GetAddress())
                                           .BuildTransaction(true);

            Assert.True(txBuilder.Verify(sendToMultiSigTx)); //check fully signed
            var state = new MempoolValidationState(false);

            Assert.True(await validator.AcceptToMemoryPool(state, sendToMultiSigTx), $"Transaction: {nameof(sendToMultiSigTx)} failed mempool validation.");

            // AliceBobNico corp. send to Satoshi
            Coin[] corpCoins = sendToMultiSigTx.Outputs
                               .Where(o => o.ScriptPubKey == corpMultiSig)
                               .Select(o => new Coin(new OutPoint(sendToMultiSigTx.GetHash(), sendToMultiSigTx.Outputs.IndexOf(o)), o))
                               .ToArray();

            // Alice initiates the transaction
            txBuilder = new TransactionBuilder(Network.RegTest);
            Transaction multiSigTx = txBuilder
                                     .AddCoins(corpCoins)
                                     .AddKeys(alice)
                                     .Send(satoshi.GetAddress(), "4.5")
                                     .SendFees("0.001")
                                     .SetChange(corpMultiSig)
                                     .BuildTransaction(true);

            Assert.True(!txBuilder.Verify(multiSigTx)); //Well, only one signature on the two required...

            // Nico completes the transaction
            txBuilder  = new TransactionBuilder(Network.RegTest);
            multiSigTx = txBuilder
                         .AddCoins(corpCoins)
                         .AddKeys(nico)
                         .SignTransaction(multiSigTx);
            Assert.True(txBuilder.Verify(multiSigTx));

            Assert.True(await validator.AcceptToMemoryPool(state, multiSigTx), $"Transaction: {nameof(multiSigTx)} failed mempool validation.");
        }