Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support input/output type script hash as owner mode #24

Merged
merged 5 commits into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ jobs:
- name: Run tests
run: cargo test
- name: Run xudt tests
run: cd xudt && cargo test
run: cd tests/xudt_rce_rust && cargo test
- name: Run xudt simulator tests
run: cd tests/xudt_rce && bash run.sh
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ ${PROTOCOL_SCHEMA}:

fmt:
clang-format -i -style=Google $(wildcard c/rce_validator.c /always_success.c c/anyone_can_pay.c c/smt.h c/rce.h c/xudt_rce.c c/rce_validator.c tests/xudt_rce/*.c tests/xudt_rce/*.h)
cd xudt && cargo fmt --all
git diff --exit-code $(wildcard c/rce_validator.c /always_success.c c/anyone_can_pay.c c/smt.h c/rce.h c/xudt_rce.c tests/xudt_rce/*.c tests/xudt_rce/*.h)

mol:
Expand Down
74 changes: 70 additions & 4 deletions c/xudt_rce.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ int ckb_exit(signed char);
#define MAX_CODE_SIZE (1024 * 1024)
#define FLAGS_SIZE 4
#define MAX_LOCK_SCRIPT_HASH_COUNT 2048
#define OWNER_MODE_MASK 0xC0000000
#define OWNER_MODE_INPUT_TYPE_MASK 0x80000000
#define OWNER_MODE_OUTPUT_TYPE_MASK 0x40000000

#include "rce.h"

Expand Down Expand Up @@ -254,6 +257,8 @@ int load_raw_extension_data(uint8_t** var_data, uint32_t* var_len) {
int parse_args(int* owner_mode, XUDTFlags* flags, uint8_t** var_data,
uint32_t* var_len, uint8_t* hashes, uint32_t* hashes_count) {
int err = 0;
bool owner_mode_for_input_type = false;
bool owner_mode_for_output_type = false;

uint64_t len = SCRIPT_SIZE;
int ret = ckb_checked_load_script(g_script, &len, 0);
Expand All @@ -271,6 +276,16 @@ int parse_args(int* owner_mode, XUDTFlags* flags, uint8_t** var_data,
mol_seg_t args_bytes_seg = MolReader_Bytes_raw_bytes(&args_seg);
CHECK2(args_bytes_seg.size >= BLAKE2B_BLOCK_SIZE, ERROR_ARGUMENTS_LEN);

if (args_bytes_seg.size >= (FLAGS_SIZE + BLAKE2B_BLOCK_SIZE)) {
uint32_t val = *(uint32_t*)(args_bytes_seg.ptr + BLAKE2B_BLOCK_SIZE);
if (val & OWNER_MODE_INPUT_TYPE_MASK) {
owner_mode_for_input_type = true;
}
if (val & OWNER_MODE_OUTPUT_TYPE_MASK) {
owner_mode_for_output_type = true;
}
}

*hashes_count = 0;
// With owner lock script extracted, we will look through each input in the
// current transaction to see if any unlocked cell uses owner lock.
Expand Down Expand Up @@ -308,16 +323,67 @@ int parse_args(int* owner_mode, XUDTFlags* flags, uint8_t** var_data,
i += 1;
}

if (owner_mode_for_input_type) {
// input type hash
i = 0;
while (1) {
uint8_t buffer[BLAKE2B_BLOCK_SIZE];
uint64_t len2 = BLAKE2B_BLOCK_SIZE;
ret = ckb_checked_load_cell_by_field(
buffer, &len2, 0, i, CKB_SOURCE_INPUT, CKB_CELL_FIELD_TYPE_HASH);
if (ret == CKB_INDEX_OUT_OF_BOUND) {
break;
}
if (ret == CKB_ITEM_MISSING) {
i += 1;
continue;
}
CHECK(ret);
if (args_bytes_seg.size >= BLAKE2B_BLOCK_SIZE &&
memcmp(buffer, args_bytes_seg.ptr, BLAKE2B_BLOCK_SIZE) == 0) {
*owner_mode = 1;
break;
}
i += 1;
}
}
if (owner_mode_for_output_type) {
// output type hash
i = 0;
while (1) {
uint8_t buffer[BLAKE2B_BLOCK_SIZE];
uint64_t len2 = BLAKE2B_BLOCK_SIZE;
ret = ckb_checked_load_cell_by_field(
buffer, &len2, 0, i, CKB_SOURCE_OUTPUT, CKB_CELL_FIELD_TYPE_HASH);
if (ret == CKB_INDEX_OUT_OF_BOUND) {
break;
}
if (ret == CKB_ITEM_MISSING) {
i += 1;
continue;
}
CHECK(ret);
if (args_bytes_seg.size >= BLAKE2B_BLOCK_SIZE &&
memcmp(buffer, args_bytes_seg.ptr, BLAKE2B_BLOCK_SIZE) == 0) {
*owner_mode = 1;
break;
}
i += 1;
}
}

// parse xUDT args
if (args_bytes_seg.size < (FLAGS_SIZE + BLAKE2B_BLOCK_SIZE)) {
*var_data = NULL;
*var_len = 0;
*flags = XUDTFlagsPlain;
} else {
uint32_t* flag_ptr = (uint32_t*)(args_bytes_seg.ptr + BLAKE2B_BLOCK_SIZE);
if (*flag_ptr == XUDTFlagsPlain) {
uint32_t temp_flags =
(*(uint32_t*)(args_bytes_seg.ptr + BLAKE2B_BLOCK_SIZE)) &
~OWNER_MODE_MASK;
if (temp_flags == XUDTFlagsPlain) {
*flags = XUDTFlagsPlain;
} else if (*flag_ptr == XUDTFlagsInArgs) {
} else if (temp_flags == XUDTFlagsInArgs) {
uint32_t real_size = 0;
*flags = XUDTFlagsInArgs;
*var_len = args_bytes_seg.size - BLAKE2B_BLOCK_SIZE - FLAGS_SIZE;
Expand All @@ -327,7 +393,7 @@ int parse_args(int* owner_mode, XUDTFlags* flags, uint8_t** var_data,
CHECK(err);
// note, it's different than "flag = 2"
CHECK2(real_size == *var_len, ERROR_INVALID_ARGS_FORMAT);
} else if (*flag_ptr == XUDTFlagsInWitness) {
} else if (temp_flags == XUDTFlagsInWitness) {
*flags = XUDTFlagsInWitness;
uint32_t hash_size =
args_bytes_seg.size - BLAKE2B_BLOCK_SIZE - FLAGS_SIZE;
Expand Down
2 changes: 2 additions & 0 deletions tests/xudt_rce/ckb_syscall_xudt_sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,8 @@ int ckb_load_cell_by_field(void* addr, uint64_t* len, size_t offset,
} else {
ASSERT(false);
}
} else if (field == CKB_CELL_FIELD_TYPE_HASH) {
return CKB_INDEX_OUT_OF_BOUND;
}
return 0;
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions xudt/tests/misc.rs → tests/xudt_rce_rust/tests/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ pub const PERSONALIZATION: &[u8] = b"ckb-default-hash";

lazy_static! {
pub static ref RCE_VALIDATOR_BIN: ckb_types::bytes::Bytes =
ckb_types::bytes::Bytes::from(include_bytes!("../../build/rce_validator").as_ref());
ckb_types::bytes::Bytes::from(include_bytes!("../../../build/rce_validator").as_ref());
pub static ref ALWAYS_SUCCESS_BIN: ckb_types::bytes::Bytes =
ckb_types::bytes::Bytes::from(include_bytes!("../../build/always_success").as_ref());
ckb_types::bytes::Bytes::from(include_bytes!("../../../build/always_success").as_ref());
pub static ref SMT_EXISTING: H256 = H256::from([
1, 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
Expand Down
Loading