Simplify lock tx script.

Raise version.
This commit is contained in:
tecnovert 2020-12-11 00:43:36 +02:00
parent 2979b3e244
commit 8c372cc5dc
No known key found for this signature in database
GPG key ID: 8ED6D8750C4E3F93
7 changed files with 159 additions and 313 deletions

View file

@ -1,3 +1,3 @@
name = "basicswap"
__version__ = "0.0.6"
__version__ = "0.0.7"

View file

@ -60,7 +60,7 @@ from .messages_pb2 import (
XmrSplitMessage,
XmrBidLockTxSigsMessage,
XmrBidLockSpendTxMessage,
XmrBidSecretMessage,
XmrBidLockReleaseMessage,
OfferRevokeMessage,
)
from .db import (
@ -108,7 +108,7 @@ class MessageTypes(IntEnum):
XMR_BID_ACCEPT_LF = auto()
XMR_BID_TXN_SIGS_FL = auto()
XMR_BID_LOCK_SPEND_TX_LF = auto()
XMR_BID_SECRET_LF = auto()
XMR_BID_LOCK_RELEASE_LF = auto()
OFFER_REVOKE = auto()
@ -138,7 +138,7 @@ class BidStates(IntEnum):
XMR_SWAP_SCRIPT_COIN_LOCKED = auto()
XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX = auto()
XMR_SWAP_NOSCRIPT_COIN_LOCKED = auto()
XMR_SWAP_SECRET_SHARED = auto()
XMR_SWAP_LOCK_RELEASED = auto()
XMR_SWAP_SCRIPT_TX_REDEEMED = auto()
XMR_SWAP_NOSCRIPT_TX_REDEEMED = auto()
XMR_SWAP_NOSCRIPT_TX_RECOVERED = auto()
@ -181,7 +181,7 @@ class EventTypes(IntEnum):
SIGN_XMR_SWAP_LOCK_TX_A = auto()
SEND_XMR_SWAP_LOCK_TX_A = auto()
SEND_XMR_SWAP_LOCK_TX_B = auto()
SEND_XMR_SECRET = auto()
SEND_XMR_LOCK_RELEASE = auto()
REDEEM_XMR_SWAP_LOCK_TX_A = auto() # Follower
REDEEM_XMR_SWAP_LOCK_TX_B = auto() # Leader
RECOVER_XMR_SWAP_LOCK_TX_B = auto()
@ -257,8 +257,8 @@ def strBidState(state):
return 'Script coin spend tx valid'
if state == BidStates.XMR_SWAP_NOSCRIPT_COIN_LOCKED:
return 'Scriptless coin locked'
if state == BidStates.XMR_SWAP_SECRET_SHARED:
return 'Secret shared'
if state == BidStates.XMR_SWAP_LOCK_RELEASED:
return 'Script coin lock released'
if state == BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED:
return 'Script tx redeemed'
if state == BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED:
@ -1727,21 +1727,18 @@ class BasicSwap(BaseApp):
kbsf = self.getPathKey(coin_from, coin_to, bid_created_at, xmr_swap.contract_count, 2, for_ed25519=True)
kaf = self.getPathKey(coin_from, coin_to, bid_created_at, xmr_swap.contract_count, 3)
karf = self.getPathKey(coin_from, coin_to, bid_created_at, xmr_swap.contract_count, 4)
xmr_swap.vkbvf = kbvf
xmr_swap.pkbvf = ci_to.getPubkey(kbvf)
xmr_swap.pkbsf = ci_to.getPubkey(kbsf)
xmr_swap.pkaf = ci_from.getPubkey(kaf)
xmr_swap.pkarf = ci_from.getPubkey(karf)
xmr_swap.kbsf_dleag = ci_to.proveDLEAG(kbsf)
xmr_swap.pkasf = xmr_swap.kbsf_dleag[0: 33]
assert(xmr_swap.pkasf == ci_from.getPubkey(kbsf))
msg_buf.pkaf = xmr_swap.pkaf
msg_buf.pkarf = xmr_swap.pkarf
msg_buf.kbvf = kbvf
msg_buf.kbsf_dleag = xmr_swap.kbsf_dleag[:16000]
@ -1831,13 +1828,10 @@ class BasicSwap(BaseApp):
if xmr_swap.contract_count is None:
xmr_swap.contract_count = self.getNewContractId()
contract_secret = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 1)
kbvl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 1, for_ed25519=True)
kbsl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 2, for_ed25519=True)
kbvl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 2, for_ed25519=True)
kbsl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 3, for_ed25519=True)
kal = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 4)
karl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 5)
kal = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 3)
xmr_swap.vkbvl = kbvl
xmr_swap.pkbvl = ci_to.getPubkey(kbvl)
@ -1847,19 +1841,14 @@ class BasicSwap(BaseApp):
xmr_swap.pkbv = ci_to.sumPubkeys(xmr_swap.pkbvl, xmr_swap.pkbvf)
xmr_swap.pkbs = ci_to.sumPubkeys(xmr_swap.pkbsl, xmr_swap.pkbsf)
xmr_swap.sh = hashlib.sha256(contract_secret).digest()
xmr_swap.pkal = ci_from.getPubkey(kal)
xmr_swap.pkarl = ci_from.getPubkey(karl)
xmr_swap.kbsl_dleag = ci_to.proveDLEAG(kbsl)
# MSG2F
xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script = ci_from.createScriptLockTx(
bid.amount,
xmr_swap.sh,
xmr_swap.pkal, xmr_swap.pkaf,
xmr_offer.lock_time_1,
xmr_swap.pkarl, xmr_swap.pkarf,
)
xmr_swap.a_lock_tx = ci_from.fundTx(xmr_swap.a_lock_tx, xmr_offer.a_fee_rate)
@ -1868,15 +1857,14 @@ class BasicSwap(BaseApp):
xmr_swap.a_lock_refund_tx, xmr_swap.a_lock_refund_tx_script, xmr_swap.a_swap_refund_value = ci_from.createScriptLockRefundTx(
xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script,
xmr_swap.pkarl, xmr_swap.pkarf,
xmr_offer.lock_time_2,
xmr_swap.pkaf,
xmr_swap.pkal, xmr_swap.pkaf,
xmr_offer.lock_time_1, xmr_offer.lock_time_2,
xmr_offer.a_fee_rate
)
xmr_swap.a_lock_refund_tx_id = ci_from.getTxHash(xmr_swap.a_lock_refund_tx)
xmr_swap.al_lock_refund_tx_sig = ci_from.signTx(karl, xmr_swap.a_lock_refund_tx, 0, xmr_swap.a_lock_tx_script, bid.amount)
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_tx, xmr_swap.al_lock_refund_tx_sig, xmr_swap.pkarl, 0, xmr_swap.a_lock_tx_script, bid.amount)
xmr_swap.al_lock_refund_tx_sig = ci_from.signTx(kal, xmr_swap.a_lock_refund_tx, 0, xmr_swap.a_lock_tx_script, bid.amount)
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_tx, xmr_swap.al_lock_refund_tx_sig, xmr_swap.pkal, 0, xmr_swap.a_lock_tx_script, bid.amount)
assert(v)
pkh_refund_to = ci_from.decodeAddress(self.getReceiveAddressForCoin(coin_from))
@ -1889,9 +1877,7 @@ class BasicSwap(BaseApp):
msg_buf = XmrBidAcceptMessage()
msg_buf.bid_msg_id = bid_id
msg_buf.sh = xmr_swap.sh
msg_buf.pkal = xmr_swap.pkal
msg_buf.pkarl = xmr_swap.pkarl
msg_buf.kbvl = kbvl
msg_buf.kbsl_dleag = xmr_swap.kbsl_dleag[:16000]
@ -2657,13 +2643,13 @@ class BasicSwap(BaseApp):
if bid.was_received:
delay = random.randrange(self.min_delay_event, self.max_delay_event)
self.log.info('Releasing xmr swap secret for bid %s in %d seconds', bid_id.hex(), delay)
self.createEventInSession(delay, EventTypes.SEND_XMR_SECRET, bid_id, session)
self.log.info('Releasing xmr script coin lock tx for bid %s in %d seconds', bid_id.hex(), delay)
self.createEventInSession(delay, EventTypes.SEND_XMR_LOCK_RELEASE, bid_id, session)
if bid_changed:
self.saveBidInSession(bid_id, bid, session, xmr_swap)
session.commit()
elif state == BidStates.XMR_SWAP_SECRET_SHARED:
elif state == BidStates.XMR_SWAP_LOCK_RELEASED:
# Wait for script spend tx to confirm
# TODO: Use explorer to get tx / block hash for getrawtransaction
@ -2966,7 +2952,7 @@ class BasicSwap(BaseApp):
spending_txid = bytes.fromhex(spend_txid_hex)
if spending_txid == xmr_swap.a_lock_spend_tx_id:
if state == BidStates.XMR_SWAP_SECRET_SHARED:
if state == BidStates.XMR_SWAP_LOCK_RELEASED:
xmr_swap.a_lock_spend_tx = bytes.fromhex(spend_txn_hex)
bid.setState(BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED) # TODO: Wait for confirmation?
@ -3154,8 +3140,8 @@ class BasicSwap(BaseApp):
self.sendXmrBidCoinALockTx(row.linked_id, session)
elif row.event_type == EventTypes.SEND_XMR_SWAP_LOCK_TX_B:
self.sendXmrBidCoinBLockTx(row.linked_id, session)
elif row.event_type == EventTypes.SEND_XMR_SECRET:
self.sendXmrBidSecret(row.linked_id, session)
elif row.event_type == EventTypes.SEND_XMR_LOCK_RELEASE:
self.sendXmrBidLockRelease(row.linked_id, session)
elif row.event_type == EventTypes.REDEEM_XMR_SWAP_LOCK_TX_A:
self.redeemXmrBidCoinALockTx(row.linked_id, session)
elif row.event_type == EventTypes.REDEEM_XMR_SWAP_LOCK_TX_B:
@ -3550,8 +3536,6 @@ class BasicSwap(BaseApp):
if not ci_from.verifyPubkey(xmr_swap.pkaf):
raise ValueError('Invalid pubkey.')
if not ci_from.verifyPubkey(xmr_swap.pkarf):
raise ValueError('Invalid pubkey.')
self.log.info('Received valid bid %s for xmr offer %s', bid.bid_id.hex(), bid.offer_id.hex())
@ -3604,8 +3588,6 @@ class BasicSwap(BaseApp):
if not ci_from.verifyPubkey(xmr_swap.pkal):
raise ValueError('Invalid pubkey.')
if not ci_from.verifyPubkey(xmr_swap.pkarl):
raise ValueError('Invalid pubkey.')
if xmr_swap.pkbvl == xmr_swap.pkbvf:
raise ValueError('Duplicate scriptless view pubkey.')
@ -3613,8 +3595,6 @@ class BasicSwap(BaseApp):
raise ValueError('Duplicate scriptless spend pubkey.')
if xmr_swap.pkal == xmr_swap.pkaf:
raise ValueError('Duplicate script spend pubkey.')
if xmr_swap.pkarl == xmr_swap.pkarf:
raise ValueError('Duplicate script spend pubkey.')
bid.setState(BidStates.SWAP_DELAYING)
self.saveBidInSession(bid.bid_id, bid, session, xmr_swap)
@ -3663,7 +3643,6 @@ class BasicSwap(BaseApp):
bid_id=bid_id,
dest_af=bid_data.dest_af,
pkaf=bid_data.pkaf,
pkarf=bid_data.pkarf,
vkbvf=bid_data.kbvf,
pkbvf=ci_to.getPubkey(bid_data.kbvf),
kbsf_dleag=bid_data.kbsf_dleag,
@ -3702,11 +3681,7 @@ class BasicSwap(BaseApp):
ci_to = self.ci(Coins(offer.coin_to))
try:
assert(len(msg_data.sh) == 32), 'Bad secret hash length'
xmr_swap.sh = msg_data.sh
xmr_swap.pkal = msg_data.pkal
xmr_swap.pkarl = msg_data.pkarl
xmr_swap.vkbvl = msg_data.kbvl
xmr_swap.pkbvl = ci_to.getPubkey(msg_data.kbvl)
xmr_swap.kbsl_dleag = msg_data.kbsl_dleag
@ -3724,10 +3699,8 @@ class BasicSwap(BaseApp):
xmr_swap.a_lock_tx_id, xmr_swap.a_lock_tx_vout = ci_from.verifyLockTx(
xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script,
bid.amount,
xmr_swap.sh,
xmr_swap.pkal, xmr_swap.pkaf,
xmr_offer.lock_time_1, xmr_offer.a_fee_rate,
xmr_swap.pkarl, xmr_swap.pkarf,
xmr_offer.a_fee_rate,
check_a_lock_tx_inputs
)
a_lock_tx_dest = ci_from.getScriptDest(xmr_swap.a_lock_tx_script)
@ -3735,9 +3708,8 @@ class BasicSwap(BaseApp):
xmr_swap.a_lock_refund_tx_id, xmr_swap.a_swap_refund_value = ci_from.verifyLockRefundTx(
xmr_swap.a_lock_refund_tx, xmr_swap.a_lock_refund_tx_script,
xmr_swap.a_lock_tx_id, xmr_swap.a_lock_tx_vout, xmr_offer.lock_time_1, xmr_swap.a_lock_tx_script,
xmr_swap.pkarl, xmr_swap.pkarf,
xmr_swap.pkal, xmr_swap.pkaf,
xmr_offer.lock_time_2,
xmr_swap.pkaf,
bid.amount, xmr_offer.a_fee_rate
)
@ -3749,7 +3721,7 @@ class BasicSwap(BaseApp):
)
logging.info('Checking leader\'s lock refund tx signature')
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_tx, xmr_swap.al_lock_refund_tx_sig, xmr_swap.pkarl, 0, xmr_swap.a_lock_tx_script, bid.amount)
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_tx, xmr_swap.al_lock_refund_tx_sig, xmr_swap.pkal, 0, xmr_swap.a_lock_tx_script, bid.amount)
bid.setState(BidStates.BID_RECEIVING_ACC)
self.saveBid(bid.bid_id, bid, xmr_swap=xmr_swap)
@ -3785,10 +3757,10 @@ class BasicSwap(BaseApp):
ci_to = self.ci(coin_to)
try:
karf = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 4)
kaf = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 3)
xmr_swap.af_lock_refund_spend_tx_esig = ci_from.signTxOtVES(karf, xmr_swap.pkasl, xmr_swap.a_lock_refund_spend_tx, 0, xmr_swap.a_lock_refund_tx_script, xmr_swap.a_swap_refund_value)
xmr_swap.af_lock_refund_tx_sig = ci_from.signTx(karf, xmr_swap.a_lock_refund_tx, 0, xmr_swap.a_lock_tx_script, bid.amount)
xmr_swap.af_lock_refund_spend_tx_esig = ci_from.signTxOtVES(kaf, xmr_swap.pkasl, xmr_swap.a_lock_refund_spend_tx, 0, xmr_swap.a_lock_refund_tx_script, xmr_swap.a_swap_refund_value)
xmr_swap.af_lock_refund_tx_sig = ci_from.signTx(kaf, xmr_swap.a_lock_refund_tx, 0, xmr_swap.a_lock_tx_script, bid.amount)
self.addLockRefundSigs(xmr_swap, ci_from)
@ -3843,7 +3815,7 @@ class BasicSwap(BaseApp):
ci_from = self.ci(coin_from)
ci_to = self.ci(coin_to)
kal = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 4)
kal = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 3)
xmr_swap.a_lock_spend_tx = ci_from.createScriptLockSpendTx(
xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script,
@ -3853,10 +3825,13 @@ class BasicSwap(BaseApp):
xmr_swap.a_lock_spend_tx_id = ci_from.getTxHash(xmr_swap.a_lock_spend_tx)
xmr_swap.al_lock_spend_tx_esig = ci_from.signTxOtVES(kal, xmr_swap.pkasf, xmr_swap.a_lock_spend_tx, 0, xmr_swap.a_lock_tx_script, bid.amount) # self.a_swap_value
# Proof leader can sign for kal
xmr_swap.kal_sig = ci_from.signCompact(kal, 'proof key owned for swap')
msg_buf = XmrBidLockSpendTxMessage(
bid_msg_id=bid_id,
a_lock_spend_tx=xmr_swap.a_lock_spend_tx,
al_lock_spend_tx_esig=xmr_swap.al_lock_spend_tx_esig)
kal_sig=xmr_swap.kal_sig)
msg_bytes = msg_buf.SerializeToString()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_LOCK_SPEND_TX_LF) + msg_bytes.hex()
@ -3947,7 +3922,7 @@ class BasicSwap(BaseApp):
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
def sendXmrBidSecret(self, bid_id, session):
def sendXmrBidLockRelease(self, bid_id, session):
# Leader sending lock tx a release secret (MSG5F)
self.log.debug('Sending bid secret for xmr bid %s', bid_id.hex())
@ -3961,14 +3936,12 @@ class BasicSwap(BaseApp):
coin_from = Coins(offer.coin_from)
coin_to = Coins(offer.coin_to)
contract_secret = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 1)
msg_buf = XmrBidSecretMessage(
msg_buf = XmrBidLockReleaseMessage(
bid_msg_id=bid_id,
secret_value=contract_secret)
al_lock_spend_tx_esig=xmr_swap.al_lock_spend_tx_esig)
msg_bytes = msg_buf.SerializeToString()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_SECRET_LF) + msg_bytes.hex()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_LOCK_RELEASE_LF) + msg_bytes.hex()
options = {'decodehex': True, 'ttl_is_seconds': True}
# TODO: set msg_valid based on bid / offer parameters
@ -3976,7 +3949,7 @@ class BasicSwap(BaseApp):
ro = self.callrpc('smsgsend', [offer.addr_from, bid.bid_addr, payload_hex, False, msg_valid, False, options])
xmr_swap.coin_a_lock_refund_spend_tx_msg_id = bytes.fromhex(ro['msgid'])
bid.setState(BidStates.XMR_SWAP_SECRET_SHARED)
bid.setState(BidStates.XMR_SWAP_LOCK_RELEASED)
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
def redeemXmrBidCoinALockTx(self, bid_id, session):
@ -4010,8 +3983,6 @@ class BasicSwap(BaseApp):
b'',
al_lock_spend_sig,
af_lock_spend_sig,
xmr_swap.sv,
bytes((1,)),
xmr_swap.a_lock_tx_script,
]
@ -4050,7 +4021,7 @@ class BasicSwap(BaseApp):
kbsf = ci_from.recoverEncKey(xmr_swap.al_lock_spend_tx_esig, xmr_swap.al_lock_spend_tx_sig, xmr_swap.pkasf)
assert(kbsf is not None)
kbsl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 3, for_ed25519=True)
kbsl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 2, for_ed25519=True)
vkbs = ci_to.sumKeys(kbsl, kbsf)
address_to = ci_to.getMainWalletAddress()
@ -4144,11 +4115,11 @@ class BasicSwap(BaseApp):
xmr_swap.af_lock_refund_spend_tx_esig = msg_data.af_lock_refund_spend_tx_esig
xmr_swap.af_lock_refund_tx_sig = msg_data.af_lock_refund_tx_sig
kbsl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 3, for_ed25519=True)
karl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 5)
kbsl = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 2, for_ed25519=True)
kal = self.getPathKey(coin_from, coin_to, bid.created_at, xmr_swap.contract_count, 3)
xmr_swap.af_lock_refund_spend_tx_sig = ci_from.decryptOtVES(kbsl, xmr_swap.af_lock_refund_spend_tx_esig)
al_lock_refund_spend_tx_sig = ci_from.signTx(karl, xmr_swap.a_lock_refund_spend_tx, 0, xmr_swap.a_lock_refund_tx_script, xmr_swap.a_swap_refund_value)
al_lock_refund_spend_tx_sig = ci_from.signTx(kal, xmr_swap.a_lock_refund_spend_tx, 0, xmr_swap.a_lock_refund_tx_script, xmr_swap.a_swap_refund_value)
self.log.debug('Setting lock refund spend tx sigs')
witness_stack = [
@ -4162,7 +4133,7 @@ class BasicSwap(BaseApp):
assert(signed_tx), 'setTxSignature failed'
xmr_swap.a_lock_refund_spend_tx = signed_tx
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_spend_tx, xmr_swap.af_lock_refund_spend_tx_sig, xmr_swap.pkarf, 0, xmr_swap.a_lock_refund_tx_script, xmr_swap.a_swap_refund_value)
v = ci_from.verifyTxSig(xmr_swap.a_lock_refund_spend_tx, xmr_swap.af_lock_refund_spend_tx_sig, xmr_swap.pkaf, 0, xmr_swap.a_lock_refund_tx_script, xmr_swap.a_swap_refund_value)
assert(v), 'Invalid signature for lock refund spend txn'
self.addLockRefundSigs(xmr_swap, ci_from)
@ -4201,17 +4172,14 @@ class BasicSwap(BaseApp):
try:
xmr_swap.a_lock_spend_tx = msg_data.a_lock_spend_tx
xmr_swap.a_lock_spend_tx_id = ci_from.getTxHash(xmr_swap.a_lock_spend_tx)
xmr_swap.al_lock_spend_tx_esig = msg_data.al_lock_spend_tx_esig
xmr_swap.kal_sig = msg_data.kal_sig
ci_from.verifyLockSpendTx(
xmr_swap.a_lock_spend_tx,
xmr_swap.a_lock_tx, xmr_swap.a_lock_tx_script,
xmr_swap.dest_af, xmr_offer.a_fee_rate)
v = ci_from.verifyTxOtVES(
xmr_swap.a_lock_spend_tx, xmr_swap.al_lock_spend_tx_esig,
xmr_swap.pkal, xmr_swap.pkasf, 0, xmr_swap.a_lock_tx_script, bid.amount)
assert(v), 'verifyTxOtVES failed'
ci_from.verifyCompact(xmr_swap.pkal, 'proof key owned for swap', xmr_swap.kal_sig)
bid.setState(BidStates.XMR_SWAP_HAVE_SCRIPT_COIN_SPEND_TX)
self.saveBid(bid_id, bid, xmr_swap=xmr_swap)
@ -4242,11 +4210,11 @@ class BasicSwap(BaseApp):
dbr.created_at = now
self.saveToDB(dbr)
def processXmrSecretMessage(self, msg):
def processXmrLockReleaseMessage(self, msg):
self.log.debug('Processing xmr secret msg %s', msg['msgid'])
now = int(time.time())
msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = XmrBidSecretMessage()
msg_data = XmrBidLockReleaseMessage()
msg_data.ParseFromString(msg_bytes)
# Validate data
@ -4260,14 +4228,27 @@ class BasicSwap(BaseApp):
offer, xmr_offer = self.getXmrOffer(bid.offer_id, sent=False)
assert(offer), 'Offer not found: {}.'.format(bid.offer_id.hex())
assert(xmr_offer), 'XMR offer not found: {}.'.format(bid.offer_id.hex())
ci_from = self.ci(Coins(offer.coin_from))
xmr_swap.sv = msg_data.secret_value
xmr_swap.al_lock_spend_tx_esig = msg_data.al_lock_spend_tx_esig
try:
v = ci_from.verifyTxOtVES(
xmr_swap.a_lock_spend_tx, xmr_swap.al_lock_spend_tx_esig,
xmr_swap.pkal, xmr_swap.pkasf, 0, xmr_swap.a_lock_tx_script, bid.amount)
assert(v), 'verifyTxOtVES failed'
except Exception as e:
if self.debug:
traceback.print_exc()
self.setBidError(bid_id, bid, str(ex))
self.swaps_in_progress[bid_id] = (bid, offer)
return
delay = random.randrange(self.min_delay_event, self.max_delay_event)
self.log.info('Redeeming coin A lock tx for xmr bid %s in %d seconds', bid_id.hex(), delay)
self.createEvent(delay, EventTypes.REDEEM_XMR_SWAP_LOCK_TX_A, bid_id)
bid.setState(BidStates.XMR_SWAP_SECRET_SHARED)
bid.setState(BidStates.XMR_SWAP_LOCK_RELEASED)
self.saveBid(bid_id, bid, xmr_swap=xmr_swap)
self.swaps_in_progress[bid_id] = (bid, offer)
@ -4293,8 +4274,8 @@ class BasicSwap(BaseApp):
self.processXmrBidLockSpendTx(msg)
elif msg_type == MessageTypes.XMR_BID_SPLIT:
self.processXmrSplitMessage(msg)
elif msg_type == MessageTypes.XMR_BID_SECRET_LF:
self.processXmrSecretMessage(msg)
elif msg_type == MessageTypes.XMR_BID_LOCK_RELEASE_LF:
self.processXmrLockReleaseMessage(msg)
if msg_type == MessageTypes.OFFER_REVOKE:
self.processOfferRevoke(msg)
@ -4409,7 +4390,7 @@ class BasicSwap(BaseApp):
else:
self.log.debug('TODO - determine in-progress for manualBidUpdate')
if offer.swap_type == SwapTypes.XMR_SWAP:
if bid.state and bid.state in (BidStates.XMR_SWAP_SECRET_SHARED, BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED):
if bid.state and bid.state in (BidStates.XMR_SWAP_LOCK_RELEASED, BidStates.XMR_SWAP_NOSCRIPT_TX_REDEEMED):
activate_bid = True
if activate_bid:
@ -4635,7 +4616,6 @@ class BasicSwap(BaseApp):
b'',
xmr_swap.al_lock_refund_tx_sig,
xmr_swap.af_lock_refund_tx_sig,
b'',
xmr_swap.a_lock_tx_script,
]

