Remove protobuf dependency.

master^2
tecnovert 7 months ago
parent adc80eabb0
commit d3e3c3c95b
  1. 2
      .cirrus.yml
  2. 2
      .travis.yml
  3. 9
      Dockerfile
  4. 2
      basicswap/__init__.py
  5. 92
      basicswap/basicswap.py
  6. 160
      basicswap/messages.proto
  7. 53
      basicswap/messages_npb.py
  8. 54
      basicswap/messages_pb2.py
  9. 3
      doc/install.md
  10. 11
      doc/release-notes.md
  11. 10
      docker/production/swapclient/Dockerfile
  12. 2
      guix.scm
  13. 1
      requirements.txt
  14. 1
      setup.py
  15. 64
      tests/basicswap/test_other.py

@ -21,7 +21,7 @@ test_task:
- XMR_BINDIR: ${BIN_DIR}/monero - XMR_BINDIR: ${BIN_DIR}/monero
setup_script: setup_script:
- apt-get update - apt-get update
- apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config - apt-get install -y wget python3-pip gnupg unzip automake libtool pkg-config
- pip install tox pytest - pip install tox pytest
- python3 setup.py install - python3 setup.py install
- wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/refs/tags/anonswap_v0.2.zip - wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/refs/tags/anonswap_v0.2.zip

@ -18,7 +18,7 @@ cache:
directories: directories:
- "$BIN_DIR" - "$BIN_DIR"
before_install: before_install:
- sudo apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config - sudo apt-get install -y wget python3-pip gnupg unzip automake libtool pkg-config
install: install:
- travis_retry pip install tox pytest - travis_retry pip install tox pytest
before_script: before_script:

@ -7,14 +7,6 @@ ENV LANG=C.UTF-8 \
RUN apt-get update; \ RUN apt-get update; \
apt-get install -y wget python3-pip gnupg unzip make g++ autoconf automake libtool pkg-config gosu tzdata; apt-get install -y wget python3-pip gnupg unzip make g++ autoconf automake libtool pkg-config gosu tzdata;
# Must install protoc directly as latest package is only on 3.12
RUN wget -O protobuf_src.tar.gz https://github.com/protocolbuffers/protobuf/releases/download/v21.1/protobuf-python-4.21.1.tar.gz && \
tar xvf protobuf_src.tar.gz && \
cd protobuf-3.21.1 && \
./configure --prefix=/usr && \
make -j$(nproc) install && \
ldconfig
ARG COINCURVE_VERSION=v0.2 ARG COINCURVE_VERSION=v0.2
RUN wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/refs/tags/anonswap_$COINCURVE_VERSION.zip && \ RUN wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/refs/tags/anonswap_$COINCURVE_VERSION.zip && \
unzip coincurve-anonswap.zip && \ unzip coincurve-anonswap.zip && \
@ -28,7 +20,6 @@ RUN pip3 install -r requirements.txt
COPY . basicswap-master COPY . basicswap-master
RUN cd basicswap-master; \ RUN cd basicswap-master; \
protoc -I=basicswap --python_out=basicswap basicswap/messages.proto; \
pip3 install .; pip3 install .;
RUN useradd -ms /bin/bash swap_user && \ RUN useradd -ms /bin/bash swap_user && \

@ -1,3 +1,3 @@
name = "basicswap" name = "basicswap"
__version__ = "0.13.1" __version__ = "0.13.2"

