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

BREAKING CHANGE: change ckb decimal to 18 #675

Merged
merged 19 commits into from
May 7, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
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
9 changes: 6 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ jobs:
- name: Test TOML serialization
run: cargo run --bin godwoken -- generate-example-config -o test.toml

# FIXME: change to nervosnetwork/godwoken-tests after merge pr 675
integration-test:
uses: nervosnetwork/godwoken-tests/.github/workflows/reusable-integration-test-v1.yml@develop
uses: zeroqn/godwoken-tests/.github/workflows/reusable-integration-test-v1.yml@13e3482b6c00dc29891db8e624769762d19968b3
with:
# github.ref: The branch or tag ref that triggered the workflow run. For branches this is the format refs/heads/<branch_name>, and for tags it is refs/tags/<tag_name>.
godwoken_ref: ${{ github.ref }}
kicker_ref: refs/pull/235/head # https://github.com/RetricSu/godwoken-kicker/pull/235
tests_ref: develop # https://github.com/nervosnetwork/godwoken-tests/commits/develop
gw_prebuild_image_name: ghcr.io/zeroqn/godwoken-prebuilds
gw_prebuild_image_tag: v1.1-feat-change-ckb-decimal-to-18 # For godwoken-scripts and godwoken-polyjuice binaries
kicker_ref: refs/pull/239/head # https://github.com/RetricSu/godwoken-kicker/pull/239
tests_ref: refs/pull/105/head # https://github.com/nervosnetwork/godwoken-tests/pull/105
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ In the new version, we improve the compatibility of Godwoken:
- Support Ethereum signature format and EIP-712. User can view the transaction before signing, instead of signing a random 32 bytes message. [#561](https://github.com/nervosnetwork/godwoken/pull/561)
- Fix the total supply interface of sUDT ERC-20 proxy contract [#560](https://github.com/nervosnetwork/godwoken/pull/560)
- Support interactive with eth address that haven't been registered to Godwoken.
- Unify layer 2 fungible token represatation as uint256.
- Change layer 2 ckb decimal from 8 to 18, improve compatibility between metamask and native ckb. [#675](https://github.com/nervosnetwork/godwoken/pull/675)

In short, as a developer, you can use Godwoken v1 just like anyother Ethereum compatible chain, all you need to do is to switch the network to Godwoken. The polyjuice-provider web3 plugin is removed in the v1 version.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In short, developers can use Godwoken v1 the same way as other ethereum compatible chains, all that has to be done is to switch the network to Godwoken. The polyjuice-provider web3 plugin has been removed in v1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes


Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions crates/benches/benches/benchmarks/fee_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn bench_add_full(b: &mut Bencher) {
.raw(RawL2Transaction::new_builder().nonce(i.pack()).build())
.build(),
),
fee: 100 * 1000,
fee: (100 * 1000u64).into(),
cycles_limit: 1000,
sender: 2,
order: queue.len(),
Expand All @@ -66,7 +66,7 @@ fn bench_add_full(b: &mut Bencher) {
)
.build(),
),
fee: 100 * 1000,
fee: (100 * 1000u64).into(),
cycles_limit: 1000,
sender: 2,
order: queue.len(),
Expand Down Expand Up @@ -102,7 +102,7 @@ fn bench_add_fetch_20(b: &mut Bencher) {
.raw(RawL2Transaction::new_builder().nonce(i.pack()).build())
.build(),
),
fee: 100 * 1000,
fee: (100 * 1000u64).into(),
cycles_limit: 1000,
sender: 2,
order: queue.len(),
Expand All @@ -125,7 +125,7 @@ fn bench_add_fetch_20(b: &mut Bencher) {
)
.build(),
),
fee: 100 * 1000,
fee: (100 * 1000u64).into(),
cycles_limit: 1000,
sender: 2,
order: queue.len(),
Expand Down
7 changes: 4 additions & 3 deletions crates/benches/benches/benchmarks/smt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use gw_types::{
SubmitTransactions,
},
prelude::*,
U256,
};
use pprof::criterion::{Output, PProfProfiler};

