-
Notifications
You must be signed in to change notification settings - Fork 3
/
AccountTransactionPayload.cs
135 lines (126 loc) · 5.26 KB
/
AccountTransactionPayload.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
using Concordium.Sdk.Exceptions;
using Concordium.Sdk.Types;
using PayloadCase = Concordium.Grpc.V2.AccountTransactionPayload.PayloadOneofCase;
namespace Concordium.Sdk.Transactions;
/// <summary>
/// Represents the payload of account transaction.
///
/// Inheriting records should implement data specific to the transaction they
/// model as well as helpers for constructing serialized transaction payloads
/// to be sent to the Concordium node.
/// </summary>
public abstract record AccountTransactionPayload
{
/// <summary>
/// Copies the on-chain data in the binary format expected by the node to a byte array.
/// </summary>
public abstract byte[] ToBytes();
/// <summary>
/// Gets the size (number of bytes) of the payload.
/// </summary>
internal abstract PayloadSize Size();
/// <summary>
/// Converts the transaction to its corresponding protocol buffer message instance.
/// </summary>
public Grpc.V2.AccountTransactionPayload ToProto() =>
new() { RawPayload = Google.Protobuf.ByteString.CopyFrom(this.ToBytes()) };
internal static AccountTransactionPayload From(Grpc.V2.AccountTransactionPayload payload) => payload.PayloadCase switch
{
PayloadCase.TransferWithMemo => new TransferWithMemo(
CcdAmount.From(payload.TransferWithMemo.Amount),
AccountAddress.From(payload.TransferWithMemo.Receiver),
OnChainData.From(payload.TransferWithMemo.Memo)
),
PayloadCase.Transfer => new Transfer(
CcdAmount.From(payload.Transfer.Amount),
AccountAddress.From(payload.Transfer.Receiver)
),
PayloadCase.RegisterData => new RegisterData(
OnChainData.From(payload.RegisterData)
),
PayloadCase.DeployModule => new DeployModule(
VersionedModuleSourceFactory.From(payload.DeployModule)
),
PayloadCase.RawPayload => ParseRawPayload(payload.RawPayload),
PayloadCase.InitContract => throw new NotImplementedException(),
PayloadCase.UpdateContract => new UpdateContract(
CcdAmount.From(payload.UpdateContract.Amount),
ContractAddress.From(payload.UpdateContract.Address),
ReceiveName.From(payload.UpdateContract.ReceiveName),
Parameter.From(payload.UpdateContract.Parameter)
),
PayloadCase.None => throw new MissingEnumException<PayloadCase>(payload.PayloadCase),
_ => throw new MissingEnumException<PayloadCase>(payload.PayloadCase),
};
private static AccountTransactionPayload ParseRawPayload(Google.Protobuf.ByteString payload)
{
(AccountTransactionPayload?, string?) parsedPayload = (null, null);
switch ((TransactionType)payload.First())
{
case TransactionType.Transfer:
{
Transfer.TryDeserial(payload.ToArray(), out var output);
parsedPayload = output;
break;
}
case TransactionType.TransferWithMemo:
{
TransferWithMemo.TryDeserial(payload.ToArray(), out var output);
parsedPayload = output;
break;
}
case TransactionType.RegisterData:
{
RegisterData.TryDeserial(payload.ToArray(), out var output);
parsedPayload = output;
break;
}
case TransactionType.DeployModule:
{
DeployModule.TryDeserial(payload.ToArray(), out var output);
parsedPayload = output;
break;
}
case TransactionType.InitContract:
{
InitContract.TryDeserial(payload.ToArray(), out var output);
parsedPayload = output;
break;
}
case TransactionType.Update:
{
UpdateContract.TryDeserial(payload.ToArray(), out var output);
parsedPayload = output;
break;
}
case TransactionType.AddBaker:
case TransactionType.RemoveBaker:
case TransactionType.UpdateBakerStake:
case TransactionType.UpdateBakerRestakeEarnings:
case TransactionType.UpdateBakerKeys:
case TransactionType.UpdateCredentialKeys:
case TransactionType.EncryptedAmountTransfer:
case TransactionType.TransferToEncrypted:
case TransactionType.TransferToPublic:
case TransactionType.TransferWithSchedule:
case TransactionType.UpdateCredentials:
case TransactionType.EncryptedAmountTransferWithMemo:
case TransactionType.TransferWithScheduleAndMemo:
case TransactionType.ConfigureBaker:
case TransactionType.ConfigureDelegation:
parsedPayload = (new RawPayload(payload.ToArray()), null);
break;
default:
throw new MissingEnumException<TransactionType>((TransactionType)payload.First());
};
if (parsedPayload.Item2 != null)
{
throw new DeserialException(parsedPayload.Item2);
}
if (parsedPayload.Item1 == null)
{
throw new DeserialNullException();
}
return parsedPayload.Item1;
}
}