use std::collections::{BTreeMap, BTreeSet};
use bitcoin::OutPoint;
use bp::seals::txout::CloseMethod;
use rgb_core::bundle::NoDataError;
use rgb_core::schema::OwnedRightType;
use rgb_core::{
seal, NodeId, NodeOutpoint, OwnedRights, ParentOwnedRights, Transition, TransitionBundle,
TypedAssignments,
};
use crate::state::OutpointState;
pub const BLANK_TRANSITION_TYPE: u16 = 0x8000;
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display, Error, From)]
#[display(doc_comments)]
pub enum Error {
NoOutpoint(OwnedRightType),
DuplicateAssignments(NodeOutpoint, TypedAssignments),
#[from(NoDataError)]
EmptyData,
}
pub trait BlankBundle {
fn blank(
prev_state: &BTreeMap<OutPoint, BTreeSet<OutpointState>>,
new_outpoints: &BTreeMap<OwnedRightType, (OutPoint, CloseMethod)>,
) -> Result<TransitionBundle, Error>;
}
impl BlankBundle for TransitionBundle {
fn blank(
prev_state: &BTreeMap<OutPoint, BTreeSet<OutpointState>>,
new_outpoints: &BTreeMap<OwnedRightType, (OutPoint, CloseMethod)>,
) -> Result<TransitionBundle, Error> {
let mut transitions: BTreeMap<Transition, BTreeSet<u16>> = bmap! {};
for (tx_outpoint, inputs) in prev_state {
let mut parent_owned_rights: BTreeMap<NodeId, BTreeMap<OwnedRightType, Vec<u16>>> =
bmap! {};
let mut owned_rights: BTreeMap<OwnedRightType, TypedAssignments> = bmap! {};
for OutpointState {
node_outpoint: input,
state,
} in inputs
{
parent_owned_rights
.entry(input.node_id)
.or_default()
.entry(input.ty)
.or_default()
.push(input.no);
let (op, close_method) = new_outpoints
.get(&input.ty)
.ok_or(Error::NoOutpoint(input.ty))?;
let new_seal = seal::Revealed::new(*close_method, *op);
let new_assignments = state.to_revealed_assignment_vec(new_seal);
owned_rights.insert(input.ty, new_assignments);
}
let transition = Transition::with(
BLANK_TRANSITION_TYPE,
empty!(),
empty!(),
OwnedRights::from(owned_rights),
empty!(),
ParentOwnedRights::from(parent_owned_rights),
);
transitions.insert(transition, bset! { tx_outpoint.vout as u16 });
}
TransitionBundle::try_from(transitions).map_err(Error::from)
}
}