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 byte[] SerializeMetadata(TransactionMetadata metadata) { Messages.TransactionMetadata transactionMetadataBuilder = new Messages.TransactionMetadata(); transactionMetadataBuilder.Signatures.Add(metadata.Signatures.Select( signature => new Messages.TransactionMetadata.Types.SignatureEvidence() { PublicKey = Google.Protobuf.ByteString.CopyFrom(signature.PublicKey.ToByteArray()), Signature = Google.Protobuf.ByteString.CopyFrom(signature.Signature.ToByteArray()) })); return(transactionMetadataBuilder.ToByteArray()); }