예제 #1
0
        public override Task <TransactionalBlockEssense> GetLastTransactionalBlock(TransactionalBlockRequest request, ServerCallContext context)
        {
            if (request.PublicKey == null)
            {
                throw new ArgumentNullException(nameof(request.PublicKey));
            }

            byte[] keyBytes = request.PublicKey.ToByteArray();

            if (keyBytes.Length != Globals.NODE_PUBLIC_KEY_SIZE)
            {
                throw new ArgumentException($"Public key size must be of {Globals.NODE_PUBLIC_KEY_SIZE} bytes");
            }

            IKey key = _identityKeyProvider.GetKey(keyBytes);
            TransactionalPacketBase transactionalBlockBase = (TransactionalPacketBase)_transactionalDataService.GetLastBlock(key);

            TransactionalBlockEssense transactionalBlockEssense = new TransactionalBlockEssense
            {
                Height = transactionalBlockBase?.BlockHeight ?? 0,
                //TODO: need to reconsider hash calculation here since it is potential point of DoS attack
                Hash          = ByteString.CopyFrom(transactionalBlockBase != null ? _hashCalculation.CalculateHash(transactionalBlockBase.RawData) : new byte[Globals.DEFAULT_HASH_SIZE]),
                UpToDateFunds = transactionalBlockBase?.UptodateFunds ?? 0
            };

            return(Task.FromResult(transactionalBlockEssense));
        }
예제 #2
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            TransactionalPacketBase block = null;

            if (version == 1)
            {
                byte[] target = spanBody.Slice(0, Globals.DEFAULT_HASH_SIZE).ToArray();

                block = new TransferFundsBlock
                {
                    TargetOriginalHash = target
                };

                transactionalBlockBase = block;

                return(spanBody.Slice(Globals.DEFAULT_HASH_SIZE));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #3
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            TransactionalPacketBase block = null;

            if (version == 1)
            {
                byte[] origin = spanBody.Slice(0, Globals.DEFAULT_HASH_SIZE).ToArray();
                ulong  funds  = BinaryPrimitives.ReadUInt64LittleEndian(spanBody.Span.Slice(Globals.DEFAULT_HASH_SIZE));

                block = new AcceptFundsBlock()
                {
                    SourceOriginalHash = origin,
                    UptodateFunds      = funds,
                };

                transactionalBlockBase = block;

                return(spanBody.Slice(Globals.DEFAULT_HASH_SIZE + 8));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #4
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            if (version == 1)
            {
                int readBytes = 0;

                ushort acceptedUnblindingAssetABsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                ushort acceptedUnblindingAssetUtxosLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                AcceptedAssetUnblindingAB[]   acceptedUnblindingAssetABs   = new AcceptedAssetUnblindingAB[acceptedUnblindingAssetABsLength];
                AcceptedAssetUnblindingUtxo[] acceptedUnblindingAssetUtxos = new AcceptedAssetUnblindingUtxo[acceptedUnblindingAssetUtxosLength];

                for (int i = 0; i < acceptedUnblindingAssetABsLength; i++)
                {
                    byte[] assetId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;
                    byte[] blindingFactor = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;
                    byte[] sourceAddress = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;
                    ulong height = BinaryPrimitives.ReadUInt64LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ulong);

                    acceptedUnblindingAssetABs[i] = new AcceptedAssetUnblindingAB
                    {
                        AcceptedAssetsUnblinding = new AcceptedAssetUnblinding
                        {
                            AssetId        = assetId,
                            BlindingFactor = blindingFactor
                        },
                        SourceAddress = sourceAddress,
                        SourceHeight  = height
                    };
                }

                for (int i = 0; i < acceptedUnblindingAssetUtxosLength; i++)
                {
                    byte[] assetId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;
                    byte[] blindingFactor = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;
                    byte[] sourceKey = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                    acceptedUnblindingAssetUtxos[i] = new AcceptedAssetUnblindingUtxo
                    {
                        AcceptedAssetsUnblinding = new AcceptedAssetUnblinding
                        {
                            AssetId        = assetId,
                            BlindingFactor = blindingFactor
                        },
                        SourceKey = sourceKey
                    };
                }

                ushort assetsGroupsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                AssetsGroup[] assetsGroups = new AssetsGroup[assetsGroupsLength];

                for (int i = 0; i < assetsGroupsLength; i++)
                {
                    uint groupId = BinaryPrimitives.ReadUInt32LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(uint);

                    ushort totalAssetIdsCount = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ushort);

                    byte[][] assetIds = new byte[totalAssetIdsCount][];
                    ulong[]  amounts  = new ulong[totalAssetIdsCount];

                    for (int j = 0; j < totalAssetIdsCount; i++)
                    {
                        assetIds[j] = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes  += Globals.NODE_PUBLIC_KEY_SIZE;
                    }

                    for (int j = 0; j < totalAssetIdsCount; i++)
                    {
                        amounts[j] = BinaryPrimitives.ReadUInt64LittleEndian(spanBody.Slice(readBytes).Span);
                        readBytes += sizeof(ulong);
                    }

                    assetsGroups[i] = new AssetsGroup
                    {
                        GroupId      = groupId,
                        AssetIds     = assetIds,
                        AssetAmounts = amounts
                    };
                }


                AcceptAssets acceptAssetTransitionBlock = new AcceptAssets
                {
                    AcceptedAssetUnblindingABs   = acceptedUnblindingAssetABs,
                    AcceptedAssetUnblindingUtxos = acceptedUnblindingAssetUtxos,
                    AssetsGroups = assetsGroups
                };

                transactionalBlockBase = acceptAssetTransitionBlock;

                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #5
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            int readBytes = 0;

            byte[] target = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
            readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

            Memory <byte> spanPostBody = ParseTransactionalNonTransitional(version, spanBody.Slice(readBytes), out TransactionalNonTransitionalPacketBase transactionalNonTransitionalPacketBase);

            transactionalNonTransitionalPacketBase.Target = target;

            transactionalBlockBase = transactionalNonTransitionalPacketBase;

            return(spanPostBody);
        }
