@ -7,22 +7,17 @@ use crate::{
} ,
execution_params ::ExecutionParams ,
monero ,
monero_ext ::ScalarExt ,
protocol ::{
alice ::{ Message1 , Message3 , TransferProof },
bob ::{ EncryptedSignature, Message0, Message2 , Message4 } ,
alice ::{ Message1 , Message3 },
bob ::{ Message0, Message2 , Message4 } ,
CROSS_CURVE_PROOF_SYSTEM ,
} ,
} ;
use anyhow ::{ anyhow , bail , Context , Result } ;
use ecdsa_fun ::{
adaptor ::{ Adaptor , HashTranscript } ,
nonce ::Deterministic ,
} ;
use libp2p ::PeerId ;
use monero_rpc ::wallet ::BlockHeight ;
use rand ::{ CryptoRng , RngCore } ;
use serde ::{ Deserialize , Serialize } ;
use sha2 ::Sha256 ;
use sigma_fun ::ext ::dl_secp256k1_ed25519_eq ::CrossCurveDLEQProof ;
use std ::fmt ;
@ -37,27 +32,33 @@ pub enum AliceState {
state3 : Box < State3 > ,
} ,
XmrLocked {
monero_wallet_restore_blockheight : BlockHeight ,
state3 : Box < State3 > ,
} ,
EncSigLearned {
monero_wallet_restore_blockheight : BlockHeight ,
encrypted_signature : Box < bitcoin ::EncryptedSignature > ,
state3 : Box < State3 > ,
} ,
BtcRedeemed ,
BtcCancelled {
monero_wallet_restore_blockheight : BlockHeight ,
tx_cancel : Box < TxCancel > ,
state3 : Box < State3 > ,
} ,
BtcRefunded {
monero_wallet_restore_blockheight : BlockHeight ,
spend_key : monero ::PrivateKey ,
state3 : Box < State3 > ,
} ,
BtcPunishable {
monero_wallet_restore_blockheight : BlockHeight ,
tx_refund : TxRefund ,
state3 : Box < State3 > ,
} ,
XmrRefunded ,
CancelTimelockExpired {
monero_wallet_restore_blockheight : BlockHeight ,
state3 : Box < State3 > ,
} ,
BtcPunished ,
@ -349,191 +350,3 @@ impl State3 {
. await
}
}
#[ derive(Clone, Debug, Deserialize, Serialize) ]
pub struct State4 {
a : bitcoin ::SecretKey ,
B : bitcoin ::PublicKey ,
s_a : monero ::Scalar ,
S_b_monero : monero ::PublicKey ,
S_b_bitcoin : bitcoin ::PublicKey ,
v : monero ::PrivateViewKey ,
xmr : monero ::Amount ,
cancel_timelock : CancelTimelock ,
punish_timelock : PunishTimelock ,
refund_address : bitcoin ::Address ,
redeem_address : bitcoin ::Address ,
punish_address : bitcoin ::Address ,
tx_lock : bitcoin ::TxLock ,
tx_punish_sig_bob : bitcoin ::Signature ,
tx_cancel_sig_bob : bitcoin ::Signature ,
}
impl State4 {
pub async fn lock_xmr < W > ( self , monero_wallet : & W ) -> Result < State5 >
where
W : monero ::Transfer ,
{
let S_a = monero ::PublicKey ::from_private_key ( & monero ::PrivateKey { scalar : self . s_a } ) ;
let S_b = self . S_b_monero ;
let ( tx_lock_proof , fee ) = monero_wallet
. transfer ( S_a + S_b , self . v . public ( ) , self . xmr )
. await ? ;
Ok ( State5 {
a : self . a ,
B : self . B ,
s_a : self . s_a ,
S_b_monero : self . S_b_monero ,
S_b_bitcoin : self . S_b_bitcoin ,
v : self . v ,
cancel_timelock : self . cancel_timelock ,
punish_timelock : self . punish_timelock ,
refund_address : self . refund_address ,
redeem_address : self . redeem_address ,
punish_address : self . punish_address ,
tx_lock : self . tx_lock ,
tx_lock_proof ,
tx_punish_sig_bob : self . tx_punish_sig_bob ,
tx_cancel_sig_bob : self . tx_cancel_sig_bob ,
lock_xmr_fee : fee ,
} )
}
pub async fn punish < W : bitcoin ::BroadcastSignedTransaction > (
& self ,
bitcoin_wallet : & W ,
) -> Result < ( ) > {
let tx_cancel =
bitcoin ::TxCancel ::new ( & self . tx_lock , self . cancel_timelock , self . a . public ( ) , self . B ) ;
let tx_punish =
bitcoin ::TxPunish ::new ( & tx_cancel , & self . punish_address , self . punish_timelock ) ;
{
let sig_a = self . a . sign ( tx_cancel . digest ( ) ) ;
let sig_b = self . tx_cancel_sig_bob . clone ( ) ;
let signed_tx_cancel = tx_cancel . clone ( ) . add_signatures (
& self . tx_lock ,
( self . a . public ( ) , sig_a ) ,
( self . B , sig_b ) ,
) ? ;
let _ = bitcoin_wallet
. broadcast_signed_transaction ( signed_tx_cancel )
. await ? ;
}
{
let sig_a = self . a . sign ( tx_punish . digest ( ) ) ;
let sig_b = self . tx_punish_sig_bob . clone ( ) ;
let signed_tx_punish =
tx_punish . add_signatures ( & tx_cancel , ( self . a . public ( ) , sig_a ) , ( self . B , sig_b ) ) ? ;
let _ = bitcoin_wallet
. broadcast_signed_transaction ( signed_tx_punish )
. await ? ;
}
Ok ( ( ) )
}
}
#[ derive(Clone, Debug, Deserialize, Serialize) ]
pub struct State5 {
a : bitcoin ::SecretKey ,
B : bitcoin ::PublicKey ,
s_a : monero ::Scalar ,
S_b_monero : monero ::PublicKey ,
S_b_bitcoin : bitcoin ::PublicKey ,
v : monero ::PrivateViewKey ,
cancel_timelock : CancelTimelock ,
punish_timelock : PunishTimelock ,
refund_address : bitcoin ::Address ,
redeem_address : bitcoin ::Address ,
punish_address : bitcoin ::Address ,
tx_lock : bitcoin ::TxLock ,
tx_lock_proof : monero ::TransferProof ,
tx_punish_sig_bob : bitcoin ::Signature ,
tx_cancel_sig_bob : bitcoin ::Signature ,
lock_xmr_fee : monero ::Amount ,
}
impl State5 {
pub fn next_message ( & self ) -> TransferProof {
TransferProof {
tx_lock_proof : self . tx_lock_proof . clone ( ) ,
}
}
pub fn receive ( self , msg : EncryptedSignature ) -> State6 {
State6 {
a : self . a ,
B : self . B ,
s_a : self . s_a ,
S_b_monero : self . S_b_monero ,
S_b_bitcoin : self . S_b_bitcoin ,
v : self . v ,
cancel_timelock : self . cancel_timelock ,
punish_timelock : self . punish_timelock ,
refund_address : self . refund_address ,
redeem_address : self . redeem_address ,
punish_address : self . punish_address ,
tx_lock : self . tx_lock ,
tx_punish_sig_bob : self . tx_punish_sig_bob ,
tx_redeem_encsig : msg . tx_redeem_encsig ,
lock_xmr_fee : self . lock_xmr_fee ,
}
}
}
#[ derive(Clone, Debug, Deserialize, Serialize) ]
pub struct State6 {
a : bitcoin ::SecretKey ,
B : bitcoin ::PublicKey ,
s_a : monero ::Scalar ,
S_b_monero : monero ::PublicKey ,
S_b_bitcoin : bitcoin ::PublicKey ,
v : monero ::PrivateViewKey ,
cancel_timelock : CancelTimelock ,
punish_timelock : PunishTimelock ,
refund_address : bitcoin ::Address ,
redeem_address : bitcoin ::Address ,
punish_address : bitcoin ::Address ,
tx_lock : bitcoin ::TxLock ,
tx_punish_sig_bob : bitcoin ::Signature ,
tx_redeem_encsig : bitcoin ::EncryptedSignature ,
lock_xmr_fee : monero ::Amount ,
}
impl State6 {
pub async fn redeem_btc < W : bitcoin ::BroadcastSignedTransaction > (
& self ,
bitcoin_wallet : & W ,
) -> Result < ( ) > {
let adaptor = Adaptor ::< HashTranscript < Sha256 > , Deterministic < Sha256 > > ::default ( ) ;
let tx_redeem = bitcoin ::TxRedeem ::new ( & self . tx_lock , & self . redeem_address ) ;
let sig_a = self . a . sign ( tx_redeem . digest ( ) ) ;
let sig_b =
adaptor . decrypt_signature ( & self . s_a . to_secpfun_scalar ( ) , self . tx_redeem_encsig . clone ( ) ) ;
let sig_tx_redeem =
tx_redeem . add_signatures ( & self . tx_lock , ( self . a . public ( ) , sig_a ) , ( self . B , sig_b ) ) ? ;
bitcoin_wallet
. broadcast_signed_transaction ( sig_tx_redeem )
. await ? ;
Ok ( ( ) )
}
pub fn lock_xmr_fee ( & self ) -> monero ::Amount {
self . lock_xmr_fee
}
}