public void TransferGroupedAssetsToUtxoBlockSerializerTest() { ulong syncBlockHeight = 1; uint nonce = 4; byte[] powHash = BinaryHelper.GetPowHash(1234); ushort version = 1; ulong blockHeight = 9; byte[] body; ulong uptodateFunds = 10001; byte[] transactionPublicKey = ConfidentialAssetsHelper.GetRandomSeed(); byte[] destinationKey = ConfidentialAssetsHelper.GetRandomSeed(); byte[] assetId = ConfidentialAssetsHelper.GetRandomSeed(); byte[] assetCommitment = ConfidentialAssetsHelper.GetRandomSeed(); ushort blindedAssetsGroupsCount = 2; ushort assetsCount = 10; uint[] groupIds = new uint[blindedAssetsGroupsCount]; byte[][][] ownedAssetCommitments = new byte[blindedAssetsGroupsCount][][]; byte[][] surjectionAssetCommitment = new byte[blindedAssetsGroupsCount * assetsCount + 1][]; byte[][] e = new byte[blindedAssetsGroupsCount * assetsCount + 1][]; byte[][][] s = new byte[blindedAssetsGroupsCount * assetsCount + 1][][]; byte[] mask = ConfidentialAssetsHelper.GetRandomSeed(); Random random = new Random(); for (int i = 0; i < blindedAssetsGroupsCount; i++) { groupIds[i] = (uint)i; ownedAssetCommitments[i] = new byte[assetsCount][]; for (int j = 0; j < assetsCount; j++) { ownedAssetCommitments[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); } } for (int i = 0; i < blindedAssetsGroupsCount * assetsCount + 1; i++) { surjectionAssetCommitment[i] = ConfidentialAssetsHelper.GetRandomSeed(); e[i] = ConfidentialAssetsHelper.GetRandomSeed(); s[i] = new byte[blindedAssetsGroupsCount * assetsCount + 1][]; for (int j = 0; j < blindedAssetsGroupsCount * assetsCount + 1; j++) { s[i][j] = ConfidentialAssetsHelper.GetRandomSeed(); } } using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(uptodateFunds); bw.Write(destinationKey); bw.Write(transactionPublicKey); // TransferredAsset // ============================== bw.Write(assetCommitment); bw.Write(assetId); bw.Write(mask); // ============================== bw.Write(blindedAssetsGroupsCount); for (int i = 0; i < blindedAssetsGroupsCount; i++) { bw.Write(groupIds[i]); bw.Write(assetsCount); for (int j = 0; j < assetsCount; j++) { bw.Write(ownedAssetCommitments[i][j]); } } for (int i = 0; i < blindedAssetsGroupsCount * assetsCount + 1; i++) { bw.Write(surjectionAssetCommitment[i]); bw.Write(e[i]); bw.Write((ushort)(blindedAssetsGroupsCount * assetsCount + 1)); for (int j = 0; j < blindedAssetsGroupsCount * assetsCount + 1; j++) { bw.Write(s[i][j]); } } } body = ms.ToArray(); } byte[] expectedPacket = BinaryHelper.GetSignedPacket(PacketType.Transactional, syncBlockHeight, nonce, powHash, version, BlockTypes.Transaction_TransferGroupedAssetsToUtxo, blockHeight, null, body, _privateKey, out byte[] expectedSignature); EncryptedAsset transferredAsset = new EncryptedAsset { AssetCommitment = assetCommitment, EcdhTuple = new EcdhTupleCA { AssetId = assetId, Mask = mask } }; BlindedAssetsGroup[] blindedAssetsGroups = new BlindedAssetsGroup[blindedAssetsGroupsCount]; for (int i = 0; i < blindedAssetsGroupsCount; i++) { blindedAssetsGroups[i] = new BlindedAssetsGroup { GroupId = groupIds[i], AssetCommitments = ownedAssetCommitments[i] }; } InversedSurjectionProof[] inversedSurjectionProofs = new InversedSurjectionProof[blindedAssetsGroupsCount * assetsCount + 1]; for (int i = 0; i < blindedAssetsGroupsCount * assetsCount + 1; i++) { inversedSurjectionProofs[i] = new InversedSurjectionProof { AssetCommitment = surjectionAssetCommitment[i], Rs = new BorromeanRingSignature { E = e[i], S = s[i] } }; } TransferGroupedAssetToUtxo block = new TransferGroupedAssetToUtxo { SyncBlockHeight = syncBlockHeight, Nonce = nonce, PowHash = powHash, BlockHeight = blockHeight, UptodateFunds = uptodateFunds, DestinationKey = destinationKey, TransactionPublicKey = transactionPublicKey, TransferredAsset = transferredAsset, BlindedAssetsGroups = blindedAssetsGroups, InversedSurjectionProofs = inversedSurjectionProofs }; TransferGroupedAssetsToUtxoSerializer serializer = new TransferGroupedAssetsToUtxoSerializer(); serializer.Initialize(block); serializer.SerializeBody(); _signingService.Sign(block); byte[] actualPacket = serializer.GetBytes(); Assert.Equal(expectedPacket, actualPacket); }
protected override Memory <byte> ParseTransactionalTransitional(ushort version, Memory <byte> spanBody, out TransactionalTransitionalPacketBase transactionalBlockBase) { TransferGroupedAssetToUtxo 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[] 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; EncryptedAsset transferedAsset = 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; 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 }; } InversedSurjectionProof[] inversedSurjectionProofs = new InversedSurjectionProof[totalCommitments + 1]; for (int i = 0; i < inversedSurjectionProofs.Length; i++) { inversedSurjectionProofs[i] = ReadInversedSurjectionProof(spanBody.Slice(readBytes).Span, out int count); readBytes += count; } block = new TransferGroupedAssetToUtxo { TransferredAsset = transferedAsset, BlindedAssetsGroups = blindedAssetsGroups, InversedSurjectionProofs = inversedSurjectionProofs }; transactionalBlockBase = block; return(spanBody.Slice(readBytes)); } throw new BlockVersionNotSupportedException(version, BlockType); }