private async Task TransfertInternal(string from, string to, long amount, string asset) { var lAsset = LedgerPath.Parse(asset); var aFrom = new AccountKey(LedgerPath.Parse(from), lAsset); var aTo = new AccountKey(LedgerPath.Parse(to), lAsset); var accounts = await Engine.GetAccounts(new[] { aFrom, aTo }); var adFrom = accounts[aFrom]; var adTo = accounts[aTo]; var rFrom = new Record(aFrom.Key.ToBinary(), LongToByteString(adFrom.Balance - amount), adFrom.Version); var rTo = new Record(aTo.Key.ToBinary(), LongToByteString(adTo.Balance + amount), adTo.Version); Mutation m = new Mutation(ByteString.Empty, new[] { rFrom, rTo }, ByteString.Empty); int c = System.Threading.Interlocked.Increment(ref gcounter); Transaction t = new Transaction( new ByteString(MessageSerializer.SerializeMutation(m)), DateTime.UtcNow, new ByteString(BitConverter.GetBytes(c)) ); await Engine.AddTransactions(new[] { new ByteString(MessageSerializer.SerializeTransaction(t)) }); //Output.WriteLine($"{prefix} - {from} ==> {to} Success Retry : {tryCount}"); }
public async Task <ByteString> PostTransaction(ByteString rawMutation, IReadOnlyList <SignatureEvidence> authentication) { Mutation mutation; try { // Verify that the mutation can be deserialized mutation = MessageSerializer.DeserializeMutation(rawMutation); } catch (InvalidProtocolBufferException) { throw new TransactionInvalidException("InvalidMutation"); } ParsedMutation parsedMutation = ParsedMutation.Parse(mutation); IReadOnlyDictionary <AccountKey, AccountStatus> accounts = await ValidateMutation(mutation, parsedMutation); ValidateAuthentication(authentication, MessageSerializer.ComputeHash(rawMutation.ToByteArray())); DateTime date = DateTime.UtcNow; IList <Mutation> generatedMutations = await this.validator.Validate(parsedMutation, authentication, accounts); TransactionMetadata metadata = new TransactionMetadata(authentication); byte[] rawMetadata = SerializeMetadata(metadata); Transaction transaction = new Transaction(rawMutation, date, new ByteString(rawMetadata)); byte[] serializedTransaction = MessageSerializer.SerializeTransaction(transaction); List <ByteString> transactions = new List <ByteString>() { new ByteString(serializedTransaction) }; transactions.AddRange(await Task.WhenAll(generatedMutations.Select(async generatedMutation => { await ValidateMutation(generatedMutation, ParsedMutation.Parse(generatedMutation)); Transaction generatedTransaction = new Transaction(new ByteString(MessageSerializer.SerializeMutation(generatedMutation)), date, ByteString.Empty); return(new ByteString(MessageSerializer.SerializeTransaction(generatedTransaction))); }))); try { await this.store.AddTransactions(transactions); } catch (ConcurrentMutationException) { throw new TransactionInvalidException("OptimisticConcurrency"); } return(new ByteString(MessageSerializer.ComputeHash(serializedTransaction))); }
private async Task <ByteString> AddTransaction(params Record[] records) { Mutation mutation = new Mutation(ByteString.Parse("0123"), records, ByteString.Parse("4567")); ByteString serializedMutation = new ByteString(MessageSerializer.SerializeMutation(mutation)); Transaction transaction = new Transaction( serializedMutation, new DateTime(1, 2, 3, 4, 5, 6), ByteString.Parse("abcdef")); await this.Store.AddTransactions(new[] { new ByteString(MessageSerializer.SerializeTransaction(transaction)) }); return(new ByteString(MessageSerializer.ComputeHash(serializedMutation.ToByteArray()))); }
public void Transaction_Success() { Transaction transaction = new Transaction( binaryData[0], new DateTime(1, 2, 3, 4, 5, 6), binaryData[1]); byte[] result = MessageSerializer.SerializeTransaction(transaction); Transaction finalTransaction = MessageSerializer.DeserializeTransaction(new ByteString(result)); Assert.Equal(79, result.Length); Assert.Equal(transaction.Mutation, finalTransaction.Mutation); Assert.Equal(transaction.Timestamp, finalTransaction.Timestamp); Assert.Equal(transaction.TransactionMetadata, finalTransaction.TransactionMetadata); }
private ByteString AddRecord(string key) { Mutation mutation = new Mutation( ByteString.Empty, new Record[] { new Record(new ByteString(Encoding.UTF8.GetBytes(key)), ByteString.Empty, ByteString.Empty) }, ByteString.Empty); Transaction transaction = new Transaction( new ByteString(MessageSerializer.SerializeMutation(mutation)), new DateTime(), ByteString.Empty); this.transactions.Add(new ByteString(MessageSerializer.SerializeTransaction(transaction))); return(new ByteString(MessageSerializer.ComputeHash(MessageSerializer.SerializeTransaction(transaction)))); }
private async Task AddRecords(params string[] keys) { Mutation mutation = new Mutation( ByteString.Empty, keys.Select(key => new Record( new ByteString(Encoding.UTF8.GetBytes(key)), ByteString.Empty, ByteString.Empty)), ByteString.Empty); Transaction transaction = new Transaction( new ByteString(MessageSerializer.SerializeMutation(mutation)), new DateTime(), ByteString.Empty); await store.AddTransactions(new[] { new ByteString(MessageSerializer.SerializeTransaction(transaction)) }); }
private ByteString CreateTransaction(params string[] keys) { Mutation mutation = new Mutation( ByteString.Empty, keys.Select(key => new Record( new ByteString(Encoding.UTF8.GetBytes(key)), ByteString.Parse("ab"), ByteString.Parse("cd"))), ByteString.Empty); byte[] serializedMutation = MessageSerializer.SerializeMutation(mutation); Transaction transaction = new Transaction( new ByteString(MessageSerializer.SerializeMutation(mutation)), new DateTime(), ByteString.Empty); return(new ByteString(MessageSerializer.SerializeTransaction(transaction))); }
private async Task <ByteString> AddRecords(ByteString version, ByteString value, params string[] keys) { Mutation mutation = new Mutation( ByteString.Empty, keys.Select(key => new Record( new ByteString(Encoding.UTF8.GetBytes(key)), value, version)), ByteString.Empty); byte[] serializedMutation = MessageSerializer.SerializeMutation(mutation); Transaction transaction = new Transaction( new ByteString(MessageSerializer.SerializeMutation(mutation)), new DateTime(), ByteString.Empty); await Engine.AddTransactions(new[] { new ByteString(MessageSerializer.SerializeTransaction(transaction)) }); return(new ByteString(MessageSerializer.ComputeHash(serializedMutation))); }
public async Task AddTransaction_MultipleTransactionsSuccess() { IList <Record> records1 = new Record[] { new Record(binaryData[0], binaryData[1], ByteString.Empty), new Record(binaryData[2], binaryData[3], ByteString.Empty), }; ByteString mutation1 = new ByteString(MessageSerializer.SerializeMutation(new Mutation(ByteString.Empty, records1, ByteString.Empty))); ByteString mutationHash1 = new ByteString(MessageSerializer.ComputeHash(mutation1.ToByteArray())); IList <Record> records2 = new Record[] { new Record(binaryData[2], binaryData[5], mutationHash1), new Record(binaryData[6], binaryData[7], ByteString.Empty), }; ByteString mutation2 = new ByteString(MessageSerializer.SerializeMutation(new Mutation(ByteString.Empty, records2, ByteString.Empty))); ByteString mutationHash2 = new ByteString(MessageSerializer.ComputeHash(mutation2.ToByteArray())); // Submit both transactions at once await this.Store.AddTransactions(new[] { new ByteString(MessageSerializer.SerializeTransaction(new Transaction(mutation1, new DateTime(), ByteString.Empty))), new ByteString(MessageSerializer.SerializeTransaction(new Transaction(mutation2, new DateTime(), ByteString.Empty))) }); IReadOnlyList <Record> result1 = await this.Store.GetRecords(new[] { binaryData[0] }); IReadOnlyList <Record> result2 = await this.Store.GetRecords(new[] { binaryData[2] }); IReadOnlyList <Record> result3 = await this.Store.GetRecords(new[] { binaryData[6] }); AssertRecord(result1[0], binaryData[0], binaryData[1], mutationHash1); AssertRecord(result2[0], binaryData[2], binaryData[5], mutationHash2); AssertRecord(result3[0], binaryData[6], binaryData[7], mutationHash2); }
public async Task AddTransaction_MultipleTransactionsError() { IList <Record> records1 = new Record[] { new Record(binaryData[0], binaryData[1], ByteString.Empty), new Record(binaryData[2], binaryData[3], ByteString.Empty), }; ByteString mutation1 = new ByteString(MessageSerializer.SerializeMutation(new Mutation(ByteString.Empty, records1, ByteString.Empty))); IList <Record> records2 = new Record[] { new Record(binaryData[2], binaryData[5], ByteString.Empty), new Record(binaryData[6], binaryData[7], ByteString.Empty), }; ByteString mutation2 = new ByteString(MessageSerializer.SerializeMutation(new Mutation(ByteString.Empty, records2, ByteString.Empty))); // Submit both transactions at once ConcurrentMutationException exception = await Assert.ThrowsAsync <ConcurrentMutationException>(() => this.Store.AddTransactions(new[] { new ByteString(MessageSerializer.SerializeTransaction(new Transaction(mutation1, new DateTime(), ByteString.Empty))), new ByteString(MessageSerializer.SerializeTransaction(new Transaction(mutation2, new DateTime(), ByteString.Empty))) })); IReadOnlyList <Record> result1 = await this.Store.GetRecords(new[] { binaryData[0] }); IReadOnlyList <Record> result2 = await this.Store.GetRecords(new[] { binaryData[2] }); IReadOnlyList <Record> result3 = await this.Store.GetRecords(new[] { binaryData[6] }); AssertRecord(exception.FailedMutation, binaryData[2], binaryData[5], ByteString.Empty); AssertRecord(result1[0], binaryData[0], ByteString.Empty, ByteString.Empty); AssertRecord(result2[0], binaryData[2], ByteString.Empty, ByteString.Empty); AssertRecord(result3[0], binaryData[6], ByteString.Empty, ByteString.Empty); }
public async Task <ByteString> PostTransaction(ByteString rawMutation, IReadOnlyList <SignatureEvidence> authentication) { Mutation mutation; try { // Verify that the mutation can be deserialized mutation = MessageSerializer.DeserializeMutation(rawMutation); } catch (InvalidProtocolBufferException) { throw new TransactionInvalidException("InvalidMutation"); } if (!mutation.Namespace.Equals(this.Namespace)) { throw new TransactionInvalidException("InvalidNamespace"); } if (mutation.Records.Count == 0) { throw new TransactionInvalidException("InvalidMutation"); } if (mutation.Records.Any(record => record.Key.Value.Count > MaxKeySize)) { throw new TransactionInvalidException("InvalidMutation"); } ValidateAuthentication(authentication, MessageSerializer.ComputeHash(rawMutation.ToByteArray())); ParsedMutation parsedMutation = ParsedMutation.Parse(mutation); // All assets must have an overall zero balance IReadOnlyDictionary <AccountKey, AccountStatus> accounts = await this.store.GetAccounts(parsedMutation.AccountMutations.Select(entry => entry.AccountKey)); var groups = parsedMutation.AccountMutations .GroupBy(account => account.AccountKey.Asset.FullPath) .Select(group => group.Sum(entry => entry.Balance - accounts[entry.AccountKey].Balance)); if (groups.Any(group => group != 0)) { throw new TransactionInvalidException("UnbalancedTransaction"); } DateTime date = DateTime.UtcNow; await this.validator.Validate(parsedMutation, authentication, accounts); TransactionMetadata metadata = new TransactionMetadata(authentication); byte[] rawMetadata = SerializeMetadata(metadata); Transaction transaction = new Transaction(rawMutation, date, new ByteString(rawMetadata)); byte[] serializedTransaction = MessageSerializer.SerializeTransaction(transaction); try { await this.store.AddTransactions(new[] { new ByteString(serializedTransaction) }); } catch (ConcurrentMutationException) { throw new TransactionInvalidException("OptimisticConcurrency"); } return(new ByteString(MessageSerializer.ComputeHash(serializedTransaction))); }