View file

@ -12,7 +12,7 @@ from sqlalchemy.ext.declarative import declarative_base
from enum import IntEnum, auto
CURRENT_DB_VERSION = 5
CURRENT_DB_VERSION = 6
Base = declarative_base()
@ -264,17 +264,12 @@ class XmrSwap(Base):
contract_count = sa.Column(sa.Integer)
sv = sa.Column(sa.LargeBinary) # Secret value
sh = sa.Column(sa.LargeBinary) # Secret hash
dest_af = sa.Column(sa.LargeBinary) # Destination for coin A amount to follower when swap completes successfully
pkal = sa.Column(sa.LargeBinary)
pkarl = sa.Column(sa.LargeBinary)
pkasl = sa.Column(sa.LargeBinary)
pkaf = sa.Column(sa.LargeBinary)
pkarf = sa.Column(sa.LargeBinary)
pkasf = sa.Column(sa.LargeBinary)
vkbvl = sa.Column(sa.LargeBinary)
@ -315,6 +310,7 @@ class XmrSwap(Base):
a_lock_spend_tx = sa.Column(sa.LargeBinary)
a_lock_spend_tx_id = sa.Column(sa.LargeBinary)
al_lock_spend_tx_esig = sa.Column(sa.LargeBinary)
kal_sig = sa.Column(sa.LargeBinary)
a_lock_refund_swipe_tx = sa.Column(sa.LargeBinary) # Follower spends script coin lock refund tx

