public void testTransactionGroup() { Address from = new Address("UPYAFLHSIPMJOHVXU2MPLQ46GXJKSDCEMZ6RLCQ7GWB5PRDKJUWKKXECXI"); Address to = new Address("UPYAFLHSIPMJOHVXU2MPLQ46GXJKSDCEMZ6RLCQ7GWB5PRDKJUWKKXECXI"); ulong fee = 1000; ulong amount = 2000; string genesisID = "devnet-v1.0"; Digest genesisHash = new Digest("sC3P7e2SdbqKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0E="); ulong firstRound1 = 710399; byte[] note1 = Convert.FromBase64String("wRKw5cJ0CMo="); var tx1 = new Transaction(from, fee, firstRound1, firstRound1 + 1000, note1, amount, to, genesisID, genesisHash); ulong firstRound2 = 710515; byte[] note2 = Convert.FromBase64String("dBlHI6BdrIg="); var tx2 = new Transaction(from, fee, firstRound2, firstRound2 + 1000, note2, amount, to, genesisID, genesisHash); // check serialization/deserialization without group field Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx1)), tx1); Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx2)), tx2); string goldenTx1 = "gaN0eG6Ko2FtdM0H0KNmZWXNA+iiZnbOAArW/6NnZW6rZGV2bmV0LXYxLjCiZ2jEILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bomx2zgAK2uekbm90ZcQIwRKw5cJ0CMqjcmN2xCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNLKNzbmTEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0spHR5cGWjcGF5"; string goldenTx2 = "gaN0eG6Ko2FtdM0H0KNmZWXNA+iiZnbOAArXc6NnZW6rZGV2bmV0LXYxLjCiZ2jEILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bomx2zgAK21ukbm90ZcQIdBlHI6BdrIijcmN2xCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNLKNzbmTEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0spHR5cGWjcGF5"; // goal clerk send dumps unsigned transaction as signed with empty signature in order to save tx type SignedTransaction stx1 = new SignedTransaction(tx1, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx1.TxID()); SignedTransaction stx2 = new SignedTransaction(tx2, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx2.TxID()); Assert.AreEqual(Convert.ToBase64String(Encoder.EncodeToMsgPack(stx1)), goldenTx1); Assert.AreEqual(Convert.ToBase64String(Encoder.EncodeToMsgPack(stx2)), goldenTx2); TestUtil.SerializeDeserializeCheck(stx1); TestUtil.SerializeDeserializeCheck(stx2); Digest gid = TxGroup.ComputeGroupID(tx1, tx2); tx1.AssignGroupID(gid); tx2.AssignGroupID(gid); // check serialization/deserialization with group field set Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx1)), tx1); Assert.AreEqual(Encoder.DecodeFromMsgPack <Transaction>(Encoder.EncodeToMsgPack(tx2)), tx2); // goal clerk group sets Group to every transaction and concatenate them in output file // simulating that behavior here string goldenTxg = "gaN0eG6Lo2FtdM0H0KNmZWXNA+iiZnbOAArW/6NnZW6rZGV2bmV0LXYxLjCiZ2jEILAtz+3tknW6iiStLW4gnSvbXUqW3ul3ghinaDc5pY9Bo2dycMQgLiQ9OBup9H/bZLSfQUH2S6iHUM6FQ3PLuv9FNKyt09SibHbOAAra56Rub3RlxAjBErDlwnQIyqNyY3bEIKPwAqzyQ9iXHremmPXDnjXSqQxEZn0Vih81g9fEak0so3NuZMQgo/ACrPJD2Jcet6aY9cOeNdKpDERmfRWKHzWD18RqTSykdHlwZaNwYXmBo3R4boujYW10zQfQo2ZlZc0D6KJmds4ACtdzo2dlbqtkZXZuZXQtdjEuMKJnaMQgsC3P7e2SdbqKJK0tbiCdK9tdSpbe6XeCGKdoNzmlj0GjZ3JwxCAuJD04G6n0f9tktJ9BQfZLqIdQzoVDc8u6/0U0rK3T1KJsds4ACttbpG5vdGXECHQZRyOgXayIo3JjdsQgo/ACrPJD2Jcet6aY9cOeNdKpDERmfRWKHzWD18RqTSyjc25kxCCj8AKs8kPYlx63ppj1w5410qkMRGZ9FYofNYPXxGpNLKR0eXBlo3BheQ=="; stx1 = new SignedTransaction(tx1, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx1.TxID()); stx2 = new SignedTransaction(tx2, new Signature(), new MultisigSignature(), new LogicsigSignature(), tx2.TxID()); byte[] stx1Enc = Encoder.EncodeToMsgPack(stx1); byte[] stx2Enc = Encoder.EncodeToMsgPack(stx2); var concat = stx1Enc.ToList(); concat.AddRange(stx2Enc); Assert.AreEqual(Convert.ToBase64String(concat.ToArray()), goldenTxg); // check assignGroupID Transaction[] result = TxGroup.AssignGroupID(tx1, tx2); Assert.AreEqual(result.Length, 2); result = TxGroup.AssignGroupID(from, tx1, tx2); Assert.AreEqual(result.Length, 2); result = TxGroup.AssignGroupID(to, tx1, tx2); Assert.AreEqual(result.Length, 0); }