예제 #6
0
 protected abstract Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase);
예제 #7
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            IssueAsset block = null;

            if (version == 1)
            {
                int    readBytes = 0;
                byte[] assetId   = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte strLen = spanBody.Slice(readBytes, 1).ToArray()[0];
                readBytes++;

                string issuedAssetInfo = Encoding.ASCII.GetString(spanBody.Slice(readBytes, strLen).ToArray());
                readBytes += strLen;

                AssetIssuance assetIssuance = new AssetIssuance
                {
                    AssetId         = assetId,
                    IssuedAssetInfo = issuedAssetInfo
                };

                block = new IssueAsset
                {
                    AssetIssuance = assetIssuance
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #8
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            IssueGroupedAssets block = null;

            if (version == 1)
            {
                int readBytes = 0;

                ushort assetsIssuanceGroupsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                ushort blindedAssetsIssuanceGroupsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                AssetsIssuanceGroup[]        assetsIssuanceGroups        = new AssetsIssuanceGroup[assetsIssuanceGroupsLength];
                BlindedAssetsIssuanceGroup[] blindedAssetsIssuanceGroups = new BlindedAssetsIssuanceGroup[blindedAssetsIssuanceGroupsLength];

                for (int i = 0; i < assetsIssuanceGroupsLength; i++)
                {
                    uint groupId = BinaryPrimitives.ReadUInt32LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(uint);

                    ushort assetIdsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ushort);

                    AssetIssuance[] assetIssuances = new AssetIssuance[assetIdsLength];

                    for (int j = 0; j < assetIdsLength; j++)
                    {
                        byte[] assetId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                        byte strLen = spanBody.Slice(readBytes, 1).ToArray()[0];
                        readBytes++;

                        string issuedAssetInfo = Encoding.ASCII.GetString(spanBody.Slice(readBytes, strLen).ToArray());
                        readBytes += strLen;

                        assetIssuances[j] = new AssetIssuance
                        {
                            AssetId         = assetId,
                            IssuedAssetInfo = issuedAssetInfo
                        };
                    }

                    assetsIssuanceGroups[i] = new AssetsIssuanceGroup
                    {
                        GroupId        = groupId,
                        AssetIssuances = assetIssuances
                    };
                }

                for (int i = 0; i < blindedAssetsIssuanceGroupsLength; i++)
                {
                    uint groupId = BinaryPrimitives.ReadUInt32LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(uint);

                    ushort assetCommitmentsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ushort);

                    byte[][] assetCommitments = new byte[assetCommitmentsLength][];

                    for (int j = 0; j < assetCommitmentsLength; j++)
                    {
                        assetCommitments[j] = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes          += Globals.NODE_PUBLIC_KEY_SIZE;
                    }

                    AssetIssuance[] blindedAssetIssuances = new AssetIssuance[assetCommitmentsLength];
                    for (int j = 0; j < assetCommitmentsLength; j++)
                    {
                        byte[] assetId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                        byte strLen = spanBody.Slice(readBytes, 1).ToArray()[0];
                        readBytes++;

                        string issuedAssetInfo = Encoding.ASCII.GetString(spanBody.Slice(readBytes, strLen).ToArray());
                        readBytes += strLen;

                        blindedAssetIssuances[i] = new AssetIssuance
                        {
                            AssetId         = assetId,
                            IssuedAssetInfo = issuedAssetInfo
                        };
                    }

                    IssuanceProof[] issuanceProofs = new IssuanceProof[assetCommitmentsLength];
                    for (int j = 0; j < assetCommitmentsLength; j++)
                    {
                        SurjectionProof surjectionProof = ReadSurjectionProof(spanBody.Slice(readBytes).Span, out int count);
                        readBytes += count;

                        byte[] mask = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                        issuanceProofs[j] = new IssuanceProof
                        {
                            SurjectionProof = surjectionProof,
                            Mask            = mask,
                        };
                    }

                    blindedAssetsIssuanceGroups[i] = new BlindedAssetsIssuanceGroup
                    {
                        GroupId          = groupId,
                        AssetCommitments = assetCommitments,
                        AssetIssuances   = blindedAssetIssuances,
                        IssuanceProofs   = issuanceProofs
                    };
                }

                byte strLen2 = spanBody.Slice(readBytes, 1).ToArray()[0];
                readBytes++;

                string issuanceInfo = Encoding.ASCII.GetString(spanBody.Slice(readBytes, strLen2).ToArray());
                readBytes += strLen2;

                ushort assetsGroupsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                ushort blindedAssetGroupsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                AssetsGroup[]        assetsGroups        = new AssetsGroup[assetsGroupsLength];
                BlindedAssetsGroup[] blindedAssetsGroups = new BlindedAssetsGroup[blindedAssetGroupsLength];

                for (int i = 0; i < assetsGroupsLength; i++)
                {
                    uint groupId = BinaryPrimitives.ReadUInt32LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(uint);

                    ushort assetIdsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ushort);

                    byte[][] assetIds = new byte[assetIdsLength][];
                    ulong[]  amounts  = new ulong[assetIdsLength];

                    for (int j = 0; j < assetIdsLength; j++)
                    {
                        assetIds[j] = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes  += Globals.NODE_PUBLIC_KEY_SIZE;

                        amounts[j] = BinaryPrimitives.ReadUInt64LittleEndian(spanBody.Slice(readBytes).Span);
                        readBytes += sizeof(ulong);
                    }

                    assetsGroups[i] = new AssetsGroup
                    {
                        GroupId      = groupId,
                        AssetIds     = assetIds,
                        AssetAmounts = amounts
                    };
                }

                for (int i = 0; i < blindedAssetGroupsLength; i++)
                {
                    uint groupId = BinaryPrimitives.ReadUInt32LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(uint);

                    ushort assetCommitmentsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ushort);

                    byte[][] assetCommitments = new byte[assetCommitmentsLength][];

                    for (int j = 0; j < assetCommitmentsLength; j++)
                    {
                        assetCommitments[j] = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes          += Globals.NODE_PUBLIC_KEY_SIZE;
                    }

                    blindedAssetsGroups[i] = new BlindedAssetsGroup
                    {
                        GroupId          = groupId,
                        AssetCommitments = assetCommitments
                    };
                }

                block = new IssueGroupedAssets
                {
                    AssetsIssuanceGroups        = assetsIssuanceGroups,
                    BlindedAssetsIssuanceGroups = blindedAssetsIssuanceGroups,
                    IssuanceInfo        = issuanceInfo,
                    AssetsGroups        = assetsGroups,
                    BlindedAssetsGroups = blindedAssetsGroups
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #9
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            IssueBlindedAsset block = null;

            if (version == 1)
            {
                int readBytes = 0;

                byte[] groupId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] assetCommitment = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] keyImage = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] ringSignatureC = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] ringSignatureR = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                block = new IssueBlindedAsset
                {
                    GroupId          = groupId,
                    AssetCommitment  = assetCommitment,
                    KeyImage         = keyImage,
                    UniquencessProof = new RingSignature
                    {
                        C = ringSignatureC,
                        R = ringSignatureR
                    }
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #10
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            BlindAsset block = null;

            if (version == 1)
            {
                int readBytes = 0;

                byte[] assetCommitment = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] mask = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] encryptedAssetId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                ushort assetCommitmentsCount = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                byte[][] assetCommitments = new byte[assetCommitmentsCount][];

                for (int i = 0; i < assetCommitmentsCount; i++)
                {
                    assetCommitments[i] = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes          += Globals.NODE_PUBLIC_KEY_SIZE;
                }

                byte[] e = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[][] s = new byte[assetCommitmentsCount][];

                for (int i = 0; i < assetCommitmentsCount; i++)
                {
                    s[i]       = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;
                }

                block = new BlindAsset
                {
                    EncryptedAsset = new DataModel.Transactional.Internal.EncryptedAsset
                    {
                        AssetCommitment = assetCommitment,
                        EcdhTuple       = new Wist.Core.Cryptography.EcdhTupleCA
                        {
                            Mask    = mask,
                            AssetId = encryptedAssetId
                        }
                    },
                    SurjectionProof = new Wist.Core.Cryptography.SurjectionProof
                    {
                        AssetCommitments = assetCommitments,
                        Rs = new Wist.Core.Cryptography.BorromeanRingSignature
                        {
                            E = e,
                            S = s
                        }
                    }
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #11
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            TransferGroupedAssets block = null;

            if (version == 1)
            {
                int readBytes = 0;

                byte[] target = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                ushort transferredAssetsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                EncryptedAsset[] transferedAssets = new EncryptedAsset[transferredAssetsLength];

                for (int i = 0; i < transferredAssetsLength; i++)
                {
                    byte[] assetCommitment = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                    byte[] assetId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                    byte[] mask = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                    readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                    transferedAssets[i] = new EncryptedAsset
                    {
                        AssetCommitment = assetCommitment,
                        EcdhTuple       = new EcdhTupleCA {
                            AssetId = assetId, Mask = mask
                        }
                    };
                }

                ushort blindedAssetsGroupsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                BlindedAssetsGroup[] blindedAssetsGroups = new BlindedAssetsGroup[blindedAssetsGroupsLength];

                ushort totalCommitments = 0;

                for (int i = 0; i < blindedAssetsGroupsLength; i++)
                {
                    uint groupId = BinaryPrimitives.ReadUInt32LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(uint);

                    ushort assetCommitmentsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ushort);

                    totalCommitments += assetCommitmentsLength;
                    byte[][] assetCommitments = new byte[assetCommitmentsLength][];

                    for (int j = 0; j < assetCommitmentsLength; i++)
                    {
                        assetCommitments[j] = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes          += Globals.NODE_PUBLIC_KEY_SIZE;
                    }

                    blindedAssetsGroups[i] = new BlindedAssetsGroup
                    {
                        GroupId          = groupId,
                        AssetCommitments = assetCommitments
                    };
                }

                InversedSurjectionProof[] inversedSurjectionProofs = new InversedSurjectionProof[transferredAssetsLength + totalCommitments];
                for (int i = 0; i < inversedSurjectionProofs.Length; i++)
                {
                    inversedSurjectionProofs[i] = ReadInversedSurjectionProof(spanBody.Slice(readBytes).Span, out int count);
                    readBytes += count;
                }

                block = new TransferGroupedAssets
                {
                    TransferedAssets         = transferedAssets,
                    BlindedAssetsGroups      = blindedAssetsGroups,
                    InversedSurjectionProofs = inversedSurjectionProofs
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }
예제 #12
0
        protected override Memory <byte> ParseTransactional(ushort version, Memory <byte> spanBody, out TransactionalPacketBase transactionalBlockBase)
        {
            IssueAssociatedBlindedAsset block = null;

            if (version == 1)
            {
                int readBytes = 0;

                byte[] groupId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] assetCommitment = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] rootAssetCommitment = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                block = new IssueAssociatedBlindedAsset
                {
                    GroupId             = groupId,
                    AssetCommitment     = assetCommitment,
                    RootAssetCommitment = rootAssetCommitment
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }