Skip to content

Commit

Permalink
containers: fix consignment checks
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Aug 1, 2024
1 parent bc2ec1c commit 014ebdf
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 72 deletions.
8 changes: 4 additions & 4 deletions asset/armored_transfer.default
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
-----BEGIN RGB CONSIGNMENT-----
Id: rgb:csg:Kej4ueIS-4VLOUQe-SpFUOCe-BzEZ$Lt-C4PNmJC-J0Um7WM#cigar-pretend-mayor
Id: rgb:csg:9jMKgkmP-alPghZC-bu65ctP-GT5tKgM-cAbaTLT-rhu8xQo#urban-athena-adam
Version: 2
Type: contract
Type: transfer
Contract: rgb:T24t0N1D-eiInTgb-BXlrrXz-$7OgV6n-WJWHPUD-BWNuqZw
Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
Check-SHA256: 562a944631243e23a8de1d2aa2a5621be13351fc6f4d9aa8127c12ac4fb54d97

0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0s#O3000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
0000000000000

Expand Down
Binary file modified asset/transfer.default
Binary file not shown.
104 changes: 63 additions & 41 deletions src/containers/consignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use amplify::confinement::{
Confined, LargeOrdSet, MediumBlob, SmallOrdMap, SmallOrdSet, TinyOrdMap, TinyOrdSet,
};
use amplify::{ByteArray, Bytes32};
use armor::{ArmorHeader, AsciiArmor, StrictArmor};
use armor::{ArmorHeader, AsciiArmor, StrictArmor, StrictArmorError};
use baid64::{Baid64ParseError, DisplayBaid64, FromBaid64Str};
use commit_verify::{CommitEncode, CommitEngine, CommitId, CommitmentId, DigestExt, Sha256};
use rgb::validation::{ResolveWitness, Validator, Validity, Warning, CONSIGNMENT_MAX_LIBS};
Expand Down Expand Up @@ -421,14 +421,42 @@ impl<const TRANSFER: bool> StrictArmor for Consignment<TRANSFER> {
}
headers
}
fn parse_armor_headers(&mut self, headers: Vec<ArmorHeader>) -> Result<(), StrictArmorError> {
// TODO: Check remaining headers - terminals, version, iface, contract, schema
if let Some(header) = headers
.iter()
.find(|header| header.title == ASCII_ARMOR_CONSIGNMENT_TYPE)
{
if self.transfer && header.values.len() != 1 && header.values[0] != "transfer" {
// TODO: Add header-specific errors to StrictArmorError
// return Err(Strict)
}
}
Ok(())
}
}

// TODO: Remove after header-specific variants are added to StrictArmorError
#[derive(Debug, Display, Error, From)]
pub enum ConsignmentParseError {
#[display(inner)]
#[from]
Armor(armor::StrictArmorError),

#[display("required consignment type doesn't match the actual type")]
Type,
}

impl<const TRANSFER: bool> FromStr for Consignment<TRANSFER> {
type Err = armor::StrictArmorError;
type Err = ConsignmentParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::from_ascii_armored_str(s)
let consignment = Self::from_ascii_armored_str(s)?;

// TODO: Ensure that contract.transfer == TRANSFER
if consignment.transfer != TRANSFER {
return Err(ConsignmentParseError::Type);
}

Ok(consignment)
}
}

