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

fix: try to resolve xudt compatibility issue #5

Merged
merged 2 commits into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions contracts/commitment-lock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This is a simple commitment lock script for ckb fiber network.

The lock script args is the hash result of blake160(local_delay_epoch || local_delay_pubkey_hash || revocation_pubkey_hash || N * pending_htlc), to unlock this lock, the transaction must provide following fields in the witness:

- `empty_witness_args`: 16 bytes, fixed to 0x10000000100000001000000010000000, for compatibility with the xudt
- `local_delay_epoch`: 8 bytes, u64 in little endian, must be a relative EpochNumberWithFraction
- `local_delay_pubkey_hash`: 20 bytes, hash result of blake160(local_delay_pubkey)
- `revocation_pubkey_hash`: 20 bytes, hash result of blake160(revocation_pubkey)
Expand Down
12 changes: 11 additions & 1 deletion contracts/commitment-lock/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub enum Error {
InvalidHtlcType,
ArgsLenError,
WitnessLenError,
EmptyWitnessArgsError,
WitnessHashError,
OutputCapacityError,
OutputLockError,
Expand Down Expand Up @@ -68,6 +69,8 @@ pub fn program_entry() -> i8 {
}
}

// a placeholder for empty witness args, to resolve the issue of xudt compatibility
const EMPTY_WITNESS_ARGS: [u8; 16] = [16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0];
// min witness script length: 8 (local_delay_epoch) + 20 (local_delay_pubkey_hash) + 20 (revocation_pubkey_hash) = 48
const MIN_WITNESS_SCRIPT_LEN: usize = 48;
// HTLC script length: 1 (htlc_type) + 16 (payment_amount) + 20 (payment_hash) + 20 (remote_htlc_pubkey_hash) + 20 (local_htlc_pubkey_hash) + 8 (htlc_expiry) = 85
Expand Down Expand Up @@ -120,7 +123,14 @@ fn auth() -> Result<(), Error> {
if args.len() != 20 {
return Err(Error::ArgsLenError);
}
let witness = load_witness(0, Source::GroupInput)?;
let mut witness = load_witness(0, Source::GroupInput)?;
if witness
.drain(0..EMPTY_WITNESS_ARGS.len())
.collect::<Vec<_>>()
!= EMPTY_WITNESS_ARGS
{
return Err(Error::EmptyWitnessArgsError);
}
let witness_len = witness.len();
if witness_len < MIN_WITNESS_LEN {
return Err(Error::WitnessLenError);
Expand Down
1 change: 1 addition & 0 deletions contracts/funding-lock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This is a simple funding lock script for ckb fiber network. It utilizes the [ckb

The lock script args is a blake160 hash of the aggregated public key of the two parties, to unlock this lock, the transaction must provide following fields in the witness:

- `empty_witness_args`: 16 bytes, fixed to 0x10000000100000001000000010000000, for compatibility with the xudt
- `version`: 8 bytes, u64 in little-endian
- `funding_out_point`: 36 bytes, out point of the funding transaction
- `pubkey`: 32 bytes, x only aggregated public key
Expand Down
15 changes: 13 additions & 2 deletions contracts/funding-lock/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ckb_std::entry!(program_entry);
#[cfg(not(test))]
default_alloc!();

use alloc::ffi::CString;
use alloc::{ffi::CString, vec::Vec};
use ckb_std::{
ckb_constants::Source,
ckb_types::{bytes::Bytes, core::ScriptHashType, prelude::*},
Expand All @@ -34,6 +34,7 @@ pub enum Error {
// Add customized errors here...
MultipleInputs,
WitnessLenError,
EmptyWitnessArgsError,
FundingOutPointError,
AuthError,
}
Expand All @@ -57,12 +58,22 @@ pub fn program_entry() -> i8 {
}
}

// a placeholder for empty witness args, to resolve the issue of xudt compatibility
const EMPTY_WITNESS_ARGS: [u8; 16] = [16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0];

fn auth() -> Result<(), Error> {
// funding lock will be unlocked by the commitment transaction, it should only have one input
if load_input_since(1, Source::GroupInput).is_ok() {
return Err(Error::MultipleInputs);
}
let witness = load_witness(0, Source::GroupInput)?;
let mut witness = load_witness(0, Source::GroupInput)?;
if witness
.drain(0..EMPTY_WITNESS_ARGS.len())
.collect::<Vec<_>>()
!= EMPTY_WITNESS_ARGS
{
return Err(Error::EmptyWitnessArgsError);
}
if witness.len() != 8 + 36 + 32 + 64 {
return Err(Error::WitnessLenError);
}
Expand Down
106 changes: 93 additions & 13 deletions tests/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use secp256k1::{
};

const MAX_CYCLES: u64 = 10_000_000;

const BYTE_SHANNONS: u64 = 100_000_000;
const EMPTY_WITNESS_ARGS: [u8; 16] = [16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0];

#[test]
fn test_funding_lock() {
Expand Down Expand Up @@ -152,6 +152,7 @@ fn test_funding_lock() {
println!("signature: {:?}", aggregated_signature_1.to_bytes());

let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
version.to_vec(),
funding_out_point.to_vec(),
x_only_pub_key.to_vec(),
Expand Down Expand Up @@ -250,7 +251,13 @@ fn test_commitment_lock_no_pending_htlcs() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0xFF], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0xFF],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -284,7 +291,13 @@ fn test_commitment_lock_no_pending_htlcs() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script, vec![0xFF], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script,
vec![0xFF],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -400,7 +413,13 @@ fn test_commitment_lock_with_two_pending_htlcs() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0xFF], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0xFF],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -434,7 +453,13 @@ fn test_commitment_lock_with_two_pending_htlcs() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0xFF], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0xFF],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -488,6 +513,7 @@ fn test_commitment_lock_with_two_pending_htlcs() {
.unwrap()
.serialize();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x00],
signature.clone(),
Expand All @@ -503,6 +529,7 @@ fn test_commitment_lock_with_two_pending_htlcs() {

// sign with remote_htlc_pubkey and wrong preimage should fail
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x00],
signature.clone(),
Expand All @@ -519,7 +546,13 @@ fn test_commitment_lock_with_two_pending_htlcs() {
println!("error: {}", error);

// sign with remote_htlc_pubkey and empty preimage should fail
let witness = [witness_script.clone(), vec![0x00], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x00],
signature,
]
.concat();