View file

@ -20,6 +20,7 @@ from .util import (
toWIF,
decodeAddress)
from coincurve.keys import (
PrivateKey,
PublicKey)
from coincurve.dleag import (
verify_secp256k1_point)
@ -221,72 +222,30 @@ class BTCInterface(CoinInterface):
def extractScriptLockScriptValues(self, script_bytes):
script_len = len(script_bytes)
assert_cond(script_len > 112, 'Bad script length')
assert_cond(script_bytes[0] == OP_IF)
assert_cond(script_bytes[1] == OP_SIZE)
assert_cond(script_bytes[2:4] == bytes((1, 32))) # 0120, CScriptNum length, then data
assert_cond(script_bytes[4] == OP_EQUALVERIFY)
assert_cond(script_bytes[5] == OP_SHA256)
assert_cond(script_bytes[6] == 32)
secret_hash = script_bytes[7: 7 + 32]
assert_cond(script_bytes[39] == OP_EQUALVERIFY)
assert_cond(script_bytes[40] == OP_2)
assert_cond(script_bytes[41] == 33)
pk1 = script_bytes[42: 42 + 33]
assert_cond(script_bytes[75] == 33)
pk2 = script_bytes[76: 76 + 33]
assert_cond(script_bytes[109] == OP_2)
assert_cond(script_bytes[110] == OP_CHECKMULTISIG)
assert_cond(script_bytes[111] == OP_ELSE)
o = 112
# Decode script num
csv_val, nb = decodeScriptNum(script_bytes, o)
o += nb
assert_cond(script_len == o + 8 + 66, 'Bad script length') # Fails if script too long
assert_cond(script_bytes[o] == OP_CHECKSEQUENCEVERIFY)
o += 1
assert_cond(script_bytes[o] == OP_DROP)
o += 1
assert_cond(script_len == 71, 'Bad script length')
o = 0
assert_cond(script_bytes[o] == OP_2)
o += 1
assert_cond(script_bytes[o] == 33)
o += 1
pk3 = script_bytes[o: o + 33]
assert_cond(script_bytes[o + 1] == 33)
o += 2
pk1 = script_bytes[o: o + 33]
o += 33
assert_cond(script_bytes[o] == 33)
o += 1
pk4 = script_bytes[o: o + 33]
pk2 = script_bytes[o: o + 33]
o += 33
assert_cond(script_bytes[o] == OP_2)
o += 1
assert_cond(script_bytes[o] == OP_CHECKMULTISIG)
o += 1
assert_cond(script_bytes[o] == OP_ENDIF)
assert_cond(script_bytes[o + 1] == OP_CHECKMULTISIG)
return secret_hash, pk1, pk2, csv_val, pk3, pk4
def genScriptLockTxScript(self, sh, Kal, Kaf, lock_blocks, Karl, Karf):
return pk1, pk2
def genScriptLockTxScript(self, Kal, Kaf):
Kal_enc = Kal if len(Kal) == 33 else self.encodePubkey(Kal)
Kaf_enc = Kaf if len(Kaf) == 33 else self.encodePubkey(Kaf)
Karl_enc = Karl if len(Karl) == 33 else self.encodePubkey(Karl)
Karf_enc = Karf if len(Karf) == 33 else self.encodePubkey(Karf)
return CScript([
CScriptOp(OP_IF),
CScriptOp(OP_SIZE), 32, CScriptOp(OP_EQUALVERIFY),
CScriptOp(OP_SHA256), sh, CScriptOp(OP_EQUALVERIFY),
2, Kal_enc, Kaf_enc, 2, CScriptOp(OP_CHECKMULTISIG),
CScriptOp(OP_ELSE),
lock_blocks, CScriptOp(OP_CHECKSEQUENCEVERIFY), CScriptOp(OP_DROP),
2, Karl_enc, Karf_enc, 2, CScriptOp(OP_CHECKMULTISIG),
CScriptOp(OP_ENDIF)])
return CScript([2, Kal_enc, Kaf_enc, 2, CScriptOp(OP_CHECKMULTISIG)])
def createScriptLockTx(self, value, sh, Kal, Kaf, lock_blocks, Karl, Karf):
script = self.genScriptLockTxScript(sh, Kal, Kaf, lock_blocks, Karl, Karf)
def createScriptLockTx(self, value, Kal, Kaf):
script = self.genScriptLockTxScript(Kal, Kaf)
tx = CTransaction()
tx.nVersion = self.txVersion()
tx.vout.append(self.txoType(value, self.getScriptDest(script)))
@ -324,21 +283,20 @@ class BTCInterface(CoinInterface):
return pk1, pk2, csv_val, pk3
def genScriptLockRefundTxScript(self, Karl, Karf, csv_val, Kaf):
def genScriptLockRefundTxScript(self, Kal, Kaf, csv_val):
Kal_enc = Kal if len(Kal) == 33 else self.encodePubkey(Kal)
Kaf_enc = Kaf if len(Kaf) == 33 else self.encodePubkey(Kaf)
Karl_enc = Karl if len(Karl) == 33 else self.encodePubkey(Karl)
Karf_enc = Karf if len(Karf) == 33 else self.encodePubkey(Karf)
return CScript([
CScriptOp(OP_IF),
2, Karl_enc, Karf_enc, 2, CScriptOp(OP_CHECKMULTISIG),
2, Kal_enc, Kaf_enc, 2, CScriptOp(OP_CHECKMULTISIG),
CScriptOp(OP_ELSE),
csv_val, CScriptOp(OP_CHECKSEQUENCEVERIFY), CScriptOp(OP_DROP),
Kaf_enc, CScriptOp(OP_CHECKSIG),
CScriptOp(OP_ENDIF)])
def createScriptLockRefundTx(self, tx_lock_bytes, script_lock, Karl, Karf, csv_val, Kaf, tx_fee_rate):
def createScriptLockRefundTx(self, tx_lock_bytes, script_lock, Kal, Kaf, lock1_value, csv_val, tx_fee_rate):
tx_lock = CTransaction()
tx_lock = FromHex(tx_lock, tx_lock_bytes.hex())
@ -350,9 +308,7 @@ class BTCInterface(CoinInterface):
tx_lock.rehash()
tx_lock_hash_int = tx_lock.sha256
sh, A, B, lock1_value, C, D = self.extractScriptLockScriptValues(script_lock)
refund_script = self.genScriptLockRefundTxScript(Karl, Karf, csv_val, Kaf)
refund_script = self.genScriptLockRefundTxScript(Kal, Kaf, csv_val)
tx = CTransaction()
tx.nVersion = self.txVersion()
tx.vin.append(CTxIn(COutPoint(tx_lock_hash_int, locked_n), nSequence=lock1_value))
@ -475,10 +431,8 @@ class BTCInterface(CoinInterface):
def verifyLockTx(self, tx_bytes, script_out,
swap_value,
sh,
Kal, Kaf,
lock_value, feerate,
Karl, Karf,
feerate,
check_lock_tx_inputs):
# Verify:
#
@ -502,13 +456,9 @@ class BTCInterface(CoinInterface):
assert_cond(locked_coin == swap_value, 'Bad locked value')
# Check script and values
shv, A, B, csv_val, C, D = self.extractScriptLockScriptValues(script_out)
assert_cond(shv == sh, 'Bad hash lock')
A, B = self.extractScriptLockScriptValues(script_out)
assert_cond(A == Kal, 'Bad script pubkey')
assert_cond(B == Kaf, 'Bad script pubkey')
assert_cond(csv_val == lock_value, 'Bad script csv value')
assert_cond(C == Karl, 'Bad script pubkey')
assert_cond(D == Karf, 'Bad script pubkey')
if check_lock_tx_inputs:
# Check that inputs are unspent and verify fee rate
@ -547,7 +497,7 @@ class BTCInterface(CoinInterface):
def verifyLockRefundTx(self, tx_bytes, script_out,
prevout_id, prevout_n, prevout_seq, prevout_script,
Karl, Karf, csv_val_expect, Kaf, swap_value, feerate):
Kal, Kaf, csv_val_expect, swap_value, feerate):
# Verify:
# Must have only one input with correct prevout and sequence
# Must have only one output to the p2wsh of the lock refund script
@ -574,8 +524,8 @@ class BTCInterface(CoinInterface):
# Check script and values
A, B, csv_val, C = self.extractScriptLockRefundScriptValues(script_out)
assert_cond(A == Karl, 'Bad script pubkey')
assert_cond(B == Karf, 'Bad script pubkey')
assert_cond(A == Kal, 'Bad script pubkey')
assert_cond(B == Kaf, 'Bad script pubkey')
assert_cond(csv_val == csv_val_expect, 'Bad script csv value')
assert_cond(C == Kaf, 'Bad script pubkey')
@ -892,87 +842,21 @@ class BTCInterface(CoinInterface):
params = [addr_to, value, '', '', subfee, True, self._conf_target]
return self.rpc_callback('sendtoaddress', params)
def signCompact(self, k, message):
message_hash = hashlib.sha256(bytes(message, 'utf-8')).digest()
privkey = PrivateKey(k)
return privkey.sign_recoverable(message_hash, hasher=None)[:64]
def verifyCompact(self, K, message, sig):
message_hash = hashlib.sha256(bytes(message, 'utf-8')).digest()
pubkey = PublicKey(K)
rv = pubkey.verify_compact(sig, message_hash, hasher=None)
assert(rv is True)
def testBTCInterface():
print('testBTCInterface')
script_bytes = bytes.fromhex('6382012088a820aaf125ff9a34a74c7a17f5e7ee9d07d17cc5e53a539f345d5f73baa7e79b65e28852210224019219ad43c47288c937ae508f26998dd81ec066827773db128fd5e262c04f21039a0fd752bd1a2234820707852e7a30253620052ecd162948a06532a817710b5952ae670114b2755221038689deba25c5578e5457ddadbaf8aeb8badf438dc22f540503dbd4ae10e14f512103c9c5d5acc996216d10852a72cd67c701bfd4b9137a4076350fd32f08db39575552ae68')
i = BTCInterface(None)
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes)
assert(csv_val == 20)
script_bytes_t = script_bytes + bytes((0x00,))
try:
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(False), 'Should fail'
except Exception as e:
assert(str(e) == 'Bad script length')
script_bytes_t = script_bytes[:-1]
try:
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(False), 'Should fail'
except Exception as e:
assert(str(e) == 'Bad script length')
script_bytes_t = bytes((0x00,)) + script_bytes[1:]
try:
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(False), 'Should fail'
except Exception as e:
assert(str(e) == 'Bad opcode')
# Remove the csv value
script_part_a = script_bytes[:112]
script_part_b = script_bytes[114:]
script_bytes_t = script_part_a + bytes((0x00,)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == 0)
script_bytes_t = script_part_a + bytes((OP_16,)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == 16)
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(17)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == 17)
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(-15)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == -15)
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(4000)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == 4000)
max_pos = 0x7FFFFFFF
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(max_pos)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == max_pos)
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(max_pos - 1)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == max_pos - 1)
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(max_pos + 1)) + script_part_b
try:
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(False), 'Should fail'
except Exception as e:
assert(str(e) == 'Bad scriptnum length')
min_neg = -2147483647
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(min_neg)) + script_part_b
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(csv_val == min_neg)
script_bytes_t = script_part_a + CScriptNum.encode(CScriptNum(min_neg - 1)) + script_part_b
try:
sh, a, b, csv_val, c, d = i.extractScriptLockScriptValues(script_bytes_t)
assert(False), 'Should fail'
except Exception as e:
assert(str(e) == 'Bad scriptnum length')
print('Passed.')
if __name__ == "__main__":

