Skip to content

Commit 175b8b0

Browse files
committed
fix: Implement bit masks in the correct way
1 parent f224f5c commit 175b8b0

File tree

1 file changed

+117
-118
lines changed

1 file changed

+117
-118
lines changed

c/open_transaction.c

Lines changed: 117 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,23 @@
4545
#define LABEL_INPUT_CELL_SINCE 0x3
4646
#define LABEL_INPUT_OUTPOINT 0x4
4747

48-
#define MASK_CELL_CAPACITY 0x0
49-
#define MASK_CELL_TYPE_CODE_HASH 0x1
50-
#define MASK_CELL_TYPE_ARGS 0x2
51-
#define MASK_CELL_TYPE_HASH_TYPE 0x3
52-
#define MASK_CELL_LOCK_CODE_HASH 0x4
53-
#define MASK_CELL_LOCK_ARGS 0x5
54-
#define MASK_CELL_LOCK_HASH_TYPE 0x6
55-
#define MASK_CELL_DATA 0x7
48+
#define MASK_CELL_CAPACITY 0x1
49+
#define MASK_CELL_TYPE_CODE_HASH 0x2
50+
#define MASK_CELL_TYPE_ARGS 0x4
51+
#define MASK_CELL_TYPE_HASH_TYPE 0x8
52+
#define MASK_CELL_ANY_TYPE \
53+
(MASK_CELL_TYPE_CODE_HASH | MASK_CELL_TYPE_ARGS | MASK_CELL_TYPE_HASH_TYPE)
54+
#define MASK_CELL_LOCK_CODE_HASH 0x10
55+
#define MASK_CELL_LOCK_ARGS 0x20
56+
#define MASK_CELL_LOCK_HASH_TYPE 0x40
57+
#define MASK_CELL_ANY_LOCK \
58+
(MASK_CELL_LOCK_CODE_HASH | MASK_CELL_LOCK_ARGS | MASK_CELL_LOCK_HASH_TYPE)
59+
#define MASK_CELL_DATA 0x80
5660
#define MASK_CELL_ALL 0xFF
5761

58-
#define MASK_OUTPOINT_TX_HASH 0x0
59-
#define MASK_OUTPOINT_INDEX 0x1
60-
#define MASK_OUTPOINT_SINCE 0x2
62+
#define MASK_OUTPOINT_TX_HASH 0x1
63+
#define MASK_OUTPOINT_INDEX 0x2
64+
#define MASK_OUTPOINT_SINCE 0x4
6165
#define MASK_OUTPOINT_ALL 0xFF
6266

6367
// Extract lock from WitnessArgs
@@ -117,6 +121,38 @@ int hash_input(blake2b_state *ctx, size_t index_code, size_t source) {
117121
return load_and_hash(ctx, index_code, source, ckb_load_input);
118122
}
119123

