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

Proposal to unlocking blind utxo #204

Merged
merged 1 commit into from
Sep 30, 2022
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
1 change: 1 addition & 0 deletions Cargo.lock

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

8 changes: 6 additions & 2 deletions cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,13 @@ impl Exec for Opts {
fs::write(psbt_out.unwrap_or(psbt_in), psbt_bytes)?;
}

TransferCommand::Consume { force, consignment } => {
TransferCommand::Consume {
force,
consignment,
reveal,
} => {
let consignment = StateTransfer::strict_file_load(&consignment)?;
let status = client.consume_transfer(consignment, force, progress)?;
let status = client.consume_transfer(consignment, force, reveal, progress)?;
report_validation(status);
}
},
Expand Down
14 changes: 13 additions & 1 deletion cli/src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use internet2::addr::{NodeAddr, ServiceAddr};
use lnpbp::chain::Chain;
use rgb::schema::TransitionType;
use rgb::{Contract, ContractId, SealEndpoint};
use rgb_rpc::RGB_NODE_RPC_ENDPOINT;
use rgb_rpc::{Reveal, RGB_NODE_RPC_ENDPOINT};

/// Command-line tool for working with RGB node
#[derive(Parser, Clone, PartialEq, Eq, Debug)]
Expand Down Expand Up @@ -185,6 +185,18 @@ pub enum TransferCommand {

/// State transfer consignment send by the payee.
consignment: PathBuf,

/// Try reveal the conceal seal.
///
/// The reveal infomration contains the outpoint and close method used
/// to generated blind utxo and blinding_factor generated
///
/// Examples:
///
/// tapret1st@<outpoint>#<blinding_factor>
/// opret1st@<outpoint>#<blinding_factor>
#[clap(short, long)]
reveal: Option<Reveal>,
},
}

Expand Down
1 change: 1 addition & 0 deletions rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ lnpbp = "0.8.0"
bitcoin = "0.28.1"
psbt = "0.8.4"
internet2 = "0.8.3"
bp-core = { version = "0.8.0", features = ["psbt"] }
microservices = { version = "0.8.10", default-features = false, features = ["client"] }
serde_crate = { package = "serde", version = "1", features = ["derive"], optional = true }
serde_with = { version = "1.8", optional = true }
Expand Down
7 changes: 5 additions & 2 deletions rpc/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use rgb::{Contract, ContractId, ContractState, ContractStateMap, SealEndpoint, S

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

// We have just a single service bus (RPC), so we can use any id
Expand Down Expand Up @@ -133,6 +133,7 @@ impl Client {
self.request(RpcMsg::ConsumeContract(AcceptReq {
consignment: contract,
force,
reveal: None,
}))?;
loop {
match self.response()?.failure_to_error()? {
Expand Down Expand Up @@ -244,10 +245,12 @@ impl Client {
&mut self,
transfer: StateTransfer,
force: bool,
reveal: Option<Reveal>,
progress: impl Fn(String),
) -> Result<ContractValidity, Error> {
self.request(RpcMsg::ConsumeTransfer(AcceptReq {
consignment: transfer,
reveal,
force,
}))?;
loop {
Expand Down
2 changes: 2 additions & 0 deletions rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub mod client;
mod error;
mod messages;
mod service_id;
mod reveal;

pub use client::Client;
pub use error::{Error, FailureCode};
Expand All @@ -34,6 +35,7 @@ pub use messages::{
AcceptReq, ComposeReq, ContractValidity, HelloReq, OutpointFilter, RpcMsg, TransferFinalize,
TransferReq,
};
pub use reveal::Reveal;
pub use service_id::ServiceId;

pub const RGB_NODE_RPC_ENDPOINT: &str = "0.0.0.0:63963";
3 changes: 2 additions & 1 deletion rpc/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use rgb::{
ContractStateMap, InmemConsignment, SealEndpoint, StateTransfer, TransferConsignment,
};

use crate::FailureCode;
use crate::{FailureCode, Reveal};

/// We need this wrapper type to be compatible with RGB Node having multiple message buses
#[derive(Clone, Debug, Display, From, Api)]
Expand Down Expand Up @@ -161,6 +161,7 @@ impl OutpointFilter {
pub struct AcceptReq<T: ConsignmentType> {
pub consignment: InmemConsignment<T>,
pub force: bool,
pub reveal: Option<Reveal>,
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
Expand Down
117 changes: 117 additions & 0 deletions rpc/src/reveal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// RGB node providing smart contracts functionality for Bitcoin & Lightning.
//
// Written in 2022 by
// Dr. Maxim Orlovsky <orlovsky@lnp-bp.org>
//
// Copyright (C) 2022 by LNP/BP Standards Association, Switzerland.
//
// You should have received a copy of the MIT License along with this software.
// If not, see <https://opensource.org/licenses/MIT>.

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

#[derive(From, PartialEq, Eq, Debug, Clone, StrictEncode, StrictDecode)]
pub struct Reveal {
/// Outpoint blinding factor (generated when the utxo blinded was created)
pub blinding_factor: u64,

/// Locally-controlled outpoint (specified when the utxo blinded was created)
pub outpoint: OutPoint,

/// method (specified when the utxo blinded was created)
pub close_method: CloseMethod,
}

impl std::fmt::Display for Reveal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}@{}#{}", self.close_method, self.outpoint, self.blinding_factor)
}
}

/// Parses a blinding factor.
fn parse_blind(s: &str) -> Result<u64, ParseRevealError> {
s.parse().map_err(ParseRevealError::BlindingFactor)
}

impl ::core::str::FromStr for Reveal {
type Err = ParseRevealError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
// 9 + 19 + 1 + 64 + 1 + 10
if s.len() > 97 {
return Err(ParseRevealError::TooLong);
}
let find_method = s.find('@');
if find_method == None {
return Err(ParseRevealError::Format);
}

let colon_method = find_method.unwrap();
if colon_method == 0 || colon_method == s.len() - 1 {
return Err(ParseRevealError::Format);
}

let find_blind = s.find('#');
if find_blind == None {
return Err(ParseRevealError::Format);
}

let colon_blind = find_blind.unwrap();
if colon_blind == 0 || colon_blind == s.len() - 1 {
return Err(ParseRevealError::Format);
}

Ok(Reveal {
close_method: match CloseMethod::from_str(&s[..colon_method]) {
Ok(it) => it,
Err(_) => return Err(ParseRevealError::CloseMethod),
},
outpoint: match OutPoint::from_str(&s[colon_method + 1..colon_blind]) {
Ok(it) => it,
Err(_) => return Err(ParseRevealError::Outpoint),
},
blinding_factor: parse_blind(&s[colon_blind + 1..])?,
})
}
}

/// An error in parsing an OutPoint.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ParseRevealError {
/// Error in outpoint part.
CloseMethod,
/// Error in outpoint part.
Outpoint,
/// Error in blinding factor part.
BlindingFactor(::core::num::ParseIntError),
/// Error in general format.
Format,
/// Size exceeds max.
TooLong,
}

impl std::fmt::Display for ParseRevealError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
ParseRevealError::CloseMethod => write!(f, "error parsing CloseMethod"),
ParseRevealError::Outpoint => write!(f, "error parsing OutPoint"),
ParseRevealError::BlindingFactor(ref e) => {
write!(f, "error parsing blinding_factor: {}", e)
}
ParseRevealError::Format => {
write!(f, "Reveal not in <blind_factor>@<txid>:<vout> format")
}
ParseRevealError::TooLong => write!(f, "reveal should be at most 95 digits"),
}
}
}

impl ::std::error::Error for ParseRevealError {
fn cause(&self) -> Option<&dyn ::std::error::Error> {
match *self {
ParseRevealError::BlindingFactor(ref e) => Some(e),
_ => None,
}
}
}
2 changes: 2 additions & 0 deletions shell/_rgb-cli
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ _arguments "${_arguments_options[@]}" \
;;
(consume)
_arguments "${_arguments_options[@]}" \
'-r+[Try reveal the conceal seal]:REVEAL: ' \
'--reveal=[Try reveal the conceal seal]:REVEAL: ' \
'-R+[ZMQ socket for connecting daemon RPC interface]:CONNECT: ' \
'--rpc=[ZMQ socket for connecting daemon RPC interface]:CONNECT: ' \
'-n+[Blockchain to use]:CHAIN: ' \
Expand Down
2 changes: 2 additions & 0 deletions shell/_rgb-cli.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ Register-ArgumentCompleter -Native -CommandName 'rgb-cli' -ScriptBlock {
break
}
'rgb-cli;transfer;consume' {
[CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Try reveal the conceal seal')
[CompletionResult]::new('--reveal', 'reveal', [CompletionResultType]::ParameterName, 'Try reveal the conceal seal')
[CompletionResult]::new('-R', 'R', [CompletionResultType]::ParameterName, 'ZMQ socket for connecting daemon RPC interface')
[CompletionResult]::new('--rpc', 'rpc', [CompletionResultType]::ParameterName, 'ZMQ socket for connecting daemon RPC interface')
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Blockchain to use')
Expand Down
10 changes: 9 additions & 1 deletion shell/rgb-cli.bash
Original file line number Diff line number Diff line change
Expand Up @@ -556,12 +556,20 @@ _rgb-cli() {
return 0
;;
rgb__cli__transfer__consume)
opts="-f -h -R -n -v --force --help --rpc --chain --verbose <CONSIGNMENT>"
opts="-f -r -h -R -n -v --force --reveal --help --rpc --chain --verbose <CONSIGNMENT>"
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
return 0
fi
case "${prev}" in
--reveal)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
-r)
COMPREPLY=($(compgen -f "${cur}"))
return 0
;;
--rpc)
COMPREPLY=($(compgen -f "${cur}"))
return 0
Expand Down
Loading