public void AddOversizedProductionTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096, 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); var sozu = GetSozuTable(volatileStore, hash); var context = new BlockAlias(123, 0); for (var i = 0; i < 3; ++i) { var coin = GetCoin(rand); var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret); } var coin2 = GetCoin(rand, SozuTable.PayloadOversizeInBytes + 10, new BlockAlias(123, 0)); var ret2 = sozu.AddProduction(hash.Hash(ref coin2.Outpoint), ref coin2.Outpoint, false, coin2.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret2); var pl = volatileStore.Read(volatileStore.LayerCount - 1, 0); Assert.True(pl.TryGet(ref coin2.Outpoint, out var coin2_p0)); Assert.True(coin2.Span.SequenceEqual(coin2_p0.Span)); }
public void AddProductionThenOverflowTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096, 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); var sozu = GetSozuTable(volatileStore, hash); int cumulSize = 0; do { var coin = GetCoin(rand); var context = new BlockAlias(123, 0); var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret); cumulSize += coin.SizeInBytes; } while (cumulSize <= 4096); var p0 = volatileStore.Read(0, 0); Assert.True(p0.OutpointSigCount > 0); }
public void OverflowToLastLayerTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096, 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); var sozu = GetSozuTable(volatileStore, hash); int cumulSize = 0; do { var coin = GetCoin(rand); var context = new BlockAlias(123, 0); var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret); cumulSize += coin.SizeInBytes; } while (cumulSize <= 4096 * 2); var p0 = volatileStore.Read(0, 0); Assert.True(p0.OutpointSigCount > 0, "First layer doesn't have probabilistic filter."); var p1 = volatileStore.Read(1, 0); var pl = volatileStore.Read(volatileStore.LayerCount - 1, 0); Assert.True(pl.CoinCount > 0, "Last layer doesn't have any coin."); Assert.True(p1.CoinCount + pl.CoinCount == p0.OutpointSigCount, "probabilistic filter count mismatches" + "deeper layers coins count."); }
public void AddConsumption_InConsistentContext_Test() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); var sozu = GetSozuTable(volatileStore, hash); var context = new BlockAlias(123, 0); var coin1 = GetCoin(rand); var ret1 = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret1); for (var i = 0; i < 3; ++i) { var coin = GetCoin(rand); var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret); } ret1 = sozu.AddConsumption(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, context, new MockLineage(() => false)); Assert.Equal(CoinChangeStatus.InvalidContext, ret1); }
public void AliasHandleRoundTrip() { var rand = new Random(42); for (var i = 0; i < 70000; i++) { for (var j = 0; j < 64; j++) { var alias = new BlockAlias(i, j); Assert.True(alias.IsDefined); Assert.Equal(i, alias.BlockHeight); Assert.Equal(j, alias.SubIndex); var mask = new ClientId((uint)rand.Next()).Mask; var handle = alias.ConvertToBlockHandle(mask); Assert.True(handle.IsDefined); var aliasBis = handle.ConvertToBlockAlias(mask); Assert.Equal(alias, aliasBis); } } }
public void TryGetTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); var pack = volatileStore.Read(0, 0); pack.Append(GetCoin(rand, new BlockAlias(123, 0))); pack.Append(GetCoin(rand, new BlockAlias(123, 0))); var coin1 = GetCoin(rand, new BlockAlias(123, 0)); pack.Append(coin1); var context = new BlockAlias(123, 0); Coin coin2; var sozu = GetSozuTable(volatileStore, hash); bool res = sozu.TryGet(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, context, new MockLineage((out BlockAlias result) => result = context, MockLineage.Undefined), out coin2, out var production, out var consumption); Assert.True(res, "Sozu2 TryGet failed to get an existing outpoint."); Assert.True(coin1.Span.SequenceEqual(coin2.Span), "Sozu2 TryGet mismatch."); Assert.Equal(production, context); Assert.False(consumption.IsDefined); Coin coin3 = GetCoin(rand); res = sozu.TryGet(hash.Hash(ref coin3.Outpoint), ref coin3.Outpoint, context, new MockLineage(), out coin2, out var production3, out var consumption3); Assert.False(res, "Sozu2 TryGet returns an nonexistent outpoint."); }
public bool TryGet(ulong outpointHash, ref Outpoint outpoint, BlockAlias context, ILineage lineage, out Coin coin, out BlockAlias production, out BlockAlias consumption) { production = BlockAlias.Undefined; consumption = BlockAlias.Undefined; if (_coins.TryGetValue(outpoint, out var fatCoin)) { foreach (var ev in fatCoin.Events) { if (ev.Kind == CoinEventKind.Production) { production = ev.BlockAlias; } if (ev.Kind == CoinEventKind.Consumption) { consumption = ev.BlockAlias; } } if (lineage == null || lineage.TryGetEventsInContext(fatCoin.Events.ToArray(), context, out production, out consumption)) { coin = fatCoin.Coin; return(true); } } coin = Coin.Empty; return(false); }
private static unsafe Coin GetCoin(Random rand, BlockAlias production) { var coin = new Coin(new byte[4096]); var outpoint = new Outpoint(); for (var i = 0; i < 32; i++) { outpoint.TxId[i] = (byte)rand.Next(); } outpoint.TxIndex = rand.Next(); coin.Outpoint = outpoint; var events = new[] { new CoinEvent(production, CoinEventKind.Production) }; coin.SetEvents(events); var script = new byte[100]; rand.NextBytes(script); var payload = new Payload(new byte[100 + sizeof(uint) + sizeof(ulong) + sizeof(int)]); payload.NLockTime = (uint)rand.Next(); payload.Satoshis = (ulong)rand.Next(); payload.Append(script); coin.SetPayload(payload); return(coin); }
public bool TryGetEventsInContext(Span <CoinEvent> events, BlockAlias context, out BlockAlias production, out BlockAlias consumption) { _readProduction(out production); _readConsumption(out consumption); return(true); }
public GetCoinResponse( RequestId requestId, ClientId clientId, GetCoinStatus status, ref Outpoint outpoint, OutpointFlags flags, BlockAlias context, BlockAlias production, BlockAlias consumption, ulong satoshis, uint nLockTime, Span <byte> script, BlockHandleMask mask, SpanPool <byte> pool) { var messageSizeInBytes = Header.SizeInBytes + script.Length; _buffer = pool.GetSpan(messageSizeInBytes); AsHeader.ResponseHeader.MessageSizeInBytes = messageSizeInBytes; AsHeader.ResponseHeader.RequestId = requestId; AsHeader.ResponseHeader.ClientId = clientId; AsHeader.ResponseHeader.MessageKind = MessageKind.GetCoinResponse; AsHeader.Status = status; AsHeader.Outpoint = outpoint; AsHeader.Flags = flags; AsHeader.Context = context.ConvertToBlockHandle(mask); AsHeader.Production = production.ConvertToBlockHandle(mask); AsHeader.Consumption = consumption.ConvertToBlockHandle(mask); AsHeader.Satoshis = satoshis; AsHeader.NLockTime = nLockTime; script.CopyTo(_buffer.Slice(Header.SizeInBytes)); }
/// <summary> /// Allocate an array. Intended for testing purposes only. /// </summary> internal static ProduceCoinRequest From( RequestId requestId, ClientId clientId, Outpoint outpoint, OutpointFlags flags, BlockAlias context, ulong satoshis, uint nLockTime, Span <byte> script, BlockHandleMask mask) { var request = new ProduceCoinRequest { _buffer = new Span <byte>(new byte[Header.SizeInBytes + script.Length]) }; request.MessageHeader.MessageSizeInBytes = Header.SizeInBytes + script.Length; request.MessageHeader.RequestId = requestId; request.MessageHeader.ClientId = clientId; request.MessageHeader.MessageKind = MessageKind.ProduceCoin; request.AsHeader.Outpoint = outpoint; request.AsHeader.Flags = flags; request.AsHeader.Context = context.ConvertToBlockHandle(mask); request.AsHeader.Satoshis = satoshis; request.AsHeader.NLockTime = nLockTime; script.CopyTo(request._buffer.Slice(Header.SizeInBytes)); return(request); }
public void RemoveSigsAfterPruningTest() { var hash = GetMockHash().Object; var rand = new Random(2); var volatileStore = new VolatilePackStore(1, new[] { 4096, 4096 }); var sozu = GetSozuTable(volatileStore, hash); var lineage = new MockLineage(); var pruneCount = 3; int cumulSize = 0; for (var i = 0; i < pruneCount; i++) { var coin1 = GetCoin(rand); var ret1 = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, MockLineage.CoinEventToPrune.BlockAlias, lineage); Assert.Equal(CoinChangeStatus.Success, ret1); cumulSize += coin1.SizeInBytes; } do { var coin = GetCoin(rand); var context = new BlockAlias(123, 0); var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, lineage); Assert.Equal(CoinChangeStatus.Success, ret); cumulSize += coin.SizeInBytes; } while (cumulSize <= 4096); var p0 = volatileStore.Read(0, 0); cumulSize = p0.SizeInBytes; int sigsCount = 0; int opCount = 0; do { var coin = GetCoin(rand); var context = new BlockAlias(123, 0); if (cumulSize + coin.SizeInBytes > 4096) { p0 = volatileStore.Read(0, 0); sigsCount = p0.OutpointSigCount; opCount = p0.CoinCount + 1; lineage.PruningActive = true; } var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, lineage); Assert.Equal(CoinChangeStatus.Success, ret); cumulSize += coin.SizeInBytes; } while (cumulSize <= 4096); p0 = volatileStore.Read(0, 0); Assert.True(opCount - p0.CoinCount + sigsCount - p0.OutpointSigCount == pruneCount); }
public void ConvertToBlockAlias() { var alias = new BlockAlias(100, 1); var handle = alias.ConvertToBlockHandle(new BlockHandleMask(0x5678abcd)); var aliasFromHandle = handle.ConvertToBlockAlias(new BlockHandleMask(0x5678abcd)); Assert.Equal(alias, aliasFromHandle); }
/// <summary> /// Allocate an array. Intended for testing purposes only. /// </summary> internal static ConsumeCoinRequest From(RequestId requestId, ref Outpoint outpoint, BlockAlias context, BlockHandleMask mask) { return(new ConsumeCoinRequest(requestId, ref outpoint, context.ConvertToBlockHandle(mask), new SpanPool <byte>(Header.SizeInBytes))); }
public static GetBlockInformation DeserializeGetBlockInfo(ReadOnlySpan <byte> message) { var editor = new SpanBinaryReader(message); var header = ParseMessageHeader(ref editor, GetBlockInformation.Info); var blockHandle = new BlockAlias(editor.ReadUInt32()); return(new GetBlockInformation(header.RequestId, header.ClientId, blockHandle)); }
public static OpenBlock DeserializeOpenBlock(ReadOnlySpan <byte> message) { var editor = new SpanBinaryReader(message); var header = ParseMessageHeader(ref editor, OpenBlock.Info); var parentAlias = new BlockAlias(editor.ReadUInt32()); return(new OpenBlock(header.RequestId, header.ClientId, parentAlias)); }
public static BlockHandle ConvertToBlockHandle(this BlockAlias alias, BlockHandleMask mask) { if (!alias.IsDefined) { return(BlockHandle.Undefined); } // Idem, see above. return(new BlockHandle(alias.Value ^ (~0x01u & (BlockHandle.DefaultMask ^ mask.Value)))); }
public OpenedBlock( uint requestId, uint clientId, TempBlockId uncommittedBlockId, BlockAlias alias) : base(requestId, clientId, MessageType.OpenedBlock) { UncommittedBlockId = uncommittedBlockId; Alias = alias; }
public static CommitBlock DeserializeCommitBlock(ReadOnlySpan <byte> message) { var editor = new SpanBinaryReader(message); var header = ParseMessageHeader(ref editor, CommitBlock.Info); var blockHandle = new BlockAlias(editor.ReadUInt32()); var blockId = BlockId.Create(ref editor); return(new CommitBlock(header.RequestId, header.ClientId, blockHandle, blockId)); }
public GetBlockHandleResponse( ref MessageHeader requestHeader, BlockHandleMask mask, BlockAlias alias, SpanPool <byte> pool) { _buffer = pool.GetSpan(Header.SizeInBytes); AsHeader.ResponseHeader = requestHeader; AsHeader.ResponseHeader.MessageKind = MessageKind.BlockHandleResponse; AsHeader.ResponseHeader.MessageSizeInBytes = Header.SizeInBytes; AsHeader.Status = GetBlockHandleStatus.Success; AsHeader.Handle = alias.ConvertToBlockHandle(mask); }
public UncommittedBlockInformation( uint requestId, uint clientId, TempBlockId uncommittedBlockId, BlockAlias alias, int height, BlockAlias parent) : base(requestId, clientId, MessageType.UncommittedBlockInfo) { BlockHeight = height; UncommittedBlockId = uncommittedBlockId; Alias = alias; Parent = parent; }
public CommittedBlockInformation( uint requestId, uint clientId, BlockId blockId, BlockAlias alias, int height, BlockAlias parent) : base(requestId, clientId, MessageType.CommittedBlockInfo) { BlockHeight = height; BlockId = blockId; Alias = alias; Parent = parent; }
public OpenBlockResponse( ref MessageHeader requestHeader, BlockHandleMask mask, BlockAlias alias, UncommittedBlockId uncommittedBlockId, SpanPool <byte> pool) { _buffer = pool.GetSpan(Header.SizeInBytes); AsHeader.ResponseHeader = requestHeader; AsHeader.ResponseHeader.MessageKind = MessageKind.OpenBlockResponse; AsHeader.ResponseHeader.MessageSizeInBytes = Header.SizeInBytes; AsHeader.Status = OpenBlockStatus.Success; AsHeader.Handle = alias.ConvertToBlockHandle(mask); AsHeader.UncommittedBlockId = uncommittedBlockId; }
public CoinChangeStatus Remove(ulong outpointHash, ref Outpoint outpoint, BlockAlias context, CoinRemoveOption option, ILineage lineage) { if (!_coins.TryGetValue(outpoint, out var fatCoin)) { return(CoinChangeStatus.OutpointNotFound); } fatCoin.Events.RemoveAll(ev => ev.BlockAlias == context && (((option & CoinRemoveOption.RemoveProduction) != 0 && ev.Kind == CoinEventKind.Production) || ((option & CoinRemoveOption.RemoveConsumption) != 0 && ev.Kind == CoinEventKind.Consumption))); return(CoinChangeStatus.Success); }
public void TryAddConsumptionInSideChainTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); // Create a real lineage var cBlocks = new List <CommittedBlock>(); cBlocks.Add(new CommittedBlock(CommittedBlockId.Genesis, BlockAlias.Genesis, BlockAlias.GenesisParent)); var uncBlocks = new List <UncommittedBlock>(); var firstBlockAlias = new BlockAlias(1, 0); var uncId = new byte[16]; rand.NextBytes(uncId); uncBlocks.Add(new UncommittedBlock( UncommittedBlockId.ReadFrom(uncId), firstBlockAlias, BlockAlias.Genesis)); var parallelBlockAlias = new BlockAlias(1, 1); rand.NextBytes(uncId); uncBlocks.Add(new UncommittedBlock( UncommittedBlockId.ReadFrom(uncId), parallelBlockAlias, BlockAlias.Genesis)); var realLineage = new Lineage(cBlocks, uncBlocks, 100); var sozu = GetSozuTable(volatileStore, hash); var coin1 = GetCoin(rand); var ret = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, firstBlockAlias, realLineage); Assert.Equal(CoinChangeStatus.Success, ret); var cons = sozu.AddConsumption(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, parallelBlockAlias, realLineage); Assert.Equal(CoinChangeStatus.InvalidContext, cons); }
public void ReadExistingCoin() { var sozu = new VolatileCoinStore(); var inbox = new BoundedInbox(); var outbox = new BoundedInbox(); var controller = new CoinController(inbox, outbox, sozu, _hash); var coin = GetCoin(_rand); sozu.AddProduction( _hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, new BlockAlias(3), null); // lineage is not used in VolatileCoinStore var clientId = new ClientId(); var reqId = new RequestId(1); var context = new BlockAlias(3); var readCoinRequest = GetCoinRequest.From(reqId, clientId, coin.Outpoint, context, clientId.Mask); inbox.TryWrite(readCoinRequest.Span); controller.HandleRequest(); var raw = outbox.Peek(); var response = new GetCoinResponse(raw.Span); Assert.Equal(response.MessageHeader.MessageSizeInBytes, raw.Length); // verify response contents Assert.Equal(reqId, response.MessageHeader.RequestId); Assert.Equal(clientId, response.MessageHeader.ClientId); Assert.Equal(MessageKind.GetCoinResponse, response.MessageHeader.MessageKind); Assert.Equal(coin.Outpoint, response.Outpoint); Assert.Equal(OutpointFlags.None, response.OutpointFlags); Assert.Equal(context, response.Context.ConvertToBlockAlias(clientId.Mask)); Assert.Equal(context, response.Production.ConvertToBlockAlias(clientId.Mask)); Assert.Equal(BlockAlias.Undefined.ConvertToBlockHandle(clientId.Mask), response.Consumption); Assert.Equal(coin.Payload.Satoshis, response.Satoshis); Assert.Equal(coin.Payload.NLockTime, response.NLockTime); Assert.True(coin.Payload.Script.SequenceEqual(response.Script)); }
public void RemoveConsumption_Test() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); var sozu = GetSozuTable(volatileStore, hash); var context = new BlockAlias(123, 0); var coin1 = GetCoin(rand); var ret1 = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret1); ret1 = sozu.AddConsumption(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret1); for (var i = 0; i < 3; ++i) { var coin = GetCoin(rand); var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret); } ret1 = sozu.Remove(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, context, CoinRemoveOption.RemoveConsumption, new MockLineage(MockLineage.Undefined, (out BlockAlias result) => result = context)); Assert.Equal(CoinChangeStatus.Success, ret1); var p0 = volatileStore.Read(0, 0); Assert.True(p0.TryGet(ref coin1.Outpoint, out var coin1_p0)); Assert.Equal(1, coin1_p0.Events.Length); Assert.Equal(coin1_p0.Events[0], new CoinEvent(context, CoinEventKind.Production)); Assert.True(coin1_p0.Payload.Span.SequenceEqual(coin1.Payload.Span)); }
public void AddConsumptionTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); var sozu = GetSozuTable(volatileStore, hash); var context = new BlockAlias(123, 0); var coin1 = GetCoin(rand); var ret1 = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret1); for (var i = 0; i < 3; ++i) { var coin = GetCoin(rand); var ret = sozu.AddProduction(hash.Hash(ref coin.Outpoint), ref coin.Outpoint, false, coin.Payload, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret); } ret1 = sozu.AddConsumption(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, context, new MockLineage()); Assert.Equal(CoinChangeStatus.Success, ret1); // test add consumption idempotence ret1 = sozu.AddConsumption(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, context, new MockLineage(() => false)); Assert.Equal(CoinChangeStatus.Success, ret1); var p0 = volatileStore.Read(0, 0); Assert.True(p0.TryGet(ref coin1.Outpoint, out var coin1_p0)); Assert.Equal(2, coin1_p0.Events.Length); Assert.True(coin1_p0.Payload.Span.SequenceEqual(coin1.Payload.Span)); }
public void GetPriorAlias() { var alias = new BlockAlias(100, 1); var priorAlias = alias.GetPriorAlias(50); Assert.Equal(priorAlias, new BlockAlias(50, 0)); priorAlias = alias.GetPriorAlias(100); Assert.Equal(priorAlias, new BlockAlias(0, 0)); priorAlias = alias.GetPriorAlias(101); Assert.Equal(priorAlias, BlockAlias.GenesisParent); priorAlias = alias.GetPriorAlias(0); Assert.Equal(priorAlias, new BlockAlias(100, 0)); // negative values are not allowed anymore //Assert.Throws<ArgumentException>(() => alias.GetPriorAlias(-1)); //Assert.Throws<ArgumentException>(() => alias.GetPriorAlias(-100)); }
public void TryAddConsumptionInPastTest() { var volatileStore = new VolatilePackStore(1, new[] { 4096 }); var hash = GetMockHash().Object; var rand = new Random(2); // Create a real lineage var cBlocks = new List <CommittedBlock>(); cBlocks.Add(new CommittedBlock(CommittedBlockId.Genesis, BlockAlias.Genesis, BlockAlias.GenesisParent)); var firstBlockAlias = new BlockAlias(1, 0); cBlocks.Add(new CommittedBlock( CommittedBlockId.ReadFromHex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD"), firstBlockAlias, BlockAlias.Genesis)); var futureBlockAlias = new BlockAlias(2, 0); cBlocks.Add(new CommittedBlock( CommittedBlockId.ReadFromHex("AAAABBBBBBBBCCCCCCCCDDDDDDDDAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDAAAA"), futureBlockAlias, firstBlockAlias)); var realLineage = new Lineage(cBlocks, new List <UncommittedBlock>(), 100); var sozu = GetSozuTable(volatileStore, hash); var coin1 = GetCoin(rand); // The next two commands will work because the fact that a block is uncommitted is not verified anymore. // If this test is moved into the ICoinStore at any point, adding a previous consumption should fail // already because a 'previous' block always has to be committed. var ret = sozu.AddProduction(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, false, coin1.Payload, futureBlockAlias, realLineage); Assert.Equal(CoinChangeStatus.Success, ret); var cons = sozu.AddConsumption(hash.Hash(ref coin1.Outpoint), ref coin1.Outpoint, firstBlockAlias, realLineage); Assert.Equal(CoinChangeStatus.InvalidContext, cons); }