124+
int hash_script_fields(blake2b_state *ctx, size_t index_code, size_t source,
125+
size_t field, uint8_t lock_masks) {
126+
unsigned char script[SCRIPT_SIZE];
127+
uint64_t len = SCRIPT_SIZE;
128+
int ret = ckb_checked_load_cell_by_field(script, &len, 0, index_code, source,
129+
field);
130+
if (ret != CKB_SUCCESS) {
131+
return ret;
132+
}
133+
mol_seg_t script_seg;
134+
script_seg.ptr = (uint8_t *)script;
135+
script_seg.size = len;
136+
if (MolReader_Script_verify(&script_seg, false) != MOL_OK) {
137+
return ERROR_ENCODING;
138+
}
139+
140+
if ((lock_masks & MASK_CELL_LOCK_CODE_HASH) != 0) {
141+
mol_seg_t item_seg = MolReader_Script_get_code_hash(&script_seg);
142+
blake2b_update(ctx, item_seg.ptr, item_seg.size);
143+
}
144+
if ((lock_masks & MASK_CELL_LOCK_ARGS) != 0) {
145+
mol_seg_t item_seg = MolReader_Script_get_args(&script_seg);
146+
blake2b_update(ctx, item_seg.ptr, item_seg.size);
147+
}
148+
if ((lock_masks & MASK_CELL_LOCK_HASH_TYPE) != 0) {
149+
mol_seg_t item_seg = MolReader_Script_get_hash_type(&script_seg);
150+
blake2b_update(ctx, item_seg.ptr, item_seg.size);
151+
}
152+
153+
return CKB_SUCCESS;
154+
}
155+
120156
int main() {
121157
unsigned char witness[WITNESS_SIZE];
122158
// Load witness of first input
@@ -191,10 +227,17 @@ int main() {
191227
case LABEL_INPUT_CELL_SINCE: {
192228
size_t source =
193229
(label == LABEL_OUTPUT) ? CKB_SOURCE_OUTPUT : CKB_SOURCE_INPUT;
194-
size_t field;
195-
uint8_t item;
196-
switch (mask) {
197-
case MASK_CELL_CAPACITY: {
230+
if (mask == MASK_CELL_ALL) {
231+
ret = hash_cell(&blake2b_ctx, index_code, source);
232+
if (ret != CKB_SUCCESS) {
233+
return ret;
234+
}
235+
ret = hash_cell_data(&blake2b_ctx, index_code, source);
236+
if (ret != CKB_SUCCESS) {
237+
return ret;
238+
}
239+
} else {
240+
if ((mask & MASK_CELL_CAPACITY) != 0) {
198241
uint64_t capacity = 0;
199242
uint64_t len = 8;
200243
int ret = ckb_load_cell_by_field((uint8_t *)(&capacity), &len, 0,
@@ -204,137 +247,93 @@ int main() {
204247
return ret;
205248
}
206249
blake2b_update(&blake2b_ctx, (uint8_t *)(&capacity), 8);
207-
} break;
208-
case MASK_CELL_LOCK_CODE_HASH:
209-
case MASK_CELL_LOCK_ARGS:
210-
case MASK_CELL_LOCK_HASH_TYPE:
211-
field = CKB_CELL_FIELD_LOCK;
212-
item = mask;
213-
goto PROCESS_SCRIPT;
214-
case MASK_CELL_TYPE_CODE_HASH:
215-
field = CKB_CELL_FIELD_TYPE;
216-
item = MASK_CELL_LOCK_CODE_HASH;
217-
goto PROCESS_SCRIPT;
218-
case MASK_CELL_TYPE_ARGS:
219-
field = CKB_CELL_FIELD_TYPE;
220-
item = MASK_CELL_LOCK_ARGS;
221-
goto PROCESS_SCRIPT;
222-
case MASK_CELL_TYPE_HASH_TYPE:
223-
field = CKB_CELL_FIELD_TYPE;
224-
item = MASK_CELL_LOCK_HASH_TYPE;
225-
PROCESS_SCRIPT : {
226-
unsigned char script[SCRIPT_SIZE];
227-
uint64_t len = SCRIPT_SIZE;
228-
int ret = ckb_checked_load_cell_by_field(script, &len, 0,
229-
index_code, source, field);
230-
if (ret != CKB_SUCCESS) {
231-
return ret;
250+
}
251+
if ((mask & MASK_CELL_ANY_TYPE) != 0) {
252+
uint8_t lock_masks = 0;
253+
if ((mask & MASK_CELL_TYPE_CODE_HASH) != 0) {
254+
lock_masks |= MASK_CELL_LOCK_CODE_HASH;
232255
}
233-
234-
mol_seg_t script_seg;
235-
script_seg.ptr = (uint8_t *)script;
236-
script_seg.size = len;
237-
if (MolReader_Script_verify(&script_seg, false) != MOL_OK) {
238-
return ERROR_ENCODING;
256+
if ((mask & MASK_CELL_TYPE_ARGS) != 0) {
257+
lock_masks |= MASK_CELL_LOCK_ARGS;
239258
}
240-
241-
mol_seg_t item_seg;
242-
switch (item) {
243-
case MASK_CELL_LOCK_CODE_HASH:
244-
item_seg = MolReader_Script_get_code_hash(&script_seg);
245-
blake2b_update(&blake2b_ctx, item_seg.ptr, item_seg.size);
246-
break;
247-
case MASK_CELL_LOCK_ARGS:
248-
item_seg = MolReader_Script_get_args(&script_seg);
249-
blake2b_update(&blake2b_ctx, item_seg.ptr, item_seg.size);
250-
break;
251-
case MASK_CELL_LOCK_HASH_TYPE:
252-
item_seg = MolReader_Script_get_hash_type(&script_seg);
253-
blake2b_update(&blake2b_ctx, item_seg.ptr, item_seg.size);
254-
break;
259+
if ((mask & MASK_CELL_TYPE_HASH_TYPE) != 0) {
260+
lock_masks |= MASK_CELL_LOCK_HASH_TYPE;
255261
}
256-
} break;
257-
case MASK_CELL_DATA:
258-
ret = hash_cell_data(&blake2b_ctx, index_code, source);
262+
ret = hash_script_fields(&blake2b_ctx, index_code, source,
263+
CKB_CELL_FIELD_TYPE, lock_masks);
259264
if (ret != CKB_SUCCESS) {
260265
return ret;
261266
}
262-
break;
263-
case MASK_CELL_ALL:
264-
ret = hash_cell(&blake2b_ctx, index_code, source);
267+
}
268+
if ((mask & MASK_CELL_ANY_LOCK) != 0) {
269+
ret = hash_script_fields(&blake2b_ctx, index_code, source,
270+
CKB_CELL_FIELD_LOCK, mask);
265271
if (ret != CKB_SUCCESS) {
266272
return ret;
267273
}
274+
}
275+
if ((mask & MASK_CELL_DATA) != 0) {
268276
ret = hash_cell_data(&blake2b_ctx, index_code, source);
269277
if (ret != CKB_SUCCESS) {
270278
return ret;
271279
}
272-
break;
273-
default:
274-
return ERROR_INVALID_MASK;
280+
}
275281
}
276282
if (label == LABEL_INPUT_CELL_SINCE) {
277283
uint8_t since[8];
278284
uint64_t len = 8;
279-
int ret = ckb_load_input_by_field(since, &len, 0, index_code, source,
280-
CKB_INPUT_FIELD_SINCE);
285+
int ret = ckb_checked_load_input_by_field(
286+
since, &len, 0, index_code, source, CKB_INPUT_FIELD_SINCE);
281287
if (ret != CKB_SUCCESS) {
282288
return ret;
283289
}
284290
blake2b_update(&blake2b_ctx, since, 8);
285291
}
286292
} break;
287293
case LABEL_INPUT_OUTPOINT: {
288-
uint8_t buf[INPUT_SIZE];
289-
uint64_t len = INPUT_SIZE;
290-
int ret;
291294
if (mask == MASK_OUTPOINT_ALL) {
292-
ret = ckb_checked_load_input(buf, &len, 0, index_code,
293-
CKB_SOURCE_INPUT);
295+
ret = hash_input(&blake2b_ctx, index_code, CKB_SOURCE_INPUT);
296+
if (ret != CKB_SUCCESS) {
297+
return ret;
298+
}
294299
} else {
295-
switch (mask) {
296-
case MASK_OUTPOINT_SINCE:
297-
ret = ckb_checked_load_input_by_field(buf, &len, 0, index_code,
298-
CKB_SOURCE_INPUT,
299-
CKB_INPUT_FIELD_SINCE);
300-
break;
301-
case MASK_OUTPOINT_TX_HASH:
302-
case MASK_OUTPOINT_INDEX: {
303-
uint8_t temp[INPUT_SIZE];
304-
uint64_t temp_len = INPUT_SIZE;
305-
ret = ckb_checked_load_input_by_field(
306-
temp, &temp_len, 0, index_code, CKB_SOURCE_INPUT,
307-
CKB_INPUT_FIELD_OUT_POINT);
308-
if (ret != CKB_SUCCESS) {
309-
return ret;
310-
}
311-
mol_seg_t outpoint_seg;
312-
outpoint_seg.ptr = temp;
313-
outpoint_seg.size = temp_len;
314-
if (MolReader_OutPoint_verify(&outpoint_seg, false) != MOL_OK) {
315-
return ERROR_ENCODING;
316-
}
317-
if (mask == MASK_OUTPOINT_TX_HASH) {
318-
mol_seg_t tx_hash_seg =
319-
MolReader_OutPoint_get_tx_hash(&outpoint_seg);
320-
memcpy(buf, tx_hash_seg.ptr, tx_hash_seg.size);
321-
len = tx_hash_seg.size;
322-
} else {
323-
mol_seg_t index_seg =
324-
MolReader_OutPoint_get_tx_hash(&index_seg);
325-
memcpy(buf, index_seg.ptr, index_seg.size);
326-
len = index_seg.size;
327-
}
328-
ret = CKB_SUCCESS;
329-
} break;
330-
default:
331-
return ERROR_INVALID_MASK;
300+
if ((mask & MASK_OUTPOINT_SINCE) != 0) {
301+
uint8_t since[8];
302+
uint64_t len = 8;
303+
ret = ckb_checked_load_input_by_field(since, &len, 0, index_code,
304+
CKB_SOURCE_INPUT,
305+
CKB_INPUT_FIELD_SINCE);
306+
if (ret != CKB_SUCCESS) {
307+
return ret;
308+
}
309+
blake2b_update(&blake2b_ctx, since, 8);
310+
}
311+
312+
uint8_t input_buf[INPUT_SIZE];
313+
uint64_t input_len = INPUT_SIZE;
314+
ret = ckb_checked_load_input_by_field(input_buf, &input_len, 0,
315+
index_code, CKB_SOURCE_INPUT,
316+
CKB_INPUT_FIELD_OUT_POINT);
317+
if (ret != CKB_SUCCESS) {
318+
return ret;
319+
}
320+
mol_seg_t outpoint_seg;
321+
outpoint_seg.ptr = input_buf;
322+
outpoint_seg.size = input_len;
323+
if (MolReader_OutPoint_verify(&outpoint_seg, false) != MOL_OK) {
324+
return ERROR_ENCODING;
325+
}
326+
327+
if ((mask & MASK_OUTPOINT_TX_HASH) != 0) {
328+
mol_seg_t tx_hash_seg =
329+
MolReader_OutPoint_get_tx_hash(&outpoint_seg);
330+
blake2b_update(&blake2b_ctx, tx_hash_seg.ptr, tx_hash_seg.size);
331+
}
332+
if ((mask & MASK_OUTPOINT_INDEX) != 0) {
333+
mol_seg_t index_seg = MolReader_OutPoint_get_tx_hash(&index_seg);
334+
blake2b_update(&blake2b_ctx, index_seg.ptr, index_seg.size);
332335
}
333336
}
334-
if (ret != CKB_SUCCESS) {
335-
return ret;
336-
}
337-
blake2b_update(&blake2b_ctx, buf, len);
338337
} break;
339338
case LABEL_END_OF_LIST:
340339
has_more = 0;

0 commit comments

Comments
 (0)