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); }
private static Coin GetCoin(Random rand, int scriptLength) { 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(new BlockAlias(123, 0), CoinEventKind.Production) }; coin.SetEvents(events); var script = new byte[scriptLength]; rand.NextBytes(script); var payload = new Payload(new byte[4096]); payload.NLockTime = (uint)rand.Next(); payload.Satoshis = (ulong)rand.Next(); payload.Append(script); coin.SetPayload(payload); return(coin); }
private static Coin GetCoin(Random rand) { var scriptLength = (byte)rand.Next(); 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 script = new byte[scriptLength]; rand.NextBytes(script); var payload = new Payload(new byte[4096]); payload.NLockTime = (uint)rand.Next(); payload.Satoshis = (ulong)rand.Next(); payload.Append(script); coin.SetPayload(payload); return(coin); }
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); }
/// <exception cref="IOException"/> public override void BitcoinSerializeToStream(Stream stream) { Outpoint.BitcoinSerializeToStream(stream); stream.Write(new VarInt((ulong)ScriptBytes.Length).Encode()); stream.Write(ScriptBytes); stream.WriteLittleEndian(_sequence); }
public void OverFlowVolatile() { var sozuTable = PrepareTests(2, /*firstLayerVolatile*/ true); var whatToWrite = new TxoPack(new Outpoint[120], new byte[8192]); var wa = whatToWrite.GetResetWriter(); for (var i = 0UL; i < 20; i++) { var txid = new TxId(new Hash256(0xF111111111111122UL, 0x22222222UL, 0x33333333UL, 0x44444444UL + i)); var outpoint = new Outpoint(txid, 0, 200); var payload = new byte[200]; payload[8] = 8; payload[16 + i] = 42; wa.Write(in outpoint, payload); } sozuTable.Write(whatToWrite); var txoRead = new TxoPack(new Outpoint[120], new byte[8192]); sozuTable.Read(whatToWrite, txoRead); Assert.Equal(txoRead.Count, whatToWrite.Count); for (var i = 0; i < txoRead.Count; ++i) { Assert.True(txoRead.OutPoints[i].Equals(whatToWrite.OutPoints[i])); Assert.True(txoRead.Payloads.SequenceEqual(whatToWrite.Payloads)); } }
public void Read() { var path = @"Read-Test.store"; File.Delete(path); File.Delete(Path.Combine(Path.GetDirectoryName(path), @"hot-" + Path.GetFileName(path))); using (var fw = File.OpenWrite(path)) { fw.Write(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0xf1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xb8, 0x02, 0xb4, 0xb6, 0x09, 0x57, 0x75, 0x10, 0x92, 0xd2, 0x04, 0x1b, 0xac, 0xae, 0x6e, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x17, 0xe6, 0x61, 0x8f, 0xa0, 0xb9, 0x49, 0x99, 0xf9, 0xb2, 0x89, 0xe1, 0xb1, 0x72, 0xac, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x92, 0x65, 0xbe, 0xf7, 0x46, 0xc3, 0x12, 0xd1, 0xa2, 0x27, 0xfa, 0x1b, 0x2f, 0x3e, 0x4c, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0x26, 0x9a, 0x14, 0x9f, 0x07, 0xc9, 0xa8, 0x7d, 0xeb, 0xd7, 0xf7, 0x4f, 0x94, 0x9b, 0x7e }); } var startHash = new Hash256(0xC000000000000000UL); var endHash = new Hash256(0xF400000000000000UL); var sozuFactoryConfigs = new SozuFactoryConfig[1]; sozuFactoryConfigs[0] = new SozuFactoryConfig(2, SozuFactory.TwoPhaseStoreType, 88); var whatToWrite = new TxoPack(new Outpoint[1], new byte[2048]); var firstHash = new TxId(new Hash256(0xF111111111111122UL, 0x22222222UL, 0x33333333UL, 0x44444444UL)); var wa = whatToWrite.GetResetWriter(); var outpoint = new Outpoint(firstHash, 0, 8); var payload = new byte[8]; payload[0] = 42; wa.Write(in outpoint, payload); var txoRead = new TxoPack(new Outpoint[1], new byte[2048]); var sozuTable = new SozuFactory(null, startHash, endHash, sozuFactoryConfigs, path).Create(); sozuTable.Read(whatToWrite, txoRead); Assert.Equal(txoRead.Count, whatToWrite.Count); Assert.True(txoRead.OutPoints[0].Equals(whatToWrite.OutPoints[0])); Assert.True(payload.AsSpan().SequenceEqual(txoRead.Payloads.Slice(0, 8))); }
public override void WriteToBitcoinBuffer(byte[] buffer, int offset) { Outpoint.WriteToBitcoinBuffer(buffer, offset); ScriptLength.WriteToBitcoinBuffer(buffer, offset + SCRIPTLEN_OFFSET); Array.Copy(_script, 0, buffer, offset + SCRIPTLEN_OFFSET + (int)ScriptLength.ByteSize, (int)ScriptLength.Value); Sequence.WriteBytes(buffer, offset + SCRIPTLEN_OFFSET + (int)ScriptLength.ByteSize + (int)ScriptLength.Value * BufferOperations.UINT8_SIZE); }
/// <exception cref="IOException"/> public override void BitcoinSerializeToStream(Stream stream) { Outpoint.BitcoinSerializeToStream(stream); stream.Write(new VarInt((ulong)ScriptBytes.Length).Encode()); stream.Write(ScriptBytes); Utils.Uint32ToByteStreamLe(_sequence, stream); }
private void Work() { var txoIn = TxoPack.Create(); var txoOut = TxoPack.Create(); // local array for capturing outpoints from inbox then sorting var outpoints = new Outpoint[Constants.MaxOutpointsCount]; // array of inbox messages headers var messageHeaders = new byte[Constants.MaxOutpointsCount][]; // array of inbox messages payloads // var payloads = new byte[MaxTxoCount][]; // not used in read request // provide index array for argsort var argsort = new int[Constants.MaxOutpointsCount]; int txoCount = 0; while (!_source.Token.IsCancellationRequested) { var message = _inbox.Peek(); if (message.Length > 0) { // parse current message and add txo to txopack var outpoint = Outpoint.CreateNaked( message.Slice(ClientServerMessage.PayloadStart, Outpoint.KeySizeInBytes)); outpoints[txoCount] = outpoint; messageHeaders[txoCount] = message.Slice(0, ClientServerMessage.PayloadStart).ToArray(); // payloads[messageCount] = message.Slice(ClientServerMessage.PayloadStart).ToArray(); // not used in read request argsort[txoCount] = txoCount; ++txoCount; Debug.Assert(txoCount <= Constants.MaxOutpointsCount, "MaxTxoCount reached when looping inbox messages."); _inbox.Next(message.Length); } else { // current round of inbox message picking is over Array.Sort(outpoints, argsort, 0, txoCount); // sort txopack ref var writer = ref txoIn.GetResetWriter(); // identify identical outpoint, and write querying txopack ref var previous = ref outpoints[argsort[0]]; writer.Write(in previous, ReadOnlySpan <byte> .Empty); for (ushort index = 1; index < txoCount; ++index) { ref var current = ref outpoints[argsort[index]]; if (previous != current) { previous = current; writer.Write(in previous, ReadOnlySpan <byte> .Empty); } }
/// <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 OutpointFixture() { SpecificTxId = new TxId(new Hash256(a1, a2, a3, a4)); Zero = new TxId(new Hash256(0UL)); NonZero = new TxId(new Hash256(~0UL, ~0UL, ~0UL, ~0UL)); Outpoint = new Outpoint(SpecificTxId, 0, 512); ZeroOutpoint = new Outpoint(Zero, 0, 0); NotZeroOutpoint = new Outpoint(NonZero, ~0, ushort.MaxValue, OutpointFlags.None); }
public ulong Hash(ref Outpoint outpoint) { ulong hash = 0; for (var i = 0; i < 8; i++) { hash += ((ulong)outpoint.TxId[i]) << (i * 8); } return(hash); }
static unsafe Outpoint GetOutpoint(int seed) { var outpoint = new Outpoint(); for (var i = 0; i < 4; i++) { outpoint.TxId[i] = (byte)(seed >> (i * 8)); } outpoint.TxIndex = seed; return(outpoint); }
private static unsafe Outpoint GetOutpoint(CoinSketch sketch, int seed) { var outpoint = new Outpoint(); for (var i = 0; i < 4; i++) { outpoint.TxId[i] = (byte)(sketch.CoinId >> (i * 8 + 2)); } for (var i = 0; i < 4; i++) { outpoint.TxId[i + 4] = (byte)(seed >> (i * 8)); } return(outpoint); }
/// <summary> Client-side perspective. </summary> public GetCoinRequest( RequestId requestId, ref Outpoint outpoint, BlockHandle context, SpanPool <byte> pool) { _buffer = pool.GetSpan(Header.SizeInBytes); _mask = default; AsHeader.RequestHeader.MessageSizeInBytes = Header.SizeInBytes; AsHeader.RequestHeader.RequestId = requestId; AsHeader.RequestHeader.MessageKind = MessageKind.GetCoin; Outpoint = outpoint; HandleContext = context; }
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 From() { var rand = new Random(42); var outpoint = new Outpoint(); for (var i = 0; i < 32; i++) { outpoint.TxId[i] = 123; } var sig = OutpointSig.From((ulong)rand.Next()); // Dummy, mostly for coverage Assert.True(sig.Value != 0); }
public CoinChangeStatus AddConsumption(ulong outpointHash, ref Outpoint outpoint, BlockAlias context, ILineage lineage) { if (!_coins.TryGetValue(outpoint, out var fatCoin)) { return(CoinChangeStatus.OutpointNotFound); } var consumption = new CoinEvent(context, CoinEventKind.Consumption); if (fatCoin.Events.Contains(consumption)) { return(CoinChangeStatus.Success); } fatCoin.Events.Add(consumption); return(CoinChangeStatus.Success); }
public void WriteVolatile() { var sozuTable = PrepareTests(1, /*firstLayerVolatile*/ true); var whatToWrite = new TxoPack(new Outpoint[1], new byte[2048]); var firstHash = new TxId(new Hash256(0xF111111111111122UL, 0x22222222UL, 0x33333333UL, 0x44444444UL)); var wa = whatToWrite.GetResetWriter(); var outpoint = new Outpoint(firstHash, 0, 100); var payload = new byte[100]; payload[0] = 42; wa.Write(in outpoint, payload); sozuTable.Write(whatToWrite); var txoRead = new TxoPack(new Outpoint[1], new byte[2048]); sozuTable.Read(whatToWrite, txoRead); Assert.Equal(txoRead.Count, whatToWrite.Count); Assert.True(txoRead.OutPoints[0].Equals(whatToWrite.OutPoints[0])); Assert.True(txoRead.Payloads.SequenceEqual(whatToWrite.Payloads)); }
/// <summary> Coin removal. Client-side perspective. </summary> public RemoveCoinRequest( Span <byte> buffer, RequestId requestId, ref Outpoint outpoint, BlockHandle context, bool removeProduction, bool removeConsumption) { _buffer = buffer; _mask = default; AsHeader.RequestHeader.MessageSizeInBytes = Header.SizeInBytes; AsHeader.RequestHeader.RequestId = requestId; AsHeader.RequestHeader.MessageKind = MessageKind.RemoveCoin; Outpoint = outpoint; HandleContext = context; RemoveProduction = removeProduction; RemoveConsumption = removeConsumption; }
/// <summary> /// Allocate an array. Intended for testing purposes only. /// </summary> internal static GetCoinRequest From( RequestId requestId, ClientId clientId, Outpoint outpoint, BlockAlias context, BlockHandleMask mask) { var request = new GetCoinRequest { _buffer = new Span <byte>(new byte[Header.SizeInBytes]) }; request.MessageHeader.MessageSizeInBytes = Header.SizeInBytes; request.MessageHeader.RequestId = requestId; request.MessageHeader.ClientId = clientId; request.MessageHeader.MessageKind = MessageKind.GetCoin; request.AsHeader.Outpoint = outpoint; request.AsHeader.Context = context.ConvertToBlockHandle(mask); return(request); }
public NoneCoinbaseTransactionBuilder Spend(IEnumerable <byte> txId, UInt32 index, IEnumerable <byte> signatureScript, uint sequence = 0xffffffff) { if (txId == null) { throw new ArgumentNullException(nameof(txId)); } if (index < 0) { // TODO : THROW } if (signatureScript == null) { throw new ArgumentNullException(nameof(signatureScript)); } var outpoint = new Outpoint(txId, index); var transactionIn = new TransactionInNoneCoinbase(outpoint, signatureScript, sequence); Transaction.TransactionIn.Add(transactionIn); return(this); }
public CoinChangeStatus AddProduction(ulong outpointHash, ref Outpoint outpoint, bool isCoinBase, Payload payload, BlockAlias context, ILineage lineage) { var production = new CoinEvent(context, CoinEventKind.Production); if (_coins.TryGetValue(outpoint, out var fatCoin)) { if (fatCoin.Events.Contains(production)) { return(CoinChangeStatus.Success); // done } fatCoin.Events.Add(production); return(CoinChangeStatus.Success); } var coin = new Coin(ref outpoint, isCoinBase, payload, production, _pool); _coins.Add(outpoint, new FatCoin(coin, production)); return(CoinChangeStatus.Success); }
public bool TryGet(ulong outpointHash, ref Outpoint outpoint, BlockAlias context, ILineage lineage, out Coin coin, out BlockAlias production, out BlockAlias consumption) { var sectorIndex = (uint)(outpointHash % (uint)_store.SectorCount); production = BlockAlias.Undefined; consumption = BlockAlias.Undefined; // Check layer 0. var pack0 = _store.Read(layerIndex: 0, sectorIndex); if (pack0.TryGet(ref outpoint, out coin)) { return(lineage.TryGetEventsInContext(coin.Events, context, out production, out consumption)); } var sig = OutpointSig.From(outpointHash); // Layer 0 has a probabilistic filter. No false negative are possible. if (!pack0.PositiveMatch(sig)) { return(false); } // Check next layers. for (var layerIndex = 1; layerIndex < _store.LayerCount; layerIndex++) { var packN = _store.Read(layerIndex: layerIndex, sectorIndex); if (packN.TryGet(ref outpoint, out coin)) { return(lineage.TryGetEventsInContext(coin.Events, context, out production, out consumption)); } } // Not found, it was a false positive on the probabilistic filter. return(false); }
/// <summary> Coin production. Client-side perspective. </summary> public ProduceCoinRequest( RequestId requestId, ref Outpoint outpoint, OutpointFlags flags, BlockHandle context, ulong satoshis, uint nLockTime, int scriptSizeInBytes, SpanPool <byte> pool) { _buffer = pool.GetSpan(Header.SizeInBytes + scriptSizeInBytes); _mask = default; AsHeader.RequestHeader.MessageSizeInBytes = Header.SizeInBytes + scriptSizeInBytes; AsHeader.RequestHeader.RequestId = requestId; AsHeader.RequestHeader.MessageKind = MessageKind.ProduceCoin; Outpoint = outpoint; HandleContext = context; Flags = flags; Satoshis = satoshis; NLockTime = nLockTime; }
/// <summary> /// Return a random outpoint and a random payload. /// </summary> private (Outpoint, Memory <byte>) MakeRandomRawTxo(int lowLimit, int upLimit) { var content = new byte[Outpoint.TotalSizeInBytes].AsMemory(); var temp = new byte[Outpoint.KeySizeInBytes - 4]; _rand.NextBytes(temp); temp.CopyTo(content); var index = _rand.Next(0, 20); BitConverter.GetBytes(index).CopyTo(content.Slice(Outpoint.KeySizeInBytes - 4, 4)); var payloadLength = _rand.Next(lowLimit, upLimit); BitConverter.GetBytes(payloadLength).CopyTo(content.Slice(Outpoint.KeySizeInBytes, 4)); var payload = new byte[payloadLength]; _rand.NextBytes(payload); var numberOfEvents = _rand.Next(1, 5); // write data length inside payload BitConverter.TryWriteBytes(payload.AsSpan(sizeof(ulong), sizeof(int)), payloadLength - sizeof(ulong) - sizeof(int) - BlockEvent.SizeInBytes * numberOfEvents); var writer = new PayloadWriter(payload.AsSpan(payloadLength - BlockEvent.SizeInBytes * numberOfEvents)); for (var i = 0; i < numberOfEvents; ++i) { var ev = new BlockEvent((uint)_rand.Next(0, 1_000_000)); writer.Write(ev); } return(Outpoint.Create(content.Span), payload); }
/// <summary> /// return a random TxoPack for a given number of outpoint inside /// </summary> /// <param name="number">number of outpoints</param> private TxoPack MakeRandomTxoPack(int number) { var outpointsArray = new Outpoint[number]; var payloadStream = new MemoryStream(); var listTxo = new List <ValueTuple <Outpoint, ReadOnlyMemory <byte> > >(number); for (var i = 0; i < number; i++) { listTxo.Add(MakeRandomRawTxo(PayloadLengthLowLimit, PayloadLengthUpLimit)); } listTxo.Sort((a, b) => a.Item1.CompareTo(b.Item1)); var j = 0; foreach (var(outpoint, payload) in listTxo) { outpointsArray[j] = outpoint; j++; payloadStream.Write(payload.ToArray(), 0, payload.Length); } return(new TxoPack(outpointsArray, payloadStream.ToArray())); }
public string GetPaymentId() { return(Outpoint.ToString()); }