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.PurpleRegTest); ITestChainContext context = await TestChainFactory.CreateAsync(Network.PurpleRegTest, minerSecret.PubKey.Hash.ScriptPubKey, dataDir); IMempoolValidator validator = context.MempoolValidator; Assert.NotNull(validator); BitcoinSecret destSecret = new BitcoinSecret(new Key(), Network.PurpleRegTest); 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); }
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.PurpleRegTest); ITestChainContext context = await TestChainFactory.CreateAsync(Network.PurpleRegTest, miner.PubKey.ScriptPubKey.WitHash.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, 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); }
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); }
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); }