public async Task MinerCreateBlockRelativeTimeLockedAsync() { var context = new TestContext(); await context.InitializeAsync(); var tx = context.network.CreateTransaction(); tx.AddInput(new TxIn()); tx.AddOutput(new TxOut()); Transaction.LockTimeFlags flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast; // height map var prevheights = new List <int>(); prevheights.Add(1); // relative time locked tx.Version = 2; tx.Inputs[0].PrevOut.Hash = context.txFirst[1].GetHash(); tx.Inputs[0].ScriptSig = new Script(OpcodeType.OP_1); tx.Inputs[0].PrevOut.N = 0; tx.Inputs[0].Sequence = new Sequence(TimeSpan.FromMinutes(10)); // txFirst[1] is the 3rd block tx.Outputs[0].Value = context.BLOCKSUBSIDY - context.HIGHFEE; tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1); tx.LockTime = 0; prevheights[0] = context.baseheight + 2; context.hash = tx.GetHash(); context.mempool.AddUnchecked(context.hash, context.entry.Time(context.DateTimeProvider.GetTime()).FromTx(tx)); Assert.True(MempoolValidator.CheckFinalTransaction(context.ChainIndexer, context.DateTimeProvider, tx, flags)); // Locktime passes Assert.True(!this.TestSequenceLocks(context, context.ChainIndexer.Tip, tx, flags)); // Sequence locks fail }
public void MinerCreateBlockAbsoluteTimeLocked() { var context = new TestContext(); var tx = new Transaction(); tx.AddInput(new TxIn()); tx.AddOutput(new TxOut()); var flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast; List <int> prevheights = new List <int>(); prevheights.Add(1); tx.Version = 2; tx.Inputs[0].PrevOut.Hash = context.txFirst[3].GetHash(); tx.Inputs[0].ScriptSig = new Script(OpcodeType.OP_1); tx.Inputs[0].PrevOut.N = 0; tx.Outputs[0].Value = context.BLOCKSUBSIDY - context.HIGHFEE; tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1); // absolute time locked tx.LockTime = context.chain.Tip.GetMedianTimePast().AddMinutes(1); tx.Inputs[0].Sequence = Sequence.Final - 1; prevheights[0] = context.baseheight + 4; context.hash = tx.GetHash(); context.mempool.AddUnchecked(context.hash, context.entry.Time(context.date.GetTime()).FromTx(tx)); Assert.True(!MempoolValidator.CheckFinalTransaction(context.chain, context.date, tx, flags)); // Locktime fails Assert.True(TestSequenceLocks(context, context.chain.Tip, tx, flags)); // Sequence locks pass context.chain.SetTip(new BlockHeader { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512 }); context.chain.SetTip(new BlockHeader { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512 }); Assert.True(tx.IsFinal(context.chain.Tip.GetMedianTimePast().AddMinutes(2), context.chain.Tip.Height + 2)); // Locktime passes 2 min later }
public async Task MinerCreateBlockAbsoluteHeightLockedAsync() { var context = new TestContext(); await context.InitializeAsync(); var tx = new Transaction(); tx.AddInput(new TxIn()); tx.AddOutput(new TxOut()); var flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast; int MedianTimeSpan = 11; List <int> prevheights = new List <int>(); prevheights.Add(1); tx.Version = 2; tx.Inputs[0].PrevOut.Hash = context.txFirst[1].GetHash(); tx.Inputs[0].ScriptSig = new Script(OpcodeType.OP_1); tx.Inputs[0].PrevOut.N = 0; tx.Inputs[0].Sequence = new Sequence(TimeSpan.FromMinutes(10)); // txFirst[1] is the 3rd block tx.Outputs[0].Value = context.BLOCKSUBSIDY - context.HIGHFEE; tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1); tx.LockTime = 0; prevheights[0] = context.baseheight + 2; for (int i = 0; i < MedianTimeSpan; i++) { context.chain.SetTip(new BlockHeader { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512 }); } var locks = (tx.CalculateSequenceLocks(prevheights.ToArray(), context.chain.Tip, flags)); Assert.True(locks.Evaluate(context.chain.Tip)); context = new TestContext(); await context.InitializeAsync(); // absolute height locked tx.Inputs[0].PrevOut.Hash = context.txFirst[2].GetHash(); tx.Inputs[0].Sequence = Sequence.Final - 1; prevheights[0] = context.baseheight + 3; tx.LockTime = context.chain.Tip.Height + 1; context.hash = tx.GetHash(); context.mempool.AddUnchecked(context.hash, context.entry.Time(context.DateTimeProvider.GetTime()).FromTx(tx)); Assert.True(!MempoolValidator.CheckFinalTransaction(context.chain, context.DateTimeProvider, tx, flags)); // Locktime fails Assert.True(this.TestSequenceLocks(context, context.chain.Tip, tx, flags)); // Sequence locks pass context.chain.SetTip(new BlockHeader { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512 }); context.chain.SetTip(new BlockHeader { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 512 }); Assert.True(tx.IsFinal(context.chain.Tip.GetMedianTimePast(), context.chain.Tip.Height + 2)); // Locktime passes on 2nd block }
public async Task MinerCreateBlockNonFinalTxsInMempoolAsync() { var context = new TestContext(); await context.InitializeAsync(); var tx = context.network.CreateTransaction(); tx.AddInput(new TxIn()); tx.AddOutput(new TxOut()); // non - final txs in mempool (context.DateTimeProvider as DateTimeProviderSet).time = context.ChainIndexer.Tip.Header.Time + 1; //SetMockTime(chainActive.Tip().GetMedianTimePast() + 1); Transaction.LockTimeFlags flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast; // height map var prevheights = new List <int>(); // relative height locked tx.Version = 2; prevheights.Add(1); tx.Inputs[0].PrevOut.Hash = context.txFirst[0].GetHash(); // only 1 transaction tx.Inputs[0].PrevOut.N = 0; tx.Inputs[0].ScriptSig = new Script(OpcodeType.OP_1); tx.Inputs[0].Sequence = new Sequence(context.ChainIndexer.Tip.Height + 1); // txFirst[0] is the 2nd block prevheights[0] = context.baseheight + 1; tx.Outputs[0].Value = context.BLOCKSUBSIDY - context.HIGHFEE; tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1); tx.LockTime = 0; context.hash = tx.GetHash(); context.mempool.AddUnchecked(context.hash, context.entry.Fee(context.HIGHFEE).Time(context.DateTimeProvider.GetTime()).SpendsCoinbase(true).FromTx(tx)); Assert.True(MempoolValidator.CheckFinalTransaction(context.ChainIndexer, context.DateTimeProvider, tx, flags)); // Locktime passes Assert.True(!this.TestSequenceLocks(context, context.ChainIndexer.Tip, tx, flags)); // Sequence locks fail BlockHeader blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader(); blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock; blockHeader.Time = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 1; context.ChainIndexer.SetTip(blockHeader); blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader(); blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock; blockHeader.Time = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 1; context.ChainIndexer.SetTip(blockHeader); blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader(); blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock; blockHeader.Time = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 1; context.ChainIndexer.SetTip(blockHeader); SequenceLock locks = tx.CalculateSequenceLocks(prevheights.ToArray(), context.ChainIndexer.Tip, flags); Assert.True(locks.Evaluate(context.ChainIndexer.Tip)); // Sequence locks pass on 2nd block }
public void MinerCreateBlockNonFinalTxsInMempool() { var context = new TestContext(); var tx = new Transaction(); tx.AddInput(new TxIn()); tx.AddOutput(new TxOut()); // non - final txs in mempool (context.date as MemoryPoolTests.DateTimeProviderSet).time = context.chain.Tip.Header.Time + 1; //SetMockTime(chainActive.Tip().GetMedianTimePast() + 1); var flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast; // height map List <int> prevheights = new List <int>(); // relative height locked tx.Version = 2; prevheights.Add(1); tx.Inputs[0].PrevOut.Hash = context.txFirst[0].GetHash(); // only 1 transaction tx.Inputs[0].PrevOut.N = 0; tx.Inputs[0].ScriptSig = new Script(OpcodeType.OP_1); tx.Inputs[0].Sequence = new Sequence(context.chain.Tip.Height + 1); // txFirst[0] is the 2nd block prevheights[0] = context.baseheight + 1; tx.Outputs[0].Value = context.BLOCKSUBSIDY - context.HIGHFEE; tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1); tx.LockTime = 0; context.hash = tx.GetHash(); context.mempool.AddUnchecked(context.hash, context.entry.Fee(context.HIGHFEE).Time(context.date.GetTime()).SpendsCoinbase(true).FromTx(tx)); Assert.True(MempoolValidator.CheckFinalTransaction(context.chain, context.date, tx, flags)); // Locktime passes Assert.True(!TestSequenceLocks(context, context.chain.Tip, tx, flags)); // Sequence locks fail context.chain.SetTip(new BlockHeader() { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 1 }); context.chain.SetTip(new BlockHeader() { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 1 }); context.chain.SetTip(new BlockHeader() { HashPrevBlock = context.chain.Tip.HashBlock, Time = Utils.DateTimeToUnixTime(context.chain.Tip.GetMedianTimePast()) + 1 }); var locks = tx.CalculateSequenceLocks(prevheights.ToArray(), context.chain.Tip, flags); Assert.True(locks.Evaluate(context.chain.Tip)); // Sequence locks pass on 2nd block }
public async Task MinerCreateBlockAbsoluteTimeLockedAsync() { var context = new TestContext(); await context.InitializeAsync(); var tx = context.network.CreateTransaction(); tx.AddInput(new TxIn()); tx.AddOutput(new TxOut()); Transaction.LockTimeFlags flags = Transaction.LockTimeFlags.VerifySequence | Transaction.LockTimeFlags.MedianTimePast; var prevheights = new List <int>(); prevheights.Add(1); tx.Version = 2; tx.Inputs[0].PrevOut.Hash = context.txFirst[3].GetHash(); tx.Inputs[0].ScriptSig = new Script(OpcodeType.OP_1); tx.Inputs[0].PrevOut.N = 0; tx.Outputs[0].Value = context.BLOCKSUBSIDY - context.HIGHFEE; tx.Outputs[0].ScriptPubKey = new Script(OpcodeType.OP_1); // absolute time locked tx.LockTime = context.ChainIndexer.Tip.GetMedianTimePast().AddMinutes(1); tx.Inputs[0].Sequence = Sequence.Final - 1; prevheights[0] = context.baseheight + 4; context.hash = tx.GetHash(); context.mempool.AddUnchecked(context.hash, context.entry.Time(context.DateTimeProvider.GetTime()).FromTx(tx)); Assert.True(!MempoolValidator.CheckFinalTransaction(context.ChainIndexer, context.DateTimeProvider, tx, flags)); // Locktime fails Assert.True(this.TestSequenceLocks(context, context.ChainIndexer.Tip, tx, flags)); // Sequence locks pass BlockHeader blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader(); blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock; blockHeader.Time = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 512; context.ChainIndexer.SetTip(blockHeader); blockHeader = context.network.Consensus.ConsensusFactory.CreateBlockHeader(); blockHeader.HashPrevBlock = context.ChainIndexer.Tip.HashBlock; blockHeader.Time = Utils.DateTimeToUnixTime(context.ChainIndexer.Tip.GetMedianTimePast()) + 512; context.ChainIndexer.SetTip(blockHeader); Assert.True(tx.IsFinal(context.ChainIndexer.Tip.GetMedianTimePast().AddMinutes(2), context.ChainIndexer.Tip.Height + 2)); // Locktime passes 2 min later }