Skip to content

Fungible operation history #126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

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

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

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

[patch.crates-io]
rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "v0.11" }
15 changes: 15 additions & 0 deletions invoice/src/amount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use std::fmt::{Display, Formatter, Write};
use std::iter::Sum;

use bp::Sats;
use rgb::{FungibleState, KnownState, RevealedValue};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use strict_encoding::{StrictDeserialize, StrictSerialize};
Expand Down Expand Up @@ -55,6 +56,20 @@ pub struct Amount(
impl StrictSerialize for Amount {}
impl StrictDeserialize for Amount {}

impl KnownState for Amount {}

impl From<RevealedValue> for Amount {
fn from(value: RevealedValue) -> Self { Amount(value.value.as_u64()) }
}

impl From<FungibleState> for Amount {
fn from(state: FungibleState) -> Self { Amount(state.as_u64()) }
}

impl From<Amount> for FungibleState {
fn from(amount: Amount) -> Self { FungibleState::Bits64(amount.0) }
}

impl Amount {
pub const ZERO: Self = Amount(0);

Expand Down
8 changes: 5 additions & 3 deletions invoice/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ use std::str::FromStr;
use rgb::ContractId;
use strict_encoding::{FieldName, TypeName};

use super::{Beneficiary, InvoiceState, Precision, RgbInvoice, RgbTransport, TransportParseError};
use super::{
Amount, Beneficiary, InvoiceState, Precision, RgbInvoice, RgbTransport, TransportParseError,
};
use crate::invoice::XChainNet;

#[derive(Clone, Eq, PartialEq, Debug)]
Expand Down Expand Up @@ -78,8 +80,8 @@ impl RgbInvoiceBuilder {
self
}

pub fn set_amount_raw(mut self, amount: u64) -> Self {
self.0.owned_state = InvoiceState::Amount(amount);
pub fn set_amount_raw(mut self, amount: impl Into<Amount>) -> Self {
self.0.owned_state = InvoiceState::Amount(amount.into());
self
}

Expand Down
4 changes: 3 additions & 1 deletion invoice/src/invoice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ use invoice::{AddressNetwork, AddressPayload, Network};
use rgb::{AttachId, ContractId, Layer1, SecretSeal};
use strict_encoding::{FieldName, TypeName};

use crate::Amount;

#[derive(Clone, Eq, PartialEq, Hash, Debug)]
#[non_exhaustive]
pub enum RgbTransport {
Expand All @@ -39,7 +41,7 @@ pub enum InvoiceState {
#[display("")]
Void,
#[display("{0}")]
Amount(u64),
Amount(Amount),
#[display("...")] // TODO
Data(Vec<u8> /* StrictVal */),
#[display(inner)]
Expand Down
4 changes: 2 additions & 2 deletions invoice/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
use rgb::{ContractId, SecretSeal};
use strict_encoding::{InvalidIdent, TypeName};

use super::{Beneficiary, InvoiceState, RgbInvoice, RgbTransport};
use super::{Amount, Beneficiary, InvoiceState, RgbInvoice, RgbTransport};
use crate::invoice::{ChainNet, XChainNet};

const OMITTED: &str = "~";
Expand Down Expand Up @@ -353,7 +353,7 @@ impl FromStr for RgbInvoice {
.unwrap_or((Some(assignment.as_str()), None));
// TODO: support other state types
let (beneficiary_str, value) = match (amount, beneficiary) {
(Some(a), Some(b)) => (b, InvoiceState::Amount(a.parse::<u64>()?)),
(Some(a), Some(b)) => (b, InvoiceState::Amount(a.parse::<Amount>()?)),
(Some(b), None) => (b, InvoiceState::Void),
_ => unreachable!(),
};
Expand Down
61 changes: 37 additions & 24 deletions src/interface/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,20 @@ use std::collections::{HashMap, HashSet};

use amplify::confinement::{Confined, TinyOrdMap, TinyOrdSet, U16};
use amplify::{confinement, Wrapper};
use invoice::Amount;
use rgb::{
AltLayer1, AltLayer1Set, AssetTag, Assign, AssignmentType, Assignments, BlindingFactor,
ContractId, ExposedSeal, FungibleType, Genesis, GenesisSeal, GlobalState, GraphSeal, Input,
Opout, RevealedData, RevealedValue, StateSchema, SubSchema, Transition, TransitionType,
TypedAssigns,
ContractId, DataState, ExposedSeal, FungibleType, Genesis, GenesisSeal, GlobalState, GraphSeal,
Input, Opout, RevealedAttach, RevealedData, RevealedValue, StateSchema, SubSchema, Transition,
TransitionType, TypedAssigns,
};
use strict_encoding::{FieldName, SerializeError, StrictSerialize, TypeName};
use strict_types::decode;

use crate::containers::{BuilderSeal, Contract};
use crate::interface::contract::AttachedState;
use crate::interface::{Iface, IfaceImpl, IfacePair, TransitionIface, TypedState};
use crate::interface::{Iface, IfaceImpl, IfacePair, TransitionIface};
use crate::persistence::PresistedState;

#[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)]
#[display(doc_comments)]
Expand Down Expand Up @@ -173,7 +175,7 @@ impl ContractBuilder {
mut self,
type_id: AssignmentType,
seal: impl Into<BuilderSeal<GenesisSeal>>,
state: TypedState,
state: PresistedState,
) -> Result<Self, BuilderError> {
self.builder = self.builder.add_owned_state_raw(type_id, seal, state)?;
Ok(self)
Expand Down Expand Up @@ -268,7 +270,7 @@ impl ContractBuilder {
pub struct TransitionBuilder {
builder: OperationBuilder<GraphSeal>,
transition_type: TransitionType,
inputs: TinyOrdMap<Input, TypedState>,
inputs: TinyOrdMap<Input, PresistedState>,
}

impl TransitionBuilder {
Expand Down Expand Up @@ -353,7 +355,7 @@ impl TransitionBuilder {
Ok(self)
}

pub fn add_input(mut self, opout: Opout, state: TypedState) -> Result<Self, BuilderError> {
pub fn add_input(mut self, opout: Opout, state: PresistedState) -> Result<Self, BuilderError> {
self.inputs.insert(Input::with(opout), state)?;
Ok(self)
}
Expand All @@ -376,9 +378,9 @@ impl TransitionBuilder {
mut self,
type_id: AssignmentType,
seal: impl Into<BuilderSeal<GraphSeal>>,
state: TypedState,
state: PresistedState,
) -> Result<Self, BuilderError> {
if matches!(state, TypedState::Amount(_, _, tag) if self.builder.asset_tag(type_id)? != tag)
if matches!(state, PresistedState::Amount(_, _, tag) if self.builder.asset_tag(type_id)? != tag)
{
return Err(BuilderError::AssetTagInvalid(type_id));
}
Expand Down Expand Up @@ -410,11 +412,11 @@ impl TransitionBuilder {
mut self,
type_id: AssignmentType,
seal: impl Into<BuilderSeal<GraphSeal>>,
value: u64,
value: impl Into<Amount>,
blinding: BlindingFactor,
) -> Result<Self, BuilderError> {
let tag = self.builder.asset_tag(type_id)?;
let state = RevealedValue::with_blinding(value, blinding, tag);
let state = RevealedValue::with_blinding(value.into(), blinding, tag);
self.builder = self.builder.add_fungible_state_raw(type_id, seal, state)?;
Ok(self)
}
Expand Down Expand Up @@ -507,7 +509,7 @@ pub struct OperationBuilder<Seal: ExposedSeal> {
TinyOrdMap<AssignmentType, Confined<HashMap<BuilderSeal<Seal>, RevealedValue>, 1, U16>>,
data: TinyOrdMap<AssignmentType, Confined<HashMap<BuilderSeal<Seal>, RevealedData>, 1, U16>>,
attachments:
TinyOrdMap<AssignmentType, Confined<HashMap<BuilderSeal<Seal>, AttachedState>, 1, U16>>,
TinyOrdMap<AssignmentType, Confined<HashMap<BuilderSeal<Seal>, RevealedAttach>, 1, U16>>,
// TODO: add valencies
}

Expand Down Expand Up @@ -632,7 +634,8 @@ impl<Seal: ExposedSeal> OperationBuilder<Seal> {
.type_system
.strict_deserialize_type(sem_id, &serialized)?;

self.global.add_state(type_id, serialized.into())?;
self.global
.add_state(type_id, RevealedData::new_random_salt(serialized))?;

Ok(self)
}
Expand All @@ -641,17 +644,23 @@ impl<Seal: ExposedSeal> OperationBuilder<Seal> {
self,
type_id: AssignmentType,
seal: impl Into<BuilderSeal<Seal>>,
state: TypedState,
state: PresistedState,
) -> Result<Self, BuilderError> {
match state {
TypedState::Void => self.add_rights_raw(type_id, seal),
TypedState::Amount(value, blinding, tag) => self.add_fungible_state_raw(
PresistedState::Void => self.add_rights_raw(type_id, seal),
PresistedState::Amount(value, blinding, tag) => self.add_fungible_state_raw(
type_id,
seal,
RevealedValue::with_blinding(value, blinding, tag),
),
TypedState::Data(data) => self.add_data_raw(type_id, seal, data),
TypedState::Attachment(attach) => self.add_attachment_raw(type_id, seal, attach),
PresistedState::Data(data, salt) => {
self.add_data_raw(type_id, seal, RevealedData::with_salt(data, salt))
}
PresistedState::Attachment(attach, salt) => self.add_attachment_raw(
type_id,
seal,
RevealedAttach::with_salt(attach.id, attach.media_type, salt),
),
}
}

Expand Down Expand Up @@ -768,20 +777,20 @@ impl<Seal: ExposedSeal> OperationBuilder<Seal> {
) -> Result<Self, BuilderError> {
let name = name.into();
let serialized = value.to_strict_serialized::<U16>()?;
let state = RevealedData::from(serialized);
let state = DataState::from(serialized);

let type_id = self
.assignments_type(&name, ty)
.ok_or(BuilderError::AssignmentNotFound(name))?;

self.add_data_raw(type_id, seal, state)
self.add_data_raw(type_id, seal, RevealedData::new_random_salt(state))
}

fn add_attachment_raw(
mut self,
type_id: AssignmentType,
seal: impl Into<BuilderSeal<Seal>>,
state: AttachedState,
state: RevealedAttach,
) -> Result<Self, BuilderError> {
let state_schema = self.state_schema(type_id);
if let StateSchema::Structured(_) = *state_schema {
Expand Down Expand Up @@ -814,12 +823,16 @@ impl<Seal: ExposedSeal> OperationBuilder<Seal> {
.assignments_type(&name, ty)
.ok_or(BuilderError::AssignmentNotFound(name))?;

self.add_attachment_raw(type_id, seal, state)
self.add_attachment_raw(
type_id,
seal,
RevealedAttach::new_random_salt(state.id, state.media_type),
)
}

fn complete(
self,
inputs: Option<&TinyOrdMap<Input, TypedState>>,
inputs: Option<&TinyOrdMap<Input, PresistedState>>,
) -> (SubSchema, IfacePair, GlobalState, Assignments<Seal>, TinyOrdMap<AssignmentType, AssetTag>)
{
let owned_state = self.fungible.into_iter().map(|(id, vec)| {
Expand All @@ -846,7 +859,7 @@ impl<Seal: ExposedSeal> OperationBuilder<Seal> {
i.iter()
.filter(|(out, _)| out.prev_out.ty == id)
.map(|(_, ts)| match ts {
TypedState::Amount(_, blinding, _) => *blinding,
PresistedState::Amount(_, blinding, _) => *blinding,
_ => panic!("previous state has invalid type"),
})
.collect::<Vec<_>>()
Expand Down
Loading