Skip to content
This repository has been archived by the owner on Dec 9, 2023. It is now read-only.

Commit

Permalink
allow many transfers by cli
Browse files Browse the repository at this point in the history
  • Loading branch information
crisdut committed Jan 12, 2023
1 parent 770ce83 commit fcdf41f
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 314 deletions.
47 changes: 28 additions & 19 deletions cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
// You should have received a copy of the MIT License along with this software.
// If not, see <https://opensource.org/licenses/MIT>.

use std::collections::BTreeSet;
use std::collections::{BTreeMap, BTreeSet};
use std::{fs, io};

use crate::opts::{ContractCommand, OutpointCommand, TransferCommand};
use crate::{Command, Opts};
use amplify::IoError;
use bitcoin::consensus;
use bitcoin::psbt::serialize::{Deserialize, Serialize};
Expand All @@ -20,13 +22,10 @@ use microservices::shell::Exec;
use psbt::Psbt;
use rgb::blank::BlankBundle;
use rgb::psbt::{RgbExt, RgbInExt};
use rgb::{Node, StateTransfer, Transition, TransitionBundle};
use rgb::{Node, SealEndpoint, StateTransfer, Transition, TransitionBundle};
use rgb_rpc::{Client, ContractValidity};
use strict_encoding::{StrictDecode, StrictEncode};

use crate::opts::{ContractCommand, OutpointCommand, TransferCommand};
use crate::{Command, Opts};

#[derive(Debug, Display, Error, From)]
#[display(inner)]
pub enum Error {
Expand Down Expand Up @@ -93,10 +92,7 @@ impl TransferCommand {
format!("Composing consignment for state transfer for contract {}", contract_id)
}
Self::Combine { .. } => s!("Preparing PSBT for the state transfer"),
Self::Finalize {
send: Some(addr), ..
} => format!("Finalizing state transfer and sending it to {}", addr),
Self::Finalize { send: None, .. } => s!("Finalizing state transfer"),
Self::Finalize { .. } => s!("Finalizing state transfers"),
Self::Consume { .. } => s!("Verifying and consuming state transfer"),
}
}
Expand Down Expand Up @@ -261,23 +257,36 @@ impl Exec for Opts {
}

TransferCommand::Finalize {
endseal,
psbt: psbt_in,
consignment_in,
consignment_out,
endseals,
send,
psbt_out,
} => {
let psbt_bytes = fs::read(&psbt_in)?;
let psbt = Psbt::deserialize(&psbt_bytes)?;
let consignment = StateTransfer::strict_file_load(&consignment_in)?;
let transfer = client.transfer(consignment, endseals, psbt, send, progress)?;

transfer
.consignment
.strict_file_save(consignment_out.unwrap_or(consignment_in))?;
let mut consig_paths = BTreeMap::new();
let transfers: Vec<(StateTransfer, Vec<SealEndpoint>)> = endseal
.into_iter()
.map(|b| -> (StateTransfer, Vec<SealEndpoint>) {
let consignment =
StateTransfer::strict_file_load(b.consignment.clone())
.expect("Valid consignment file");
consig_paths.insert(consignment.contract_id(), b.consignment);
(consignment, b.endseals)
})
.collect();

let transfers = client.finalize_transfers(transfers, psbt, progress)?;
for transfer in transfers.consignments {
if consig_paths.contains_key(&transfer.contract_id()) {
let path = consig_paths
.get(&transfer.contract_id())
.expect("Invalid consignment path");
let _ = transfer.strict_file_save(path);
}
}

let psbt_bytes = transfer.psbt.serialize();
let psbt_bytes = transfers.psbt.serialize();
fs::write(psbt_out.unwrap_or(psbt_in), psbt_bytes)?;
}

Expand Down
25 changes: 10 additions & 15 deletions cli/src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
use std::path::PathBuf;

