public void Constructor_ExceptionTest() { var ut = new MockUtxoDatabase(); var mem = new MockMempool(null); var c = new MockConsensus(MockHeight); Assert.Throws <ArgumentNullException>(() => new TransactionVerifier(true, null, mem, c)); Assert.Throws <ArgumentNullException>(() => new TransactionVerifier(true, ut, null, c)); Assert.Throws <ArgumentNullException>(() => new TransactionVerifier(true, ut, mem, null)); }
public static IEnumerable <object[]> GetCoinBasePrimCases() { var c = new MockConsensus(MockHeight) { bip34 = true }; yield return(new object[] { c, new MockTxPropInOut(new TxIn[0], null), false, "Coinbase transaction must contain only one input.", 0 }); yield return(new object[] { c, new MockTxPropInOut(new TxIn[2], null), false, "Coinbase transaction must contain only one input.", 0 }); yield return(new object[] { c, new MockTxPropInOut(new TxIn[1], new TxOut[0]), false, "Transaction must contain at least one output.", 0 }); byte[] badHash = new byte[32]; badHash[0] = 1; yield return(new object[] { c, new MockTxPropInOut(new TxIn[1] { new TxIn(badHash, uint.MaxValue, null, 1234) }, new TxOut[1]), false, "Invalid coinbase outpoint.", 0 }); yield return(new object[] { c, new MockTxPropInOut(new TxIn[1] { new TxIn(new byte[32], 0, null, 1234) }, new TxOut[1]), false, "Invalid coinbase outpoint.", 0 }); var mockFailSigScr = new MockCoinbaseVerifySigScript(MockHeight, false); yield return(new object[] { c, new MockTxPropInOut(new TxIn[1] { new TxIn(new byte[32], uint.MaxValue, mockFailSigScr, 1234) }, new TxOut[1]), false, "Invalid coinbase signature script.", 0 }); var mockPassSigScr = new MockCoinbaseVerifySigScript(MockHeight, true, 100); TxOut t1 = new TxOut(50, new MockSigOpCountPubScript(20)); TxOut t2 = new TxOut(60, new MockSigOpCountPubScript(3)); yield return(new object[] { c, new MockTxPropInOut(new TxIn[1] { new TxIn(new byte[32], uint.MaxValue, mockPassSigScr, 1234) }, new TxOut[2] { t1, t2 }), true, null, 492 // 4*100 + 4*20 + 4*3 }); }
public static IEnumerable <object[]> GetTxVerifyCases() { var c = new MockConsensus() { expHeight = MockHeight, bip65 = true, bip112 = true, strictDer = true, bip147 = true, bip16 = true, segWit = true, }; byte[] simpTxHash1 = new byte[32]; simpTxHash1[1] = 1; byte[] simpTxHash2 = new byte[32]; simpTxHash2[1] = 2; byte[] simpTxHash3 = new byte[32]; simpTxHash3[1] = 3; var simpPubScr = new PubkeyScript(); var simpSigScr = new SignatureScript(new byte[1] { (byte)OP._1 }); // *** Fee Tests *** yield return(new object[] { new MockUtxoDatabase(simpTxHash1, new MockUtxo() { Amount = 0, Index = 0, PubScript = simpPubScr }), new MockMempool(null), c, new Transaction() { TxInList = new TxIn[1] { new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue) }, TxOutList = new TxOut[1] { new TxOut(0, simpPubScr) } }, true, // Verification success null, // Error 0, // Added SigOpCount 0, // Added fee false, // AnySegWit }); yield return(new object[] { new MockUtxoDatabase(simpTxHash1, new MockUtxo() { Amount = 0, Index = 0, PubScript = simpPubScr }), new MockMempool(null), c, new Transaction() { TxInList = new TxIn[1] { new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue) }, TxOutList = new TxOut[1] { new TxOut(1, simpPubScr) } }, false, // Verification success "Transaction is spending more than it can.", // Error 0, // Added SigOpCount 0, // Added fee false, // AnySegWit }); yield return(new object[] { new MockUtxoDatabase(simpTxHash1, new MockUtxo() { Amount = 123, Index = 0, PubScript = simpPubScr }), new MockMempool(null), c, new Transaction() { TxInList = new TxIn[1] { new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue) }, TxOutList = new TxOut[1] { new TxOut(3, simpPubScr) } }, true, // Verification success null, // Error 0, // Added SigOpCount 120, // Added fee false, // AnySegWit }); yield return(new object[] { // Make sure ulong is being used for calculation of fee new MockUtxoDatabase(simpTxHash1, new MockUtxo() { Amount = Constants.TotalSupply, Index = 0, PubScript = simpPubScr }), new MockMempool(null), c, new Transaction() { TxInList = new TxIn[1] { new TxIn(simpTxHash1, 0, simpSigScr, uint.MaxValue) }, TxOutList = new TxOut[1] { new TxOut(1000, simpPubScr) } }, true, // Verification success null, // Error 0, // Added SigOpCount Constants.TotalSupply - 1000UL, // Added fee false, // AnySegWit }); yield return(new object[] { new MockUtxoDatabase(new byte[][] { simpTxHash1, simpTxHash2, simpTxHash3 }, new IUtxo[] { new MockUtxo() { Amount = 13, Index = 3, PubScript = simpPubScr }, new MockUtxo() { Amount = 57, Index = 7, PubScript = simpPubScr }, new MockUtxo() { Amount = 73, Index = 5, PubScript = simpPubScr }, }), new MockMempool(null), c, new Transaction() { TxInList = new TxIn[3] { new TxIn(simpTxHash1, 3, simpSigScr, uint.MaxValue), new TxIn(simpTxHash2, 7, simpSigScr, uint.MaxValue), new TxIn(simpTxHash3, 5, simpSigScr, uint.MaxValue), }, TxOutList = new TxOut[3] { new TxOut(140, simpPubScr), new TxOut(3, simpPubScr), new TxOut(1, simpPubScr), } }, false, // Verification success "Transaction is spending more than it can.", // Error 0, // Added SigOpCount 0, // Added fee false, // AnySegWit }); yield return(new object[] { new MockUtxoDatabase(new byte[][] { simpTxHash1, simpTxHash2, simpTxHash3 }, new IUtxo[] { new MockUtxo() { Amount = 13, Index = 3, PubScript = simpPubScr }, new MockUtxo() { Amount = 57, Index = 7, PubScript = simpPubScr }, new MockUtxo() { Amount = 73, Index = 5, PubScript = simpPubScr }, }), new MockMempool(null), c, new Transaction() { TxInList = new TxIn[3] { new TxIn(simpTxHash1, 3, simpSigScr, uint.MaxValue), new TxIn(simpTxHash2, 7, simpSigScr, uint.MaxValue), new TxIn(simpTxHash3, 5, simpSigScr, uint.MaxValue), }, TxOutList = new TxOut[3] { new TxOut(12, simpPubScr), new TxOut(6, simpPubScr), new TxOut(50, simpPubScr), } }, true, // Verification success null, // Error 0, // Added SigOpCount 75, // Added fee false, // AnySegWit }); // *** Transaction Tests (from signtx cases) *** foreach (var Case in Helper.ReadResource <JArray>("SignedTxTestData")) { Transaction prevTx = new Transaction(); prevTx.TryDeserialize(new FastStreamReader(Helper.HexToBytes(Case["TxToSpend"].ToString())), out string _); byte[] prevTxHash = prevTx.GetTransactionHash(); var utxoDb = new MockUtxoDatabase(); for (int i = 0; i < prevTx.TxOutList.Length; i++) { var utxo = new MockUtxo() { Amount = prevTx.TxOutList[i].Amount, Index = (uint)i, PubScript = prevTx.TxOutList[i].PubScript }; utxoDb.Add(prevTxHash, utxo); } foreach (var item in Case["Cases"]) { Transaction tx = new Transaction(); FastStreamReader stream = new FastStreamReader(Helper.HexToBytes(item["SignedTx"].ToString())); if (!tx.TryDeserialize(stream, out string err)) { throw new ArgumentException($"Could not deseralize the given tx case: " + $"{item["TestName"]}. Error: {err}"); } int sigOpCount = (int)item["SigOpCount"]; ulong fee = (ulong)item["Fee"]; yield return(new object[] { utxoDb, new MockMempool(null), c, tx, true, // Verification success null, // Error sigOpCount, fee, tx.WitnessList != null, // AnySegWit }); } } }
public static IEnumerable <object[]> GetLocatorCases() { var fman = new MockFileManager() { expReadFN = "Headers", returnReadData = BlockHeaderTests.GetSampleBlockHeaderBytes(), blockInfo = new byte[32 + 4 + 4] }; var consensus = new MockConsensus(); var bver = new BlockVerifier(null, consensus); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(1), GetHeaders(1) }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(2), GetHeaders(2).Reverse() }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(10), GetHeaders(10).Reverse() }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(11), GetHeaders(11).Reverse() }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(12), GetHeaders(12).Reverse() }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(13), new BlockHeader[12] { new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(4, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(3, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(2, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(14), new BlockHeader[13] { new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(4, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(3, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(1, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(15), new BlockHeader[13] { new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(4, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(2, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(16), new BlockHeader[13] { new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(3, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(17), new BlockHeader[13] { new BlockHeader(16, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(4, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(18), new BlockHeader[14] { new BlockHeader(17, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(16, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(1, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); yield return(new object[] { GetChain(fman, bver, consensus), GetHeaders(19), new BlockHeader[14] { new BlockHeader(18, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(17, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(16, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(2, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); yield return(new object[] { GetChain(fman, bver, consensus), new BlockHeader[19] { new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(1, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(2, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(3, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(4, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(16, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(17, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(18, new byte[32], new byte[32], (uint)UnixTimeStamp.TimeToEpoch(DateTime.Now.Subtract(TimeSpan.FromHours(1))), 0, 0), }, new BlockHeader[14] { // Last block (18) is not included new BlockHeader(17, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(16, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(1, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); uint yesterday = (uint)UnixTimeStamp.TimeToEpoch(DateTime.UtcNow.Subtract(TimeSpan.FromHours(25))); yield return(new object[] { GetChain(fman, bver, consensus), new BlockHeader[19] { new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(1, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(2, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(3, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(4, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(5, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(7, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(16, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(17, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(18, new byte[32], new byte[32], yesterday, 0, 0), }, new BlockHeader[14] { new BlockHeader(18, new byte[32], new byte[32], yesterday, 0, 0), new BlockHeader(17, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(16, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(15, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(14, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(13, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(12, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(11, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(10, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(9, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(8, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(6, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(2, new byte[32], new byte[32], 0, 0, 0), new BlockHeader(0, new byte[32], new byte[32], 0, 0, 0), } }); }