let fail_tx = tx.as_advanced_builder().witness(witness.pack()).build();

Expand Down Expand Up @@ -556,7 +589,13 @@ fn test_commitment_lock_with_two_pending_htlcs() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0x00], signature.clone()].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x00],
signature.clone(),
]
.concat();

let success_tx = tx.as_advanced_builder().witness(witness.pack()).build();
let cycles = context
Expand Down Expand Up @@ -586,7 +625,13 @@ fn test_commitment_lock_with_two_pending_htlcs() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0x00], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x00],
signature,
]
.concat();

let fail_tx = tx.as_advanced_builder().witness(witness.pack()).build();
let error = context
Expand Down Expand Up @@ -637,7 +682,13 @@ fn test_commitment_lock_with_two_pending_htlcs() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0x01], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x01],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -673,6 +724,7 @@ fn test_commitment_lock_with_two_pending_htlcs() {
.unwrap()
.serialize();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x01],
signature.clone(),
Expand All @@ -688,6 +740,7 @@ fn test_commitment_lock_with_two_pending_htlcs() {

// sign with local_htlc_pubkey and wrong preimage should fail
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x01],
signature.clone(),
Expand All @@ -702,7 +755,13 @@ fn test_commitment_lock_with_two_pending_htlcs() {
println!("error: {}", error);

// sign with local_htlc_pubkey and empty preimage should fail
let witness = [witness_script.clone(), vec![0x01], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x01],
signature,
]
.concat();

let fail_tx = tx.as_advanced_builder().witness(witness.pack()).build();
let error = context
Expand Down Expand Up @@ -828,7 +887,13 @@ fn test_commitment_lock_with_two_pending_htlcs_and_sudt() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0xFF], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0xFF],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -862,7 +927,13 @@ fn test_commitment_lock_with_two_pending_htlcs_and_sudt() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0xFF], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0xFF],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -920,6 +991,7 @@ fn test_commitment_lock_with_two_pending_htlcs_and_sudt() {
.unwrap()
.serialize();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x00],
signature,
Expand Down Expand Up @@ -965,6 +1037,7 @@ fn test_commitment_lock_with_two_pending_htlcs_and_sudt() {
.unwrap()
.serialize();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x00],
signature,
Expand Down Expand Up @@ -1028,7 +1101,13 @@ fn test_commitment_lock_with_two_pending_htlcs_and_sudt() {
.sign_recoverable(&message.into())
.unwrap()
.serialize();
let witness = [witness_script.clone(), vec![0x01], signature].concat();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x01],
signature,
]
.concat();

let tx = tx.as_advanced_builder().witness(witness.pack()).build();
println!("tx: {:?}", tx);
Expand Down Expand Up @@ -1065,6 +1144,7 @@ fn test_commitment_lock_with_two_pending_htlcs_and_sudt() {
.unwrap()
.serialize();
let witness = [
EMPTY_WITNESS_ARGS.to_vec(),
witness_script.clone(),
vec![0x01],
signature,
Expand Down
Loading