Exemple #1
0
        public async Task AcceptToMemoryPool_WithValidP2PKHTxn_IsSuccessfullAsync()
        {
            string dataDir = Path.Combine("TestData", nameof(MempoolValidatorTest), nameof(this.AcceptToMemoryPool_WithValidP2PKHTxn_IsSuccessfullAsync));

            Directory.CreateDirectory(dataDir);

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

            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.");

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

            Directory.CreateDirectory(dataDir);

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

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

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

            // 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, miner.PubKey.ScriptPubKey);
            TransactionBuilder txBuilder   = new TransactionBuilder();
            Transaction        p2wshTx     = txBuilder
                                             .AddCoins(witnessCoin)
                                             .AddKeys(miner)
                                             .Send(bob, "42.00")
                                             .SendFees("0.001")
                                             .SetChange(miner)
                                             .BuildTransaction(true);

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

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

            Directory.Delete(dataDir, true);
        }
Exemple #3
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.RegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(Network.RegTest, miner.PubKey.Hash.ScriptPubKey, dataDir);

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

            BitcoinSecret alice   = new BitcoinSecret(new Key(), Network.RegTest);
            BitcoinSecret bob     = new BitcoinSecret(new Key(), Network.RegTest);
            BitcoinSecret satoshi = new BitcoinSecret(new Key(), Network.RegTest);
            BitcoinSecret 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 });

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

            // 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);
        }
Exemple #4
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.RegTest);
            ITestChainContext context = await TestChainFactory.CreateAsync(Network.RegTest, miner.PubKey.Hash.ScriptPubKey, dataDir);

            IMempoolValidator validator = context.MempoolValidator;

            Assert.NotNull(validator);

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

            // 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);
        }