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

Commit 56cf7c4

Browse files
authored
Merge pull request #204 from crisdut/feat/consume-reveal
Proposal to unlocking blind utxo
2 parents 5db101b + 2954e69 commit 56cf7c4

15 files changed

+279
-26
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/src/command.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,13 @@ impl Exec for Opts {
279279
fs::write(psbt_out.unwrap_or(psbt_in), psbt_bytes)?;
280280
}
281281

282-
TransferCommand::Consume { force, consignment } => {
282+
TransferCommand::Consume {
283+
force,
284+
consignment,
285+
reveal,
286+
} => {
283287
let consignment = StateTransfer::strict_file_load(&consignment)?;
284-
let status = client.consume_transfer(consignment, force, progress)?;
288+
let status = client.consume_transfer(consignment, force, reveal, progress)?;
285289
report_validation(status);
286290
}
287291
},

cli/src/opts.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use internet2::addr::{NodeAddr, ServiceAddr};
1515
use lnpbp::chain::Chain;
1616
use rgb::schema::TransitionType;
1717
use rgb::{Contract, ContractId, SealEndpoint};
18-
use rgb_rpc::RGB_NODE_RPC_ENDPOINT;
18+
use rgb_rpc::{Reveal, RGB_NODE_RPC_ENDPOINT};
1919

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

186186
/// State transfer consignment send by the payee.
187187
consignment: PathBuf,
188+
189+
/// Try reveal the conceal seal.
190+
///
191+
/// The reveal infomration contains the outpoint and close method used
192+
/// to generated blind utxo and blinding_factor generated
193+
///
194+
/// Examples:
195+
///
196+
/// tapret1st@<outpoint>#<blinding_factor>
197+
/// opret1st@<outpoint>#<blinding_factor>
198+
#[clap(short, long)]
199+
reveal: Option<Reveal>,
188200
},
189201
}
190202

rpc/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ lnpbp = "0.8.0"
2222
bitcoin = "0.28.1"
2323
psbt = "0.8.4"
2424
internet2 = "0.8.3"
25+
bp-core = { version = "0.8.0", features = ["psbt"] }
2526
microservices = { version = "0.8.10", default-features = false, features = ["client"] }
2627
serde_crate = { package = "serde", version = "1", features = ["derive"], optional = true }
2728
serde_with = { version = "1.8", optional = true }

