mirror of
https://github.com/basicswap/basicswap.git
synced 2024-11-17 00:07:56 +00:00
coins: Decode pivx v3 transactions correctly.
This commit is contained in:
parent
45d6b9ecbf
commit
f210024e93
7 changed files with 148 additions and 52 deletions
|
@ -11,6 +11,7 @@ import socket
|
||||||
import urllib
|
import urllib
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
import traceback
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import basicswap.config as cfg
|
import basicswap.config as cfg
|
||||||
|
@ -176,6 +177,11 @@ class BaseApp:
|
||||||
socket.getaddrinfo = self.default_socket_getaddrinfo
|
socket.getaddrinfo = self.default_socket_getaddrinfo
|
||||||
socket.setdefaulttimeout(self.default_socket_timeout)
|
socket.setdefaulttimeout(self.default_socket_timeout)
|
||||||
|
|
||||||
|
def logException(self, message):
|
||||||
|
self.log.error(message)
|
||||||
|
if self.debug:
|
||||||
|
self.log.error(traceback.format_exc())
|
||||||
|
|
||||||
def torControl(self, query):
|
def torControl(self, query):
|
||||||
try:
|
try:
|
||||||
command = 'AUTHENTICATE "{}"\r\n{}\r\nQUIT\r\n'.format(self.tor_control_password, query).encode('utf-8')
|
command = 'AUTHENTICATE "{}"\r\n{}\r\nQUIT\r\n'.format(self.tor_control_password, query).encode('utf-8')
|
||||||
|
|
|
@ -903,17 +903,13 @@ class BasicSwap(BaseApp):
|
||||||
try:
|
try:
|
||||||
self.activateBid(session, bid)
|
self.activateBid(session, bid)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.log.error('Failed to activate bid! Error: %s', str(ex))
|
self.logException(f'Failed to activate bid! Error: {ex}')
|
||||||
if self.debug:
|
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
try:
|
try:
|
||||||
bid.setState(BidStates.BID_ERROR, 'Failed to activate')
|
bid.setState(BidStates.BID_ERROR, 'Failed to activate')
|
||||||
offer = session.query(Offer).filter_by(offer_id=bid.offer_id).first()
|
offer = session.query(Offer).filter_by(offer_id=bid.offer_id).first()
|
||||||
self.deactivateBid(session, offer, bid)
|
self.deactivateBid(session, offer, bid)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.log.error('Further error deactivating: %s', str(ex))
|
self.logException(f'Further error deactivating: {ex}')
|
||||||
if self.debug:
|
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
self.buildNotificationsCache(session)
|
self.buildNotificationsCache(session)
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
|
@ -2464,8 +2460,6 @@ class BasicSwap(BaseApp):
|
||||||
coin_to = Coins(offer.coin_to)
|
coin_to = Coins(offer.coin_to)
|
||||||
ci_to = self.ci(coin_to)
|
ci_to = self.ci(coin_to)
|
||||||
|
|
||||||
bid_date = dt.datetime.fromtimestamp(bid.created_at).date()
|
|
||||||
|
|
||||||
secret_hash = atomic_swap_1.extractScriptSecretHash(bid.initiate_tx.script)
|
secret_hash = atomic_swap_1.extractScriptSecretHash(bid.initiate_tx.script)
|
||||||
pkhash_seller = bid.pkhash_seller
|
pkhash_seller = bid.pkhash_seller
|
||||||
pkhash_buyer_refund = bid.pkhash_buyer
|
pkhash_buyer_refund = bid.pkhash_buyer
|
||||||
|
@ -3242,7 +3236,7 @@ class BasicSwap(BaseApp):
|
||||||
if bid.initiate_tx.conf is not None:
|
if bid.initiate_tx.conf is not None:
|
||||||
self.log.debug('initiate_txnid %s confirms %d', initiate_txnid_hex, bid.initiate_tx.conf)
|
self.log.debug('initiate_txnid %s confirms %d', initiate_txnid_hex, bid.initiate_tx.conf)
|
||||||
|
|
||||||
if bid.initiate_tx.vout is None:
|
if bid.initiate_tx.vout is None and tx_height > 0:
|
||||||
bid.initiate_tx.vout = index
|
bid.initiate_tx.vout = index
|
||||||
# Start checking for spends of initiate_txn before fully confirmed
|
# Start checking for spends of initiate_txn before fully confirmed
|
||||||
bid.initiate_tx.chain_height = self.setLastHeightChecked(coin_from, tx_height)
|
bid.initiate_tx.chain_height = self.setLastHeightChecked(coin_from, tx_height)
|
||||||
|
@ -3480,9 +3474,7 @@ class BasicSwap(BaseApp):
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
||||||
session.commit()
|
session.commit()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.log.error('process_XMR_SWAP_A_LOCK_tx_spend %s', str(ex))
|
self.logException(f'process_XMR_SWAP_A_LOCK_tx_spend {ex}')
|
||||||
if self.debug:
|
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
session.remove()
|
session.remove()
|
||||||
|
@ -3537,9 +3529,7 @@ class BasicSwap(BaseApp):
|
||||||
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
self.saveBidInSession(bid_id, bid, session, xmr_swap, save_in_progress=offer)
|
||||||
session.commit()
|
session.commit()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.log.error('process_XMR_SWAP_A_LOCK_REFUND_tx_spend %s', str(ex))
|
self.logException(f'process_XMR_SWAP_A_LOCK_REFUND_tx_spend {ex}')
|
||||||
if self.debug:
|
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
session.remove()
|
session.remove()
|
||||||
|
@ -3598,7 +3588,7 @@ class BasicSwap(BaseApp):
|
||||||
last_height_checked = bci['pruneheight']
|
last_height_checked = bci['pruneheight']
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
self.log.error(f'getblock error {e}')
|
self.logException(f'getblock error {e}')
|
||||||
break
|
break
|
||||||
|
|
||||||
for tx in block['tx']:
|
for tx in block['tx']:
|
||||||
|
@ -3688,9 +3678,7 @@ class BasicSwap(BaseApp):
|
||||||
else:
|
else:
|
||||||
self.log.warning('Unknown event type: %d', row.event_type)
|
self.log.warning('Unknown event type: %d', row.event_type)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
if self.debug:
|
self.logException(f'checkQueuedActions failed: {ex}')
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
self.log.error('checkQueuedActions failed: {}'.format(str(ex)))
|
|
||||||
|
|
||||||
if self.debug:
|
if self.debug:
|
||||||
session.execute('UPDATE actions SET active_ind = 2 WHERE trigger_at <= {}'.format(now))
|
session.execute('UPDATE actions SET active_ind = 2 WHERE trigger_at <= {}'.format(now))
|
||||||
|
@ -3988,9 +3976,7 @@ class BasicSwap(BaseApp):
|
||||||
use_session)
|
use_session)
|
||||||
return False
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.error('shouldAutoAcceptBid: %s', str(e))
|
self.logException(f'shouldAutoAcceptBid {e}')
|
||||||
if self.debug:
|
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
if session is None:
|
if session is None:
|
||||||
|
@ -5101,9 +5087,7 @@ class BasicSwap(BaseApp):
|
||||||
except zmq.Again as ex:
|
except zmq.Again as ex:
|
||||||
pass
|
pass
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.log.error('smsg zmq %s', str(ex))
|
self.logException(f'smsg zmq {ex}')
|
||||||
if self.debug:
|
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
|
|
||||||
self.mxDB.acquire()
|
self.mxDB.acquire()
|
||||||
try:
|
try:
|
||||||
|
@ -5150,9 +5134,7 @@ class BasicSwap(BaseApp):
|
||||||
self._last_checked_xmr_swaps = now
|
self._last_checked_xmr_swaps = now
|
||||||
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
self.log.error('update %s', str(ex))
|
self.logException(f'update {ex}')
|
||||||
if self.debug:
|
|
||||||
self.log.error(traceback.format_exc())
|
|
||||||
finally:
|
finally:
|
||||||
self.mxDB.release()
|
self.mxDB.release()
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
form_id = form_data[b'formid'][0].decode('utf-8')
|
form_id = form_data[b'formid'][0].decode('utf-8')
|
||||||
if self.server.last_form_id.get(name, None) == form_id:
|
if self.server.last_form_id.get(name, None) == form_id:
|
||||||
messages.append('Prevented double submit for form {}.'.format(form_id))
|
messages.append('Prevented double submit for form {}.'.format(form_id))
|
||||||
else:
|
return None
|
||||||
self.server.last_form_id[name] = form_id
|
self.server.last_form_id[name] = form_id
|
||||||
return form_data
|
return form_data
|
||||||
|
|
||||||
def render_template(self, template, args_dict, status_code=200):
|
def render_template(self, template, args_dict, status_code=200):
|
||||||
|
@ -184,7 +184,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
explorer = -1
|
explorer = -1
|
||||||
action = -1
|
action = -1
|
||||||
messages = []
|
messages = []
|
||||||
form_data = self.checkForm(post_string, 'explorers', messages)
|
err_messages = []
|
||||||
|
form_data = self.checkForm(post_string, 'explorers', err_messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
|
|
||||||
explorer = form_data[b'explorer'][0].decode('utf-8')
|
explorer = form_data[b'explorer'][0].decode('utf-8')
|
||||||
|
@ -211,6 +212,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
template = env.get_template('explorers.html')
|
template = env.get_template('explorers.html')
|
||||||
return self.render_template(template, {
|
return self.render_template(template, {
|
||||||
|
'messages': messages,
|
||||||
|
'err_messages': err_messages,
|
||||||
'explorers': listAvailableExplorers(swap_client),
|
'explorers': listAvailableExplorers(swap_client),
|
||||||
'explorer': explorer,
|
'explorer': explorer,
|
||||||
'actions': listExplorerActions(swap_client),
|
'actions': listExplorerActions(swap_client),
|
||||||
|
@ -227,7 +230,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
coin_type = -1
|
coin_type = -1
|
||||||
coin_id = -1
|
coin_id = -1
|
||||||
messages = []
|
messages = []
|
||||||
form_data = self.checkForm(post_string, 'rpc', messages)
|
err_messages = []
|
||||||
|
form_data = self.checkForm(post_string, 'rpc', err_messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
try:
|
try:
|
||||||
coin_id = int(form_data[b'coin_type'][0])
|
coin_id = int(form_data[b'coin_type'][0])
|
||||||
|
@ -273,6 +277,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
coins.append((-4, 'Monero Wallet'))
|
coins.append((-4, 'Monero Wallet'))
|
||||||
|
|
||||||
return self.render_template(template, {
|
return self.render_template(template, {
|
||||||
|
'messages': messages,
|
||||||
|
'err_messages': err_messages,
|
||||||
'coins': coins,
|
'coins': coins,
|
||||||
'coin_type': coin_id,
|
'coin_type': coin_id,
|
||||||
'result': result,
|
'result': result,
|
||||||
|
@ -286,18 +292,20 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
result = None
|
result = None
|
||||||
messages = []
|
messages = []
|
||||||
form_data = self.checkForm(post_string, 'wallets', messages)
|
err_messages = []
|
||||||
|
form_data = self.checkForm(post_string, 'wallets', err_messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
if have_data_entry(form_data, 'reinit_xmr'):
|
if have_data_entry(form_data, 'reinit_xmr'):
|
||||||
try:
|
try:
|
||||||
swap_client.initialiseWallet(Coins.XMR)
|
swap_client.initialiseWallet(Coins.XMR)
|
||||||
messages.append('Done.')
|
messages.append('Done.')
|
||||||
except Exception as a:
|
except Exception as a:
|
||||||
messages.append('Failed.')
|
err_messages.append('Failed.')
|
||||||
|
|
||||||
template = env.get_template('debug.html')
|
template = env.get_template('debug.html')
|
||||||
return self.render_template(template, {
|
return self.render_template(template, {
|
||||||
'messages': messages,
|
'messages': messages,
|
||||||
|
'err_messages': err_messages,
|
||||||
'result': result,
|
'result': result,
|
||||||
'summary': summary,
|
'summary': summary,
|
||||||
})
|
})
|
||||||
|
@ -319,7 +327,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
summary = swap_client.getSummary()
|
summary = swap_client.getSummary()
|
||||||
|
|
||||||
messages = []
|
messages = []
|
||||||
form_data = self.checkForm(post_string, 'settings', messages)
|
err_messages = []
|
||||||
|
form_data = self.checkForm(post_string, 'settings', err_messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
for name, c in swap_client.settings['chainclients'].items():
|
for name, c in swap_client.settings['chainclients'].items():
|
||||||
if have_data_entry(form_data, 'apply_' + name):
|
if have_data_entry(form_data, 'apply_' + name):
|
||||||
|
@ -389,6 +398,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
template = env.get_template('settings.html')
|
template = env.get_template('settings.html')
|
||||||
return self.render_template(template, {
|
return self.render_template(template, {
|
||||||
'messages': messages,
|
'messages': messages,
|
||||||
|
'err_messages': err_messages,
|
||||||
'chains': chains_formatted,
|
'chains': chains_formatted,
|
||||||
'summary': summary,
|
'summary': summary,
|
||||||
})
|
})
|
||||||
|
@ -412,10 +422,11 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
page_data = {}
|
page_data = {}
|
||||||
messages = []
|
messages = []
|
||||||
|
err_messages = []
|
||||||
smsgaddresses = []
|
smsgaddresses = []
|
||||||
|
|
||||||
listaddresses = True
|
listaddresses = True
|
||||||
form_data = self.checkForm(post_string, 'smsgaddresses', messages)
|
form_data = self.checkForm(post_string, 'smsgaddresses', err_messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
edit_address_id = None
|
edit_address_id = None
|
||||||
for key in form_data:
|
for key in form_data:
|
||||||
|
@ -473,6 +484,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
template = env.get_template('smsgaddresses.html')
|
template = env.get_template('smsgaddresses.html')
|
||||||
return self.render_template(template, {
|
return self.render_template(template, {
|
||||||
'messages': messages,
|
'messages': messages,
|
||||||
|
'err_messages': err_messages,
|
||||||
'data': page_data,
|
'data': page_data,
|
||||||
'smsgaddresses': smsgaddresses,
|
'smsgaddresses': smsgaddresses,
|
||||||
'network_addr': network_addr,
|
'network_addr': network_addr,
|
||||||
|
@ -487,7 +499,8 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
page_data = {'identity_address': identity_address}
|
page_data = {'identity_address': identity_address}
|
||||||
messages = []
|
messages = []
|
||||||
form_data = self.checkForm(post_string, 'identity', messages)
|
err_messages = []
|
||||||
|
form_data = self.checkForm(post_string, 'identity', err_messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
if have_data_entry(form_data, 'edit'):
|
if have_data_entry(form_data, 'edit'):
|
||||||
page_data['show_edit_form'] = True
|
page_data['show_edit_form'] = True
|
||||||
|
@ -498,7 +511,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
swap_client.updateIdentity(identity_address, new_label)
|
swap_client.updateIdentity(identity_address, new_label)
|
||||||
messages.append('Updated')
|
messages.append('Updated')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
messages.append('Error')
|
err_messages.append(str(e))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
identity = swap_client.getIdentity(identity_address)
|
identity = swap_client.getIdentity(identity_address)
|
||||||
|
@ -517,6 +530,7 @@ class HttpHandler(BaseHTTPRequestHandler):
|
||||||
template = env.get_template('identity.html')
|
template = env.get_template('identity.html')
|
||||||
return self.render_template(template, {
|
return self.render_template(template, {
|
||||||
'messages': messages,
|
'messages': messages,
|
||||||
|
'err_messages': err_messages,
|
||||||
'data': page_data,
|
'data': page_data,
|
||||||
'summary': summary,
|
'summary': summary,
|
||||||
})
|
})
|
||||||
|
|
|
@ -418,43 +418,114 @@ class CTxOut:
|
||||||
bytes_to_hex_str(self.scriptPubKey))
|
bytes_to_hex_str(self.scriptPubKey))
|
||||||
|
|
||||||
|
|
||||||
|
class SpendDescription:
|
||||||
|
def deserialize(self, f):
|
||||||
|
self.cv = deser_uint256(f)
|
||||||
|
self.anchor = deser_uint256(f)
|
||||||
|
self.nullifier = deser_uint256(f)
|
||||||
|
self.rk = deser_uint256(f)
|
||||||
|
self.zkproof = f.read(192)
|
||||||
|
self.spendAuthSig = f.read(64)
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
r = b""
|
||||||
|
r += ser_uint256(self.cv)
|
||||||
|
r += ser_uint256(self.anchor)
|
||||||
|
r += ser_uint256(self.nullifier)
|
||||||
|
r += ser_uint256(self.rk)
|
||||||
|
r += self.zkproof
|
||||||
|
r += self.spendAuthSig
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
class OutputDescription:
|
||||||
|
def deserialize(self, f):
|
||||||
|
self.cv = deser_uint256(f)
|
||||||
|
self.cmu = deser_uint256(f)
|
||||||
|
self.ephemeralKey = deser_uint256(f)
|
||||||
|
self.encCiphertext = f.read(580)
|
||||||
|
self.outCiphertext = f.read(80)
|
||||||
|
self.zkproof = f.read(192)
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
r = b""
|
||||||
|
r += ser_uint256(self.cv)
|
||||||
|
r += ser_uint256(self.cmu)
|
||||||
|
r += ser_uint256(self.ephemeralKey)
|
||||||
|
r += self.encCiphertext
|
||||||
|
r += self.outCiphertext
|
||||||
|
r += self.zkproof
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
class SaplingTxData:
|
||||||
|
def deserialize(self, f):
|
||||||
|
self.pre = f.read(1)
|
||||||
|
self.valueBalance = struct.unpack("<q", f.read(8))[0]
|
||||||
|
|
||||||
|
self.vShieldedSpend = deser_vector(f, SpendDescription)
|
||||||
|
self.vShieldedOutput = deser_vector(f, OutputDescription)
|
||||||
|
|
||||||
|
self.bindingSig = f.read(64)
|
||||||
|
|
||||||
|
def serialize(self):
|
||||||
|
r = b""
|
||||||
|
r += self.pre
|
||||||
|
r += struct.pack("<q", self.valueBalance)
|
||||||
|
r += ser_vector(self.vShieldedSpend)
|
||||||
|
r += ser_vector(self.vShieldedOutput)
|
||||||
|
r += self.bindingSig
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
class CTransaction:
|
class CTransaction:
|
||||||
def __init__(self, tx=None):
|
def __init__(self, tx=None):
|
||||||
if tx is None:
|
if tx is None:
|
||||||
self.nVersion = 1
|
self.nVersion = 1
|
||||||
|
self.nType = 0
|
||||||
self.vin = []
|
self.vin = []
|
||||||
self.vout = []
|
self.vout = []
|
||||||
self.sapData = b""
|
self.sapData = None
|
||||||
|
self.extraData = b""
|
||||||
self.nLockTime = 0
|
self.nLockTime = 0
|
||||||
self.sha256 = None
|
self.sha256 = None
|
||||||
self.hash = None
|
self.hash = None
|
||||||
else:
|
else:
|
||||||
self.nVersion = tx.nVersion
|
self.nVersion = tx.nVersion
|
||||||
|
self.nType = tx.nType
|
||||||
self.vin = copy.deepcopy(tx.vin)
|
self.vin = copy.deepcopy(tx.vin)
|
||||||
self.vout = copy.deepcopy(tx.vout)
|
self.vout = copy.deepcopy(tx.vout)
|
||||||
self.nLockTime = tx.nLockTime
|
self.nLockTime = tx.nLockTime
|
||||||
self.sapData = tx.sapData
|
self.sapData = tx.sapData
|
||||||
|
self.extraData = tx.extraData
|
||||||
self.sha256 = tx.sha256
|
self.sha256 = tx.sha256
|
||||||
self.hash = tx.hash
|
self.hash = tx.hash
|
||||||
|
|
||||||
def deserialize(self, f):
|
def deserialize(self, f):
|
||||||
self.nVersion = struct.unpack("<i", f.read(4))[0]
|
self.nVersion = struct.unpack("<h", f.read(2))[0]
|
||||||
|
self.nType = struct.unpack("<h", f.read(2))[0]
|
||||||
self.vin = deser_vector(f, CTxIn)
|
self.vin = deser_vector(f, CTxIn)
|
||||||
self.vout = deser_vector(f, CTxOut)
|
self.vout = deser_vector(f, CTxOut)
|
||||||
self.nLockTime = struct.unpack("<I", f.read(4))[0]
|
self.nLockTime = struct.unpack("<I", f.read(4))[0]
|
||||||
if self.nVersion >= 2:
|
if self.nVersion >= 3:
|
||||||
self.sapData = deser_string(f)
|
self.sapData = SaplingTxData()
|
||||||
|
self.sapData.deserialize(f)
|
||||||
|
if self.nType != 0:
|
||||||
|
self.extraData = deser_string(f)
|
||||||
self.sha256 = None
|
self.sha256 = None
|
||||||
self.hash = None
|
self.hash = None
|
||||||
|
|
||||||
def serialize_without_witness(self):
|
def serialize_without_witness(self):
|
||||||
r = b""
|
r = b""
|
||||||
r += struct.pack("<i", self.nVersion)
|
r += struct.pack("<h", self.nVersion)
|
||||||
|
r += struct.pack("<h", self.nType)
|
||||||
r += ser_vector(self.vin)
|
r += ser_vector(self.vin)
|
||||||
r += ser_vector(self.vout)
|
r += ser_vector(self.vout)
|
||||||
r += struct.pack("<I", self.nLockTime)
|
r += struct.pack("<I", self.nLockTime)
|
||||||
if self.nVersion >= 2:
|
if self.nVersion >= 3:
|
||||||
r += ser_string(self.sapData)
|
r += self.sapData.serialize()
|
||||||
|
if self.nType != 0:
|
||||||
|
r += ser_string(self.extraData)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
# Regular serialization is with witness -- must explicitly
|
# Regular serialization is with witness -- must explicitly
|
||||||
|
@ -504,8 +575,8 @@ class CTransaction:
|
||||||
x.prevout.hash == outpoint.hash and x.prevout.n == outpoint.n]) > 0
|
x.prevout.hash == outpoint.hash and x.prevout.n == outpoint.n]) > 0
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "CTransaction(nVersion=%i vin=%s vout=%s nLockTime=%i)" \
|
return "CTransaction(nVersion=%i nType=%i vin=%s vout=%s nLockTime=%i)" \
|
||||||
% (self.nVersion, repr(self.vin), repr(self.vout), self.nLockTime)
|
% (self.nVersion, self.nType, repr(self.vin), repr(self.vout), self.nLockTime)
|
||||||
|
|
||||||
|
|
||||||
class CBlockHeader:
|
class CBlockHeader:
|
||||||
|
|
|
@ -417,9 +417,9 @@ def page_offer(self, url_split, post_string):
|
||||||
|
|
||||||
ci_from = swap_client.ci(Coins(offer.coin_from))
|
ci_from = swap_client.ci(Coins(offer.coin_from))
|
||||||
ci_to = swap_client.ci(Coins(offer.coin_to))
|
ci_to = swap_client.ci(Coins(offer.coin_to))
|
||||||
debugind = -1
|
|
||||||
|
|
||||||
# Set defaults
|
# Set defaults
|
||||||
|
debugind = -1
|
||||||
bid_amount = ci_from.format_amount(offer.amount_from)
|
bid_amount = ci_from.format_amount(offer.amount_from)
|
||||||
bid_rate = ci_to.format_amount(offer.rate)
|
bid_rate = ci_to.format_amount(offer.rate)
|
||||||
|
|
||||||
|
|
|
@ -172,8 +172,8 @@ def page_wallet(self, url_split, post_string):
|
||||||
page_data = {}
|
page_data = {}
|
||||||
messages = []
|
messages = []
|
||||||
err_messages = []
|
err_messages = []
|
||||||
form_data = self.checkForm(post_string, 'wallet', err_messages)
|
|
||||||
show_utxo_groups = False
|
show_utxo_groups = False
|
||||||
|
form_data = self.checkForm(post_string, 'wallet', err_messages)
|
||||||
if form_data:
|
if form_data:
|
||||||
cid = str(int(coin_id))
|
cid = str(int(coin_id))
|
||||||
|
|
||||||
|
|
|
@ -349,9 +349,6 @@ class Test(unittest.TestCase):
|
||||||
ro = btcRpc('getblockchaininfo')
|
ro = btcRpc('getblockchaininfo')
|
||||||
checkForks(ro)
|
checkForks(ro)
|
||||||
|
|
||||||
ro = pivxRpc('getwalletinfo')
|
|
||||||
print('pivxRpc', ro)
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
cls.update_thread = threading.Thread(target=run_loop, args=(cls,))
|
cls.update_thread = threading.Thread(target=run_loop, args=(cls,))
|
||||||
cls.update_thread.start()
|
cls.update_thread.start()
|
||||||
|
@ -553,6 +550,32 @@ class Test(unittest.TestCase):
|
||||||
json_rv = json.loads(post_json_req('http://127.0.0.1:{}/json/wallets/pivx/withdraw'.format(TEST_HTTP_PORT + 0), post_json))
|
json_rv = json.loads(post_json_req('http://127.0.0.1:{}/json/wallets/pivx/withdraw'.format(TEST_HTTP_PORT + 0), post_json))
|
||||||
assert (len(json_rv['txid']) == 64)
|
assert (len(json_rv['txid']) == 64)
|
||||||
|
|
||||||
|
def test_09_v3_tx(self):
|
||||||
|
logging.info('---------- Test PIVX v3 txns')
|
||||||
|
|
||||||
|
generate_addr = pivxRpc('getnewaddress \"generate test\"')
|
||||||
|
pivx_addr = pivxRpc('getnewaddress \"Sapling test\"')
|
||||||
|
pivx_sapling_addr = pivxRpc('getnewshieldaddress \"shield addr\"')
|
||||||
|
|
||||||
|
pivxRpc(f'sendtoaddress \"{pivx_addr}\" 6.0')
|
||||||
|
pivxRpc(f'generatetoaddress 1 \"{generate_addr}\"')
|
||||||
|
|
||||||
|
txid = pivxRpc('shieldsendmany "{}" "[{{\\"address\\": \\"{}\\", \\"amount\\": 1}}]"'.format(pivx_addr, pivx_sapling_addr))
|
||||||
|
rtx = pivxRpc(f'getrawtransaction \"{txid}\" true')
|
||||||
|
assert(rtx['version'] == 3)
|
||||||
|
|
||||||
|
block_hash = pivxRpc(f'generatetoaddress 1 \"{generate_addr}\"')[0]
|
||||||
|
|
||||||
|
ci = self.swap_clients[0].ci(Coins.PIVX)
|
||||||
|
block = ci.getBlockWithTxns(block_hash)
|
||||||
|
|
||||||
|
found = False
|
||||||
|
for tx in block['tx']:
|
||||||
|
if txid == tx['txid']:
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
assert found
|
||||||
|
|
||||||
def pass_99_delay(self):
|
def pass_99_delay(self):
|
||||||
global stop_test
|
global stop_test
|
||||||
logging.info('Delay')
|
logging.info('Delay')
|
||||||
|
|
Loading…
Reference in a new issue