Skip to content

Commit

Permalink
Merge pull request #18 from WeBankBlockchain/dev
Browse files Browse the repository at this point in the history
merge release 1.0.0-rc3
  • Loading branch information
bxq2011hust authored Apr 1, 2022
2 parents a28e44c + 2be9ce3 commit 576ca79
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 45 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Cargo-liquid Github Actions
on:
on:
push:
pull_request:
release:
Expand All @@ -19,15 +19,16 @@ jobs:
- name: install rust nightly
uses: actions-rs/toolchain@v1
with:
components: rustc-dev, rust-src
toolchain: nightly-2021-06-23
components: rustc-dev, rust-src, llvm-tools-preview
- name: install cargo-liquid
run: cargo install --path . --force
- name: compile test contract
run: cd .\tests\conflict_analysis_test\contract && cargo liquid build
- name: setup python
uses: actions/setup-python@v2
with:
python-version: '3.x'
python-version: '3.8'
architecture: 'x64'
- name: verify conflict analysis result
run: cd .\tests\conflict_analysis_test && python .\verify_conflict.py
1 change: 0 additions & 1 deletion rust-toolchain

This file was deleted.

3 changes: 3 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[toolchain]
channel = "nightly-2021-06-23"
components = [ "rust-src", "rustc-dev", "llvm-tools-preview" ]
16 changes: 8 additions & 8 deletions src/analyzer/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,18 +130,18 @@ impl AnalysisCallbacks {
/// The index of which state variable will be visited.
slot: usize,
kind: field_kind::Type,
/// If `kind` equals to `All` or `Len`, then `path` must be empty;
/// If `kind` equals to `All` or `Len`, then `value` must be empty;
///
/// if `kind` equals to `Env`, then `path` must only contain one element, and the element
/// if `kind` equals to `Env`, then `value` must only contain one element, and the element
/// represents which kind of context information the contract needs to acquire.
///
/// if `kind` equals to `Var`, then `path` contains an access path described via integer
/// if `kind` equals to `Var`, then `value` contains an access path described via integer
/// indices, e.g., "[2, 0]" means key coming from the **1st** data member of the **3rd**
/// parameter;
///
/// if `kind` equals to `Const`, the `path` contains the **raw** bytes representation of
/// if `kind` equals to `Const`, the `value` contains the **raw** bytes representation of
/// the corresponding constant value.
path: Vec<usize>,
value: Vec<usize>,
/// Whether this conflict field is used to visit some a state variable mutably.
read_only: bool,
}
Expand Down Expand Up @@ -244,7 +244,7 @@ impl AnalysisCallbacks {
FieldDesc {
slot: *container,
kind,
path,
value: path,
read_only: *read_only,
}
} else {
Expand Down Expand Up @@ -289,14 +289,14 @@ impl AnalysisCallbacks {
let field_i = &conflict_fields[i];
let field_j = &conflict_fields[j];
if field_i.kind == field_j.kind
&& field_i.path == field_j.path
&& field_i.value == field_j.value
&& field_i.slot == field_j.slot
&& !field_i.read_only
&& field_j.read_only
{
add_to_composed(FieldDesc {
kind: field_i.kind,
path: field_i.path.clone(),
value: field_i.value.clone(),
slot: field_i.slot,
read_only: false,
});
Expand Down
59 changes: 41 additions & 18 deletions src/main/cmd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ fn parse_ty(ty_info: &Map<String, Value>) -> String {
}
}

fn calc_selector(source: &[u8], use_gm: bool) -> String {
fn calc_selector(source: &[u8], use_gm: bool) -> u32 {
let hash_result = if !use_gm {
let mut hash_result = [0u8; 32];
let mut keccak_hasher = tiny_keccak::Keccak::v256();
Expand All @@ -366,14 +366,12 @@ fn calc_selector(source: &[u8], use_gm: bool) -> String {
sm3_hash.get_hash()
};

let selector = u32::from_le_bytes([
u32::from_le_bytes([
hash_result[0],
hash_result[1],
hash_result[2],
hash_result[3],
]) as i32;

format!("i32.const {}", selector)
])
}

fn generate_abi(
Expand Down Expand Up @@ -430,20 +428,19 @@ fn generate_abi(
let fn_info = f.as_object().unwrap();
let ty = fn_info.get("type").unwrap().as_str().unwrap();
if ty == "function" {
let fn_name =
fn_info.get("name").unwrap().as_str().unwrap().to_string();
let inputs = fn_info.get("inputs").unwrap().as_array().unwrap();
let sig = inputs
.iter()
.map(|input| parse_ty(input.as_object().unwrap()))
.join(",");
let sig = format!("{}({})", fn_name, sig);
let new_sel = calc_selector(sig.as_bytes(), use_gm);

let (fn_name, new_sel) = get_name_and_selector(fn_info, use_gm);
let new_sel = format!("i32.const {}", new_sel);
let old_sel = if is_iface {
calc_selector((scope.to_owned() + &fn_name).as_bytes(), use_gm)
format!(
"i32.const {}",
calc_selector((scope.to_owned() + &fn_name).as_bytes(), use_gm)
as i32
)
} else {
calc_selector(fn_name.as_bytes(), use_gm)
format!(
"i32.const {}",
calc_selector(fn_name.as_bytes(), use_gm) as i32
)
};

let entry = sel_replacements
Expand Down Expand Up @@ -530,6 +527,18 @@ fn generate_abi(
Ok(())
}

fn get_name_and_selector(fn_info: &Map<String, Value>, use_gm: bool) -> (String, u32) {
let fn_name = fn_info.get("name").unwrap().as_str().unwrap().to_string();
let inputs = fn_info.get("inputs").unwrap().as_array().unwrap();
let sig = inputs
.iter()
.map(|input| parse_ty(input.as_object().unwrap()))
.join(",");
let sig = format!("{}({})", fn_name, sig);
let new_sel = calc_selector(sig.as_bytes(), use_gm);
(fn_name, new_sel)
}

static LOOKING_GLASS: Emoji<'_, '_> = Emoji("🔍 ", "d(・ω・d)");
static TRUCK: Emoji<'_, '_> = Emoji("🚚 ", "(∫・ω・)∫");
static CLIP: Emoji<'_, '_> = Emoji("🔗 ", "∇(・ω・∇)");
Expand Down Expand Up @@ -578,11 +587,25 @@ pub(crate) fn execute_build(
&& method.contains_key("type")
&& method["type"] == Value::String("function".into())
{
let method_name = String::from(method["name"].as_str().unwrap());
// calculate selector of method
let (method_name, selector) = get_name_and_selector(method, use_gm);
if cfa_result.contains_key(&method_name) {
method
.insert("conflictFields".into(), cfa_result[&method_name].clone());
}
if use_gm {
let (_, normal_selector) = get_name_and_selector(method, false);
method.insert(
"selector".into(),
serde_json::to_value(vec![normal_selector, selector]).unwrap(),
);
} else {
let (_, gm_selector) = get_name_and_selector(method, true);
method.insert(
"selector".into(),
serde_json::to_value(vec![selector, gm_selector]).unwrap(),
);
}
}
});
let new_abi = serde_json::to_string(&origin_abi).unwrap();
Expand Down
2 changes: 2 additions & 0 deletions template/collaboration/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly-2021-06-23"
2 changes: 2 additions & 0 deletions template/contract/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly-2021-06-23"
30 changes: 15 additions & 15 deletions tests/conflict_analysis_test/verify_conflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@

# Ground true of test cases
ground_true_dict = {
"visit_val_container": [{'kind': 0, 'path': [], 'read_only': False, 'slot': 0}],
"change_complex_data_structure": [{'kind': 1, 'path': [], 'read_only': False, 'slot': 7}],
"test_env_caller": [{'kind': 2, 'path': [0], 'read_only': True, 'slot': 1}],
"test_env_tx_origin": [{'kind': 2, 'path': [1], 'read_only': True, 'slot': 1}],
"test_env_now": [{'kind': 2, 'path': [2], 'read_only': True, 'slot': 2}],
"test_env_block_number": [{'kind': 2, 'path': [3], 'read_only': True, 'slot': 3}],
"test_env_address": [{'kind': 2, 'path': [4], 'read_only': True, 'slot': 1}],
"test_method_parameter": [{'kind': 3, 'path': [0, 0], 'read_only': True, 'slot': 3}],
"test_constant_positive": [{'kind': 4, 'path': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'read_only': True, 'slot': 4}],
"test_constant_zero": [{'kind': 4, 'path': [0], 'read_only': True, 'slot': 5}],
"test_constant_negative": [{'kind': 4, 'path': [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], 'read_only': True, 'slot': 6}],
"test_interprocedural_calling": [{'kind': 3, 'path': [0, 0], 'read_only': True, 'slot': 3}],
"test_branch_statement": [{'kind': 2, 'path': [0], 'read_only': True, 'slot': 1}, {'kind': 2, 'path': [1], 'read_only': True, 'slot': 1}]
"visit_val_container": [{'kind': 0, 'value': [], 'read_only': False, 'slot': 0}],
"change_complex_data_structure": [{'kind': 1, 'value': [], 'read_only': False, 'slot': 7}],
"test_env_caller": [{'kind': 2, 'value': [0], 'read_only': True, 'slot': 1}],
"test_env_tx_origin": [{'kind': 2, 'value': [1], 'read_only': True, 'slot': 1}],
"test_env_now": [{'kind': 2, 'value': [2], 'read_only': True, 'slot': 2}],
"test_env_block_number": [{'kind': 2, 'value': [3], 'read_only': True, 'slot': 3}],
"test_env_address": [{'kind': 2, 'value': [4], 'read_only': True, 'slot': 1}],
"test_method_parameter": [{'kind': 3, 'value': [0, 0], 'read_only': True, 'slot': 3}],
"test_constant_positive": [{'kind': 4, 'value': [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'read_only': True, 'slot': 4}],
"test_constant_zero": [{'kind': 4, 'value': [0], 'read_only': True, 'slot': 5}],
"test_constant_negative": [{'kind': 4, 'value': [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], 'read_only': True, 'slot': 6}],
"test_interprocedural_calling": [{'kind': 3, 'value': [0, 0], 'read_only': True, 'slot': 3}],
"test_branch_statement": [{'kind': 2, 'value': [0], 'read_only': True, 'slot': 1}, {'kind': 2, 'value': [1], 'read_only': True, 'slot': 1}]
}

# Compare two conflict domain results
Expand Down Expand Up @@ -62,11 +62,11 @@ def cmp(test_case_data, ground_true_data):
# Ignore the constructor
if "name" not in func.keys():
continue

# Ignore functions outside the scope of the test
if func["name"] not in ground_true_dict.keys():
continue

# Record processed test cases
temp_index = list(ground_true_dict.keys()).index(func["name"])
triggered_test_cases_record[temp_index] = 1
Expand Down

0 comments on commit 576ca79

Please sign in to comment.