Skip to content

Commit

Permalink
RGB: consignment validation for extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Sep 30, 2020
1 parent 7bf926c commit 4bc2d52
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 15 deletions.
23 changes: 13 additions & 10 deletions src/rgb/stash/consignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ pub struct Consignment {
version: u16,
pub genesis: Genesis,
pub endpoints: ConsignmentEndpoints,
pub data: OwnedData,
pub extensions: ExtensionData,
pub owned_data: OwnedData,
pub extension_data: ExtensionData,
}

impl Consignment {
Expand All @@ -48,22 +48,25 @@ impl Consignment {
Self {
version: RGB_CONSIGNMENT_VERSION,
genesis,
extensions,
extension_data: extensions,
endpoints,
data,
owned_data: data,
}
}

#[inline]
pub fn txids(&self) -> BTreeSet<Txid> {
self.data.iter().map(|(anchor, _)| anchor.txid).collect()
self.owned_data
.iter()
.map(|(anchor, _)| anchor.txid)
.collect()
}

#[inline]
pub fn node_ids(&self) -> BTreeSet<NodeId> {
let mut set = bset![self.genesis.node_id()];
set.extend(self.data.iter().map(|(_, node)| node.node_id()));
set.extend(self.extensions.iter().map(Extension::node_id));
set.extend(self.owned_data.iter().map(|(_, node)| node.node_id()));
set.extend(self.extension_data.iter().map(Extension::node_id));
set
}

Expand All @@ -79,7 +82,7 @@ impl Consignment {
impl StrictEncode for Consignment {
fn strict_encode<E: io::Write>(&self, mut e: E) -> Result<usize, strict_encoding::Error> {
Ok(
strict_encode_list!(e; self.version, self.genesis, self.endpoints, self.data, self.extensions),
strict_encode_list!(e; self.version, self.genesis, self.endpoints, self.owned_data, self.extension_data),
)
}
}
Expand All @@ -90,8 +93,8 @@ impl StrictDecode for Consignment {
version: u16::strict_decode(&mut d)?,
genesis: Genesis::strict_decode(&mut d)?,
endpoints: ConsignmentEndpoints::strict_decode(&mut d)?,
data: OwnedData::strict_decode(&mut d)?,
extensions: ExtensionData::strict_decode(&mut d)?,
owned_data: OwnedData::strict_decode(&mut d)?,
extension_data: ExtensionData::strict_decode(&mut d)?,
})
}
}
Expand Down
17 changes: 12 additions & 5 deletions src/rgb/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use super::schema::OccurrencesError;
use super::{
schema, seal, Anchor, AnchorId, Consignment, ContractId, Node, NodeId, Schema, SchemaId,
};
use crate::rgb::schema::NodeType;
use crate::rgb::AssignmentsVariant;

#[derive(Clone, Copy, PartialEq, Eq, Debug, Display, Error)]
Expand Down Expand Up @@ -245,12 +246,16 @@ impl<'validator, R: TxResolver> Validator<'validator, R> {
// Create indexes
let mut node_index = BTreeMap::<NodeId, &dyn Node>::new();
let mut anchor_index = BTreeMap::<NodeId, &Anchor>::new();
for (anchor, transition) in &consignment.data {
for (anchor, transition) in &consignment.owned_data {
let node_id = transition.node_id();
node_index.insert(node_id, transition);
anchor_index.insert(node_id, anchor);
}
node_index.insert(genesis_id, &consignment.genesis);
for extension in &consignment.extension_data {
let node_id = extension.node_id();
node_index.insert(node_id, extension);
}

// Collect all endpoint transitions
// This is pretty simple operation; it takes a lot of code because
Expand Down Expand Up @@ -382,6 +387,7 @@ impl<'validator, R: TxResolver> Validator<'validator, R> {
queue.push_back(node);
while let Some(node) = queue.pop_front() {
let node_id = node.node_id();
let node_type = node.node_type();

// [VALIDATION]: Verify node against the schema. Here we check
// only a single node, not state evolution (it
Expand All @@ -392,8 +398,8 @@ impl<'validator, R: TxResolver> Validator<'validator, R> {
}

// Making sure we do have a corresponding anchor; otherwise
// reporting failure (see below) - with the except of genesis
// node, which does not have a corresponding anchor
// reporting failure (see below) - with the except of genesis and
// extension nodes, which does not have a corresponding anchor
if let Some(anchor) = self.anchor_index.get(&node_id).cloned() {
// Ok, now we have the `node` and the `anchor`, let's do all
// required checks
Expand All @@ -409,9 +415,9 @@ impl<'validator, R: TxResolver> Validator<'validator, R> {
self.validate_graph_node(node, anchor);

// Ouch, we are out of that multi-level nested cycles :)
} else if node_id != self.genesis_id {
} else if node_type != NodeType::Genesis && node_type != NodeType::Extension {
// This point is actually unreachable: b/c of the
// consignment structure, each node (other then genesis)
// consignment structure, each state transition
// has a corresponding anchor. So if we've got here there
// is something broken with LNP/BP core library.
// TODO: Consider to remove this failure and replace it
Expand Down Expand Up @@ -443,6 +449,7 @@ impl<'validator, R: TxResolver> Validator<'validator, R> {
fn validate_graph_node(&mut self, node: &'validator dyn Node, anchor: &'validator Anchor) {
let txid = anchor.txid;
let node_id = node.node_id();
let node_type = node.node_type();

// Check that the anchor is committed into a transaction spending all of
// the transition inputs.
Expand Down

0 comments on commit 4bc2d52

Please sign in to comment.