rpc/src/client.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use rgb::{Contract, ContractId, ContractState, ContractStateMap, SealEndpoint, S
2424

2525
use crate::messages::{HelloReq, TransferFinalize};
2626
use crate::{
27-
AcceptReq, BusMsg, ComposeReq, ContractValidity, Error, FailureCode, OutpointFilter, RpcMsg,
28-
ServiceId, TransferReq,
27+
AcceptReq, BusMsg, ComposeReq, ContractValidity, Error, FailureCode, OutpointFilter, Reveal,
28+
RpcMsg, ServiceId, TransferReq,
2929
};
3030

3131
// We have just a single service bus (RPC), so we can use any id
@@ -133,6 +133,7 @@ impl Client {
133133
self.request(RpcMsg::ConsumeContract(AcceptReq {
134134
consignment: contract,
135135
force,
136+
reveal: None,
136137
}))?;
137138
loop {
138139
match self.response()?.failure_to_error()? {
@@ -244,10 +245,12 @@ impl Client {
244245
&mut self,
245246
transfer: StateTransfer,
246247
force: bool,
248+
reveal: Option<Reveal>,
247249
progress: impl Fn(String),
248250
) -> Result<ContractValidity, Error> {
249251
self.request(RpcMsg::ConsumeTransfer(AcceptReq {
250252
consignment: transfer,
253+
reveal,
251254
force,
252255
}))?;
253256
loop {

rpc/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub mod client;
2626
mod error;
2727
mod messages;
2828
mod service_id;
29+
mod reveal;
2930

3031
pub use client::Client;
3132
pub use error::{Error, FailureCode};
@@ -34,6 +35,7 @@ pub use messages::{
3435
AcceptReq, ComposeReq, ContractValidity, HelloReq, OutpointFilter, RpcMsg, TransferFinalize,
3536
TransferReq,
3637
};
38+
pub use reveal::Reveal;
3739
pub use service_id::ServiceId;
3840

3941
pub const RGB_NODE_RPC_ENDPOINT: &str = "0.0.0.0:63963";

rpc/src/messages.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rgb::{
2323
ContractStateMap, InmemConsignment, SealEndpoint, StateTransfer, TransferConsignment,
2424
};
2525

26-
use crate::FailureCode;
26+
use crate::{FailureCode, Reveal};
2727

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

166167
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]

rpc/src/reveal.rs

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
// RGB node providing smart contracts functionality for Bitcoin & Lightning.
2+
//
3+
// Written in 2022 by
4+
// Dr. Maxim Orlovsky <orlovsky@lnp-bp.org>
5+
//
6+
// Copyright (C) 2022 by LNP/BP Standards Association, Switzerland.
7+
//
8+
// You should have received a copy of the MIT License along with this software.
9+
// If not, see <https://opensource.org/licenses/MIT>.
10+
11+
use bitcoin::OutPoint;
12+
use bp::seals::txout::CloseMethod;
13+
14+
#[derive(From, PartialEq, Eq, Debug, Clone, StrictEncode, StrictDecode)]
15+
pub struct Reveal {
16+
/// Outpoint blinding factor (generated when the utxo blinded was created)
17+
pub blinding_factor: u64,
18+
19+
/// Locally-controlled outpoint (specified when the utxo blinded was created)
20+
pub outpoint: OutPoint,
21+
22+
/// method (specified when the utxo blinded was created)
23+
pub close_method: CloseMethod,
24+
}
25+
26+
impl std::fmt::Display for Reveal {
27+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28+
write!(f, "{}@{}#{}", self.close_method, self.outpoint, self.blinding_factor)
29+
}
30+
}
31+
32+
/// Parses a blinding factor.
33+
fn parse_blind(s: &str) -> Result<u64, ParseRevealError> {
34+
s.parse().map_err(ParseRevealError::BlindingFactor)
35+
}
36+
37+
impl ::core::str::FromStr for Reveal {
38+
type Err = ParseRevealError;
39+
40+
fn from_str(s: &str) -> Result<Self, Self::Err> {
41+
// 9 + 19 + 1 + 64 + 1 + 10
42+
if s.len() > 97 {
43+
return Err(ParseRevealError::TooLong);
44+
}
45+
let find_method = s.find('@');
46+
if find_method == None {
47+
return Err(ParseRevealError::Format);
48+
}
49+
50+
let colon_method = find_method.unwrap();
51+
if colon_method == 0 || colon_method == s.len() - 1 {
52+
return Err(ParseRevealError::Format);
53+
}
54+
55+
let find_blind = s.find('#');
56+
if find_blind == None {
57+
return Err(ParseRevealError::Format);
58+
}
59+
60+
let colon_blind = find_blind.unwrap();
61+
if colon_blind == 0 || colon_blind == s.len() - 1 {
62+
return Err(ParseRevealError::Format);
63+
}
64+
65+
Ok(Reveal {
66+
close_method: match CloseMethod::from_str(&s[..colon_method]) {
67+
Ok(it) => it,
68+
Err(_) => return Err(ParseRevealError::CloseMethod),
69+
},
70+
outpoint: match OutPoint::from_str(&s[colon_method + 1..colon_blind]) {
71+
Ok(it) => it,
72+
Err(_) => return Err(ParseRevealError::Outpoint),
73+
},
74+
blinding_factor: parse_blind(&s[colon_blind + 1..])?,
75+
})
76+
}
77+
}
78+
79+
/// An error in parsing an OutPoint.
80+
#[derive(Clone, PartialEq, Eq, Debug)]
81+
pub enum ParseRevealError {
82+
/// Error in outpoint part.
83+
CloseMethod,
84+
/// Error in outpoint part.
85+
Outpoint,
86+
/// Error in blinding factor part.
87+
BlindingFactor(::core::num::ParseIntError),
88+
/// Error in general format.
89+
Format,
90+
/// Size exceeds max.
91+
TooLong,
92+
}
93+
94+
impl std::fmt::Display for ParseRevealError {
95+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
96+
match *self {
97+
ParseRevealError::CloseMethod => write!(f, "error parsing CloseMethod"),
98+
ParseRevealError::Outpoint => write!(f, "error parsing OutPoint"),
99+
ParseRevealError::BlindingFactor(ref e) => {
100+
write!(f, "error parsing blinding_factor: {}", e)
101+
}
102+
ParseRevealError::Format => {
103+
write!(f, "Reveal not in <blind_factor>@<txid>:<vout> format")
104+
}
105+
ParseRevealError::TooLong => write!(f, "reveal should be at most 95 digits"),
106+
}
107+
}
108+
}
109+
110+
impl ::std::error::Error for ParseRevealError {
111+
fn cause(&self) -> Option<&dyn ::std::error::Error> {
112+
match *self {
113+
ParseRevealError::BlindingFactor(ref e) => Some(e),
114+
_ => None,
115+
}
116+
}
117+
}

shell/_rgb-cli

+2
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,8 @@ _arguments "${_arguments_options[@]}" \
268268
;;
269269
(consume)
270270
_arguments "${_arguments_options[@]}" \
271+
'-r+[Try reveal the conceal seal]:REVEAL: ' \
272+
'--reveal=[Try reveal the conceal seal]:REVEAL: ' \
271273
'-R+[ZMQ socket for connecting daemon RPC interface]:CONNECT: ' \
272274
'--rpc=[ZMQ socket for connecting daemon RPC interface]:CONNECT: ' \
273275
'-n+[Blockchain to use]:CHAIN: ' \

shell/_rgb-cli.ps1

+2
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ Register-ArgumentCompleter -Native -CommandName 'rgb-cli' -ScriptBlock {
220220
break
221221
}
222222
'rgb-cli;transfer;consume' {
223+
[CompletionResult]::new('-r', 'r', [CompletionResultType]::ParameterName, 'Try reveal the conceal seal')
224+
[CompletionResult]::new('--reveal', 'reveal', [CompletionResultType]::ParameterName, 'Try reveal the conceal seal')
223225
[CompletionResult]::new('-R', 'R', [CompletionResultType]::ParameterName, 'ZMQ socket for connecting daemon RPC interface')
224226
[CompletionResult]::new('--rpc', 'rpc', [CompletionResultType]::ParameterName, 'ZMQ socket for connecting daemon RPC interface')
225227
[CompletionResult]::new('-n', 'n', [CompletionResultType]::ParameterName, 'Blockchain to use')

shell/rgb-cli.bash

+9-1
Original file line numberDiff line numberDiff line change
@@ -556,12 +556,20 @@ _rgb-cli() {
556556
return 0
557557
;;
558558
rgb__cli__transfer__consume)
559-
opts="-f -h -R -n -v --force --help --rpc --chain --verbose <CONSIGNMENT>"
559+
opts="-f -r -h -R -n -v --force --reveal --help --rpc --chain --verbose <CONSIGNMENT>"
560560
if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then
561561
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
562562
return 0
563563
fi
564564
case "${prev}" in
565+
--reveal)
566+
COMPREPLY=($(compgen -f "${cur}"))
567+
return 0
568+
;;
569+
-r)
570+
COMPREPLY=($(compgen -f "${cur}"))
571+
return 0
572+
;;
565573
--rpc)
566574
COMPREPLY=($(compgen -f "${cur}"))
567575
return 0

0 commit comments

Comments
 (0)