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

feat: multisig lock move since to script args #60

Merged
merged 5 commits into from
Oct 30, 2019
Merged
Show file tree
Hide file tree
Changes from 3 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
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.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ckb-system-scripts"
version = "0.4.0-alpha.13+nonstrict-witnesses-length2"
version = "0.4.0-alpha.16+multisig-with-since2"
authors = ["Nervos Core Dev <[email protected]>"]
edition = "2018"
build = "build.rs"
Expand Down
2 changes: 1 addition & 1 deletion build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const BINARIES: &[(&str, &str)] = &[
),
(
"secp256k1_blake160_multisig_all",
"2a450c65ed903e7064a53f95a660bce48a9c94ca64f395c82d5e86884ee25195",
"109805c7dc63086bdbbd81efb1c95a5ba2c81baf91a5f3e2564c7c23c5e77264",
),
];

Expand Down
23 changes: 16 additions & 7 deletions c/secp256k1_blake160_multisig_all.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "secp256k1_helper.h"

/* script args errors */
#define ERROR_INVALID_RESERVE_FIELD -41
#define ERROR_INVALID_PUBKEYS_CNT -42
#define ERROR_INVALID_THRESHOLD -43
#define ERROR_INVALID_REQUIRE_FIRST_N -44
Expand All @@ -22,24 +23,24 @@
#define MAX_WITNESS_SIZE 32768
#define MAX_SCRIPT_SIZE 32768
#define SIGNATURE_SIZE 65
#define FLAGS_SIZE 12
#define FLAGS_SIZE 4

