Skip to content

Commit

Permalink
Merge pull request #117 from RGB-WG/v0.11
Browse files Browse the repository at this point in the history
Fix issues with accepting consignment
  • Loading branch information
dr-orlovsky authored Dec 29, 2023
2 parents e028cd6 + 0d5a826 commit 441c9f5
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 84 deletions.
32 changes: 20 additions & 12 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,9 @@ wasm-bindgen-test = "0.3"

[package.metadata.docs.rs]
features = [ "all" ]

[patch.crates-io]
bp-dbc = { git = "https://github.com/BP-WG/bp-core", branch = "v0.11" }
bp-seals = { git = "https://github.com/BP-WG/bp-core", branch = "v0.11" }
bp-core = { git = "https://github.com/BP-WG/bp-core", branch = "v0.11" }
rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "v0.11" }
2 changes: 1 addition & 1 deletion src/accessors/merge_reveal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl MergeReveal for TransitionBundle {
.known_transitions
.extend(other.known_transitions)
.is_err() ||
self.input_map.len() < self.known_transitions.len()
self.input_map.len() > self.known_transitions.len()
{
return Err(MergeRevealError::ExcessiveTransitions);
}
Expand Down
65 changes: 6 additions & 59 deletions src/containers/consignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::{BTreeMap, BTreeSet};
use std::rc::Rc;
use std::{iter, vec};
use std::collections::BTreeMap;
use std::iter;

use amplify::confinement::{LargeVec, MediumBlob, SmallOrdMap, TinyOrdMap, TinyOrdSet};
use commit_verify::Conceal;
use rgb::validation::{self, ConsignmentApi};
use rgb::validation::{self};
use rgb::{
AnchoredBundle, AssetTag, AssignmentType, AttachId, BundleId, ContractHistory, ContractId,
Extension, Genesis, GraphSeal, OpId, OpRef, Operation, Schema, SchemaId, SecretSeal, SubSchema,
Transition, XSeal,
Extension, Genesis, GraphSeal, OpId, Operation, Schema, SchemaId, SubSchema, Transition, XSeal,
};
use strict_encoding::{StrictDeserialize, StrictDumb, StrictSerialize};

Expand Down Expand Up @@ -157,13 +154,13 @@ impl<const TYPE: bool> Consignment<TYPE> {
.find(|anchored_bundle| anchored_bundle.bundle.bundle_id() == bundle_id)
}

fn transition(&self, opid: OpId) -> Option<&Transition> {
pub(super) fn transition(&self, opid: OpId) -> Option<&Transition> {
self.bundles
.iter()
.find_map(|ab| ab.bundle.known_transitions.get(&opid))
}

fn extension(&self, opid: OpId) -> Option<&Extension> {
pub(super) fn extension(&self, opid: OpId) -> Option<&Extension> {
self.extensions
.iter()
.find(|&extension| extension.id() == opid)
Expand Down Expand Up @@ -255,53 +252,3 @@ impl<const TYPE: bool> Consignment<TYPE> {
}
}
}

#[derive(Debug)]
pub struct BundleIdIter(vec::IntoIter<AnchoredBundle>);

impl Iterator for BundleIdIter {
type Item = BundleId;

fn next(&mut self) -> Option<Self::Item> {
self.0.next().as_ref().map(AnchoredBundle::bundle_id)
}
}

impl<const TYPE: bool> ConsignmentApi for Consignment<TYPE> {
type Iter<'a> = BundleIdIter;

fn schema(&self) -> &SubSchema { &self.schema }

#[inline]
fn asset_tags(&self) -> &BTreeMap<AssignmentType, AssetTag> { self.asset_tags.as_inner() }

fn operation(&self, opid: OpId) -> Option<OpRef> {
if opid == self.genesis.id() {
return Some(OpRef::Genesis(&self.genesis));
}
self.transition(opid)
.map(OpRef::from)
.or_else(|| self.extension(opid).map(OpRef::from))
}

fn genesis(&self) -> &Genesis { &self.genesis }

fn terminals(&self) -> BTreeSet<(BundleId, SecretSeal)> {
self.terminals
.iter()
.flat_map(|(bundle_id, terminal)| {
terminal
.seals
.iter()
.map(|seal| (*bundle_id, seal.conceal()))
})
.collect()
}

fn bundle_ids<'a>(&self) -> Self::Iter<'a> { BundleIdIter(self.bundles.clone().into_iter()) }

fn anchored_bundle(&self, bundle_id: BundleId) -> Option<Rc<AnchoredBundle>> {
self.anchored_bundle(bundle_id)
.map(|ab| Rc::new(ab.clone()))
}
}
118 changes: 118 additions & 0 deletions src/containers/indexed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// RGB standard library for working with smart contracts on Bitcoin & Lightning
//
// SPDX-License-Identifier: Apache-2.0
//
// Written in 2019-2023 by
// Dr Maxim Orlovsky <[email protected]>
//
// Copyright (C) 2019-2023 LNP/BP Standards Association. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::{BTreeMap, BTreeSet};
use std::ops::Deref;
use std::rc::Rc;
use std::vec;

use commit_verify::Conceal;
use rgb::validation::ConsignmentApi;
use rgb::{
AnchoredBundle, AssetTag, AssignmentType, BundleId, Genesis, OpId, OpRef, Operation, SubSchema,
WitnessId,
};

use super::Consignment;
use crate::SecretSeal;

// TODO: Add more indexes
#[derive(Clone, Debug)]
pub struct IndexedConsignment<'c, const TYPE: bool> {
consignment: &'c Consignment<TYPE>,
op_witness_ids: BTreeMap<OpId, WitnessId>,
}

impl<'c, const TYPE: bool> Deref for IndexedConsignment<'c, TYPE> {
type Target = Consignment<TYPE>;

fn deref(&self) -> &Self::Target { self.consignment }
}

impl<'c, const TYPE: bool> IndexedConsignment<'c, TYPE> {
pub fn new(consignment: &'c Consignment<TYPE>) -> Self {
let mut op_witness_ids = BTreeMap::new();
for ab in &consignment.bundles {
for opid in ab.bundle.known_transitions.keys() {
op_witness_ids.insert(*opid, ab.anchor.witness_id());
}
}
Self {
consignment,
op_witness_ids,
}
}
}

impl<'c, const TYPE: bool> ConsignmentApi for IndexedConsignment<'c, TYPE> {
type Iter<'a> = BundleIdIter;

fn schema(&self) -> &SubSchema { &self.schema }

#[inline]
fn asset_tags(&self) -> &BTreeMap<AssignmentType, AssetTag> { self.asset_tags.as_inner() }

fn operation(&self, opid: OpId) -> Option<OpRef> {
if opid == self.genesis.id() {
return Some(OpRef::Genesis(&self.genesis));
}
self.transition(opid)
.map(OpRef::from)
.or_else(|| self.extension(opid).map(OpRef::from))
}

fn genesis(&self) -> &Genesis { &self.genesis }

fn terminals(&self) -> BTreeSet<(BundleId, SecretSeal)> {
self.terminals
.iter()
.flat_map(|(bundle_id, terminal)| {
terminal
.seals
.iter()
.map(|seal| (*bundle_id, seal.conceal()))
})
.collect()
}

fn bundle_ids<'a>(&self) -> Self::Iter<'a> { BundleIdIter(self.bundles.clone().into_iter()) }

fn anchored_bundle(&self, bundle_id: BundleId) -> Option<Rc<AnchoredBundle>> {
self.consignment
.anchored_bundle(bundle_id)
.map(|ab| Rc::new(ab.clone()))
}

fn op_witness_id(&self, opid: OpId) -> Option<WitnessId> {
self.op_witness_ids.get(&opid).copied()
}
}

#[derive(Debug)]
pub struct BundleIdIter(vec::IntoIter<AnchoredBundle>);

impl Iterator for BundleIdIter {
type Item = BundleId;

fn next(&mut self) -> Option<Self::Item> {
self.0.next().as_ref().map(AnchoredBundle::bundle_id)
}
}
2 changes: 2 additions & 0 deletions src/containers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ mod util;
mod validate;
mod certs;
mod partials;
mod indexed;

pub use bindle::{Bindle, BindleContent, BindleParseError, LoadError, UniversalBindle};
pub use certs::{Cert, ContentId, ContentSigs, Identity};
pub use consignment::{Consignment, Contract, Transfer};
pub use disclosure::Disclosure;
pub use indexed::IndexedConsignment;
pub use partials::{Batch, CloseMethodSet, Fascia, TransitionInfo};
pub use seal::{BuilderSeal, TerminalSeal, VoutSeal};
pub use util::{ContainerVer, Terminal, XchainOutpoint};
14 changes: 12 additions & 2 deletions src/containers/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
// limitations under the License.

use amplify::confinement::SmallOrdSet;
use bp::{Outpoint, Tx};
use rgb::OutputSeal;
use bp::seals::txout::ExplicitSeal;
use bp::{Outpoint, Tx, Txid};
use rgb::{OutputSeal, XSeal};

use super::TerminalSeal;
use crate::LIB_NAME_RGB_STD;
Expand Down Expand Up @@ -104,3 +105,12 @@ impl From<OutputSeal> for XchainOutpoint {
}
}
}

impl From<XchainOutpoint> for XSeal<ExplicitSeal<Txid>> {
fn from(outpoint: XchainOutpoint) -> Self {
match outpoint {
XchainOutpoint::Bitcoin(outpoint) => XSeal::Bitcoin(outpoint.into()),
XchainOutpoint::Liquid(outpoint) => XSeal::Liquid(outpoint.into()),
}
}
}
5 changes: 3 additions & 2 deletions src/containers/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@

use rgb::validation::{ResolveTx, Validator, Validity, Warning};

use super::Consignment;
use super::{Consignment, IndexedConsignment};

impl<const TYPE: bool> Consignment<TYPE> {
pub fn validate<R: ResolveTx>(
mut self,
resolver: &mut R,
testnet: bool,
) -> Result<Consignment<TYPE>, Consignment<TYPE>> {
let mut status = Validator::validate(&self, resolver, testnet);
let index = IndexedConsignment::new(&self);
let mut status = Validator::validate(&index, resolver, testnet);

let validity = status.validity();

Expand Down
Loading

0 comments on commit 441c9f5

Please sign in to comment.