use bitcoin::OutPoint;
use internet2::addr::{NodeAddr, ServiceAddr};
use internet2::addr::ServiceAddr;
use lnpbp::chain::Chain;
use rgb::schema::TransitionType;
use rgb::{Contract, ContractId, SealEndpoint};
use rgb_rpc::{Reveal, RGB_NODE_RPC_ENDPOINT};
use rgb::{Contract, ContractId};
use rgb_rpc::{NewTransfer, Reveal, RGB_NODE_RPC_ENDPOINT};

/// Command-line tool for working with RGB node
#[derive(Parser, Clone, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -151,14 +151,10 @@ pub enum TransferCommand {
/// (LNP Node).
#[display("finalize ...")]
Finalize {
/// Bifrost server to send state transfer to
#[clap(short, long)]
send: Option<NodeAddr>,

/// Beneficiary blinded TXO seal - or witness transaction output numbers
/// containing allocations for the beneficiary.
#[clap(short, long = "endseal", required = true)]
endseals: Vec<SealEndpoint>,
endseal: Vec<NewTransfer>,

/// The final PSBT (not modified).
psbt: PathBuf,
Expand All @@ -167,13 +163,12 @@ pub enum TransferCommand {
/// information. If not given, the source PSBT file is overwritten.
#[clap(short = 'o', long = "out")]
psbt_out: Option<PathBuf>,
// /// State transfer consignment draft file prepared with `compose` command.
// consignment_in: PathBuf,

/// State transfer consignment draft file prepared with `compose` command.
consignment_in: PathBuf,

/// Output file to save the final consignment. If not given, the source
/// consignment file is overwritten.
consignment_out: Option<PathBuf>,
// /// Output file to save the final consignment. If not given, the source
// /// consignment file is overwritten.
// consignment_out: Option<PathBuf>,
},

/// Validate incoming transfer consignment and consume it into the stash.
Expand All @@ -194,7 +189,7 @@ pub enum TransferCommand {
/// Examples:
///
/// tapret1st@<outpoint>#<blinding_factor>
/// opret1st@<outpoint>#<blinding_factor>
/// opret1st@<outpoint>#<blinding_factor>
#[clap(short, long)]
reveal: Option<Reveal>,
},
Expand Down
29 changes: 3 additions & 26 deletions rpc/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::thread::sleep;
use std::time::Duration;

use bitcoin::{OutPoint, Txid};
use internet2::addr::{NodeAddr, ServiceAddr};
use internet2::addr::ServiceAddr;
use internet2::ZmqSocketType;
use lnpbp::chain::Chain;
use microservices::esb::{self, BusId, ClientId};
Expand All @@ -22,10 +22,10 @@ use psbt::Psbt;
use rgb::schema::TransitionType;
use rgb::{Contract, ContractId, ContractState, ContractStateMap, SealEndpoint, StateTransfer};

use crate::messages::{FinalizeTransfersRes, HelloReq, TransferFinalize, TransfersReq};
use crate::messages::{FinalizeTransfersRes, HelloReq, TransfersReq};
use crate::{
AcceptReq, BusMsg, ComposeReq, ContractValidity, Error, FailureCode, OutpointFilter, Reveal,
RpcMsg, ServiceId, TransferReq,
RpcMsg, ServiceId,
};

// We have just a single service bus (RPC), so we can use any id
Expand Down Expand Up @@ -218,29 +218,6 @@ impl Client {
}
}

pub fn transfer(
&mut self,
consignment: StateTransfer,
endseals: Vec<SealEndpoint>,
psbt: Psbt,
beneficiary: Option<NodeAddr>,
progress: impl Fn(String),
) -> Result<TransferFinalize, Error> {
self.request(RpcMsg::Transfer(TransferReq {
consignment,
endseals,
psbt,
beneficiary,
}))?;
loop {
match self.response()?.failure_to_error()? {
RpcMsg::StateTransferFinalize(transfer) => return Ok(transfer),
RpcMsg::Progress(info) => progress(info),
_ => return Err(Error::UnexpectedServerResponse),
}
}
}