/*
* Arguments:
* multisig script blake160 hash, 20 bytes.
* 1. multisig script blake160 hash, 20 bytes.
* 2. an optional since constraint, 4 bytes.
*
* Witness:
* multisig_script | Signature1 | signature2 | ...
* multisig_script: S | R | M | N | since | Pubkey1 | Pubkey2 | ...
* multisig_script: S | R | M | N | Pubkey1 | Pubkey2 | ...
*
* +------------+----------------------------------+-------+
* | | Description | Bytes |
* +------------+----------------------------------+-------+
* | S | reserved for future use | 1 |
* | S | reserved field, must be zero | 1 |
* | R | first nth public keys must match | 1 |
* | M | threshold | 1 |
* | N | total public keys | 1 |
* | since | tx since verify | 8 |
* | PubkeyN | compressed pubkey | 33 |
* | SignatureN | recoverable signature | 65 |
* +------------+----------------------------------+-------+
Expand Down Expand Up @@ -68,9 +69,14 @@ int main() {

mol_seg_t args_seg = MolReader_Script_get_args(&script_seg);
mol_seg_t args_bytes_seg = MolReader_Bytes_raw_bytes(&args_seg);
if (args_bytes_seg.size != BLAKE160_SIZE) {
if (args_bytes_seg.size != BLAKE160_SIZE &&
args_bytes_seg.size != BLAKE160_SIZE + sizeof(uint64_t)) {
return ERROR_ARGUMENTS_LEN;
}
uint64_t since = 0;
if (args_bytes_seg.size == BLAKE160_SIZE + sizeof(uint64_t)) {
since = *(uint64_t *)&args_bytes_seg.ptr[BLAKE160_SIZE];
}

/* Load witness of first input */
unsigned char witness[MAX_WITNESS_SIZE];
Expand All @@ -97,7 +103,10 @@ int main() {
uint8_t pubkeys_cnt = lock_bytes[3];
uint8_t threshold = lock_bytes[2];
uint8_t require_first_n = lock_bytes[1];
uint64_t since = *(uint64_t *)&lock_bytes[4];
uint8_t reserved_field = lock_bytes[0];
if (reserved_field != 0) {
return ERROR_INVALID_RESERVE_FIELD;
}
if (pubkeys_cnt == 0) {
return ERROR_INVALID_PUBKEYS_CNT;
}
Expand Down
51 changes: 19 additions & 32 deletions src/tests/secp256k1_blake160_multisig_all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ const ERROR_INCORRECT_SINCE: i8 = -53;
fn test_multisig_script_hash() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(3);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0);
let args = blake160(&multi_sign_script);
let raw_tx = gen_tx(&mut data_loader, args);
{
let wrong_multi_sign_script = gen_multi_sign_script(&keys, 2, 1, 0);
let wrong_multi_sign_script = gen_multi_sign_script(&keys, 2, 1);
let tx = multi_sign_tx(
raw_tx.clone(),
&wrong_multi_sign_script,
Expand All @@ -50,11 +50,11 @@ fn test_multisig_script_hash() {
fn test_invalid_flags() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(3);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0);
let args = blake160(&multi_sign_script);
let raw_tx = gen_tx(&mut data_loader, args);
{
let wrong_multi_sign_script = gen_multi_sign_script(&vec![], 2, 0, 0);
let wrong_multi_sign_script = gen_multi_sign_script(&vec![], 2, 0);
let tx = multi_sign_tx(
raw_tx.clone(),
&wrong_multi_sign_script,
Expand All @@ -67,7 +67,7 @@ fn test_invalid_flags() {
);
}
{
let wrong_multi_sign_script = gen_multi_sign_script(&keys, 4, 0, 0);
let wrong_multi_sign_script = gen_multi_sign_script(&keys, 4, 0);
let tx = multi_sign_tx(
raw_tx.clone(),
&wrong_multi_sign_script,
Expand All @@ -80,7 +80,7 @@ fn test_invalid_flags() {
);
}
{
let wrong_multi_sign_script = gen_multi_sign_script(&keys, 2, 3, 0);
let wrong_multi_sign_script = gen_multi_sign_script(&keys, 2, 3);
let tx = multi_sign_tx(
raw_tx.clone(),
&wrong_multi_sign_script,
Expand All @@ -98,7 +98,7 @@ fn test_invalid_flags() {
fn test_multisig_0_2_3_unlock() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(3);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0);
let args = blake160(&multi_sign_script);
let raw_tx = gen_tx(&mut data_loader, args);
{
Expand Down Expand Up @@ -170,7 +170,7 @@ fn test_multisig_0_2_3_unlock() {
fn test_multisig_1_2_3_unlock() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(3);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 1, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 1);
let args = blake160(&multi_sign_script);
let tx = gen_tx(&mut data_loader, args);
{
Expand Down Expand Up @@ -199,7 +199,7 @@ fn test_multisig_1_2_3_unlock() {
fn test_multisig_1_2_3_with_extra_witness_unlock() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(3);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 1, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 1);
let args = blake160(&multi_sign_script);
let tx = gen_tx(&mut data_loader, args);
let extract_witness = vec![1, 2, 3, 4];
Expand Down Expand Up @@ -237,10 +237,9 @@ fn test_multisig_1_2_3_with_extra_witness_unlock() {
fn test_multisig_1_2_3_with_multiple_inputs_unlock() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(3);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 1, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 1);
let args = blake160(&multi_sign_script);
let tx = gen_tx_with_extra_inputs(&mut data_loader, args, 1);
dbg!(format!("{}", &tx));
{
let tx = multi_sign_tx(tx.clone(), &multi_sign_script, &[&keys[0], &keys[1]]);
verify(&data_loader, &tx).expect("pass verification");
Expand All @@ -267,7 +266,7 @@ fn test_multisig_1_2_3_with_multiple_inputs_unlock() {
fn test_multisig_0_1_1_unlock() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(1);
let multi_sign_script = gen_multi_sign_script(&keys, 1, 0, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 1, 0);
let args = blake160(&multi_sign_script);
let raw_tx = gen_tx(&mut data_loader, args);
{
Expand All @@ -289,7 +288,7 @@ fn test_multisig_0_1_1_unlock() {
fn test_multisig_0_2_2_unlock() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(2);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0, 0);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0);
let args = blake160(&multi_sign_script);
let raw_tx = gen_tx(&mut data_loader, args);
{
Expand Down Expand Up @@ -378,22 +377,16 @@ fn test_multisig_0_2_3_unlock_with_since() {
let mut data_loader = DummyDataLoader::new();
let keys = generate_keys(3);
let since = 0x0000_0000_8888_8888u64;
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0, since);
let args = blake160(&multi_sign_script);
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0);
let args = {
let mut buf = blake160(&multi_sign_script).to_vec();
buf.extend(since.to_le_bytes().into_iter());
Bytes::from(buf)
};
let raw_tx = gen_tx(&mut data_loader, args);
{
let since2 = 0;
let multi_sign_script = gen_multi_sign_script(&keys, 2, 0, since2);
let tx = multi_sign_tx(raw_tx.clone(), &multi_sign_script, &[&keys[0], &keys[1]]);
let verify_result = verify(&data_loader, &tx);
assert_error_eq!(
verify_result.unwrap_err(),
ScriptError::ValidationFailure(ERROR_MULTSIG_SCRIPT_HASH),
);
}
{
let tx = multi_sign_tx(raw_tx.clone(), &multi_sign_script, &[&keys[1], &keys[2]]);
let verify_result = verify(&data_loader, &tx);
assert_error_eq!(
verify_result.unwrap_err(),
ScriptError::ValidationFailure(ERROR_INCORRECT_SINCE),
Expand Down Expand Up @@ -453,18 +446,12 @@ fn test_multisig_0_2_3_unlock_with_since() {
}
}

fn gen_multi_sign_script(
keys: &[Privkey],
threshold: u8,
require_first_n: u8,
since: u64,
) -> Bytes {
fn gen_multi_sign_script(keys: &[Privkey], threshold: u8, require_first_n: u8) -> Bytes {
let pubkeys = keys
.iter()
.map(|key| key.pubkey().unwrap())
.collect::<Vec<_>>();
let mut script = vec![0u8, require_first_n, threshold, pubkeys.len() as u8];
script.extend(since.to_le_bytes().into_iter());
pubkeys.iter().for_each(|pubkey| {
script.extend_from_slice(&pubkey.serialize());
});
Expand Down