@ -66,21 +66,19 @@ from .chainparams import (
from .script import ( from .script import (
OpCodes, OpCodes,
) )
from .messages_pb2 import ( from .messages_npb import (
BidMessage, ADSBidIntentAcceptMessage,
ADSBidIntentMessage,
BidAcceptMessage, BidAcceptMessage,
XmrBidMessage, BidMessage,
OfferMessage,
OfferRevokeMessage,
XmrBidAcceptMessage, XmrBidAcceptMessage,
XmrSplitMessage,
XmrBidLockTxSigsMessage,
XmrBidLockSpendTxMessage,
XmrBidLockReleaseMessage, XmrBidLockReleaseMessage,
OfferRevokeMessage, XmrBidLockSpendTxMessage,
ADSBidIntentMessage, XmrBidLockTxSigsMessage,
ADSBidIntentAcceptMessage, XmrBidMessage,
) XmrSplitMessage,
from .messages_npb import (
OfferMessage,
) )
from .db import ( from .db import (
CURRENT_DB_VERSION, CURRENT_DB_VERSION,
@ -1778,7 +1776,7 @@ class BasicSwap(BaseApp):
msg_buf.signature = base64.b64decode(signature_enc) msg_buf.signature = base64.b64decode(signature_enc)
msg_bytes = msg_buf.SerializeToString() msg_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.OFFER_REVOKE) + msg_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.OFFER_REVOKE) + msg_bytes.hex()
msg_valid: int = max(self.SMSG_SECONDS_IN_HOUR, offer.time_valid) msg_valid: int = max(self.SMSG_SECONDS_IN_HOUR, offer.time_valid)
@ -2407,7 +2405,7 @@ class BasicSwap(BaseApp):
else: else:
raise ValueError('TODO') raise ValueError('TODO')
bid_bytes = msg_buf.SerializeToString() bid_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.BID) + bid_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.BID) + bid_bytes.hex()
bid_addr = self.newSMSGAddress(use_type=AddressTypes.BID)[0] if addr_send_from is None else addr_send_from bid_addr = self.newSMSGAddress(use_type=AddressTypes.BID)[0] if addr_send_from is None else addr_send_from
@ -2694,7 +2692,7 @@ class BasicSwap(BaseApp):
if bid.pkhash_seller != pkhash_refund: if bid.pkhash_seller != pkhash_refund:
msg_buf.pkhash_seller = bid.pkhash_seller msg_buf.pkhash_seller = bid.pkhash_seller
bid_bytes = msg_buf.SerializeToString() bid_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.BID_ACCEPT) + bid_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.BID_ACCEPT) + bid_bytes.hex()
msg_valid: int = self.getAcceptBidMsgValidTime(bid) msg_valid: int = self.getAcceptBidMsgValidTime(bid)
@ -2715,7 +2713,7 @@ class BasicSwap(BaseApp):
sequence=1, sequence=1,
dleag=dleag[16000:32000] dleag=dleag[16000:32000]
) )
msg_bytes = msg_buf2.SerializeToString() msg_bytes = msg_buf2.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_SPLIT) + msg_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_SPLIT) + msg_bytes.hex()
bid_msg_ids[1] = self.sendSmsg(addr_from, addr_to, payload_hex, msg_valid) bid_msg_ids[1] = self.sendSmsg(addr_from, addr_to, payload_hex, msg_valid)
@ -2725,7 +2723,7 @@ class BasicSwap(BaseApp):
sequence=2, sequence=2,
dleag=dleag[32000:] dleag=dleag[32000:]
) )
msg_bytes = msg_buf3.SerializeToString() msg_bytes = msg_buf3.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_SPLIT) + msg_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_SPLIT) + msg_bytes.hex()
bid_msg_ids[2] = self.sendSmsg(addr_from, addr_to, payload_hex, msg_valid) bid_msg_ids[2] = self.sendSmsg(addr_from, addr_to, payload_hex, msg_valid)
@ -2776,7 +2774,7 @@ class BasicSwap(BaseApp):
msg_buf.amount_from = amount msg_buf.amount_from = amount
msg_buf.amount_to = amount_to msg_buf.amount_to = amount_to
bid_bytes = msg_buf.SerializeToString() bid_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.ADS_BID_LF) + bid_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.ADS_BID_LF) + bid_bytes.hex()
xmr_swap = XmrSwap() xmr_swap = XmrSwap()
@ -2865,7 +2863,7 @@ class BasicSwap(BaseApp):
msg_buf.pkaf = xmr_swap.pkaf msg_buf.pkaf = xmr_swap.pkaf
msg_buf.kbvf = kbvf msg_buf.kbvf = kbvf
bid_bytes = msg_buf.SerializeToString() bid_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_FL) + bid_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_FL) + bid_bytes.hex()
bid_addr = self.newSMSGAddress(use_type=AddressTypes.BID)[0] if addr_send_from is None else addr_send_from bid_addr = self.newSMSGAddress(use_type=AddressTypes.BID)[0] if addr_send_from is None else addr_send_from
@ -3066,7 +3064,7 @@ class BasicSwap(BaseApp):
msg_buf.a_lock_refund_spend_tx = xmr_swap.a_lock_refund_spend_tx msg_buf.a_lock_refund_spend_tx = xmr_swap.a_lock_refund_spend_tx
msg_buf.al_lock_refund_tx_sig = xmr_swap.al_lock_refund_tx_sig msg_buf.al_lock_refund_tx_sig = xmr_swap.al_lock_refund_tx_sig
msg_bytes = msg_buf.SerializeToString() msg_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_ACCEPT_LF) + msg_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_ACCEPT_LF) + msg_bytes.hex()
addr_from: str = bid.bid_addr if reverse_bid else offer.addr_from addr_from: str = bid.bid_addr if reverse_bid else offer.addr_from
@ -3155,7 +3153,7 @@ class BasicSwap(BaseApp):
msg_buf.kbvf = kbvf msg_buf.kbvf = kbvf
msg_buf.kbsf_dleag = xmr_swap.kbsf_dleag if len(xmr_swap.kbsf_dleag) < 16000 else xmr_swap.kbsf_dleag[:16000] msg_buf.kbsf_dleag = xmr_swap.kbsf_dleag if len(xmr_swap.kbsf_dleag) < 16000 else xmr_swap.kbsf_dleag[:16000]
bid_bytes = msg_buf.SerializeToString() bid_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.ADS_BID_ACCEPT_FL) + bid_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.ADS_BID_ACCEPT_FL) + bid_bytes.hex()
addr_from: str = offer.addr_from addr_from: str = offer.addr_from
@ -4809,7 +4807,7 @@ class BasicSwap(BaseApp):
def processOffer(self, msg) -> None: def processOffer(self, msg) -> None:
offer_bytes = bytes.fromhex(msg['hex'][2:-2]) offer_bytes = bytes.fromhex(msg['hex'][2:-2])
offer_data = OfferMessage() offer_data = OfferMessage(init_all=False)
try: try:
offer_data.from_bytes(offer_bytes[:2], init_all=False) offer_data.from_bytes(offer_bytes[:2], init_all=False)
ensure(offer_data.protocol_version >= MINPROTO_VERSION and offer_data.protocol_version <= MAXPROTO_VERSION, 'protocol_version out of range') ensure(offer_data.protocol_version >= MINPROTO_VERSION and offer_data.protocol_version <= MAXPROTO_VERSION, 'protocol_version out of range')
@ -4937,8 +4935,8 @@ class BasicSwap(BaseApp):
ensure(msg['to'] == self.network_addr, 'Message received on wrong address') ensure(msg['to'] == self.network_addr, 'Message received on wrong address')
msg_bytes = bytes.fromhex(msg['hex'][2:-2]) msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = OfferRevokeMessage() msg_data = OfferRevokeMessage(init_all=False)
msg_data.ParseFromString(msg_bytes) msg_data.from_bytes(msg_bytes)
now: int = self.getTime() now: int = self.getTime()
try: try:
@ -5086,8 +5084,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing bid msg %s', msg['msgid']) self.log.debug('Processing bid msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
bid_bytes = bytes.fromhex(msg['hex'][2:-2]) bid_bytes = bytes.fromhex(msg['hex'][2:-2])
bid_data = BidMessage() bid_data = BidMessage(init_all=False)
bid_data.ParseFromString(bid_bytes) bid_data.from_bytes(bid_bytes)
# Validate bid data # Validate bid data
ensure(bid_data.protocol_version >= MINPROTO_VERSION_SECRET_HASH, 'Invalid protocol version') ensure(bid_data.protocol_version >= MINPROTO_VERSION_SECRET_HASH, 'Invalid protocol version')
@ -5174,8 +5172,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing bid accepted msg %s', msg['msgid']) self.log.debug('Processing bid accepted msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
bid_accept_bytes = bytes.fromhex(msg['hex'][2:-2]) bid_accept_bytes = bytes.fromhex(msg['hex'][2:-2])
bid_accept_data = BidAcceptMessage() bid_accept_data = BidAcceptMessage(init_all=False)
bid_accept_data.ParseFromString(bid_accept_bytes) bid_accept_data.from_bytes(bid_accept_bytes)
ensure(len(bid_accept_data.bid_msg_id) == 28, 'Bad bid_msg_id length') ensure(len(bid_accept_data.bid_msg_id) == 28, 'Bad bid_msg_id length')
ensure(len(bid_accept_data.initiate_txid) == 32, 'Bad initiate_txid length') ensure(len(bid_accept_data.initiate_txid) == 32, 'Bad initiate_txid length')
@ -5393,8 +5391,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing adaptor-sig bid msg %s', msg['msgid']) self.log.debug('Processing adaptor-sig bid msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
bid_bytes = bytes.fromhex(msg['hex'][2:-2]) bid_bytes = bytes.fromhex(msg['hex'][2:-2])
bid_data = XmrBidMessage() bid_data = XmrBidMessage(init_all=False)
bid_data.ParseFromString(bid_bytes) bid_data.from_bytes(bid_bytes)
# Validate data # Validate data
ensure(bid_data.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Invalid protocol version') ensure(bid_data.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Invalid protocol version')
@ -5481,8 +5479,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing adaptor-sig bid accept msg %s', msg['msgid']) self.log.debug('Processing adaptor-sig bid accept msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
msg_bytes = bytes.fromhex(msg['hex'][2:-2]) msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = XmrBidAcceptMessage() msg_data = XmrBidAcceptMessage(init_all=False)
msg_data.ParseFromString(msg_bytes) msg_data.from_bytes(msg_bytes)
ensure(len(msg_data.bid_msg_id) == 28, 'Bad bid_msg_id length') ensure(len(msg_data.bid_msg_id) == 28, 'Bad bid_msg_id length')
@ -5618,7 +5616,7 @@ class BasicSwap(BaseApp):
af_lock_refund_tx_sig=xmr_swap.af_lock_refund_tx_sig af_lock_refund_tx_sig=xmr_swap.af_lock_refund_tx_sig
) )
msg_bytes = msg_buf.SerializeToString() msg_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_TXN_SIGS_FL) + msg_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_TXN_SIGS_FL) + msg_bytes.hex()
msg_valid: int = self.getActiveBidMsgValidTime() msg_valid: int = self.getActiveBidMsgValidTime()
@ -5825,7 +5823,7 @@ class BasicSwap(BaseApp):
bid_msg_id=bid_id, bid_msg_id=bid_id,
al_lock_spend_tx_esig=xmr_swap.al_lock_spend_tx_esig) al_lock_spend_tx_esig=xmr_swap.al_lock_spend_tx_esig)
msg_bytes = msg_buf.SerializeToString() msg_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_LOCK_RELEASE_LF) + msg_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_LOCK_RELEASE_LF) + msg_bytes.hex()
addr_send_from: str = bid.bid_addr if reverse_bid else offer.addr_from addr_send_from: str = bid.bid_addr if reverse_bid else offer.addr_from
@ -6056,7 +6054,7 @@ class BasicSwap(BaseApp):
a_lock_spend_tx=xmr_swap.a_lock_spend_tx, a_lock_spend_tx=xmr_swap.a_lock_spend_tx,
kal_sig=xmr_swap.kal_sig) kal_sig=xmr_swap.kal_sig)
msg_bytes = msg_buf.SerializeToString() msg_bytes = msg_buf.to_bytes()
payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_LOCK_SPEND_TX_LF) + msg_bytes.hex() payload_hex = str.format('{:02x}', MessageTypes.XMR_BID_LOCK_SPEND_TX_LF) + msg_bytes.hex()
msg_valid: int = self.getActiveBidMsgValidTime() msg_valid: int = self.getActiveBidMsgValidTime()
@ -6070,8 +6068,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing xmr coin a follower lock sigs msg %s', msg['msgid']) self.log.debug('Processing xmr coin a follower lock sigs msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
msg_bytes = bytes.fromhex(msg['hex'][2:-2]) msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = XmrBidLockTxSigsMessage() msg_data = XmrBidLockTxSigsMessage(init_all=False)
msg_data.ParseFromString(msg_bytes) msg_data.from_bytes(msg_bytes)
ensure(len(msg_data.bid_msg_id) == 28, 'Bad bid_msg_id length') ensure(len(msg_data.bid_msg_id) == 28, 'Bad bid_msg_id length')
bid_id = msg_data.bid_msg_id bid_id = msg_data.bid_msg_id
@ -6145,8 +6143,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing adaptor-sig bid lock spend tx msg %s', msg['msgid']) self.log.debug('Processing adaptor-sig bid lock spend tx msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
msg_bytes = bytes.fromhex(msg['hex'][2:-2]) msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = XmrBidLockSpendTxMessage() msg_data = XmrBidLockSpendTxMessage(init_all=False)
msg_data.ParseFromString(msg_bytes) msg_data.from_bytes(msg_bytes)
ensure(len(msg_data.bid_msg_id) == 28, 'Bad bid_msg_id length') ensure(len(msg_data.bid_msg_id) == 28, 'Bad bid_msg_id length')
bid_id = msg_data.bid_msg_id bid_id = msg_data.bid_msg_id
@ -6201,8 +6199,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing xmr split msg %s', msg['msgid']) self.log.debug('Processing xmr split msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
msg_bytes = bytes.fromhex(msg['hex'][2:-2]) msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = XmrSplitMessage() msg_data = XmrSplitMessage(init_all=False)
msg_data.ParseFromString(msg_bytes) msg_data.from_bytes(msg_bytes)
# Validate data # Validate data
ensure(len(msg_data.msg_id) == 28, 'Bad msg_id length') ensure(len(msg_data.msg_id) == 28, 'Bad msg_id length')
@ -6235,8 +6233,8 @@ class BasicSwap(BaseApp):
self.log.debug('Processing adaptor-sig swap lock release msg %s', msg['msgid']) self.log.debug('Processing adaptor-sig swap lock release msg %s', msg['msgid'])
now: int = self.getTime() now: int = self.getTime()
msg_bytes = bytes.fromhex(msg['hex'][2:-2]) msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = XmrBidLockReleaseMessage() msg_data = XmrBidLockReleaseMessage(init_all=False)
msg_data.ParseFromString(msg_bytes) msg_data.from_bytes(msg_bytes)
# Validate data # Validate data
ensure(len(msg_data.bid_msg_id) == 28, 'Bad msg_id length') ensure(len(msg_data.bid_msg_id) == 28, 'Bad msg_id length')
@ -6285,8 +6283,8 @@ class BasicSwap(BaseApp):
now: int = self.getTime() now: int = self.getTime()
bid_bytes = bytes.fromhex(msg['hex'][2:-2]) bid_bytes = bytes.fromhex(msg['hex'][2:-2])
bid_data = ADSBidIntentMessage() bid_data = ADSBidIntentMessage(init_all=False)
bid_data.ParseFromString(bid_bytes) bid_data.from_bytes(bid_bytes)
# Validate data # Validate data
ensure(bid_data.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Invalid protocol version') ensure(bid_data.protocol_version >= MINPROTO_VERSION_ADAPTOR_SIG, 'Invalid protocol version')
@ -6370,8 +6368,8 @@ class BasicSwap(BaseApp):
now: int = self.getTime() now: int = self.getTime()
msg_bytes = bytes.fromhex(msg['hex'][2:-2]) msg_bytes = bytes.fromhex(msg['hex'][2:-2])
msg_data = ADSBidIntentAcceptMessage() msg_data = ADSBidIntentAcceptMessage(init_all=False)
msg_data.ParseFromString(msg_bytes) msg_data.from_bytes(msg_bytes)
bid_id = msg_data.bid_msg_id bid_id = msg_data.bid_msg_id
bid, xmr_swap = self.getXmrBid(bid_id) bid, xmr_swap = self.getXmrBid(bid_id)

@ -1,160 +0,0 @@
syntax = "proto3";
package basicswap;
/* Step 1, seller -> network */
message OfferMessage {
uint32 protocol_version = 1;
uint32 coin_from = 2;
uint32 coin_to = 3;
uint64 amount_from = 4;
uint64 amount_to = 5;
uint64 min_bid_amount = 6;
uint64 time_valid = 7;
enum LockType {
NOT_SET = 0;
SEQUENCE_LOCK_BLOCKS = 1;
SEQUENCE_LOCK_TIME = 2;
ABS_LOCK_BLOCKS = 3;
ABS_LOCK_TIME = 4;
}
LockType lock_type = 8;
uint32 lock_value = 9;
uint32 swap_type = 10;
/* optional */
string proof_address = 11;
string proof_signature = 12;
bytes pkhash_seller = 13;
bytes secret_hash = 14;
uint64 fee_rate_from = 15;
uint64 fee_rate_to = 16;
bool amount_negotiable = 17;
bool rate_negotiable = 18;
bytes proof_utxos = 19; /* 32 byte txid 2 byte vout, repeated */
}
/* Step 2, buyer -> seller */
message BidMessage {
uint32 protocol_version = 1;
bytes offer_msg_id = 2;
uint64 time_valid = 3; /* seconds bid is valid for */
uint64 amount = 4; /* amount of amount_from bid is for */
uint64 amount_to = 5;
bytes pkhash_buyer = 6; /* buyer's address to receive amount_from */
string proof_address = 7;
string proof_signature = 8;
bytes proof_utxos = 9; /* 32 byte txid 2 byte vout, repeated */
/* optional */
bytes pkhash_buyer_to = 10; /* When pubkey hash is different on the to-chain */
}
/* For tests */
message BidMessage_test {
uint32 protocol_version = 1;
bytes offer_msg_id = 2;
uint64 time_valid = 3;
uint64 amount = 4;
uint64 rate = 5;
}
/* Step 3, seller -> buyer */
message BidAcceptMessage {
bytes bid_msg_id = 1;
bytes initiate_txid = 2;
bytes contract_script = 3;
bytes pkhash_seller = 4;
}
message OfferRevokeMessage {
bytes offer_msg_id = 1;
bytes signature = 2;
}
message BidRejectMessage {
bytes bid_msg_id = 1;
uint32 reject_code = 2;
}
message XmrBidMessage {
/* MSG1L, F -> L */
uint32 protocol_version = 1;
bytes offer_msg_id = 2;
uint64 time_valid = 3; /* seconds bid is valid for */
uint64 amount = 4; /* amount of amount_from bid is for */
uint64 amount_to = 5;
bytes pkaf = 6;
bytes kbvf = 7;
bytes kbsf_dleag = 8;
bytes dest_af = 9;
}
message XmrSplitMessage {
bytes msg_id = 1;
uint32 msg_type = 2; /* 1 XmrBid, 2 XmrBidAccept */
uint32 sequence = 3;
bytes dleag = 4;
}
message XmrBidAcceptMessage {
bytes bid_msg_id = 1;
bytes pkal = 2;
bytes kbvl = 3;
bytes kbsl_dleag = 4;
/* MSG2F */
bytes a_lock_tx = 5;
bytes a_lock_tx_script = 6;
bytes a_lock_refund_tx = 7;
bytes a_lock_refund_tx_script = 8;
bytes a_lock_refund_spend_tx = 9;
bytes al_lock_refund_tx_sig = 10;
}
message XmrBidLockTxSigsMessage {
/* MSG3L */
bytes bid_msg_id = 1;
bytes af_lock_refund_spend_tx_esig = 2;
bytes af_lock_refund_tx_sig = 3;
}
message XmrBidLockSpendTxMessage {
/* MSG4F */
bytes bid_msg_id = 1;
bytes a_lock_spend_tx = 2;
bytes kal_sig = 3;
}
message XmrBidLockReleaseMessage {
/* MSG5F */
bytes bid_msg_id = 1;
bytes al_lock_spend_tx_esig = 2;
}
message ADSBidIntentMessage {
/* L -> F Sent from bidder, construct a reverse bid */
uint32 protocol_version = 1;
bytes offer_msg_id = 2;
uint64 time_valid = 3; /* seconds bid is valid for */
uint64 amount_from = 4; /* amount of offer.coin_from bid is for */
uint64 amount_to = 5; /* amount of offer.coin_to bid is for, equivalent to bid.amount */
}
message ADSBidIntentAcceptMessage {
/* F -> L Sent from offerer, construct a reverse bid */
bytes bid_msg_id = 1;
bytes pkaf = 2;
bytes kbvf = 3;
bytes kbsf_dleag = 4;
bytes dest_af = 5;
}

@ -7,6 +7,8 @@
''' '''
syntax = "proto3";
0 VARINT int32, int64, uint32, uint64, sint32, sint64, bool, enum 0 VARINT int32, int64, uint32, uint64, sint32, sint64, bool, enum
1 I64 fixed64, sfixed64, double 1 I64 fixed64, sfixed64, double
2 LEN string, bytes, embedded messages, packed repeated fields 2 LEN string, bytes, embedded messages, packed repeated fields
@ -14,12 +16,45 @@
Don't encode fields of default values. Don't encode fields of default values.
When decoding initialise all fields not set from data. When decoding initialise all fields not set from data.
protobuf ParseFromString would reset the whole object, from_bytes won't.
''' '''
from basicswap.util.integer import encode_varint, decode_varint from basicswap.util.integer import encode_varint, decode_varint
class NonProtobufClass(): class NonProtobufClass():
def __init__(self, init_all: bool = True, **kwargs):
for key, value in kwargs.items():
found_field: bool = False
for field_num, v in self._map.items():
field_name, wire_type, field_type = v
if field_name == key:
setattr(self, field_name, value)
found_field = True
break
if found_field is False:
raise ValueError(f'got an unexpected keyword argument \'{key}\'')
if init_all:
self.init_fields()
def init_fields(self) -> None:
# Set default values for missing fields
for field_num, v in self._map.items():
field_name, wire_type, field_type = v
if hasattr(self, field_name):
continue
if wire_type == 0:
setattr(self, field_name, 0)
elif wire_type == 2:
if field_type == 1:
setattr(self, field_name, str())
else:
setattr(self, field_name, bytes())
else:
raise ValueError(f'Unknown wire_type {wire_type}')
def to_bytes(self) -> bytes: def to_bytes(self) -> bytes:
rv = bytes() rv = bytes()
@ -74,22 +109,8 @@ class NonProtobufClass():
setattr(self, field_name, field_value) setattr(self, field_name, field_value)
if not init_all: if init_all:
return self.init_fields()
# Set default values for missing fields
for field_num, v in self._map.items():
field_name, wire_type, field_type = v
if hasattr(self, field_name):
continue
if wire_type == 0:
setattr(self, field_name, 0)
elif wire_type == 2:
if field_type == 1:
setattr(self, field_name, str())
else:
setattr(self, field_name, bytes())
else:
raise ValueError(f'Unknown wire_type {wire_type}')
class OfferMessage(NonProtobufClass): class OfferMessage(NonProtobufClass):

@ -1,54 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: messages.proto
# Protobuf Python Version: 4.25.3
"""Generated protocol buffer code."""
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
from google.protobuf.internal import builder as _builder
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0emessages.proto\x12\tbasicswap\"\xc0\x04\n\x0cOfferMessage\x12\x18\n\x10protocol_version\x18\x01 \x01(\r\x12\x11\n\tcoin_from\x18\x02 \x01(\r\x12\x0f\n\x07\x63oin_to\x18\x03 \x01(\r\x12\x13\n\x0b\x61mount_from\x18\x04 \x01(\x04\x12\x11\n\tamount_to\x18\x05 \x01(\x04\x12\x16\n\x0emin_bid_amount\x18\x06 \x01(\x04\x12\x12\n\ntime_valid\x18\x07 \x01(\x04\x12\x33\n\tlock_type\x18\x08 \x01(\x0e\x32 .basicswap.OfferMessage.LockType\x12\x12\n\nlock_value\x18\t \x01(\r\x12\x11\n\tswap_type\x18\n \x01(\r\x12\x15\n\rproof_address\x18\x0b \x01(\t\x12\x17\n\x0fproof_signature\x18\x0c \x01(\t\x12\x15\n\rpkhash_seller\x18\r \x01(\x0c\x12\x13\n\x0bsecret_hash\x18\x0e \x01(\x0c\x12\x15\n\rfee_rate_from\x18\x0f \x01(\x04\x12\x13\n\x0b\x66\x65\x65_rate_to\x18\x10 \x01(\x04\x12\x19\n\x11\x61mount_negotiable\x18\x11 \x01(\x08\x12\x17\n\x0frate_negotiable\x18\x12 \x01(\x08\x12\x13\n\x0bproof_utxos\x18\x13 \x01(\x0c\"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\"\xe7\x01\n\nBidMessage\x12\x18\n\x10protocol_version\x18\x01 \x01(\r\x12\x14\n\x0coffer_msg_id\x18\x02 \x01(\x0c\x12\x12\n\ntime_valid\x18\x03 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x04 \x01(\x04\x12\x11\n\tamount_to\x18\x05 \x01(\x04\x12\x14\n\x0cpkhash_buyer\x18\x06 \x01(\x0c\x12\x15\n\rproof_address\x18\x07 \x01(\t\x12\x17\n\x0fproof_signature\x18\x08 \x01(\t\x12\x13\n\x0bproof_utxos\x18\t \x01(\x0c\x12\x17\n\x0fpkhash_buyer_to\x18\r \x01(\x0c\"s\n\x0f\x42idMessage_test\x12\x18\n\x10protocol_version\x18\x01 \x01(\r\x12\x14\n\x0coffer_msg_id\x18\x02 \x01(\x0c\x12\x12\n\ntime_valid\x18\x03 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x04 \x01(\x04\x12\x0c\n\x04rate\x18\x05 \x01(\x04\"m\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\x12\x15\n\rpkhash_seller\x18\x04 \x01(\x0c\"=\n\x12OfferRevokeMessage\x12\x14\n\x0coffer_msg_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\";\n\x10\x42idRejectMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x13\n\x0breject_code\x18\x02 \x01(\r\"\xb7\x01\n\rXmrBidMessage\x12\x18\n\x10protocol_version\x18\x01 \x01(\r\x12\x14\n\x0coffer_msg_id\x18\x02 \x01(\x0c\x12\x12\n\ntime_valid\x18\x03 \x01(\x04\x12\x0e\n\x06\x61mount\x18\x04 \x01(\x04\x12\x11\n\tamount_to\x18\x05 \x01(\x04\x12\x0c\n\x04pkaf\x18\x06 \x01(\x0c\x12\x0c\n\x04kbvf\x18\x07 \x01(\x0c\x12\x12\n\nkbsf_dleag\x18\x08 \x01(\x0c\x12\x0f\n\x07\x64\x65st_af\x18\t \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\x02 \x01(\x0c\x12\x0c\n\x04kbvl\x18\x03 \x01(\x0c\x12\x12\n\nkbsl_dleag\x18\x04 \x01(\x0c\x12\x11\n\ta_lock_tx\x18\x05 \x01(\x0c\x12\x18\n\x10\x61_lock_tx_script\x18\x06 \x01(\x0c\x12\x18\n\x10\x61_lock_refund_tx\x18\x07 \x01(\x0c\x12\x1f\n\x17\x61_lock_refund_tx_script\x18\x08 \x01(\x0c\x12\x1e\n\x16\x61_lock_refund_spend_tx\x18\t \x01(\x0c\x12\x1d\n\x15\x61l_lock_refund_tx_sig\x18\n \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\"\x81\x01\n\x13\x41\x44SBidIntentMessage\x12\x18\n\x10protocol_version\x18\x01 \x01(\r\x12\x14\n\x0coffer_msg_id\x18\x02 \x01(\x0c\x12\x12\n\ntime_valid\x18\x03 \x01(\x04\x12\x13\n\x0b\x61mount_from\x18\x04 \x01(\x04\x12\x11\n\tamount_to\x18\x05 \x01(\x04\"p\n\x19\x41\x44SBidIntentAcceptMessage\x12\x12\n\nbid_msg_id\x18\x01 \x01(\x0c\x12\x0c\n\x04pkaf\x18\x02 \x01(\x0c\x12\x0c\n\x04kbvf\x18\x03 \x01(\x0c\x12\x12\n\nkbsf_dleag\x18\x04 \x01(\x0c\x12\x0f\n\x07\x64\x65st_af\x18\x05 \x01(\x0c\x62\x06proto3')
_globals = globals()
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'messages_pb2', _globals)
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_globals['_OFFERMESSAGE']._serialized_start=30
_globals['_OFFERMESSAGE']._serialized_end=606
_globals['_OFFERMESSAGE_LOCKTYPE']._serialized_start=493
_globals['_OFFERMESSAGE_LOCKTYPE']._serialized_end=606
_globals['_BIDMESSAGE']._serialized_start=609
_globals['_BIDMESSAGE']._serialized_end=840
_globals['_BIDMESSAGE_TEST']._serialized_start=842
_globals['_BIDMESSAGE_TEST']._serialized_end=957
_globals['_BIDACCEPTMESSAGE']._serialized_start=959
_globals['_BIDACCEPTMESSAGE']._serialized_end=1068
_globals['_OFFERREVOKEMESSAGE']._serialized_start=1070
_globals['_OFFERREVOKEMESSAGE']._serialized_end=1131
_globals['_BIDREJECTMESSAGE']._serialized_start=1133
_globals['_BIDREJECTMESSAGE']._serialized_end=1192
_globals['_XMRBIDMESSAGE']._serialized_start=1195
_globals['_XMRBIDMESSAGE']._serialized_end=1378
_globals['_XMRSPLITMESSAGE']._serialized_start=1380
_globals['_XMRSPLITMESSAGE']._serialized_end=1464
_globals['_XMRBIDACCEPTMESSAGE']._serialized_start=1467
_globals['_XMRBIDACCEPTMESSAGE']._serialized_end=1723
_globals['_XMRBIDLOCKTXSIGSMESSAGE']._serialized_start=1725
_globals['_XMRBIDLOCKTXSIGSMESSAGE']._serialized_end=1839
_globals['_XMRBIDLOCKSPENDTXMESSAGE']._serialized_start=1841
_globals['_XMRBIDLOCKSPENDTXMESSAGE']._serialized_end=1929
_globals['_XMRBIDLOCKRELEASEMESSAGE']._serialized_start=1931
_globals['_XMRBIDLOCKRELEASEMESSAGE']._serialized_end=2008
_globals['_ADSBIDINTENTMESSAGE']._serialized_start=2011
_globals['_ADSBIDINTENTMESSAGE']._serialized_end=2140
_globals['_ADSBIDINTENTACCEPTMESSAGE']._serialized_start=2142
_globals['_ADSBIDINTENTACCEPTMESSAGE']._serialized_end=2254
# @@protoc_insertion_point(module_scope)