pub fn finalize_transfers(
&mut self,
transfers: Vec<(StateTransfer, Vec<SealEndpoint>)>,
Expand Down
6 changes: 3 additions & 3 deletions rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ pub mod client;
mod error;
mod messages;
mod service_id;
mod reveal;
mod structs;

pub use client::Client;
pub use error::{Error, FailureCode};
pub(crate) use messages::BusMsg;
pub use messages::{
AcceptReq, ComposeReq, ContractValidity, FinalizeTransfersRes, HelloReq, OutpointFilter,
RpcMsg, TransferFinalize, TransferReq, TransfersReq,
RpcMsg, TransfersReq,
};
pub use reveal::Reveal;
pub use service_id::ServiceId;
pub use structs::{NewTransfer, Reveal};

pub const RGB_NODE_RPC_ENDPOINT: &str = "0.0.0.0:63963";
25 changes: 0 additions & 25 deletions rpc/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use std::collections::BTreeSet;

use bitcoin::{OutPoint, Txid};
use internet2::addr::NodeAddr;
use internet2::presentation;
use lnpbp::chain::Chain;
use microservices::rpc;
Expand Down Expand Up @@ -71,9 +70,6 @@ pub enum RpcMsg {
#[display("process_disclosure({0})")]
ProcessDisclosure(Txid),

#[display(inner)]
Transfer(TransferReq),

#[display(inner)]
FinalizeTransfers(TransfersReq),

Expand All @@ -97,9 +93,6 @@ pub enum RpcMsg {
#[display("state_transfer(...)")]
StateTransfer(StateTransfer),

#[display("state_transfer_finalize(...)")]
StateTransferFinalize(TransferFinalize),

#[display("state_transfer_finalize(...)")]
FinalizedTransfers(FinalizeTransfersRes),

Expand Down Expand Up @@ -190,24 +183,6 @@ pub struct ComposeReq {
pub outpoints: OutpointFilter,
}

#[derive(Clone, PartialEq, Eq, Debug, Display)]
#[derive(NetworkEncode, NetworkDecode)]
#[display("transfer(...)")]
pub struct TransferReq {
pub consignment: StateTransfer,
pub endseals: Vec<SealEndpoint>,
pub psbt: Psbt,
pub beneficiary: Option<NodeAddr>,
}

#[derive(Clone, PartialEq, Eq, Debug, Display)]
#[derive(NetworkEncode, NetworkDecode)]
#[display("transfer_complete(...)")]
pub struct TransferFinalize {
pub consignment: StateTransfer,
pub psbt: Psbt,
}

#[derive(Clone, PartialEq, Eq, Debug, Display)]
#[derive(NetworkEncode, NetworkDecode)]
#[display("transfers_req(...)")]
Expand Down
82 changes: 82 additions & 0 deletions rpc/src/reveal.rs → rpc/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use bitcoin::OutPoint;
use bp::seals::txout::CloseMethod;
use rgb::SealEndpoint;

#[derive(From, PartialEq, Eq, Debug, Clone, StrictEncode, StrictDecode)]
pub struct Reveal {
Expand Down Expand Up @@ -115,3 +116,84 @@ impl ::std::error::Error for ParseRevealError {
}
}
}

#[derive(From, PartialEq, Eq, Debug, Clone, StrictEncode, StrictDecode)]
pub struct NewTransfer {
/// Beneficiary blinded TXO seal - or witness transaction output numbers
/// containing allocations for the beneficiary.
pub endseals: Vec<SealEndpoint>,

/// State transfer consignment draft file prepared with `compose` command.
pub consignment: String,
}

/// An error in parsing an OutPoint.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ParseNewTransferError {
/// Error in seal endpoint part.
SealEndpoint,
/// Error in consignment part.
Consignment,
/// Error in general format.
Format,
}

impl std::fmt::Display for ParseNewTransferError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
ParseNewTransferError::SealEndpoint => write!(f, "error parsing SealEndpoint"),
ParseNewTransferError::Consignment => write!(f, "error parsing Consignment"),
ParseNewTransferError::Format => todo!(),
}
}
}

impl std::fmt::Display for NewTransfer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let endseals: Vec<String> =
self.endseals.clone().into_iter().map(|e| e.to_string()).collect();
let endseals = endseals.join(",");
write!(f, "{}:{}", endseals, self.consignment)
}
}