Expand Down Expand Up @@ -224,11 +225,11 @@ impl BenchExecutionEnvironment {
.set(
SUDTTransfer::new_builder()
.to_address(Bytes::from(to_address.to_bytes()).pack())
.amount(1.pack())
.amount(U256::one().pack())
.fee(
Fee::new_builder()
.registry_id(ETH_REGISTRY_ACCOUNT_ID.pack())
.amount(1.pack())
.amount(1u128.pack())
.build(),
)
.build(),
Expand Down Expand Up @@ -287,7 +288,7 @@ impl BenchExecutionEnvironment {
.mapping_registry_address_to_script_hash(addr.clone(), account_script_hash)
.unwrap();
state
.mint_sudt(CKB_SUDT_ACCOUNT_ID, &addr, CKB_BALANCE)
.mint_sudt(CKB_SUDT_ACCOUNT_ID, &addr, CKB_BALANCE.into())
.unwrap();

Account { id: account_id }
Expand Down
9 changes: 5 additions & 4 deletions crates/benches/benches/benchmarks/sudt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use gw_types::{
packed::{AllowedTypeHash, BlockInfo, Fee},
packed::{RawL2Transaction, RollupConfig, SUDTArgs, SUDTTransfer, Script},
prelude::*,
U256,
};

const DUMMY_SUDT_VALIDATOR_SCRIPT_TYPE_HASH: [u8; 32] = [3u8; 32];
Expand Down Expand Up @@ -133,7 +134,7 @@ pub fn bench(c: &mut Criterion) {
)
.build();

let init_a_balance: u128 = 10000;
let init_a_balance = U256::from(10000u128);

// init accounts
let _meta = tree
Expand Down Expand Up @@ -184,7 +185,7 @@ pub fn bench(c: &mut Criterion) {
let b_script_hash = tree.get_script_hash(b_id).expect("get script hash");
tree.mapping_registry_address_to_script_hash(a_addr.clone(), a_script_hash)
.unwrap();
tree.mapping_registry_address_to_script_hash(b_addr.clone(), b_script_hash)
tree.mapping_registry_address_to_script_hash(b_addr, b_script_hash)
.unwrap();

let block_producer_script = {
Expand Down Expand Up @@ -219,8 +220,8 @@ pub fn bench(c: &mut Criterion) {
},
|(mut tree, rollup_config, sudt_id, a_id, b_script_hash, block_info)| {
// transfer from A to B
let value = 4000u128;
let fee = 42u64;
let value: U256 = 4000u128.into();
let fee = 42u128;
let b_addr = tree
.get_registry_address_by_script_hash(ETH_REGISTRY_ACCOUNT_ID, &b_script_hash)
.expect("get script hash")
Expand Down
2 changes: 1 addition & 1 deletion crates/block-producer/src/withdrawal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ mod test {
.build();

let withdrawal = {
let fee = 50u64;
let fee = 50u128;
let raw = RawWithdrawalRequest::new_builder()
.nonce(1u32.pack())
.capacity((500 * 10u64.pow(8)).pack())
Expand Down
1 change: 0 additions & 1 deletion crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ sparse-merkle-tree = { version = "0.5.2-rc1", default-features = false }
merkle-cbt = { version = "0.3.0", default-features = false }
gw-hash = { path = "../hash" }
thiserror = { version = "1.0", optional = true }
primitive-types = { version = "0.10", default-features = false }
gw-types = { path = "../types", default-features = false }

[features]
Expand Down
14 changes: 14 additions & 0 deletions crates/common/src/ckb_decimal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use gw_types::U256;

// NOTE: u64::MAX is about 10^18, U256::MAX is about 10^77. Multiple 10 pow
// `CKB_DECIMAL_POW_EXP` should not overflow.
pub const CKB_DECIMAL_POW_EXP: u32 = 10;
pub const CKB_DECIMAL_POWER_TEN: u64 = 10u64.pow(CKB_DECIMAL_POW_EXP);

pub fn to_18(amount: u64) -> U256 {
magicalne marked this conversation as resolved.
Show resolved Hide resolved
U256::from(amount) * CKB_DECIMAL_POWER_TEN
}

pub fn from_18(amount: U256) -> U256 {
zeroqn marked this conversation as resolved.
Show resolved Hide resolved
amount / CKB_DECIMAL_POWER_TEN
}
2 changes: 1 addition & 1 deletion crates/common/src/h256_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// type aliases

pub use primitive_types::U256;
use gw_types::U256;
pub use sparse_merkle_tree::H256;

pub trait H256Ext {
Expand Down
3 changes: 2 additions & 1 deletion crates/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub mod builtins;
pub mod ckb_decimal;
pub mod error;
pub mod h256_ext;
pub mod merkle_utils;
Expand All @@ -14,7 +15,7 @@ pub mod test_traits;
// re-exports

pub use gw_hash::blake2b;
pub use h256_ext::{H256, U256};
pub use h256_ext::H256;
pub use sparse_merkle_tree;

/// constants
Expand Down
28 changes: 15 additions & 13 deletions crates/common/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
//
// Thus, the first 5 bytes keeps uniqueness for different type of keys.

use gw_types::U256;

use crate::builtins::ETH_REGISTRY_ACCOUNT_ID;
use crate::error::Error;
use crate::h256_ext::{H256Ext, H256, U256};
use crate::h256_ext::{H256Ext, H256};
use crate::registry_address::RegistryAddress;
use crate::vec::Vec;
use crate::{blake2b::new_blake2b, merkle_utils::calculate_state_checkpoint};
Expand Down Expand Up @@ -200,16 +202,16 @@ pub trait State {
Ok(Some(id))
}

fn get_sudt_balance(&self, sudt_id: u32, address: &RegistryAddress) -> Result<u128, Error> {
fn get_sudt_balance(&self, sudt_id: u32, address: &RegistryAddress) -> Result<U256, Error> {
// get balance
let sudt_key = build_sudt_key(SUDT_KEY_FLAG_BALANCE, address);
let balance = self.get_value(sudt_id, &sudt_key)?;
Ok(balance.to_u128())
Ok(balance.to_u256())
}

fn get_sudt_total_supply(&self, sudt_id: u32) -> Result<U256, Error> {
let total_supoly = self.get_value(sudt_id, &SUDT_TOTAL_SUPPLY_KEY)?;
Ok(total_supoly.to_u256())
let total_supply = self.get_value(sudt_id, &SUDT_TOTAL_SUPPLY_KEY)?;
Ok(total_supply.to_u256())
}

fn store_data_hash(&mut self, data_hash: H256) -> Result<(), Error> {
Expand All @@ -229,20 +231,20 @@ pub trait State {
&mut self,
sudt_id: u32,
address: &RegistryAddress,
amount: u128,
amount: U256,
) -> Result<(), Error> {
let sudt_key = build_sudt_key(SUDT_KEY_FLAG_BALANCE, address);
let raw_key = build_account_key(sudt_id, &sudt_key);
// calculate balance
let mut balance = self.get_raw(&raw_key)?.to_u128();
let mut balance = self.get_raw(&raw_key)?.to_u256();
balance = balance.checked_add(amount).ok_or(Error::AmountOverflow)?;
self.update_raw(raw_key, H256::from_u128(balance))?;
self.update_raw(raw_key, H256::from_u256(balance))?;

// update total supply
let raw_key = build_account_key(sudt_id, &SUDT_TOTAL_SUPPLY_KEY);
let mut total_supply = self.get_raw(&raw_key)?.to_u256();
total_supply = total_supply
.checked_add(U256::from(amount))
.checked_add(amount)
.ok_or(Error::AmountOverflow)?;
self.update_raw(raw_key, H256::from_u256(total_supply))?;

Expand All @@ -254,20 +256,20 @@ pub trait State {
&mut self,
sudt_id: u32,
address: &RegistryAddress,
amount: u128,
amount: U256,
) -> Result<(), Error> {
let sudt_key = build_sudt_key(SUDT_KEY_FLAG_BALANCE, address);
let raw_key = build_account_key(sudt_id, &sudt_key);
// calculate balance
let mut balance = self.get_raw(&raw_key)?.to_u128();
let mut balance = self.get_raw(&raw_key)?.to_u256();
balance = balance.checked_sub(amount).ok_or(Error::AmountOverflow)?;
self.update_raw(raw_key, H256::from_u128(balance))?;
self.update_raw(raw_key, H256::from_u256(balance))?;

// update total supply
let raw_key = build_account_key(sudt_id, &SUDT_TOTAL_SUPPLY_KEY);
let mut total_supply = self.get_raw(&raw_key)?.to_u256();
total_supply = total_supply
.checked_sub(U256::from(amount))
.checked_sub(amount)
.ok_or(Error::AmountOverflow)?;
self.update_raw(raw_key, H256::from_u256(total_supply))?;

Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/test_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub trait StateTest: State {
self.update_value(address.registry_id, &key, value.into())?;
// address -> script
let key = build_registry_address_to_script_hash_key(&address);
self.update_value(address.registry_id, &key, script_hash.into())?;
self.update_value(address.registry_id, &key, script_hash)?;
Ok(())
}
}
9 changes: 5 additions & 4 deletions crates/generator/src/account_lock_manage/eip712/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ pub struct Withdrawal {
nonce: u32,
chain_id: u64,
// withdrawal fee, paid to block producer
fee: u64,
fee: u128,
// layer1 lock to withdraw after challenge period
layer1_owner_lock: Script,
// CKB amount
Expand All @@ -217,6 +217,7 @@ impl EIP712Encode for Withdrawal {

fn encode_data(&self, buf: &mut Vec<u8>) {
use ethabi::Token;

buf.extend(ethabi::encode(&[Token::Uint(
self.address.hash_struct().into(),
)]));
Expand Down Expand Up @@ -482,7 +483,7 @@ mod tests {
},
nonce: 1,
chain_id: 1,
fee: 1000,
fee: 1000u64.into(),
layer1_owner_lock: Script {
code_hash: hex::decode(
"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
Expand Down Expand Up @@ -514,12 +515,12 @@ mod tests {
salt: None,
};
let message = withdrawal.eip712_message(domain_seperator.hash_struct());
let signature: [u8; 65] = hex::decode("edcae58907b6e218b1bc4513afeefb30aad433bcd4a9c937fa53a24bb9abc12a6bc4bfa29ef3f1ee0e58464b1f97ad6bcebd434dbbc2c29539b02539843675681b").unwrap().try_into().unwrap();
let signature: [u8; 65] = hex::decode("22cae59f1bfaf58f423d1a414cbcaefd45a89dd54c9142fccbb2473c74f4741b45f77f1f3680b8c0b6362957c8d79f96a683a859ccbf22a6cfc1ebc311b936d301").unwrap().try_into().unwrap();
let pubkey_hash = Secp256k1Eth::default()
.recover(message.into(), &signature)
.unwrap();
assert_eq!(
"e8ae579256c3b84efb76bbb69cb6bcbef1375f00".to_string(),
"cc3e7fb0176a0e22a7f675306ceeb61d26eb0dc4".to_string(),
hex::encode(pubkey_hash)
);
}
Expand Down
19 changes: 13 additions & 6 deletions crates/generator/src/dummy_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ mod tests {
use gw_types::{
packed::Script,
prelude::{Builder, Entity, Pack},
U256,
};

use crate::{traits::StateExt, Error};
Expand Down Expand Up @@ -171,20 +172,26 @@ mod tests {
// mint sudt
let user_a = RegistryAddress::new(0, vec![1u8; 20]);
let user_b = RegistryAddress::new(0, vec![2u8; 20]);
tree.mint_sudt(sudt_id, &user_a, 100).unwrap();
tree.mint_sudt(sudt_id, &user_a, U256::from(100u64))
.unwrap();
assert_eq!(tree.get_sudt_total_supply(sudt_id).unwrap(), 100.into());
tree.mint_sudt(sudt_id, &user_a, 230).unwrap();
tree.mint_sudt(sudt_id, &user_a, U256::from(230u64))
.unwrap();
assert_eq!(tree.get_sudt_total_supply(sudt_id).unwrap(), 330.into());
tree.mint_sudt(sudt_id, &user_b, 155).unwrap();
tree.mint_sudt(sudt_id, &user_b, U256::from(155u64))
.unwrap();
assert_eq!(tree.get_sudt_total_supply(sudt_id).unwrap(), 485.into());
// burn sudt
tree.burn_sudt(sudt_id, &user_a, 85).unwrap();
tree.burn_sudt(sudt_id, &user_a, U256::from(85u64)).unwrap();
assert_eq!(tree.get_sudt_total_supply(sudt_id).unwrap(), 400.into());
// overdraft
let err = tree.burn_sudt(sudt_id, &user_b, 200).unwrap_err();
let err = tree
.burn_sudt(sudt_id, &user_b, U256::from(200u64))
.unwrap_err();
assert_eq!(err, gw_common::error::Error::AmountOverflow);
assert_eq!(tree.get_sudt_total_supply(sudt_id).unwrap(), 400.into());
tree.burn_sudt(sudt_id, &user_b, 100).unwrap();
tree.burn_sudt(sudt_id, &user_b, U256::from(100u64))
.unwrap();
assert_eq!(tree.get_sudt_total_supply(sudt_id).unwrap(), 300.into());
}

Expand Down
3 changes: 2 additions & 1 deletion crates/generator/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ pub(crate) struct L2Syscalls<'a, S, C> {
pub(crate) result: &'a mut RunResult,
}

#[allow(dead_code)]
fn load_data_u128<Mac: SupportMachine>(machine: &mut Mac, addr: u64) -> Result<u128, VMError> {
let mut data = [0u8; 16];
for (i, c) in data.iter_mut().enumerate() {
Expand Down Expand Up @@ -472,7 +473,7 @@ impl<'a, S: State, C: ChainView, Mac: SupportMachine> Syscalls<Mac> for L2Syscal
let sudt_id = machine.registers()[A2].to_u8();
let amount = {
let amount_addr = machine.registers()[A3].to_u64();
load_data_u128(machine, amount_addr)?
load_data_h256(machine, amount_addr)?.to_u256()
};

// TODO record fee payment in the generator context
Expand Down
Loading