public void IssueAssetsBlockSerializerTest() { ulong syncBlockHeight = 1; uint nonce = 4; byte[] powHash = BinaryHelper.GetPowHash(1234); ushort version = 1; ulong blockHeight = 9; byte[] body; ulong uptodateFunds = 10001; ushort ownedNonBlindedAssetGroupsCount = 3, ownedBlindedAssetGroupsCount = 3; ushort ownedNonBlindedAssetIdsCount = 5, ownedAssetCommitmentsCount = 5; uint[] nonBlindedGroupIds = new uint[ownedNonBlindedAssetGroupsCount]; byte[][][] ownedAssetIds = new byte[ownedNonBlindedAssetGroupsCount][][]; ulong[][] ownedAssetAmounts = new ulong[ownedNonBlindedAssetGroupsCount][]; uint[] blindedGroupIds = new uint[ownedBlindedAssetGroupsCount]; byte[][][] ownedAssetCommitments = new byte[ownedBlindedAssetGroupsCount][][]; ushort issuanceNonBlindedGroupsCount = 2, issuanceBlindedGroupsCount = 2; ushort issuedNonBlindedAssetsCount = 10, issuedBlindedAssetsCount = 10; uint[] issuanceNonBlindedGroupIds = new uint[issuanceNonBlindedGroupsCount], issuanceBlindedGroupIds = new uint[issuanceBlindedGroupsCount]; byte[][][] issuedNonBlindedAssetIds = new byte[issuanceNonBlindedGroupsCount][][]; string[][] issuedNonBlindedAssetInfos = new string[issuanceNonBlindedGroupsCount][]; byte[][][] issuedAssetCommitments = new byte[issuanceBlindedGroupsCount][][]; byte[][][] issuedBlindedAssetIds = new byte[issuanceNonBlindedGroupsCount][][]; string[][] issuedBlindedAssetInfos = new string[issuanceNonBlindedGroupsCount][]; byte[][][] surjectionProofCommitments = new byte[issuanceBlindedGroupsCount][][]; byte[][][] surjectionProofE = new byte[issuanceBlindedGroupsCount][][]; byte[][][] surjectionProofS = new byte[issuanceBlindedGroupsCount][][]; byte[][][] issuanceProofMask = new byte[issuanceBlindedGroupsCount][][]; for (int i = 0; i < issuanceNonBlindedGroupsCount; i++) { issuanceNonBlindedGroupIds[i] = (uint)i; issuedNonBlindedAssetIds[i] = new byte[issuedNonBlindedAssetsCount][]; issuedNonBlindedAssetInfos[i] = new string[issuedNonBlindedAssetsCount]; for (int j = 0; j < issuedNonBlindedAssetsCount; j++) { issuedNonBlindedAssetIds[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); issuedNonBlindedAssetInfos[i][j] = $"Issued Asset #{i}_{j}"; } } for (int i = 0; i < issuanceBlindedGroupsCount; i++) { issuanceBlindedGroupIds[i] = (uint)i + 10; issuedAssetCommitments[i] = new byte[issuedBlindedAssetsCount][]; issuedBlindedAssetIds[i] = new byte[issuedBlindedAssetsCount][]; issuedBlindedAssetInfos[i] = new string[issuedBlindedAssetsCount]; surjectionProofCommitments[i] = new byte[issuedBlindedAssetsCount][]; surjectionProofE[i] = new byte[issuedBlindedAssetsCount][]; surjectionProofS[i] = new byte[issuedBlindedAssetsCount][]; issuanceProofMask[i] = new byte[issuedBlindedAssetsCount][]; for (int j = 0; j < issuedBlindedAssetsCount; j++) { issuedAssetCommitments[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); issuedBlindedAssetIds[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); issuedBlindedAssetInfos[i][j] = $"Issued Blinded Asset #{i}_{j}"; surjectionProofCommitments[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); surjectionProofE[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); surjectionProofS[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); issuanceProofMask[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); } } string issuanceInfo = "Issuance Info"; Random random = new Random(); for (int i = 0; i < ownedNonBlindedAssetGroupsCount; i++) { nonBlindedGroupIds[i] = (uint)i; ownedAssetIds[i] = new byte[ownedNonBlindedAssetIdsCount][]; ownedAssetAmounts[i] = new ulong[ownedNonBlindedAssetIdsCount]; for (int j = 0; j < ownedNonBlindedAssetIdsCount; j++) { ownedAssetIds[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); ownedAssetAmounts[i][j] = (ulong)random.Next(); } } for (int i = 0; i < ownedBlindedAssetGroupsCount; i++) { blindedGroupIds[i] = (uint)i + 10; ownedAssetCommitments[i] = new byte[ownedAssetCommitmentsCount][]; for (int j = 0; j < ownedAssetCommitmentsCount; j++) { ownedAssetCommitments[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); } } using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(uptodateFunds); bw.Write(issuanceNonBlindedGroupsCount); bw.Write(issuanceBlindedGroupsCount); for (int i = 0; i < issuanceNonBlindedGroupsCount; i++) { bw.Write(issuanceNonBlindedGroupIds[i]); bw.Write(issuedNonBlindedAssetsCount); for (int j = 0; j < issuedNonBlindedAssetsCount; j++) { bw.Write(issuedNonBlindedAssetIds[i][j]); byte strLen = (byte)issuedNonBlindedAssetInfos[i][j].Length; bw.Write(strLen); bw.Write(Encoding.ASCII.GetBytes(issuedNonBlindedAssetInfos[i][j])); } } for (int i = 0; i < issuanceBlindedGroupsCount; i++) { bw.Write(issuanceBlindedGroupIds[i]); bw.Write(issuedBlindedAssetsCount); for (int j = 0; j < issuedBlindedAssetsCount; j++) { bw.Write(issuedAssetCommitments[i][j]); } for (int j = 0; j < issuedBlindedAssetsCount; j++) { bw.Write(issuedBlindedAssetIds[i][j]); byte strLen = (byte)issuedBlindedAssetInfos[i][j].Length; bw.Write(strLen); bw.Write(Encoding.ASCII.GetBytes(issuedBlindedAssetInfos[i][j])); } for (int j = 0; j < issuedBlindedAssetsCount; j++) { bw.Write((ushort)1); bw.Write(surjectionProofCommitments[i][j]); bw.Write(surjectionProofE[i][j]); bw.Write(surjectionProofS[i][j]); bw.Write(issuanceProofMask[i][j]); } } bw.Write((byte)issuanceInfo.Length); bw.Write(Encoding.ASCII.GetBytes(issuanceInfo)); bw.Write(ownedNonBlindedAssetGroupsCount); bw.Write(ownedBlindedAssetGroupsCount); for (int i = 0; i < ownedNonBlindedAssetGroupsCount; i++) { bw.Write(nonBlindedGroupIds[i]); bw.Write(ownedNonBlindedAssetIdsCount); for (int j = 0; j < ownedNonBlindedAssetIdsCount; j++) { bw.Write(ownedAssetIds[i][j]); } for (int j = 0; j < ownedNonBlindedAssetIdsCount; j++) { bw.Write(ownedAssetAmounts[i][j]); } } for (int i = 0; i < ownedBlindedAssetGroupsCount; i++) { bw.Write(blindedGroupIds[i]); bw.Write(ownedAssetCommitmentsCount); for (int j = 0; j < ownedAssetCommitmentsCount; j++) { bw.Write(ownedAssetCommitments[i][j]); } } } body = ms.ToArray(); } byte[] expectedPacket = BinaryHelper.GetSignedPacket(PacketType.Transactional, syncBlockHeight, nonce, powHash, version, BlockTypes.Transaction_IssueGroupedAssets, blockHeight, null, body, _privateKey, out byte[] expectedSignature); AssetsIssuanceGroup[] assetsIssuanceGroups = new AssetsIssuanceGroup[issuanceNonBlindedGroupsCount]; for (int i = 0; i < issuanceNonBlindedGroupsCount; i++) { assetsIssuanceGroups[i] = new AssetsIssuanceGroup { GroupId = issuanceNonBlindedGroupIds[i], AssetIssuances = new AssetIssuance[issuedNonBlindedAssetsCount] }; for (int j = 0; j < issuedNonBlindedAssetsCount; j++) { assetsIssuanceGroups[i].AssetIssuances[j] = new AssetIssuance { AssetId = issuedNonBlindedAssetIds[i][j], IssuedAssetInfo = issuedNonBlindedAssetInfos[i][j] }; } } BlindedAssetsIssuanceGroup[] blindedAssetsIssuanceGroups = new BlindedAssetsIssuanceGroup[issuanceBlindedGroupsCount]; for (int i = 0; i < issuanceBlindedGroupsCount; i++) { blindedAssetsIssuanceGroups[i] = new BlindedAssetsIssuanceGroup { GroupId = issuanceBlindedGroupIds[i], AssetCommitments = issuedAssetCommitments[i], AssetIssuances = new AssetIssuance[issuedBlindedAssetsCount], IssuanceProofs = new IssuanceProof[issuedBlindedAssetsCount] }; for (int j = 0; j < issuedBlindedAssetsCount; j++) { blindedAssetsIssuanceGroups[i].AssetIssuances[j] = new AssetIssuance { AssetId = issuedBlindedAssetIds[i][j], IssuedAssetInfo = issuedBlindedAssetInfos[i][j] }; blindedAssetsIssuanceGroups[i].IssuanceProofs[j] = new IssuanceProof { SurjectionProof = new SurjectionProof { AssetCommitments = new byte[][] { surjectionProofCommitments[i][j] }, Rs = new BorromeanRingSignature { E = surjectionProofE[i][j], S = new byte[][] { surjectionProofS[i][j] } } }, Mask = issuanceProofMask[i][j] }; } } AssetsGroup[] assetsGroups = new AssetsGroup[ownedNonBlindedAssetGroupsCount]; for (int i = 0; i < ownedNonBlindedAssetGroupsCount; i++) { assetsGroups[i] = new AssetsGroup { GroupId = nonBlindedGroupIds[i], AssetIds = ownedAssetIds[i], AssetAmounts = ownedAssetAmounts[i] }; } BlindedAssetsGroup[] blindedAssetsGroups = new BlindedAssetsGroup[ownedBlindedAssetGroupsCount]; for (int i = 0; i < ownedBlindedAssetGroupsCount; i++) { blindedAssetsGroups[i] = new BlindedAssetsGroup { GroupId = blindedGroupIds[i], AssetCommitments = ownedAssetCommitments[i] }; } IssueGroupedAssets block = new IssueGroupedAssets { SyncBlockHeight = syncBlockHeight, Nonce = nonce, PowHash = powHash, BlockHeight = blockHeight, UptodateFunds = uptodateFunds, AssetsIssuanceGroups = assetsIssuanceGroups, BlindedAssetsIssuanceGroups = blindedAssetsIssuanceGroups, AssetsGroups = assetsGroups, BlindedAssetsGroups = blindedAssetsGroups, IssuanceInfo = issuanceInfo }; IssueAssetsSerializer serializer = new IssueAssetsSerializer(); serializer.Initialize(block); serializer.SerializeBody(); _signingService.Sign(block); byte[] actualPacket = serializer.GetBytes(); Assert.Equal(expectedPacket, actualPacket); }
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); }