View file

@ -63,12 +63,11 @@ message XmrBidMessage {
uint64 amount = 3; /* amount of amount_from bid is for */
bytes pkaf = 4;
bytes pkarf = 5;
bytes kbvf = 6;
bytes kbsf_dleag = 7;
bytes kbvf = 5;
bytes kbsf_dleag = 6;
bytes dest_af = 8;
bytes dest_af = 7;
}
message XmrSplitMessage {
@ -81,20 +80,18 @@ message XmrSplitMessage {
message XmrBidAcceptMessage {
bytes bid_msg_id = 1;
bytes sh = 2;
bytes pkal = 3;
bytes pkarl = 4;
bytes kbvl = 5;
bytes kbsl_dleag = 6;
bytes kbvl = 4;
bytes kbsl_dleag = 5;
/* MSG2F */
bytes a_lock_tx = 7;
bytes a_lock_tx_script = 8;
bytes a_lock_refund_tx = 9;
bytes a_lock_refund_tx_script = 10;
bytes a_lock_refund_spend_tx = 11;
bytes al_lock_refund_tx_sig = 12;
bytes a_lock_tx = 6;
bytes a_lock_tx_script = 7;
bytes a_lock_refund_tx = 8;
bytes a_lock_refund_tx_script = 9;
bytes a_lock_refund_spend_tx = 10;
bytes al_lock_refund_tx_sig = 11;
}
message XmrBidLockTxSigsMessage {
@ -110,12 +107,12 @@ message XmrBidLockSpendTxMessage {
bytes bid_msg_id = 1;
bytes a_lock_spend_tx = 2;
bytes al_lock_spend_tx_esig = 3;
bytes kal_sig = 3;
}
message XmrBidSecretMessage {
message XmrBidLockReleaseMessage {
/* MSG5F */
bytes bid_msg_id = 1;
bytes secret_value = 2;
bytes al_lock_spend_tx_esig = 2;
}

View file

@ -19,7 +19,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_options=None,
create_key=_descriptor._internal_create_key,
serialized_pb=b'\n\x0emessages.proto\x12\tbasicswap\"\xd8\x03\n\x0cOfferMessage\x12\x11\n\tcoin_from\x18\x01 \x01(\r\x12\x0f\n\x07\x63oin_to\x18\x02 \x01(\r\x12\x13\n\x0b\x61mount_from\x18\x03 \x01(\x04\x12\x0c\n\x04rate\x18\x04 \x01(\x04\x12\x16\n\x0emin_bid_amount\x18\x05 \x01(\x04\x12\x12\n\ntime_valid\x18\x06 \x01(\x04\x12\x33\n\tlock_type\x18\x07 \x01(\x0e\x32 .basicswap.OfferMessage.LockType\x12\x12\n\nlock_value\x18\x08 \x01(\r\x12\x11\n\tswap_type\x18\t \x01(\r\x12\x15\n\rproof_address\x18\n \x01(\t\x12\x17\n\x0fproof_signature\x18\x0b \x01(\t\x12\x15\n\rpkhash_seller\x18\x0c \x01(\x0c\x12\x13\n\x0bsecret_hash\x18\r \x01(\x0c\x12\x15\n\rfee_rate_from\x18\x0e \x01(\x04\x12\x13\n\x0b\x66\x65\x65_rate_to\x18\x0f \x01(\x04\"q\n\x08LockType\x12\x0b\n\x07NOT_SET\x10\x00\x12\x18\n\x14SEQUENCE_LOCK_BLOCKS\x10\x01\x12\x16\n\x12SEQUENCE_LOCK_TIME\x10\x02\x12\x13\n\x0f\x41\x42S_LOCK_BLOCKS\x10\x03\x12\x11\n\rABS_LOCK_TIME\x10\x04\"\x8c\x01\n\nBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x14\n\x0cpkhash_buyer\x18\x04 \x01(\x0c\x12\x15\n\rproof_address\x18\x05 \x01(\t\x12\x17\n\x0fproof_signature\x18\x06 \x01(\t\"V\n\x10\x42idAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x15\n\rinitiate_txid\x18\x02 \x01(\x0c\x12\x17\n\x0f\x63ontract_script\x18\x03 \x01(\x0c\"=\n\x12OfferRevokeMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"\x99\x01\n\rXmrBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x0c\n\x04pkaf\x18\x04 \x01(\x0c\x12\r\n\x05pkarf\x18\x05 \x01(\x0c\x12\x0c\n\x04kbvf\x18\x06 \x01(\x0c\x12\x12\n\nkbsf_dleag\x18\x07 \x01(\x0c\x12\x0f\n\x07\x64\x65st_af\x18\x08 \x01(\x0c\"T\n\x0fXmrSplitMessage\x12\x0e\n\x06msg_id\x18\x01 \x01(\x0c\x12\x10\n\x08msg_type\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\x12\r\n\x05\x64leag\x18\x04 \x01(\x0c\"\x9b\x02\n\x13XmrBidAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\n\n\x02sh\x18\x02 \x01(\x0c\x12\x0c\n\x04pkal\x18\x03 \x01(\x0c\x12\r\n\x05pkarl\x18\x04 \x01(\x0c\x12\x0c\n\x04kbvl\x18\x05 \x01(\x0c\x12\x12\n\nkbsl_dleag\x18\x06 \x01(\x0c\x12\x11\n\ta_lock_tx\x18\x07 \x01(\x0c\x12\x18\n\x10\x61_lock_tx_script\x18\x08 \x01(\x0c\x12\x18\n\x10\x61_lock_refund_tx\x18\t \x01(\x0c\x12\x1f\n\x17\x61_lock_refund_tx_script\x18\n \x01(\x0c\x12\x1e\n\x16\x61_lock_refund_spend_tx\x18\x0b \x01(\x0c\x12\x1d\n\x15\x61l_lock_refund_tx_sig\x18\x0c \x01(\x0c\"r\n\x17XmrBidLockTxSigsMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12$\n\x1c\x61\x66_lock_refund_spend_tx_esig\x18\x02 \x01(\x0c\x12\x1d\n\x15\x61\x66_lock_refund_tx_sig\x18\x03 \x01(\x0c\"f\n\x18XmrBidLockSpendTxMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x17\n\x0f\x61_lock_spend_tx\x18\x02 \x01(\x0c\x12\x1d\n\x15\x61l_lock_spend_tx_esig\x18\x03 \x01(\x0c\"?\n\x13XmrBidSecretMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x14\n\x0csecret_value\x18\x02 \x01(\x0c\x62\x06proto3'
serialized_pb=b'\n\x0emessages.proto\x12\tbasicswap\"\xd8\x03\n\x0cOfferMessage\x12\x11\n\tcoin_from\x18\x01 \x01(\r\x12\x0f\n\x07\x63oin_to\x18\x02 \x01(\r\x12\x13\n\x0b\x61mount_from\x18\x03 \x01(\x04\x12\x0c\n\x04rate\x18\x04 \x01(\x04\x12\x16\n\x0emin_bid_amount\x18\x05 \x01(\x04\x12\x12\n\ntime_valid\x18\x06 \x01(\x04\x12\x33\n\tlock_type\x18\x07 \x01(\x0e\x32 .basicswap.OfferMessage.LockType\x12\x12\n\nlock_value\x18\x08 \x01(\r\x12\x11\n\tswap_type\x18\t \x01(\r\x12\x15\n\rproof_address\x18\n \x01(\t\x12\x17\n\x0fproof_signature\x18\x0b \x01(\t\x12\x15\n\rpkhash_seller\x18\x0c \x01(\x0c\x12\x13\n\x0bsecret_hash\x18\r \x01(\x0c\x12\x15\n\rfee_rate_from\x18\x0e \x01(\x04\x12\x13\n\x0b\x66\x65\x65_rate_to\x18\x0f \x01(\x04\"q\n\x08LockType\x12\x0b\n\x07NOT_SET\x10\x00\x12\x18\n\x14SEQUENCE_LOCK_BLOCKS\x10\x01\x12\x16\n\x12SEQUENCE_LOCK_TIME\x10\x02\x12\x13\n\x0f\x41\x42S_LOCK_BLOCKS\x10\x03\x12\x11\n\rABS_LOCK_TIME\x10\x04\"\x8c\x01\n\nBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x14\n\x0cpkhash_buyer\x18\x04 \x01(\x0c\x12\x15\n\rproof_address\x18\x05 \x01(\t\x12\x17\n\x0fproof_signature\x18\x06 \x01(\t\"V\n\x10\x42idAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x15\n\rinitiate_txid\x18\x02 \x01(\x0c\x12\x17\n\x0f\x63ontract_script\x18\x03 \x01(\x0c\"=\n\x12OfferRevokeMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\"\x8a\x01\n\rXmrBidMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x12\n\ntime_valid\x18\x02 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x03 \x01(\x04\x12\x0c\n\x04pkaf\x18\x04 \x01(\x0c\x12\x0c\n\x04kbvf\x18\x05 \x01(\x0c\x12\x12\n\nkbsf_dleag\x18\x06 \x01(\x0c\x12\x0f\n\x07\x64\x65st_af\x18\x07 \x01(\x0c\"T\n\x0fXmrSplitMessage\x12\x0e\n\x06msg_id\x18\x01 \x01(\x0c\x12\x10\n\x08msg_type\x18\x02 \x01(\r\x12\x10\n\x08sequence\x18\x03 \x01(\r\x12\r\n\x05\x64leag\x18\x04 \x01(\x0c\"\x80\x02\n\x13XmrBidAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x0c\n\x04pkal\x18\x03 \x01(\x0c\x12\x0c\n\x04kbvl\x18\x04 \x01(\x0c\x12\x12\n\nkbsl_dleag\x18\x05 \x01(\x0c\x12\x11\n\ta_lock_tx\x18\x06 \x01(\x0c\x12\x18\n\x10\x61_lock_tx_script\x18\x07 \x01(\x0c\x12\x18\n\x10\x61_lock_refund_tx\x18\x08 \x01(\x0c\x12\x1f\n\x17\x61_lock_refund_tx_script\x18\t \x01(\x0c\x12\x1e\n\x16\x61_lock_refund_spend_tx\x18\n \x01(\x0c\x12\x1d\n\x15\x61l_lock_refund_tx_sig\x18\x0b \x01(\x0c\"r\n\x17XmrBidLockTxSigsMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12$\n\x1c\x61\x66_lock_refund_spend_tx_esig\x18\x02 \x01(\x0c\x12\x1d\n\x15\x61\x66_lock_refund_tx_sig\x18\x03 \x01(\x0c\"X\n\x18XmrBidLockSpendTxMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x17\n\x0f\x61_lock_spend_tx\x18\x02 \x01(\x0c\x12\x0f\n\x07kal_sig\x18\x03 \x01(\x0c\"M\n\x18XmrBidLockReleaseMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x1d\n\x15\x61l_lock_spend_tx_esig\x18\x02 \x01(\x0c\x62\x06proto3'
)
@ -385,33 +385,26 @@ _XMRBIDMESSAGE = _descriptor.Descriptor(
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='pkarf', full_name='basicswap.XmrBidMessage.pkarf', index=4,
name='kbvf', full_name='basicswap.XmrBidMessage.kbvf', index=4,
number=5, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='kbvf', full_name='basicswap.XmrBidMessage.kbvf', index=5,
name='kbsf_dleag', full_name='basicswap.XmrBidMessage.kbsf_dleag', index=5,
number=6, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='kbsf_dleag', full_name='basicswap.XmrBidMessage.kbsf_dleag', index=6,
name='dest_af', full_name='basicswap.XmrBidMessage.dest_af', index=6,
number=7, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='dest_af', full_name='basicswap.XmrBidMessage.dest_af', index=7,
number=8, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
@ -425,7 +418,7 @@ _XMRBIDMESSAGE = _descriptor.Descriptor(
oneofs=[
],
serialized_start=799,
serialized_end=952,
serialized_end=937,
)
@ -477,8 +470,8 @@ _XMRSPLITMESSAGE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=954,
serialized_end=1038,
serialized_start=939,
serialized_end=1023,
)
@ -498,82 +491,68 @@ _XMRBIDACCEPTMESSAGE = _descriptor.Descriptor(
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='sh', full_name='basicswap.XmrBidAcceptMessage.sh', index=1,
number=2, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='pkal', full_name='basicswap.XmrBidAcceptMessage.pkal', index=2,
name='pkal', full_name='basicswap.XmrBidAcceptMessage.pkal', index=1,
number=3, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='pkarl', full_name='basicswap.XmrBidAcceptMessage.pkarl', index=3,
name='kbvl', full_name='basicswap.XmrBidAcceptMessage.kbvl', index=2,
number=4, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='kbvl', full_name='basicswap.XmrBidAcceptMessage.kbvl', index=4,
name='kbsl_dleag', full_name='basicswap.XmrBidAcceptMessage.kbsl_dleag', index=3,
number=5, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='kbsl_dleag', full_name='basicswap.XmrBidAcceptMessage.kbsl_dleag', index=5,
name='a_lock_tx', full_name='basicswap.XmrBidAcceptMessage.a_lock_tx', index=4,
number=6, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='a_lock_tx', full_name='basicswap.XmrBidAcceptMessage.a_lock_tx', index=6,
name='a_lock_tx_script', full_name='basicswap.XmrBidAcceptMessage.a_lock_tx_script', index=5,
number=7, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='a_lock_tx_script', full_name='basicswap.XmrBidAcceptMessage.a_lock_tx_script', index=7,
name='a_lock_refund_tx', full_name='basicswap.XmrBidAcceptMessage.a_lock_refund_tx', index=6,
number=8, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='a_lock_refund_tx', full_name='basicswap.XmrBidAcceptMessage.a_lock_refund_tx', index=8,
name='a_lock_refund_tx_script', full_name='basicswap.XmrBidAcceptMessage.a_lock_refund_tx_script', index=7,
number=9, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='a_lock_refund_tx_script', full_name='basicswap.XmrBidAcceptMessage.a_lock_refund_tx_script', index=9,
name='a_lock_refund_spend_tx', full_name='basicswap.XmrBidAcceptMessage.a_lock_refund_spend_tx', index=8,
number=10, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='a_lock_refund_spend_tx', full_name='basicswap.XmrBidAcceptMessage.a_lock_refund_spend_tx', index=10,
name='al_lock_refund_tx_sig', full_name='basicswap.XmrBidAcceptMessage.al_lock_refund_tx_sig', index=9,
number=11, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='al_lock_refund_tx_sig', full_name='basicswap.XmrBidAcceptMessage.al_lock_refund_tx_sig', index=11,
number=12, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
],
extensions=[
],
@ -586,8 +565,8 @@ _XMRBIDACCEPTMESSAGE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=1041,
serialized_end=1324,
serialized_start=1026,
serialized_end=1282,
)
@ -632,8 +611,8 @@ _XMRBIDLOCKTXSIGSMESSAGE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=1326,
serialized_end=1440,
serialized_start=1284,
serialized_end=1398,
)
@ -660,7 +639,7 @@ _XMRBIDLOCKSPENDTXMESSAGE = _descriptor.Descriptor(
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='al_lock_spend_tx_esig', full_name='basicswap.XmrBidLockSpendTxMessage.al_lock_spend_tx_esig', index=2,
name='kal_sig', full_name='basicswap.XmrBidLockSpendTxMessage.kal_sig', index=2,
number=3, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
@ -678,28 +657,28 @@ _XMRBIDLOCKSPENDTXMESSAGE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=1442,
serialized_end=1544,
serialized_start=1400,
serialized_end=1488,
)
_XMRBIDSECRETMESSAGE = _descriptor.Descriptor(
name='XmrBidSecretMessage',
full_name='basicswap.XmrBidSecretMessage',
_XMRBIDLOCKRELEASEMESSAGE = _descriptor.Descriptor(
name='XmrBidLockReleaseMessage',
full_name='basicswap.XmrBidLockReleaseMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
create_key=_descriptor._internal_create_key,
fields=[
_descriptor.FieldDescriptor(
name='bid_msg_id', full_name='basicswap.XmrBidSecretMessage.bid_msg_id', index=0,
name='bid_msg_id', full_name='basicswap.XmrBidLockReleaseMessage.bid_msg_id', index=0,
number=1, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
_descriptor.FieldDescriptor(
name='secret_value', full_name='basicswap.XmrBidSecretMessage.secret_value', index=1,
name='al_lock_spend_tx_esig', full_name='basicswap.XmrBidLockReleaseMessage.al_lock_spend_tx_esig', index=1,
number=2, type=12, cpp_type=9, label=1,
has_default_value=False, default_value=b"",
message_type=None, enum_type=None, containing_type=None,
@ -717,8 +696,8 @@ _XMRBIDSECRETMESSAGE = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=1546,
serialized_end=1609,
serialized_start=1490,
serialized_end=1567,
)
_OFFERMESSAGE.fields_by_name['lock_type'].enum_type = _OFFERMESSAGE_LOCKTYPE
@ -732,7 +711,7 @@ DESCRIPTOR.message_types_by_name['XmrSplitMessage'] = _XMRSPLITMESSAGE
DESCRIPTOR.message_types_by_name['XmrBidAcceptMessage'] = _XMRBIDACCEPTMESSAGE
DESCRIPTOR.message_types_by_name['XmrBidLockTxSigsMessage'] = _XMRBIDLOCKTXSIGSMESSAGE
DESCRIPTOR.message_types_by_name['XmrBidLockSpendTxMessage'] = _XMRBIDLOCKSPENDTXMESSAGE
DESCRIPTOR.message_types_by_name['XmrBidSecretMessage'] = _XMRBIDSECRETMESSAGE
DESCRIPTOR.message_types_by_name['XmrBidLockReleaseMessage'] = _XMRBIDLOCKRELEASEMESSAGE
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
OfferMessage = _reflection.GeneratedProtocolMessageType('OfferMessage', (_message.Message,), {
@ -798,12 +777,12 @@ XmrBidLockSpendTxMessage = _reflection.GeneratedProtocolMessageType('XmrBidLockS
})
_sym_db.RegisterMessage(XmrBidLockSpendTxMessage)
XmrBidSecretMessage = _reflection.GeneratedProtocolMessageType('XmrBidSecretMessage', (_message.Message,), {
'DESCRIPTOR' : _XMRBIDSECRETMESSAGE,
XmrBidLockReleaseMessage = _reflection.GeneratedProtocolMessageType('XmrBidLockReleaseMessage', (_message.Message,), {
'DESCRIPTOR' : _XMRBIDLOCKRELEASEMESSAGE,
'__module__' : 'messages_pb2'
# @@protoc_insertion_point(class_scope:basicswap.XmrBidSecretMessage)
# @@protoc_insertion_point(class_scope:basicswap.XmrBidLockReleaseMessage)
})
_sym_db.RegisterMessage(XmrBidSecretMessage)
_sym_db.RegisterMessage(XmrBidLockReleaseMessage)
# @@protoc_insertion_point(module_scope)

View file

@ -182,6 +182,16 @@ class Test(unittest.TestCase):
assert(vk_encrypt == recovered_key)
def test_sign_compact(self):
coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
ci = BTCInterface(coin_settings, 'regtest')
vk = i2b(ci.getNewSecretKey())
pk = ci.getPubkey(vk)
sig = ci.signCompact(vk, 'test signing message')
assert(len(sig) == 64)
ci.verifyCompact(pk, 'test signing message', sig)
def test_dleag(self):
coin_settings = {'rpcport': 0, 'walletrpcport': 0, 'walletrpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
ci = XMRInterface(coin_settings, 'regtest')