Skip to content

Commit

Permalink
Merge pull request #495 from Chia-Network/public-key-spend-bundle-con…
Browse files Browse the repository at this point in the history
…ditions

use `PublicKey` in `OwnedSpendBundleConditions`
  • Loading branch information
arvidn authored Apr 29, 2024
2 parents 7b16b7e + 8b52d0a commit 023e1cf
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 104 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/chia-consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ clvm-traits = { version = "0.7.0", path = "../clvm-traits" }
clvm-derive = { version = "0.6.0", path = "../clvm-derive" }
chia-protocol = { version = "0.7.0", path = "../chia-protocol" }
chia-puzzles = { version = "0.7.0", path = "../chia-puzzles" }
chia-bls = { version = "0.7.0", path = "../chia-bls" }
hex-literal = "0.4.1"
thiserror = "1.0.44"

Expand Down
3 changes: 3 additions & 0 deletions crates/chia-consensus/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ pub enum Error {
#[error("Validation {0}")]
Validation(#[from] ValidationErr),

#[error("BLS {0}")]
Bls(#[from] chia_bls::Error),

#[error("not a singleton mod hash")]
NotSingletonModHash,

Expand Down
63 changes: 34 additions & 29 deletions crates/chia-consensus/src/gen/owned_conditions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use chia_protocol::{Bytes, Bytes32, Bytes48};
use crate::error::Result;
use chia_bls::PublicKey;
use chia_protocol::{Bytes, Bytes32};
use chia_streamable_macro::Streamable;
use clvmr::{Allocator, NodePtr};

Expand All @@ -25,13 +27,13 @@ pub struct OwnedSpend {
pub birth_height: Option<u32>,
pub birth_seconds: Option<u64>,
pub create_coin: Vec<(Bytes32, u64, Option<Bytes>)>,
pub agg_sig_me: Vec<(Bytes48, Bytes)>,
pub agg_sig_parent: Vec<(Bytes48, Bytes)>,
pub agg_sig_puzzle: Vec<(Bytes48, Bytes)>,
pub agg_sig_amount: Vec<(Bytes48, Bytes)>,
pub agg_sig_puzzle_amount: Vec<(Bytes48, Bytes)>,
pub agg_sig_parent_amount: Vec<(Bytes48, Bytes)>,
pub agg_sig_parent_puzzle: Vec<(Bytes48, Bytes)>,
pub agg_sig_me: Vec<(PublicKey, Bytes)>,
pub agg_sig_parent: Vec<(PublicKey, Bytes)>,
pub agg_sig_puzzle: Vec<(PublicKey, Bytes)>,
pub agg_sig_amount: Vec<(PublicKey, Bytes)>,
pub agg_sig_puzzle_amount: Vec<(PublicKey, Bytes)>,
pub agg_sig_parent_amount: Vec<(PublicKey, Bytes)>,
pub agg_sig_parent_puzzle: Vec<(PublicKey, Bytes)>,
pub flags: u32,
}

Expand All @@ -53,7 +55,7 @@ pub struct OwnedSpendBundleConditions {
// ASSERT_BEFORE_SECONDS_ABSOLUTE conditions
pub before_seconds_absolute: Option<u64>,
// Unsafe Agg Sig conditions (i.e. not tied to the spend generating it)
pub agg_sig_unsafe: Vec<(Bytes48, Bytes)>,
pub agg_sig_unsafe: Vec<(PublicKey, Bytes)>,
pub cost: u64,
// the sum of all values of all spent coins
pub removal_amount: u128,
Expand All @@ -62,7 +64,7 @@ pub struct OwnedSpendBundleConditions {
}

impl OwnedSpend {
pub fn from(a: &Allocator, spend: Spend) -> Self {
pub fn from(a: &Allocator, spend: Spend) -> Result<Self> {
let mut create_coin =
Vec::<(Bytes32, u64, Option<Bytes>)>::with_capacity(spend.create_coin.len());
for c in spend.create_coin {
Expand All @@ -77,7 +79,7 @@ impl OwnedSpend {
));
}

Self {
Ok(Self {
coin_id: *spend.coin_id,
parent_id: a.atom(spend.parent_id).as_ref().try_into().unwrap(),
puzzle_hash: a.atom(spend.puzzle_hash).as_ref().try_into().unwrap(),
Expand All @@ -89,34 +91,34 @@ impl OwnedSpend {
birth_height: spend.birth_height,
birth_seconds: spend.birth_seconds,
create_coin,
agg_sig_me: convert_agg_sigs(a, &spend.agg_sig_me),
agg_sig_parent: convert_agg_sigs(a, &spend.agg_sig_parent),
agg_sig_puzzle: convert_agg_sigs(a, &spend.agg_sig_puzzle),
agg_sig_amount: convert_agg_sigs(a, &spend.agg_sig_amount),
agg_sig_puzzle_amount: convert_agg_sigs(a, &spend.agg_sig_puzzle_amount),
agg_sig_parent_amount: convert_agg_sigs(a, &spend.agg_sig_parent_amount),
agg_sig_parent_puzzle: convert_agg_sigs(a, &spend.agg_sig_parent_puzzle),
agg_sig_me: convert_agg_sigs(a, &spend.agg_sig_me)?,
agg_sig_parent: convert_agg_sigs(a, &spend.agg_sig_parent)?,
agg_sig_puzzle: convert_agg_sigs(a, &spend.agg_sig_puzzle)?,
agg_sig_amount: convert_agg_sigs(a, &spend.agg_sig_amount)?,
agg_sig_puzzle_amount: convert_agg_sigs(a, &spend.agg_sig_puzzle_amount)?,
agg_sig_parent_amount: convert_agg_sigs(a, &spend.agg_sig_parent_amount)?,
agg_sig_parent_puzzle: convert_agg_sigs(a, &spend.agg_sig_parent_puzzle)?,
flags: spend.flags,
}
})
}
}

impl OwnedSpendBundleConditions {
pub fn from(a: &Allocator, sb: SpendBundleConditions) -> Self {
pub fn from(a: &Allocator, sb: SpendBundleConditions) -> Result<Self> {
let mut spends = Vec::<OwnedSpend>::new();
for s in sb.spends {
spends.push(OwnedSpend::from(a, s));
spends.push(OwnedSpend::from(a, s)?);
}

let mut agg_sigs = Vec::<(Bytes48, Bytes)>::with_capacity(sb.agg_sig_unsafe.len());
let mut agg_sigs = Vec::<(PublicKey, Bytes)>::with_capacity(sb.agg_sig_unsafe.len());
for (pk, msg) in sb.agg_sig_unsafe {
agg_sigs.push((
a.atom(pk).as_ref().try_into().unwrap(),
PublicKey::from_bytes(a.atom(pk).as_ref().try_into().unwrap())?,
a.atom(msg).as_ref().into(),
));
}

Self {
Ok(Self {
spends,
reserve_fee: sb.reserve_fee,
height_absolute: sb.height_absolute,
Expand All @@ -127,17 +129,20 @@ impl OwnedSpendBundleConditions {
cost: sb.cost,
removal_amount: sb.removal_amount,
addition_amount: sb.addition_amount,
}
})
}
}

fn convert_agg_sigs(a: &Allocator, agg_sigs: &[(NodePtr, NodePtr)]) -> Vec<(Bytes48, Bytes)> {
let mut ret = Vec::<(Bytes48, Bytes)>::new();
fn convert_agg_sigs(
a: &Allocator,
agg_sigs: &[(NodePtr, NodePtr)],
) -> Result<Vec<(PublicKey, Bytes)>> {
let mut ret = Vec::<(PublicKey, Bytes)>::new();
for (pk, msg) in agg_sigs {
ret.push((
a.atom(*pk).as_ref().try_into().unwrap(),
PublicKey::from_bytes(a.atom(*pk).as_ref().try_into().unwrap())?,
a.atom(*msg).as_ref().into(),
));
}
ret
Ok(ret)
}
4 changes: 2 additions & 2 deletions tests/run_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def print_spend_bundle_conditions(result) -> str:
if result.before_height_absolute is not None:
ret += f"ASSERT_BEFORE_HEIGHT_ABSOLUTE {result.before_height_absolute}\n"
for a in sorted(result.agg_sig_unsafe):
ret += f"AGG_SIG_UNSAFE pk: {a[0].hex()} msg: {a[1].hex()}\n"
ret += f"AGG_SIG_UNSAFE pk: {a[0]} msg: {a[1].hex()}\n"
ret += "SPENDS:\n"
for s in sorted(result.spends, key=lambda x: x.coin_id):
ret += f"- coin id: {s.coin_id.hex()} ph: {s.puzzle_hash.hex()}\n"
Expand All @@ -72,7 +72,7 @@ def print_spend_bundle_conditions(result) -> str:
else:
ret += f" CREATE_COIN: ph: {a[0].hex()} amount: {a[1]}\n"
for a in sorted(s.agg_sig_me):
ret += f" AGG_SIG_ME pk: {a[0].hex()} msg: {a[1].hex()}\n"
ret += f" AGG_SIG_ME pk: {a[0]} msg: {a[1].hex()}\n"
ret += f"cost: {result.cost}\n"
ret += f"removal_amount: {result.removal_amount}\n"
ret += f"addition_amount: {result.addition_amount}\n"
Expand Down
56 changes: 33 additions & 23 deletions tests/test_streamable.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
from chia_rs import Spend, SpendBundleConditions, Coin, G1Element, G2Element, Program
from chia_rs import (
Spend,
SpendBundleConditions,
Coin,
G1Element,
G2Element,
Program,
AugSchemeMPL,
)
from chia_rs.sized_ints import uint64
from chia_rs.sized_bytes import bytes32
import pytest
import copy

sk = AugSchemeMPL.key_gen(bytes32.random())
pk = sk.get_g1()

coin = b"bcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbc"
parent = b"edededededededededededededededed"
ph = b"abababababababababababababababab"
ph2 = b"cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
sig = b"abababababababababababababababababababababababab"


def test_hash_spend() -> None:
Expand All @@ -25,7 +35,7 @@ def test_hash_spend() -> None:
None,
None,
[(ph2, 1000000, None)],
[(sig, b"msg")],
[(pk, b"msg")],
[],
[],
[],
Expand All @@ -46,7 +56,7 @@ def test_hash_spend() -> None:
None,
None,
[(ph2, 1000000, None)],
[(sig, b"msg")],
[(pk, b"msg")],
[],
[],
[],
Expand All @@ -65,10 +75,10 @@ def test_hash_spend() -> None:
def test_hash_spend_bundle_conditions() -> None:

a1 = SpendBundleConditions(
[], 1000, 1337, 42, None, None, [(sig, b"msg")], 12345678, 123, 456
[], 1000, 1337, 42, None, None, [(pk, b"msg")], 12345678, 123, 456
)
a2 = SpendBundleConditions(
[], 1001, 1337, 42, None, None, [(sig, b"msg")], 12345678, 123, 456
[], 1001, 1337, 42, None, None, [(pk, b"msg")], 12345678, 123, 456
)
b = hash(a1)
c = hash(a2)
Expand All @@ -91,7 +101,7 @@ def test_json_spend() -> None:
None,
None,
[(ph2, 1000000, None)],
[(sig, b"msg")],
[(pk, b"msg")],
[],
[],
[],
Expand All @@ -113,7 +123,7 @@ def test_json_spend() -> None:
"birth_height": None,
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
"agg_sig_me": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand All @@ -138,7 +148,7 @@ def test_from_json_spend() -> None:
None,
None,
[(ph2, 1000000, None)],
[(sig, b"msg")],
[(pk, b"msg")],
[],
[],
[],
Expand All @@ -161,7 +171,7 @@ def test_from_json_spend() -> None:
"birth_height": None,
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
"agg_sig_me": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand All @@ -188,7 +198,7 @@ def test_from_json_spend_set_optional() -> None:
None,
None,
[(ph2, 1000000, None)],
[(sig, b"msg")],
[(pk, b"msg")],
[],
[],
[],
Expand All @@ -211,7 +221,7 @@ def test_from_json_spend_set_optional() -> None:
"birth_height": None,
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
"agg_sig_me": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand Down Expand Up @@ -241,7 +251,7 @@ def test_invalid_hex_prefix() -> None:
"birth_height": None,
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
"agg_sig_me": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand Down Expand Up @@ -270,7 +280,7 @@ def test_invalid_hex_prefix_bytes() -> None:
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
# the message field is missing the 0x prefix and is variable length bytes
"agg_sig_me": [["0x" + sig.hex(), "6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand Down Expand Up @@ -299,7 +309,7 @@ def test_invalid_hex_digit() -> None:
"birth_height": None,
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
"agg_sig_me": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand Down Expand Up @@ -328,7 +338,7 @@ def test_invalid_hex_length() -> None:
"birth_height": None,
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
"agg_sig_me": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand Down Expand Up @@ -356,7 +366,7 @@ def test_missing_field() -> None:
"birth_height": None,
"birth_seconds": None,
"create_coin": [["0x" + ph2.hex(), 1000000, None]],
"agg_sig_me": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_me": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"agg_sig_parent": [],
"agg_sig_puzzle": [],
"agg_sig_amount": [],
Expand All @@ -371,7 +381,7 @@ def test_missing_field() -> None:
def test_json_spend_bundle_conditions() -> None:

a = SpendBundleConditions(
[], 1000, 1337, 42, None, None, [(sig, b"msg")], 12345678, 123, 456
[], 1000, 1337, 42, None, None, [(pk, b"msg")], 12345678, 123, 456
)

assert a.to_json_dict() == {
Expand All @@ -381,7 +391,7 @@ def test_json_spend_bundle_conditions() -> None:
"seconds_absolute": 42,
"before_height_absolute": None,
"before_seconds_absolute": None,
"agg_sig_unsafe": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_unsafe": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"cost": 12345678,
"removal_amount": 123,
"addition_amount": 456,
Expand All @@ -391,7 +401,7 @@ def test_json_spend_bundle_conditions() -> None:
def test_from_json_spend_bundle_conditions() -> None:

a = SpendBundleConditions(
[], 1000, 1337, 42, None, None, [(sig, b"msg")], 12345678, 123, 456
[], 1000, 1337, 42, None, None, [(pk, b"msg")], 12345678, 123, 456
)
b = SpendBundleConditions.from_json_dict(
{
Expand All @@ -401,7 +411,7 @@ def test_from_json_spend_bundle_conditions() -> None:
"seconds_absolute": 42,
"before_height_absolute": None,
"before_seconds_absolute": None,
"agg_sig_unsafe": [["0x" + sig.hex(), "0x6d7367"]],
"agg_sig_unsafe": [["0x" + bytes(pk).hex(), "0x6d7367"]],
"cost": 12345678,
"removal_amount": 123,
"addition_amount": 456,
Expand All @@ -424,7 +434,7 @@ def test_copy_spend() -> None:
None,
None,
[(ph2, 1000000, None)],
[(sig, b"msg")],
[(pk, b"msg")],
[],
[],
[],
Expand All @@ -446,7 +456,7 @@ def test_copy_spend() -> None:
def test_copy_spend_bundle_conditions() -> None:

a = SpendBundleConditions(
[], 1000, 1337, 42, None, None, [(sig, b"msg")], 12345678, 123, 456
[], 1000, 1337, 42, None, None, [(pk, b"msg")], 12345678, 123, 456
)
b = copy.copy(a)

Expand Down
Loading

0 comments on commit 023e1cf

Please sign in to comment.