@ -140,7 +140,7 @@ Continue from the [Run Using Docker](#run-using-docker) section.
### Ubuntu Setup: ### Ubuntu Setup:
apt-get install -y wget git python3-venv python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config curl jq apt-get install -y wget git python3-venv python3-pip gnupg unzip automake libtool pkg-config curl jq
### OSX Setup: ### OSX Setup:
@ -182,7 +182,6 @@ From https://pypi.org/project/certifi/
Continue installing Basicswap Continue installing Basicswap
protoc -I=basicswap --python_out=basicswap basicswap/messages.proto
pip3 install . pip3 install .

@ -1,3 +1,14 @@
0.13.2
==============
- Remove protobuf and protoc dependencies.
0.13.1
==============
- coins: Add Decred.
0.13.0 0.13.0
============== ==============

@ -7,14 +7,6 @@ ENV LANG=C.UTF-8 \
RUN apt-get update; \ RUN apt-get update; \
apt-get install -y wget python3-pip gnupg unzip make g++ autoconf automake libtool pkg-config gosu tzdata; apt-get install -y wget python3-pip gnupg unzip make g++ autoconf automake libtool pkg-config gosu tzdata;
# Must install protoc directly as latest package is not up to date
RUN wget -O protobuf_src.tar.gz https://github.com/protocolbuffers/protobuf/releases/download/v21.1/protobuf-python-4.21.1.tar.gz && \
tar xvf protobuf_src.tar.gz && \
cd protobuf-3.21.1 && \
./configure --prefix=/usr && \
make -j$(nproc) install && \
ldconfig
ARG COINCURVE_VERSION=v0.2 ARG COINCURVE_VERSION=v0.2
RUN wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/refs/tags/anonswap_$COINCURVE_VERSION.zip && \ RUN wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/refs/tags/anonswap_$COINCURVE_VERSION.zip && \
unzip coincurve-anonswap.zip && \ unzip coincurve-anonswap.zip && \
@ -28,12 +20,10 @@ RUN wget -O basicswap-repo.zip $BASICSWAP_URL; \
unzip basicswap-repo.zip; \ unzip basicswap-repo.zip; \
mv $BASICSWAP_DIR /basicswap; \ mv $BASICSWAP_DIR /basicswap; \
cd /basicswap; \ cd /basicswap; \
protoc -I=basicswap --python_out=basicswap basicswap/messages.proto; \
pip3 install .; pip3 install .;
#COPY ./test_code basicswap #COPY ./test_code basicswap
#RUN cd basicswap; \ #RUN cd basicswap; \
# protoc -I=basicswap --python_out=basicswap basicswap/messages.proto; \
# pip3 install .; # pip3 install .;
RUN groupadd -r swap_user && useradd -g swap_user -ms /bin/bash swap_user && \ RUN groupadd -r swap_user && useradd -g swap_user -ms /bin/bash swap_user && \

@ -14,7 +14,6 @@
#:use-module (gnu packages databases) #:use-module (gnu packages databases)
#:use-module (gnu packages finance) #:use-module (gnu packages finance)
#:use-module (gnu packages gnupg) #:use-module (gnu packages gnupg)
#:use-module (gnu packages protobuf)
#:use-module (gnu packages python) #:use-module (gnu packages python)
#:use-module (gnu packages python-build) #:use-module (gnu packages python-build)
#:use-module (gnu packages python-crypto) #:use-module (gnu packages python-crypto)
@ -150,7 +149,6 @@
python-coincurve-anonswap python-coincurve-anonswap
python-pycryptodome python-pycryptodome
python-pytest python-pytest
python-protobuf
python-sqlalchemy-1.4.39 python-sqlalchemy-1.4.39
python-pyzmq python-pyzmq
python-gnupg python-gnupg

@ -1,6 +1,5 @@
wheel wheel
pyzmq pyzmq
protobuf
sqlalchemy==1.4.39 sqlalchemy==1.4.39
python-gnupg python-gnupg
Jinja2 Jinja2

@ -33,7 +33,6 @@ setuptools.setup(
install_requires=[ install_requires=[
"wheel", "wheel",
"pyzmq", "pyzmq",
"protobuf",
"sqlalchemy==1.4.39", "sqlalchemy==1.4.39",
"python-gnupg", "python-gnupg",
"Jinja2", "Jinja2",

@ -42,14 +42,8 @@ from basicswap.util import (
format_amount, format_amount,
DeserialiseNum, DeserialiseNum,
validate_amount) validate_amount)
from basicswap.messages_pb2 import (
BidMessage,
BidMessage_test,
OfferMessage,
)
from basicswap.messages_npb import ( from basicswap.messages_npb import (
OfferMessage as OfferMessage_npb, BidMessage,
) )
from basicswap.contrib.test_framework.script import hash160 as hash160_btc from basicswap.contrib.test_framework.script import hash160 as hash160_btc
@ -417,49 +411,31 @@ class Test(unittest.TestCase):
assert (hash160_btc(input_data).hex() == '072985b3583a4a71f548494a5e1d5f6b00d0fe13') assert (hash160_btc(input_data).hex() == '072985b3583a4a71f548494a5e1d5f6b00d0fe13')
def test_protobuf(self): def test_protobuf(self):
# Ensure old protobuf templates can be read msg_buf = BidMessage()
msg_buf = BidMessage_test()
msg_buf.protocol_version = 2 msg_buf.protocol_version = 2
msg_buf.time_valid = 1024 msg_buf.time_valid = 1024
serialised_msg = msg_buf.SerializeToString() serialised_msg = msg_buf.to_bytes()
msg_buf_v2 = BidMessage() msg_buf_2 = BidMessage()
msg_buf_v2.ParseFromString(serialised_msg) msg_buf_2.from_bytes(serialised_msg)
assert (msg_buf_v2.protocol_version == 2) assert (msg_buf_2.protocol_version == 2)
assert (msg_buf_v2.time_valid == 1024) assert (msg_buf_2.time_valid == 1024)
assert (msg_buf_v2.amount == 0) assert (msg_buf_2.amount == 0)
assert (msg_buf_v2.pkhash_buyer is not None) assert (msg_buf_2.pkhash_buyer is not None)
assert (len(msg_buf_v2.pkhash_buyer) == 0) assert (len(msg_buf_2.pkhash_buyer) == 0)
# Decode only the first field # Decode only the first field
msg_buf_v2.ParseFromString(serialised_msg[:2]) msg_buf_3 = BidMessage()
assert (msg_buf_v2.protocol_version == 2) msg_buf_3.from_bytes(serialised_msg[:2])
assert (msg_buf_v2.time_valid == 0) assert (msg_buf_3.protocol_version == 2)
assert (msg_buf_3.time_valid == 0)
msg_buf = OfferMessage() try:
msg_buf.protocol_version = 2 msg_buf_4 = BidMessage(doesnotexist=1)
msg_buf.amount_from = 1024 except Exception as e:
msg_buf.amount_to = 0 # test if it gets encoded assert ('unexpected keyword argument' in str(e))
msg_buf.pkhash_seller = bytes((1,)) * 32 else:
msg_buf.proof_address = 'a string' raise ValueError('Should have errored.')
msg_buf.amount_negotiable = True
msg_buf.rate_negotiable = False
msg_buf.fee_rate_to = 2485
pb_serialised_msg = msg_buf.SerializeToString()
npb = OfferMessage_npb()
npb.from_bytes(pb_serialised_msg)
assert (npb.protocol_version == msg_buf.protocol_version)
assert (npb.amount_from == msg_buf.amount_from)
assert (npb.amount_to == msg_buf.amount_to)
assert (npb.pkhash_seller == msg_buf.pkhash_seller)
assert (npb.proof_address == msg_buf.proof_address)
assert (npb.amount_negotiable == msg_buf.amount_negotiable)
assert (npb.fee_rate_to == msg_buf.fee_rate_to)
npb_serialised_msg = npb.to_bytes()
assert (npb_serialised_msg == pb_serialised_msg)
def test_is_private_ip_address(self): def test_is_private_ip_address(self):
test_addresses = [ test_addresses = [

Loading…
Cancel
Save