Expand All @@ -438,35 +466,20 @@ mod test {

#[test]
fn contract_str_round_trip() {
let contract = Contract::from_str(include_str!("../../asset/armored_contract.default"))
let mut contract = Contract::from_str(include_str!("../../asset/armored_contract.default"))
.expect("contract from str should work");
assert_eq!(
contract.to_string(),
include_str!("../../asset/armored_contract.default"),
"contract string round trip fails"
);
contract.transfer = true;
eprintln!("{contract}");
}

#[test]
fn error_contract_strs() {
assert!(
Contract::from_str(
r#"-----BEGIN RGB CONSIGNMENT-----
Id: rgb:csg:Kej4ueIS-4VLOUQe-SpFUOCe-BzEZ$Lt-C4PNmJC-J0Um7WM#cigar-pretend-mayor
Version: 2
Type: contract
Contract: rgb:T24t0N1D-eiInTgb-BXlrrXz-$7OgV6n-WJWHPUD-BWNuqZw
Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
0000000000000
-----END RGB CONSIGNMENT-----"#
)
.is_ok()
);
assert!(Contract::from_str(include_str!("../../asset/armored_contract.default")).is_ok());

// Wrong Id
assert!(
Expand Down Expand Up @@ -522,37 +535,41 @@ Check-SHA256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

#[test]
fn error_transfer_strs() {
let s = include_str!("../../asset/armored_transfer.default");
assert!(matches!(Transfer::from_str(s), Ok(_)));

// Wrong Id
assert!(
Transfer::from_str(
r#"-----BEGIN RGB CONSIGNMENT-----
Id: rgb:csg:Kej4ueIS-4VLOUQe-SpFUOCe-BzEZ$Lt-C4PNmJC-J0Um7WM#cigar-pretend-mayor
Id: rgb:csg:aaaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa#guide-campus-arctic
Version: 2
Type: transfer
Contract: rgb:T24t0N1D-eiInTgb-BXlrrXz-$7OgV6n-WJWHPUD-BWNuqZw
Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
Check-SHA256: 562a944631243e23a8de1d2aa2a5621be13351fc6f4d9aa8127c12ac4fb54d97
0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0s#O3000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
0000000000000
-----END RGB CONSIGNMENT-----"#
)
.is_ok()
.is_err()
);

// Wrong Id
// Wrong checksum
assert!(
Transfer::from_str(
r#"-----BEGIN RGB CONSIGNMENT-----
Id: rgb:csg:aaaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa-aaaaaaa#guide-campus-arctic
Id: rgb:csg:9jMKgkmP-alPghZC-bu65ctP-GT5tKgM-cAbaTLT-rhu8xQo#urban-athena-adam
Version: 2
Type: transfer
Contract: rgb:qm7P!06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
Contract: rgb:T24t0N1D-eiInTgb-BXlrrXz-$7OgV6n-WJWHPUD-BWNuqZw
Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
Check-SHA256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0s#O3000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
0000000000000
Expand All @@ -561,24 +578,29 @@ Check-SHA256: 181748dae0c83cbb44f6ccfdaddf6faca0bc4122a9f35fef47bab9aea023e4a1
.is_err()
);

// Wrong checksum
assert!(
// Wrong type
// TODO: Uncomment once ASCII headers get checked
/*assert!(matches!(
Transfer::from_str(
r#"-----BEGIN RGB CONSIGNMENT-----
Id: rgb:csg:poAMvm9j-NdapxqA-MJ!5dwP-d!IIt2A-T!5OiXE-Tl54Yew#guide-campus-arctic
Id: rgb:csg:9jMKgkmP-alPghZC-bu65ctP-GT5tKgM-cAbaTLT-rhu8xQo#urban-athena-adam
Version: 2
Type: transfer
Contract: rgb:qm7P!06T-uuBQT56-ovwOLzx-9Gka7Nb-84Nwo8g-blLb8kw
Type: contract
Contract: rgb:T24t0N1D-eiInTgb-BXlrrXz-$7OgV6n-WJWHPUD-BWNuqZw
Schema: rgb:sch:CyqM42yAdM1moWyNZPQedAYt73BM$k9z$dKLUXY1voA#cello-global-deluxe
Check-SHA256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
0ssI2000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0s#O3000000000000000000000000000000000000000000000000000000D0CRI`I$>^aZh38Qb#nj!
0000000000000000000000d59ZDjxe00000000dDb8~4rVQz13d2MfXa{vGU00000000000000000000
0000000000000
-----END RGB CONSIGNMENT-----"#
)
.is_err()
);
),
Err(ConsignmentParseError::Type)
));*/
assert!(matches!(
Transfer::from_str(include_str!("../../asset/armored_contract.default")),
Err(ConsignmentParseError::Type)
));
}
}
29 changes: 8 additions & 21 deletions src/containers/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ mod test {
fn almost_default_transfer() -> Transfer {
Transfer {
version: Default::default(),
transfer: Default::default(),
transfer: true,
terminals: Default::default(),
genesis: rgb::Genesis {
ffv: Default::default(),
Expand Down Expand Up @@ -406,39 +406,26 @@ mod test {

#[test]
fn transfer_save_load_round_trip() {
let mut transfer_file = OpenOptions::new()
.read(true)
.open(DEFAULT_TRANSFER_PATH)
.unwrap();
let transfer = Transfer::load(transfer_file).expect("fail to load transfer.default");
let transfer =
Transfer::load_file(DEFAULT_TRANSFER_PATH).expect("fail to load transfer.default");

let default_transfer = almost_default_transfer();
assert_eq!(&transfer, &default_transfer, "transfer default is not same as before");

transfer_file = OpenOptions::new()
.write(true)
.open(DEFAULT_TRANSFER_PATH)
.unwrap();
default_transfer
.save(transfer_file)
.save_file(DEFAULT_TRANSFER_PATH)
.expect("fail to export transfer");

transfer_file = OpenOptions::new()
.read(true)
.open(DEFAULT_TRANSFER_PATH)
.unwrap();
let transfer = Transfer::load(transfer_file).expect("fail to load transfer.default");
let transfer =
Transfer::load_file(DEFAULT_TRANSFER_PATH).expect("fail to load transfer.default");
assert_eq!(&transfer, &default_transfer, "transfer roudtrip does not work");
}

#[cfg(feature = "fs")]
#[test]
fn armored_transfer_save_load_round_trip() {
let transfer_file = OpenOptions::new()
.read(true)
.open(DEFAULT_TRANSFER_PATH)
.unwrap();
let transfer = Transfer::load(transfer_file).expect("fail to load transfer.default");
let transfer =
Transfer::load_file(DEFAULT_TRANSFER_PATH).expect("fail to load transfer.default");
let unarmored_transfer =
Transfer::load_armored(ARMORED_TRANSFER_PATH).expect("fail to export armored transfer");
assert_eq!(transfer, unarmored_transfer, "transfer unarmored is not the same");
Expand Down
4 changes: 2 additions & 2 deletions src/containers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ pub use anchors::{
AnchorSet, AnchoredBundles, BundledWitness, PubWitness, SealWitness, ToWitnessId, XPubWitness,
};
pub use consignment::{
Consignment, ConsignmentExt, ConsignmentId, Contract, Transfer, ValidConsignment,
ValidContract, ValidTransfer,
Consignment, ConsignmentExt, ConsignmentId, ConsignmentParseError, Contract, Transfer,
ValidConsignment, ValidContract, ValidTransfer,
};
pub use disclosure::Disclosure;
pub use file::{FileContent, LoadError, UniversalFile};
Expand Down
6 changes: 2 additions & 4 deletions src/persistence/stock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,8 +704,7 @@ impl<S: StashProvider, H: StateProvider, P: IndexProvider> Stock<S, H, P> {
&self,
contract_id: ContractId,
) -> Result<Contract, StockError<S, H, P, ConsignError>> {
let mut consignment = self.consign::<false>(contract_id, [], [])?;
consignment.transfer = false;
let consignment = self.consign::<false>(contract_id, [], [])?;
Ok(consignment)
}

Expand All @@ -715,8 +714,7 @@ impl<S: StashProvider, H: StateProvider, P: IndexProvider> Stock<S, H, P> {
outputs: impl AsRef<[XOutputSeal]>,
secret_seals: impl AsRef<[XChain<SecretSeal>]>,
) -> Result<Transfer, StockError<S, H, P, ConsignError>> {
let mut consignment = self.consign(contract_id, outputs, secret_seals)?;
consignment.transfer = true;
let consignment = self.consign(contract_id, outputs, secret_seals)?;
Ok(consignment)
}

Expand Down

0 comments on commit 014ebdf

Please sign in to comment.