impl ::core::str::FromStr for NewTransfer {
type Err = ParseNewTransferError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let find_consig = s.find(':');
let index_consig = match find_consig {
Some(index) => index,
_ => return Err(ParseNewTransferError::Format),
};

println!("{}", "passou aqui");
if index_consig == 0 || index_consig == s.len() - 1 {
return Err(ParseNewTransferError::Format);
}

let find_endseals = s.find(',');
let endseals = match find_endseals {
Some(_) => s[..index_consig]
.split(',')
.into_iter()
.map(|e| SealEndpoint::from_str(e).expect("Error in SealEndpoint part"))
.collect(),
_ => {
vec![SealEndpoint::from_str(&s[..index_consig]).expect("Error in SealEndpoint part")]
}
};

Ok(NewTransfer {
endseals,
consignment: match String::try_from(&s[index_consig + 1..]) {
Ok(it) => it,
Err(_) => return Err(ParseNewTransferError::Consignment),
},
})
}
}

impl ::std::error::Error for ParseNewTransferError {
fn cause(&self) -> Option<&dyn ::std::error::Error> { None }
}
8 changes: 2 additions & 6 deletions shell/_rgb-cli
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,8 @@ _arguments "${_arguments_options[@]}" \
;;
(finalize)
_arguments "${_arguments_options[@]}" \
'-s+[Bifrost server to send state transfer to]:SEND: ' \
'--send=[Bifrost server to send state transfer to]:SEND: ' \
'*-e+[Beneficiary blinded TXO seal - or witness transaction output numbers containing allocations for the beneficiary]:ENDSEALS: ' \
'*--endseal=[Beneficiary blinded TXO seal - or witness transaction output numbers containing allocations for the beneficiary]:ENDSEALS: ' \
'*-e+[Beneficiary blinded TXO seal - or witness transaction output numbers containing allocations for the beneficiary]:ENDSEAL: ' \
'*--endseal=[Beneficiary blinded TXO seal - or witness transaction output numbers containing allocations for the beneficiary]:ENDSEAL: ' \
'-o+[Output file to save the PSBT updated with state transition(s) information. If not given, the source PSBT file is overwritten]:PSBT_OUT: ' \
'--out=[Output file to save the PSBT updated with state transition(s) information. If not given, the source PSBT file is overwritten]:PSBT_OUT: ' \
'-R+[ZMQ socket for connecting daemon RPC interface]:CONNECT: ' \
Expand All @@ -262,8 +260,6 @@ _arguments "${_arguments_options[@]}" \
'*-v[Set verbosity level]' \
'*--verbose[Set verbosity level]' \
':psbt -- The final PSBT (not modified):' \
':consignment-in -- State transfer consignment draft file prepared with `compose` command:' \
'::consignment-out -- Output file to save the final consignment. If not given, the source consignment file is overwritten:' \
&& ret=0
;;
(consume)
Expand Down
2 changes: 0 additions & 2 deletions shell/_rgb-cli.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,6 @@ Register-ArgumentCompleter -Native -CommandName 'rgb-cli' -ScriptBlock {
break
}
'rgb-cli;transfer;finalize' {
[CompletionResult]::new('-s', 's', [CompletionResultType]::ParameterName, 'Bifrost server to send state transfer to')
[CompletionResult]::new('--send', 'send', [CompletionResultType]::ParameterName, 'Bifrost server to send state transfer to')
[CompletionResult]::new('-e', 'e', [CompletionResultType]::ParameterName, 'Beneficiary blinded TXO seal - or witness transaction output numbers containing allocations for the beneficiary')
[CompletionResult]::new('--endseal', 'endseal', [CompletionResultType]::ParameterName, 'Beneficiary blinded TXO seal - or witness transaction output numbers containing allocations for the beneficiary')
[CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'Output file to save the PSBT updated with state transition(s) information. If not given, the source PSBT file is overwritten')
Expand Down
Loading

0 comments on commit fcdf41f

Please sign in to comment.