Browse Source

Fixes #368. random-peer and not-self tx broadcast.

Prior to this commit, users setting the POLICY config
option `tx_broadcast` to anything other than `self` would
cause a crash after the merge of #536 due to a bin/hex
conversion failure (before this merge, the tx would simply
fail to broadcast).
This commit adds a `JMTXBroadcast` AMP command so that makers
can send arbitrary transactions from daemon to client, for
broadcast via the blockchain interface. This allows the
existing code in `taker.push()` to function correctly, after
fixing the bin/hex conversion bug. Hence users can now select
`random-peer` or `not-self` and the transaction will be
broadcast as expected according to the comments, and the
WalletService will react to the broadcast just as it does
currently for self-broadcast.
Note that this change will be ineffective if the counterparties
do not support it; the transaction will simply remain un-broadcast.
master
Adam Gibson 5 years ago
parent
commit
d209d4d257
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 8
      jmbase/jmbase/commands.py
  2. 9
      jmbase/test/test_commands.py
  3. 16
      jmclient/jmclient/client_protocol.py
  4. 3
      jmclient/jmclient/taker.py
  5. 12
      jmdaemon/jmdaemon/daemon_protocol.py

8
jmbase/jmbase/commands.py

@ -220,3 +220,11 @@ class JMTXReceived(JMCommand):
arguments = [(b'nick', Unicode()),
(b'txhex', Unicode()),
(b'offer', Unicode())]
class JMTXBroadcast(JMCommand):
""" Accept a bitcoin transaction
sent over the wire by a counterparty
and relay it to the client for network
broadcast.
"""
arguments = [(b'txhex', Unicode())]

9
jmbase/test/test_commands.py

@ -111,7 +111,9 @@ class JMTestServerProtocol(JMBaseProtocol):
hashlen=4,
max_encoded=5,
hostid="hostid2")
self.defaultCallbacks(d3)
self.defaultCallbacks(d3)
d4 = self.callRemote(JMTXBroadcast, txhex="deadbeef")
self.defaultCallbacks(d4)
return {'accepted': True}
@ -216,6 +218,11 @@ class JMTestClientProtocol(JMBaseProtocol):
self.defaultCallbacks(d)
return {'accepted': True}
@JMTXBroadcast.responder
def on_JM_TX_BROADCAST(self, txhex):
show_receipt("JMTXBROADCAST", txhex)
return {"accepted": True}
class JMTestClientProtocolFactory(protocol.ClientFactory):
protocol = JMTestClientProtocol

16
jmclient/jmclient/client_protocol.py

@ -301,6 +301,22 @@ class JMMakerClientProtocol(JMClientProtocol):
self.defaultCallbacks(d)
return {"accepted": True}
@commands.JMTXBroadcast.responder
def on_JM_TX_BROADCAST(self, txhex):
""" Makers have no issue broadcasting anything,
so only need to prevent crashes.
Note in particular we don't check the return value,
since the transaction being accepted or not is not
our (maker)'s concern.
"""
try:
txbin = hextobin(txhex)
jm_single().bc_interface.pushtx(txbin)
except:
jlog.info("We received an invalid transaction broadcast "
"request: " + txhex)
return {"accepted": True}
def tx_match(self, txd):
for k,v in self.finalized_offers.items():
# Tx considered defined by its output set

3
jmclient/jmclient/taker.py

@ -830,8 +830,7 @@ class Taker(object):
self.on_finished_callback(False, fromtx=True)
else:
if nick_to_use:
# TODO option not currently functional
return (nick_to_use, self.latest_tx.serialize())
return (nick_to_use, bintohex(self.latest_tx.serialize()))
#if push was not successful, return None
def self_sign_and_push(self):

12
jmdaemon/jmdaemon/daemon_protocol.py

@ -9,6 +9,7 @@ from .protocol import (COMMAND_PREFIX, ORDER_KEYS, NICK_HASH_LENGTH,
COMMITMENT_PREFIXES)
from .irc import IRCMessageChannel
from jmbase import hextobin
from jmbase.commands import *
from twisted.protocols import amp
from twisted.internet import reactor, ssl
@ -432,9 +433,16 @@ class JMDaemonServerProtocol(amp.AMP, OrderbookWatch):
@maker_only
def on_push_tx(self, nick, txhex):
"""Not yet implemented; ignore rather than raise.
"""Broadcast unquestioningly, except checking
hex format.
"""
log.msg('received pushtx message, ignoring, TODO')
try:
dummy = hextobin(txhex)
except:
return
d = self.callRemote(JMTXBroadcast,
txhex=txhex)
self.defaultCallbacks(d)
@maker_only
def on_seen_tx(self, nick, txhex):

Loading…
Cancel
Save