Node/Watcher/Algorand: Handle Algorand inner transactions (#3072)
This commit is contained in:
parent
0fbfa816ba
commit
7f6213019a
|
@ -0,0 +1,867 @@
|
||||||
|
{
|
||||||
|
"Sig": [
|
||||||
|
105,
|
||||||
|
216,
|
||||||
|
195,
|
||||||
|
48,
|
||||||
|
134,
|
||||||
|
19,
|
||||||
|
231,
|
||||||
|
177,
|
||||||
|
203,
|
||||||
|
123,
|
||||||
|
39,
|
||||||
|
68,
|
||||||
|
177,
|
||||||
|
108,
|
||||||
|
49,
|
||||||
|
146,
|
||||||
|
16,
|
||||||
|
83,
|
||||||
|
252,
|
||||||
|
3,
|
||||||
|
205,
|
||||||
|
105,
|
||||||
|
155,
|
||||||
|
140,
|
||||||
|
65,
|
||||||
|
146,
|
||||||
|
72,
|
||||||
|
245,
|
||||||
|
27,
|
||||||
|
81,
|
||||||
|
157,
|
||||||
|
154,
|
||||||
|
27,
|
||||||
|
215,
|
||||||
|
57,
|
||||||
|
158,
|
||||||
|
162,
|
||||||
|
93,
|
||||||
|
67,
|
||||||
|
62,
|
||||||
|
209,
|
||||||
|
22,
|
||||||
|
227,
|
||||||
|
86,
|
||||||
|
199,
|
||||||
|
48,
|
||||||
|
33,
|
||||||
|
103,
|
||||||
|
121,
|
||||||
|
84,
|
||||||
|
4,
|
||||||
|
163,
|
||||||
|
0,
|
||||||
|
85,
|
||||||
|
27,
|
||||||
|
107,
|
||||||
|
141,
|
||||||
|
183,
|
||||||
|
243,
|
||||||
|
43,
|
||||||
|
22,
|
||||||
|
28,
|
||||||
|
134,
|
||||||
|
12
|
||||||
|
],
|
||||||
|
"Txn": {
|
||||||
|
"Type": "appl",
|
||||||
|
"Sender": [
|
||||||
|
206,
|
||||||
|
168,
|
||||||
|
201,
|
||||||
|
203,
|
||||||
|
219,
|
||||||
|
55,
|
||||||
|
61,
|
||||||
|
172,
|
||||||
|
61,
|
||||||
|
71,
|
||||||
|
177,
|
||||||
|
40,
|
||||||
|
245,
|
||||||
|
137,
|
||||||
|
33,
|
||||||
|
193,
|
||||||
|
111,
|
||||||
|
150,
|
||||||
|
6,
|
||||||
|
171,
|
||||||
|
13,
|
||||||
|
68,
|
||||||
|
81,
|
||||||
|
115,
|
||||||
|
156,
|
||||||
|
174,
|
||||||
|
167,
|
||||||
|
216,
|
||||||
|
238,
|
||||||
|
132,
|
||||||
|
137,
|
||||||
|
228
|
||||||
|
],
|
||||||
|
"Fee": 1000,
|
||||||
|
"FirstValid": 30453933,
|
||||||
|
"LastValid": 30454933,
|
||||||
|
"Note": null,
|
||||||
|
"ApplicationID": 231231217,
|
||||||
|
"OnCompletion": 0,
|
||||||
|
"ApplicationArgs": [
|
||||||
|
"hd0aKg==",
|
||||||
|
"nhxWOOMdX90rqGU4T5RVXpX+UXgAAAAADLE83Q==",
|
||||||
|
"AAAAAAAHoSA="
|
||||||
|
],
|
||||||
|
"Accounts": [
|
||||||
|
[
|
||||||
|
210,
|
||||||
|
200,
|
||||||
|
255,
|
||||||
|
178,
|
||||||
|
7,
|
||||||
|
225,
|
||||||
|
188,
|
||||||
|
18,
|
||||||
|
254,
|
||||||
|
137,
|
||||||
|
181,
|
||||||
|
25,
|
||||||
|
145,
|
||||||
|
41,
|
||||||
|
27,
|
||||||
|
249,
|
||||||
|
185,
|
||||||
|
43,
|
||||||
|
215,
|
||||||
|
225,
|
||||||
|
96,
|
||||||
|
64,
|
||||||
|
230,
|
||||||
|
126,
|
||||||
|
144,
|
||||||
|
206,
|
||||||
|
212,
|
||||||
|
182,
|
||||||
|
57,
|
||||||
|
154,
|
||||||
|
179,
|
||||||
|
83
|
||||||
|
],
|
||||||
|
[
|
||||||
|
137,
|
||||||
|
240,
|
||||||
|
161,
|
||||||
|
164,
|
||||||
|
216,
|
||||||
|
254,
|
||||||
|
162,
|
||||||
|
141,
|
||||||
|
120,
|
||||||
|
49,
|
||||||
|
250,
|
||||||
|
230,
|
||||||
|
145,
|
||||||
|
1,
|
||||||
|
126,
|
||||||
|
6,
|
||||||
|
19,
|
||||||
|
84,
|
||||||
|
124,
|
||||||
|
105,
|
||||||
|
213,
|
||||||
|
48,
|
||||||
|
63,
|
||||||
|
5,
|
||||||
|
170,
|
||||||
|
88,
|
||||||
|
13,
|
||||||
|
35,
|
||||||
|
36,
|
||||||
|
240,
|
||||||
|
151,
|
||||||
|
156
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ForeignApps": [
|
||||||
|
86525641,
|
||||||
|
86525623
|
||||||
|
],
|
||||||
|
"ForeignAssets": [
|
||||||
|
212942045
|
||||||
|
],
|
||||||
|
"BoxReferences": [
|
||||||
|
{
|
||||||
|
"ForeignAppIdx": 0,
|
||||||
|
"Name": "nhxWOOMdX90rqGU4T5RVXpX+UXgAAAAADLE83Q=="
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"LocalStateSchema": {
|
||||||
|
"NumUint": 0,
|
||||||
|
"NumByteSlice": 0
|
||||||
|
},
|
||||||
|
"GlobalStateSchema": {
|
||||||
|
"NumUint": 0,
|
||||||
|
"NumByteSlice": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EvalDelta": {
|
||||||
|
"Logs": [
|
||||||
|
"\u0015\u001f|u\u0000\u0000\u0000\u0000\u0000\u0007\ufffd "
|
||||||
|
],
|
||||||
|
"InnerTxns": [
|
||||||
|
{
|
||||||
|
"Sig": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"Txn": {
|
||||||
|
"Type": "appl",
|
||||||
|
"Sender": [
|
||||||
|
240,
|
||||||
|
31,
|
||||||
|
115,
|
||||||
|
228,
|
||||||
|
39,
|
||||||
|
220,
|
||||||
|
94,
|
||||||
|
207,
|
||||||
|
14,
|
||||||
|
189,
|
||||||
|
34,
|
||||||
|
156,
|
||||||
|
94,
|
||||||
|
159,
|
||||||
|
156,
|
||||||
|
17,
|
||||||
|
115,
|
||||||
|
89,
|
||||||
|
75,
|
||||||
|
74,
|
||||||
|
99,
|
||||||
|
141,
|
||||||
|
197,
|
||||||
|
86,
|
||||||
|
192,
|
||||||
|
137,
|
||||||
|
166,
|
||||||
|
117,
|
||||||
|
120,
|
||||||
|
234,
|
||||||
|
76,
|
||||||
|
214
|
||||||
|
],
|
||||||
|
"Fee": 3000,
|
||||||
|
"FirstValid": 30453933,
|
||||||
|
"LastValid": 30454933,
|
||||||
|
"Note": null,
|
||||||
|
"Group": [
|
||||||
|
80,
|
||||||
|
9,
|
||||||
|
220,
|
||||||
|
16,
|
||||||
|
247,
|
||||||
|
42,
|
||||||
|
178,
|
||||||
|
223,
|
||||||
|
143,
|
||||||
|
233,
|
||||||
|
199,
|
||||||
|
8,
|
||||||
|
80,
|
||||||
|
214,
|
||||||
|
173,
|
||||||
|
253,
|
||||||
|
32,
|
||||||
|
191,
|
||||||
|
226,
|
||||||
|
254,
|
||||||
|
247,
|
||||||
|
229,
|
||||||
|
92,
|
||||||
|
207,
|
||||||
|
12,
|
||||||
|
244,
|
||||||
|
184,
|
||||||
|
99,
|
||||||
|
83,
|
||||||
|
92,
|
||||||
|
146,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"ApplicationID": 86525641,
|
||||||
|
"OnCompletion": 0,
|
||||||
|
"ApplicationArgs": [
|
||||||
|
"bm9w"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Txn": {
|
||||||
|
"Type": "axfer",
|
||||||
|
"Sender": [
|
||||||
|
240,
|
||||||
|
31,
|
||||||
|
115,
|
||||||
|
228,
|
||||||
|
39,
|
||||||
|
220,
|
||||||
|
94,
|
||||||
|
207,
|
||||||
|
14,
|
||||||
|
189,
|
||||||
|
34,
|
||||||
|
156,
|
||||||
|
94,
|
||||||
|
159,
|
||||||
|
156,
|
||||||
|
17,
|
||||||
|
115,
|
||||||
|
89,
|
||||||
|
75,
|
||||||
|
74,
|
||||||
|
99,
|
||||||
|
141,
|
||||||
|
197,
|
||||||
|
86,
|
||||||
|
192,
|
||||||
|
137,
|
||||||
|
166,
|
||||||
|
117,
|
||||||
|
120,
|
||||||
|
234,
|
||||||
|
76,
|
||||||
|
214
|
||||||
|
],
|
||||||
|
"Fee": 3000,
|
||||||
|
"FirstValid": 30453933,
|
||||||
|
"LastValid": 30454933,
|
||||||
|
"Group": [
|
||||||
|
80,
|
||||||
|
9,
|
||||||
|
220,
|
||||||
|
16,
|
||||||
|
247,
|
||||||
|
42,
|
||||||
|
178,
|
||||||
|
223,
|
||||||
|
143,
|
||||||
|
233,
|
||||||
|
199,
|
||||||
|
8,
|
||||||
|
80,
|
||||||
|
214,
|
||||||
|
173,
|
||||||
|
253,
|
||||||
|
32,
|
||||||
|
191,
|
||||||
|
226,
|
||||||
|
254,
|
||||||
|
247,
|
||||||
|
229,
|
||||||
|
92,
|
||||||
|
207,
|
||||||
|
12,
|
||||||
|
244,
|
||||||
|
184,
|
||||||
|
99,
|
||||||
|
83,
|
||||||
|
92,
|
||||||
|
146,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"XferAsset": 212942045,
|
||||||
|
"AssetAmount": 500000,
|
||||||
|
"AssetReceiver": [
|
||||||
|
137,
|
||||||
|
240,
|
||||||
|
161,
|
||||||
|
164,
|
||||||
|
216,
|
||||||
|
254,
|
||||||
|
162,
|
||||||
|
141,
|
||||||
|
120,
|
||||||
|
49,
|
||||||
|
250,
|
||||||
|
230,
|
||||||
|
145,
|
||||||
|
1,
|
||||||
|
126,
|
||||||
|
6,
|
||||||
|
19,
|
||||||
|
84,
|
||||||
|
124,
|
||||||
|
105,
|
||||||
|
213,
|
||||||
|
48,
|
||||||
|
63,
|
||||||
|
5,
|
||||||
|
170,
|
||||||
|
88,
|
||||||
|
13,
|
||||||
|
35,
|
||||||
|
36,
|
||||||
|
240,
|
||||||
|
151,
|
||||||
|
156
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"AuthAddr": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"ClosingAmount": 0,
|
||||||
|
"AssetClosingAmount": 0,
|
||||||
|
"SenderRewards": 0,
|
||||||
|
"ReceiverRewards": 0,
|
||||||
|
"CloseRewards": 0,
|
||||||
|
"EvalDelta": {
|
||||||
|
"GlobalDelta": null,
|
||||||
|
"LocalDeltas": null,
|
||||||
|
"Logs": null,
|
||||||
|
"InnerTxns": null
|
||||||
|
},
|
||||||
|
"ConfigAsset": 0,
|
||||||
|
"ApplicationID": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Txn": {
|
||||||
|
"Type": "appl",
|
||||||
|
"Sender": [
|
||||||
|
240,
|
||||||
|
31,
|
||||||
|
115,
|
||||||
|
228,
|
||||||
|
39,
|
||||||
|
220,
|
||||||
|
94,
|
||||||
|
207,
|
||||||
|
14,
|
||||||
|
189,
|
||||||
|
34,
|
||||||
|
156,
|
||||||
|
94,
|
||||||
|
159,
|
||||||
|
156,
|
||||||
|
17,
|
||||||
|
115,
|
||||||
|
89,
|
||||||
|
75,
|
||||||
|
74,
|
||||||
|
99,
|
||||||
|
141,
|
||||||
|
197,
|
||||||
|
86,
|
||||||
|
192,
|
||||||
|
137,
|
||||||
|
166,
|
||||||
|
117,
|
||||||
|
120,
|
||||||
|
234,
|
||||||
|
76,
|
||||||
|
214
|
||||||
|
],
|
||||||
|
"Fee": 3000,
|
||||||
|
"FirstValid": 30453933,
|
||||||
|
"LastValid": 30454933,
|
||||||
|
"Note": null,
|
||||||
|
"GenesisID": "",
|
||||||
|
"Group": [
|
||||||
|
80,
|
||||||
|
9,
|
||||||
|
220,
|
||||||
|
16,
|
||||||
|
247,
|
||||||
|
42,
|
||||||
|
178,
|
||||||
|
223,
|
||||||
|
143,
|
||||||
|
233,
|
||||||
|
199,
|
||||||
|
8,
|
||||||
|
80,
|
||||||
|
214,
|
||||||
|
173,
|
||||||
|
253,
|
||||||
|
32,
|
||||||
|
191,
|
||||||
|
226,
|
||||||
|
254,
|
||||||
|
247,
|
||||||
|
229,
|
||||||
|
92,
|
||||||
|
207,
|
||||||
|
12,
|
||||||
|
244,
|
||||||
|
184,
|
||||||
|
99,
|
||||||
|
83,
|
||||||
|
92,
|
||||||
|
146,
|
||||||
|
8
|
||||||
|
],
|
||||||
|
"ApplicationID": 86525641,
|
||||||
|
"OnCompletion": 0,
|
||||||
|
"ApplicationArgs": [
|
||||||
|
"c2VuZFRyYW5zZmVy",
|
||||||
|
"AAAAAAyxPN0=",
|
||||||
|
"AAAAAAAHoSA=",
|
||||||
|
"AAAAAAAAAAAAAAAAnhxWOOMdX90rqGU4T5RVXpX+UXg=",
|
||||||
|
"AAAAAAAAAAU=",
|
||||||
|
"AAAAAAAAAAA="
|
||||||
|
],
|
||||||
|
"Accounts": [
|
||||||
|
[
|
||||||
|
210,
|
||||||
|
200,
|
||||||
|
255,
|
||||||
|
178,
|
||||||
|
7,
|
||||||
|
225,
|
||||||
|
188,
|
||||||
|
18,
|
||||||
|
254,
|
||||||
|
137,
|
||||||
|
181,
|
||||||
|
25,
|
||||||
|
145,
|
||||||
|
41,
|
||||||
|
27,
|
||||||
|
249,
|
||||||
|
185,
|
||||||
|
43,
|
||||||
|
215,
|
||||||
|
225,
|
||||||
|
96,
|
||||||
|
64,
|
||||||
|
230,
|
||||||
|
126,
|
||||||
|
144,
|
||||||
|
206,
|
||||||
|
212,
|
||||||
|
182,
|
||||||
|
57,
|
||||||
|
154,
|
||||||
|
179,
|
||||||
|
83
|
||||||
|
],
|
||||||
|
[
|
||||||
|
137,
|
||||||
|
240,
|
||||||
|
161,
|
||||||
|
164,
|
||||||
|
216,
|
||||||
|
254,
|
||||||
|
162,
|
||||||
|
141,
|
||||||
|
120,
|
||||||
|
49,
|
||||||
|
250,
|
||||||
|
230,
|
||||||
|
145,
|
||||||
|
1,
|
||||||
|
126,
|
||||||
|
6,
|
||||||
|
19,
|
||||||
|
84,
|
||||||
|
124,
|
||||||
|
105,
|
||||||
|
213,
|
||||||
|
48,
|
||||||
|
63,
|
||||||
|
5,
|
||||||
|
170,
|
||||||
|
88,
|
||||||
|
13,
|
||||||
|
35,
|
||||||
|
36,
|
||||||
|
240,
|
||||||
|
151,
|
||||||
|
156
|
||||||
|
],
|
||||||
|
[
|
||||||
|
137,
|
||||||
|
240,
|
||||||
|
161,
|
||||||
|
164,
|
||||||
|
216,
|
||||||
|
254,
|
||||||
|
162,
|
||||||
|
141,
|
||||||
|
120,
|
||||||
|
49,
|
||||||
|
250,
|
||||||
|
230,
|
||||||
|
145,
|
||||||
|
1,
|
||||||
|
126,
|
||||||
|
6,
|
||||||
|
19,
|
||||||
|
84,
|
||||||
|
124,
|
||||||
|
105,
|
||||||
|
213,
|
||||||
|
48,
|
||||||
|
63,
|
||||||
|
5,
|
||||||
|
170,
|
||||||
|
88,
|
||||||
|
13,
|
||||||
|
35,
|
||||||
|
36,
|
||||||
|
240,
|
||||||
|
151,
|
||||||
|
156
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ForeignApps": [
|
||||||
|
86525623
|
||||||
|
],
|
||||||
|
"ForeignAssets": [
|
||||||
|
212942045
|
||||||
|
],
|
||||||
|
"BoxReferences": null,
|
||||||
|
"LocalStateSchema": {
|
||||||
|
"NumUint": 0,
|
||||||
|
"NumByteSlice": 0
|
||||||
|
},
|
||||||
|
"GlobalStateSchema": {
|
||||||
|
"NumUint": 0,
|
||||||
|
"NumByteSlice": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EvalDelta": {
|
||||||
|
"GlobalDelta": null,
|
||||||
|
"LocalDeltas": null,
|
||||||
|
"Logs": null,
|
||||||
|
"InnerTxns": [
|
||||||
|
{
|
||||||
|
"Txn": {
|
||||||
|
"Type": "appl",
|
||||||
|
"Sender": [
|
||||||
|
98,
|
||||||
|
65,
|
||||||
|
255,
|
||||||
|
220,
|
||||||
|
3,
|
||||||
|
43,
|
||||||
|
105,
|
||||||
|
59,
|
||||||
|
251,
|
||||||
|
133,
|
||||||
|
68,
|
||||||
|
133,
|
||||||
|
143,
|
||||||
|
4,
|
||||||
|
3,
|
||||||
|
222,
|
||||||
|
200,
|
||||||
|
111,
|
||||||
|
46,
|
||||||
|
23,
|
||||||
|
32,
|
||||||
|
175,
|
||||||
|
159,
|
||||||
|
52,
|
||||||
|
248,
|
||||||
|
214,
|
||||||
|
95,
|
||||||
|
229,
|
||||||
|
116,
|
||||||
|
182,
|
||||||
|
35,
|
||||||
|
140
|
||||||
|
],
|
||||||
|
"Fee": 0,
|
||||||
|
"FirstValid": 30453933,
|
||||||
|
"LastValid": 30454933,
|
||||||
|
"Note": "cHVibGlzaE1lc3NhZ2U=",
|
||||||
|
"AssetFrozen": false,
|
||||||
|
"ApplicationID": 86525623,
|
||||||
|
"OnCompletion": 0,
|
||||||
|
"ApplicationArgs": [
|
||||||
|
"cHVibGlzaE1lc3NhZ2U=",
|
||||||
|
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB6EgAAAAAAAAAAAAAAAAnDySg9PkSFRpfNItP6okDPsDKIkABQAAAAAAAAAAAAAAAJ4cVjjjHV/dK6hlOE+UVV6V/lF4AAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"AAAAAAAAAAA="
|
||||||
|
],
|
||||||
|
"Accounts": [
|
||||||
|
[
|
||||||
|
210,
|
||||||
|
200,
|
||||||
|
255,
|
||||||
|
178,
|
||||||
|
7,
|
||||||
|
225,
|
||||||
|
188,
|
||||||
|
18,
|
||||||
|
254,
|
||||||
|
137,
|
||||||
|
181,
|
||||||
|
25,
|
||||||
|
145,
|
||||||
|
41,
|
||||||
|
27,
|
||||||
|
249,
|
||||||
|
185,
|
||||||
|
43,
|
||||||
|
215,
|
||||||
|
225,
|
||||||
|
96,
|
||||||
|
64,
|
||||||
|
230,
|
||||||
|
126,
|
||||||
|
144,
|
||||||
|
206,
|
||||||
|
212,
|
||||||
|
182,
|
||||||
|
57,
|
||||||
|
154,
|
||||||
|
179,
|
||||||
|
83
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"ForeignApps": null,
|
||||||
|
"ForeignAssets": null,
|
||||||
|
"BoxReferences": null,
|
||||||
|
"LocalStateSchema": {
|
||||||
|
"NumUint": 0,
|
||||||
|
"NumByteSlice": 0
|
||||||
|
},
|
||||||
|
"GlobalStateSchema": {
|
||||||
|
"NumUint": 0,
|
||||||
|
"NumByteSlice": 0
|
||||||
|
},
|
||||||
|
"ApprovalProgram": null,
|
||||||
|
"ClearStateProgram": null,
|
||||||
|
"ExtraProgramPages": 0,
|
||||||
|
"StateProofType": 0,
|
||||||
|
"StateProof": null,
|
||||||
|
"Message": {
|
||||||
|
"BlockHeadersCommitment": null,
|
||||||
|
"VotersCommitment": null,
|
||||||
|
"LnProvenWeight": 0,
|
||||||
|
"FirstAttestedRound": 0,
|
||||||
|
"LastAttestedRound": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"EvalDelta": {
|
||||||
|
"GlobalDelta": null,
|
||||||
|
"LocalDeltas": {
|
||||||
|
"1": {
|
||||||
|
"\u0000": {
|
||||||
|
"Action": 1,
|
||||||
|
"Bytes": "\u0000\u0000\u0000\u0000\u0000\u0000\u0003\ufffd\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000",
|
||||||
|
"Uint": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Logs": [
|
||||||
|
"AAAAAAAAA+E="
|
||||||
|
],
|
||||||
|
"InnerTxns": null
|
||||||
|
},
|
||||||
|
"ConfigAsset": 0,
|
||||||
|
"ApplicationID": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ConfigAsset": 0,
|
||||||
|
"ApplicationID": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"HasGenesisID": true,
|
||||||
|
"HasGenesisHash": false
|
||||||
|
}
|
|
@ -24,6 +24,9 @@ import (
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Algorand allows max depth of 8 inner transactions
|
||||||
|
const MAX_DEPTH = 8
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// Watcher is responsible for looking over Algorand blockchain and reporting new transactions to the appid
|
// Watcher is responsible for looking over Algorand blockchain and reporting new transactions to the appid
|
||||||
Watcher struct {
|
Watcher struct {
|
||||||
|
@ -39,6 +42,13 @@ type (
|
||||||
|
|
||||||
next_round uint64
|
next_round uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
algorandObservation struct {
|
||||||
|
emitterAddress vaa.Address
|
||||||
|
nonce uint32
|
||||||
|
sequence uint64
|
||||||
|
payload []byte
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -77,31 +87,60 @@ func NewWatcher(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gatherObservations recurses through a given transactions inner-transactions
|
||||||
|
// to find any messages emitted from the core wormhole contract.
|
||||||
|
// Algorand allows up to 8 levels of inner transactions.
|
||||||
|
func gatherObservations(e *Watcher, t types.SignedTxnWithAD, depth int, logger *zap.Logger) (obs []algorandObservation) {
|
||||||
|
|
||||||
|
// SECURITY defense-in-depth: don't recurse > max depth allowed by Algorand
|
||||||
|
if depth >= MAX_DEPTH {
|
||||||
|
logger.Error("algod client", zap.Error(fmt.Errorf("exceeded max depth of %d", MAX_DEPTH)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// recurse through nested inner transactions
|
||||||
|
for _, itxn := range t.EvalDelta.InnerTxns {
|
||||||
|
obs = append(obs, gatherObservations(e, itxn, depth+1, logger)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var at = t.Txn
|
||||||
|
var ed = t.EvalDelta
|
||||||
|
|
||||||
|
// check if the current transaction meets what we expect
|
||||||
|
// for an emitted message
|
||||||
|
if (len(at.ApplicationArgs) != 3) || (uint64(at.ApplicationID) != e.appid) || string(at.ApplicationArgs[0]) != "publishMessage" || len(ed.Logs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("emitter: " + hex.EncodeToString(at.Sender[:]))
|
||||||
|
|
||||||
|
var a vaa.Address
|
||||||
|
copy(a[:], at.Sender[:]) // 32 bytes = 8edf5b0e108c3a1a0a4b704cc89591f2ad8d50df24e991567e640ed720a94be2
|
||||||
|
|
||||||
|
obs = append(obs, algorandObservation{
|
||||||
|
nonce: uint32(binary.BigEndian.Uint64(at.ApplicationArgs[2])),
|
||||||
|
sequence: binary.BigEndian.Uint64([]byte(ed.Logs[0])),
|
||||||
|
emitterAddress: a,
|
||||||
|
payload: at.ApplicationArgs[1],
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookAtTxn takes an outer transaction from the block.payset and gathers
|
||||||
|
// observations from messages emitted in nested inner transactions
|
||||||
|
// then passes them on the relevant channels
|
||||||
func lookAtTxn(e *Watcher, t types.SignedTxnInBlock, b types.Block, logger *zap.Logger) {
|
func lookAtTxn(e *Watcher, t types.SignedTxnInBlock, b types.Block, logger *zap.Logger) {
|
||||||
for q := 0; q < len(t.EvalDelta.InnerTxns); q++ {
|
|
||||||
var it = t.EvalDelta.InnerTxns[q]
|
|
||||||
var at = it.Txn
|
|
||||||
|
|
||||||
if (len(at.ApplicationArgs) != 3) || (uint64(at.ApplicationID) != e.appid) {
|
observations := gatherObservations(e, t.SignedTxnWithAD, 0, logger)
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(at.ApplicationArgs[0]) != "publishMessage" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var ed = it.EvalDelta
|
|
||||||
if len(ed.Logs) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
emitter := at.Sender
|
|
||||||
|
|
||||||
var a vaa.Address
|
|
||||||
copy(a[:], emitter[:]) // 32 bytes = 8edf5b0e108c3a1a0a4b704cc89591f2ad8d50df24e991567e640ed720a94be2
|
|
||||||
|
|
||||||
logger.Info("emitter: " + hex.EncodeToString(emitter[:]))
|
|
||||||
|
|
||||||
|
// We use the outermost transaction id in the observation message
|
||||||
|
// so we can apply the same logic to gather any messages emitted
|
||||||
|
// by inner transactions
|
||||||
|
var txHash eth_common.Hash
|
||||||
|
if len(observations) > 0 {
|
||||||
|
// Repopulate the genesis id/hash for the transaction
|
||||||
|
// since in the block encoding, it's omitted to save space
|
||||||
t.Txn.GenesisID = b.GenesisID
|
t.Txn.GenesisID = b.GenesisID
|
||||||
t.Txn.GenesisHash = b.GenesisHash
|
t.Txn.GenesisHash = b.GenesisHash
|
||||||
Id := crypto.GetTxID(t.Txn)
|
Id := crypto.GetTxID(t.Txn)
|
||||||
|
@ -109,21 +148,22 @@ func lookAtTxn(e *Watcher, t types.SignedTxnInBlock, b types.Block, logger *zap.
|
||||||
id, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(Id)
|
id, err := base32.StdEncoding.WithPadding(base32.NoPadding).DecodeString(Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Base32 DecodeString", zap.Error(err))
|
logger.Error("Base32 DecodeString", zap.Error(err))
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("id: " + hex.EncodeToString(id) + " " + Id)
|
logger.Info("id: " + hex.EncodeToString(id) + " " + Id)
|
||||||
|
|
||||||
var txHash = eth_common.BytesToHash(id) // 32 bytes = d3b136a6a182a40554b2fafbc8d12a7a22737c10c81e33b33d1dcb74c532708b
|
txHash = eth_common.BytesToHash(id) // 32 bytes = d3b136a6a182a40554b2fafbc8d12a7a22737c10c81e33b33d1dcb74c532708b
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, obs := range observations {
|
||||||
observation := &common.MessagePublication{
|
observation := &common.MessagePublication{
|
||||||
TxHash: txHash,
|
TxHash: txHash,
|
||||||
Timestamp: time.Unix(b.TimeStamp, 0),
|
Timestamp: time.Unix(b.TimeStamp, 0),
|
||||||
Nonce: uint32(binary.BigEndian.Uint64(at.ApplicationArgs[2])),
|
Nonce: obs.nonce,
|
||||||
Sequence: binary.BigEndian.Uint64([]byte(ed.Logs[0])),
|
Sequence: obs.sequence,
|
||||||
EmitterChain: vaa.ChainIDAlgorand,
|
EmitterChain: vaa.ChainIDAlgorand,
|
||||||
EmitterAddress: a,
|
EmitterAddress: obs.emitterAddress,
|
||||||
Payload: at.ApplicationArgs[1],
|
Payload: obs.payload,
|
||||||
ConsistencyLevel: 0,
|
ConsistencyLevel: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package algorand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/algorand/go-algorand-sdk/types"
|
||||||
|
"github.com/certusone/wormhole/node/pkg/common"
|
||||||
|
gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
const APP_ID = 86525623
|
||||||
|
|
||||||
|
// Tests for nested inner transactions calling the core bridge
|
||||||
|
func TestLookAtTxnInnerTxn(t *testing.T) {
|
||||||
|
// Setup a watcher
|
||||||
|
msgC := make(chan *common.MessagePublication)
|
||||||
|
obsvReqC := make(chan *gossipv1.ObservationRequest, 50)
|
||||||
|
w := NewWatcher("", "", "", "", APP_ID, msgC, obsvReqC)
|
||||||
|
|
||||||
|
var expectedSequence uint64 = 993
|
||||||
|
|
||||||
|
// read in test block for inner transactions
|
||||||
|
b, err := os.ReadFile("test_nested_inner.block.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to read block file: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txn := types.SignedTxnInBlock{}
|
||||||
|
err = json.Unmarshal(b, &txn)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to unmarshal block: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because we are using a json blob and the type of logs array is []string
|
||||||
|
// and because go json package will refuse to properly encode/decode
|
||||||
|
// invalid utf8 characters, the json blob has the relevant log encoded as base64
|
||||||
|
// and we base64 decode it and convert it to a string _manually_ so we can
|
||||||
|
// make sure we got the right sequence number
|
||||||
|
b64Data := txn.EvalDelta.InnerTxns[2].EvalDelta.InnerTxns[0].EvalDelta.Logs[0]
|
||||||
|
bb, err := base64.StdEncoding.DecodeString(b64Data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Cant decode: %s", err)
|
||||||
|
}
|
||||||
|
txn.EvalDelta.InnerTxns[2].EvalDelta.InnerTxns[0].EvalDelta.Logs[0] = string(bb)
|
||||||
|
|
||||||
|
// for each tx in the block, check to see if its a valid
|
||||||
|
// wh emitted message
|
||||||
|
logger, _ := zap.NewProduction()
|
||||||
|
observations := gatherObservations(w, txn.SignedTxnWithAD, 0, logger)
|
||||||
|
|
||||||
|
if len(observations) != 1 {
|
||||||
|
t.Fatalf("expected 1 observation, got %d", len(observations))
|
||||||
|
}
|
||||||
|
|
||||||
|
if observations[0].sequence != expectedSequence {
|
||||||
|
t.Fatalf("expected sequence observed to be %d, got %d", expectedSequence, observations[0].sequence)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue