XMR withdrawals work.
spendBLockTx uses sweep_all.
This commit is contained in:
		
							parent
							
								
									669a465262
								
							
						
					
					
						commit
						4c200fe8d4
					
				
							
								
								
									
										11
									
								
								.cirrus.yml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								.cirrus.yml
									
									
									
									
									
								
							@ -14,24 +14,31 @@ test_task:
 | 
				
			|||||||
    - PART_VERSION: 0.19.1.2
 | 
					    - PART_VERSION: 0.19.1.2
 | 
				
			||||||
    - BTC_VERSION: 0.20.1
 | 
					    - BTC_VERSION: 0.20.1
 | 
				
			||||||
    - LTC_VERSION: 0.18.1
 | 
					    - LTC_VERSION: 0.18.1
 | 
				
			||||||
 | 
					    - XMR_VERSION: 0.17.1.5
 | 
				
			||||||
    - TEST_RELOAD_PATH: $HOME/test_basicswap1/
 | 
					    - TEST_RELOAD_PATH: $HOME/test_basicswap1/
 | 
				
			||||||
    - TEST_DIR: $HOME/test_basicswap2/
 | 
					    - TEST_DIR: $HOME/test_basicswap2/
 | 
				
			||||||
    - BIN_DIRS: $HOME/binaries
 | 
					    - BIN_DIRS: $HOME/binaries
 | 
				
			||||||
    - PARTICL_BINDIR: ${BIN_DIRS}/particl-${PART_VERSION}/bin
 | 
					    - PARTICL_BINDIR: ${BIN_DIRS}/particl-${PART_VERSION}/bin
 | 
				
			||||||
    - BITCOIN_BINDIR: ${BIN_DIRS}/bitcoin-${BTC_VERSION}/bin
 | 
					    - BITCOIN_BINDIR: ${BIN_DIRS}/bitcoin-${BTC_VERSION}/bin
 | 
				
			||||||
    - LITECOIN_BINDIR: ${BIN_DIRS}/litecoin-${LTC_VERSION}/bin
 | 
					    - LITECOIN_BINDIR: ${BIN_DIRS}/litecoin-${LTC_VERSION}/bin
 | 
				
			||||||
 | 
					    - MONERO_BINDIR: ${BIN_DIRS}/monero-${XMR_VERSION}/bin
 | 
				
			||||||
  setup_script:
 | 
					  setup_script:
 | 
				
			||||||
 | 
					    - sudo apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config
 | 
				
			||||||
    - if [ ! -d "$BIN_DIRS" ]; then mkdir -p "$BIN_DIRS" ; fi
 | 
					    - if [ ! -d "$BIN_DIRS" ]; then mkdir -p "$BIN_DIRS" ; fi
 | 
				
			||||||
    - if [ ! -d "$PARTICL_BINDIR" ]; then cd "$BIN_DIRS" && wget https://github.com/tecnovert/particl-core/releases/download/v${PART_VERSION}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz; fi
 | 
					    - if [ ! -d "$PARTICL_BINDIR" ]; then cd "$BIN_DIRS" && wget https://github.com/tecnovert/particl-core/releases/download/v${PART_VERSION}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz; fi
 | 
				
			||||||
    - if [ ! -d "$BITCOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://bitcoincore.org/bin/bitcoin-core-${BTC_VERSION}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz; fi
 | 
					    - if [ ! -d "$BITCOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://bitcoincore.org/bin/bitcoin-core-${BTC_VERSION}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz; fi
 | 
				
			||||||
    - if [ ! -d "$LITECOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://download.litecoin.org/litecoin-${LTC_VERSION}/linux/litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
					    - if [ ! -d "$LITECOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://download.litecoin.org/litecoin-${LTC_VERSION}/linux/litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
				
			||||||
 | 
					    - wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/anonswap.zip
 | 
				
			||||||
 | 
					    - unzip coincurve-anonswap.zip
 | 
				
			||||||
 | 
					    - cd coincurve-anonswap
 | 
				
			||||||
 | 
					    - python3 setup.py install --force
 | 
				
			||||||
  script:
 | 
					  script:
 | 
				
			||||||
    - cd "${CIRRUS_WORKING_DIR}"
 | 
					    - cd "${CIRRUS_WORKING_DIR}"
 | 
				
			||||||
    - export DATADIRS="${TEST_DIR}"
 | 
					    - export DATADIRS="${TEST_DIR}"
 | 
				
			||||||
    - mkdir -p ${DATADIRS}/bin/{particl,bitcoin}
 | 
					    - mkdir -p ${DATADIRS}/bin/{particl,bitcoin,monero}
 | 
				
			||||||
    - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/bitcoin"
 | 
					    - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/bitcoin"
 | 
				
			||||||
    - cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/particl"
 | 
					    - cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/particl"
 | 
				
			||||||
    - mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,bitcoin}
 | 
					    - mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,bitcoin,monero}
 | 
				
			||||||
    - cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/particl"
 | 
					    - cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/particl"
 | 
				
			||||||
    - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/bitcoin"
 | 
					    - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/bitcoin"
 | 
				
			||||||
    - python setup.py test
 | 
					    - python setup.py test
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										12
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								.travis.yml
									
									
									
									
									
								
							@ -10,28 +10,34 @@ env:
 | 
				
			|||||||
    - PART_VERSION=0.19.1.2
 | 
					    - PART_VERSION=0.19.1.2
 | 
				
			||||||
    - BTC_VERSION=0.20.1
 | 
					    - BTC_VERSION=0.20.1
 | 
				
			||||||
    - LTC_VERSION=0.18.1
 | 
					    - LTC_VERSION=0.18.1
 | 
				
			||||||
 | 
					    - XMR_VERSION=0.17.1.5
 | 
				
			||||||
    - TEST_DIR=~/test_basicswap2/
 | 
					    - TEST_DIR=~/test_basicswap2/
 | 
				
			||||||
    - TEST_RELOAD_PATH=~/test_basicswap1/
 | 
					    - TEST_RELOAD_PATH=~/test_basicswap1/
 | 
				
			||||||
    - BIN_DIRS=~/binaries
 | 
					    - BIN_DIRS=~/binaries
 | 
				
			||||||
    - PARTICL_BINDIR=${BIN_DIRS}/particl-${PART_VERSION}/bin/
 | 
					    - PARTICL_BINDIR=${BIN_DIRS}/particl-${PART_VERSION}/bin/
 | 
				
			||||||
    - BITCOIN_BINDIR=${BIN_DIRS}/bitcoin-${BTC_VERSION}/bin/
 | 
					    - BITCOIN_BINDIR=${BIN_DIRS}/bitcoin-${BTC_VERSION}/bin/
 | 
				
			||||||
    - LITECOIN_BINDIR=${BIN_DIRS}/litecoin-${LTC_VERSION}/bin/
 | 
					    - LITECOIN_BINDIR=${BIN_DIRS}/litecoin-${LTC_VERSION}/bin/
 | 
				
			||||||
 | 
					    - MONERO_BINDIR=${BIN_DIRS}/monero-${XMR_VERSION}/bin/
 | 
				
			||||||
cache:
 | 
					cache:
 | 
				
			||||||
  directories:
 | 
					  directories:
 | 
				
			||||||
    - "$BIN_DIRS"
 | 
					    - "$BIN_DIRS"
 | 
				
			||||||
before_install:
 | 
					before_install:
 | 
				
			||||||
  - sudo apt-get install -y wget gnupg2
 | 
					  - sudo apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config
 | 
				
			||||||
before_script:
 | 
					before_script:
 | 
				
			||||||
  - if [ ! -d "$BIN_DIRS" ]; then mkdir -p "$BIN_DIRS" ; fi
 | 
					  - if [ ! -d "$BIN_DIRS" ]; then mkdir -p "$BIN_DIRS" ; fi
 | 
				
			||||||
  - if [ ! -d "$PARTICL_BINDIR" ]; then cd "$BIN_DIRS" && wget https://github.com/tecnovert/particl-core/releases/download/v${PART_VERSION}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
					  - if [ ! -d "$PARTICL_BINDIR" ]; then cd "$BIN_DIRS" && wget https://github.com/tecnovert/particl-core/releases/download/v${PART_VERSION}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
				
			||||||
  - if [ ! -d "$BITCOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://bitcoincore.org/bin/bitcoin-core-${BTC_VERSION}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
					  - if [ ! -d "$BITCOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://bitcoincore.org/bin/bitcoin-core-${BTC_VERSION}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
				
			||||||
  - if [ ! -d "$LITECOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://download.litecoin.org/litecoin-${LTC_VERSION}/linux/litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
					  - if [ ! -d "$LITECOIN_BINDIR" ]; then cd "$BIN_DIRS" && wget https://download.litecoin.org/litecoin-${LTC_VERSION}/linux/litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz && tar xvf litecoin-${LTC_VERSION}-x86_64-linux-gnu.tar.gz ; fi
 | 
				
			||||||
 | 
					  - wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/anonswap.zip
 | 
				
			||||||
 | 
					  - unzip coincurve-anonswap.zip
 | 
				
			||||||
 | 
					  - cd coincurve-anonswap
 | 
				
			||||||
 | 
					  - python3 setup.py install --force
 | 
				
			||||||
script:
 | 
					script:
 | 
				
			||||||
  - cd $TRAVIS_BUILD_DIR
 | 
					  - cd $TRAVIS_BUILD_DIR
 | 
				
			||||||
  - export DATADIRS="${TEST_DIR}"
 | 
					  - export DATADIRS="${TEST_DIR}"
 | 
				
			||||||
  - mkdir -p ${DATADIRS}/bin/{particl,bitcoin}
 | 
					  - mkdir -p ${DATADIRS}/bin/{particl,bitcoin,monero}
 | 
				
			||||||
  - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/bitcoin"
 | 
					  - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${DATADIRS}/bin/bitcoin"
 | 
				
			||||||
  - mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,bitcoin}
 | 
					  - mkdir -p ${TEST_RELOAD_PATH}/bin/{particl,bitcoin,monero}
 | 
				
			||||||
  - cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/particl"
 | 
					  - cp "${BIN_DIRS}/particl-${PART_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/particl"
 | 
				
			||||||
  - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/bitcoin"
 | 
					  - cp "${BIN_DIRS}/bitcoin-${BTC_VERSION}-x86_64-linux-gnu.tar.gz" "${TEST_RELOAD_PATH}/bin/bitcoin"
 | 
				
			||||||
  - python setup.py test
 | 
					  - python setup.py test
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,10 @@ RUN wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archiv
 | 
				
			|||||||
    cd coincurve-anonswap && \
 | 
					    cd coincurve-anonswap && \
 | 
				
			||||||
    python3 setup.py install --force
 | 
					    python3 setup.py install --force
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# TODO: move coindata dir out of src dir
 | 
					# Install requirements first so as to skip in subsequent rebuilds
 | 
				
			||||||
 | 
					COPY ./requirements.txt requirements.txt
 | 
				
			||||||
 | 
					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; \
 | 
					    protoc -I=basicswap --python_out=basicswap basicswap/messages.proto; \
 | 
				
			||||||
 | 
				
			|||||||
@ -816,14 +816,12 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
            if bid.participate_tx and bid.participate_tx.txid:
 | 
					            if bid.participate_tx and bid.participate_tx.txid:
 | 
				
			||||||
                self.addWatchedOutput(coin_to, bid.bid_id, bid.participate_tx.txid.hex(), bid.participate_tx.vout, BidStates.SWAP_PARTICIPATING)
 | 
					                self.addWatchedOutput(coin_to, bid.bid_id, bid.participate_tx.txid.hex(), bid.participate_tx.vout, BidStates.SWAP_PARTICIPATING)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO: watch for xmr bid outputs
 | 
					            if self.coin_clients[coin_from]['last_height_checked'] < 1:
 | 
				
			||||||
 | 
					                if bid.initiate_tx and bid.initiate_tx.chain_height:
 | 
				
			||||||
        if self.coin_clients[coin_from]['last_height_checked'] < 1:
 | 
					                    self.coin_clients[coin_from]['last_height_checked'] = bid.initiate_tx.chain_height
 | 
				
			||||||
            if bid.initiate_tx and bid.initiate_tx.chain_height:
 | 
					            if self.coin_clients[coin_to]['last_height_checked'] < 1:
 | 
				
			||||||
                self.coin_clients[coin_from]['last_height_checked'] = bid.initiate_tx.chain_height
 | 
					                if bid.participate_tx and bid.participate_tx.chain_height:
 | 
				
			||||||
        if self.coin_clients[coin_to]['last_height_checked'] < 1:
 | 
					                    self.coin_clients[coin_to]['last_height_checked'] = bid.participate_tx.chain_height
 | 
				
			||||||
            if bid.participate_tx and bid.participate_tx.chain_height:
 | 
					 | 
				
			||||||
                self.coin_clients[coin_to]['last_height_checked'] = bid.participate_tx.chain_height
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # TODO process addresspool if bid has previously been abandoned
 | 
					        # TODO process addresspool if bid has previously been abandoned
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -980,7 +978,9 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                # TODO: Dynamic fee selection
 | 
					                # TODO: Dynamic fee selection
 | 
				
			||||||
                xmr_offer.a_fee_rate = make_int(0.00032595, self.ci(coin_from).exp())
 | 
					                xmr_offer.a_fee_rate = make_int(0.00032595, self.ci(coin_from).exp())
 | 
				
			||||||
                xmr_offer.b_fee_rate = make_int(0.0012595, self.ci(coin_to).exp())
 | 
					                # xmr_offer.b_fee_rate = make_int(0.0012595, self.ci(coin_to).exp())
 | 
				
			||||||
 | 
					                xmr_offer.b_fee_rate = make_int(0.00002, self.ci(coin_to).exp())  # abs fee
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                msg_buf.fee_rate_from = xmr_offer.a_fee_rate
 | 
					                msg_buf.fee_rate_from = xmr_offer.a_fee_rate
 | 
				
			||||||
                msg_buf.fee_rate_to = xmr_offer.b_fee_rate
 | 
					                msg_buf.fee_rate_to = xmr_offer.b_fee_rate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1198,12 +1198,19 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return self.ci(coin_type).get_fee_rate()
 | 
					        return self.ci(coin_type).get_fee_rate()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def estimateWithdrawFee(self, coin_type, fee_rate):
 | 
				
			||||||
 | 
					        if coin_type == Coins.XMR:
 | 
				
			||||||
 | 
					            self.log.error('TODO: estimateWithdrawFee XMR')
 | 
				
			||||||
 | 
					            return None
 | 
				
			||||||
 | 
					        tx_vsize = self.getContractSpendTxVSize(coin_type)
 | 
				
			||||||
 | 
					        est_fee = (fee_rate * tx_vsize) / 1000
 | 
				
			||||||
 | 
					        return est_fee
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def withdrawCoin(self, coin_type, value, addr_to, subfee):
 | 
					    def withdrawCoin(self, coin_type, value, addr_to, subfee):
 | 
				
			||||||
        self.log.info('withdrawCoin %s %s to %s %s', value, self.getTicker(coin_type), addr_to, ' subfee' if subfee else '')
 | 
					        self.log.info('withdrawCoin %s %s to %s %s', value, self.getTicker(coin_type), addr_to, ' subfee' if subfee else '')
 | 
				
			||||||
        params = [addr_to, value, '', '', subfee, True, self.coin_clients[coin_type]['conf_target']]
 | 
					
 | 
				
			||||||
        if coin_type == Coins.PART:
 | 
					        ci = self.ci(coin_type)
 | 
				
			||||||
            params.insert(5, '')  # narration
 | 
					        return ci.withdrawCoin(value, addr_to, subfee)
 | 
				
			||||||
        return self.callcoinrpc(coin_type, 'sendtoaddress', params)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def cacheNewAddressForCoin(self, coin_type):
 | 
					    def cacheNewAddressForCoin(self, coin_type):
 | 
				
			||||||
        self.log.debug('cacheNewAddressForCoin %s', coin_type)
 | 
					        self.log.debug('cacheNewAddressForCoin %s', coin_type)
 | 
				
			||||||
@ -2765,7 +2772,15 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def addWatchedOutput(self, coin_type, bid_id, txid_hex, vout, tx_type, swap_type=None):
 | 
					    def addWatchedOutput(self, coin_type, bid_id, txid_hex, vout, tx_type, swap_type=None):
 | 
				
			||||||
        self.log.debug('Adding watched output %s bid %s tx %s type %s', coin_type, bid_id.hex(), txid_hex, tx_type)
 | 
					        self.log.debug('Adding watched output %s bid %s tx %s type %s', coin_type, bid_id.hex(), txid_hex, tx_type)
 | 
				
			||||||
        self.coin_clients[coin_type]['watched_outputs'].append(WatchedOutput(bid_id, txid_hex, vout, tx_type, swap_type))
 | 
					
 | 
				
			||||||
 | 
					        watched = self.coin_clients[coin_type]['watched_outputs']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for wo in watched:
 | 
				
			||||||
 | 
					            if wo.bid_id == bid_id and wo.txid_hex == txid_hex and wo.vout == vout:
 | 
				
			||||||
 | 
					                self.log.debug('Output already being watched.')
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        watched.append(WatchedOutput(bid_id, txid_hex, vout, tx_type, swap_type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def removeWatchedOutput(self, coin_type, bid_id, txid_hex):
 | 
					    def removeWatchedOutput(self, coin_type, bid_id, txid_hex):
 | 
				
			||||||
        # Remove all for bid if txid is None
 | 
					        # Remove all for bid if txid is None
 | 
				
			||||||
@ -2862,6 +2877,8 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
            spending_txid = bytes.fromhex(spend_txid_hex)
 | 
					            spending_txid = bytes.fromhex(spend_txid_hex)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if spending_txid == xmr_swap.a_lock_spend_tx_id:
 | 
					            if spending_txid == xmr_swap.a_lock_spend_tx_id:
 | 
				
			||||||
 | 
					                self.log.debug('[rm] state %d', state)
 | 
				
			||||||
 | 
					                self.log.debug('[rm] BidStates.XMR_SWAP_SECRET_SHARED %d', BidStates.XMR_SWAP_SECRET_SHARED)
 | 
				
			||||||
                if state == BidStates.XMR_SWAP_SECRET_SHARED:
 | 
					                if state == BidStates.XMR_SWAP_SECRET_SHARED:
 | 
				
			||||||
                    xmr_swap.a_lock_spend_tx = bytes.fromhex(spend_txn['hex'])
 | 
					                    xmr_swap.a_lock_spend_tx = bytes.fromhex(spend_txn['hex'])
 | 
				
			||||||
                    bid.setState(BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED)  # TODO: Wait for confirmation?
 | 
					                    bid.setState(BidStates.XMR_SWAP_SCRIPT_TX_REDEEMED)  # TODO: Wait for confirmation?
 | 
				
			||||||
@ -4232,24 +4249,28 @@ class BasicSwap(BaseApp):
 | 
				
			|||||||
            if bid.state != data['bid_state']:
 | 
					            if bid.state != data['bid_state']:
 | 
				
			||||||
                bid.setState(data['bid_state'])
 | 
					                bid.setState(data['bid_state'])
 | 
				
			||||||
                self.log.debug('Set state to %s', strBidState(bid.state))
 | 
					                self.log.debug('Set state to %s', strBidState(bid.state))
 | 
				
			||||||
 | 
					                self.log.debug('[rm] Set bid.state %d', bid.state)
 | 
				
			||||||
                has_changed = True
 | 
					                has_changed = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if has_changed:
 | 
					            if has_changed:
 | 
				
			||||||
                session = scoped_session(self.session_factory)
 | 
					                session = scoped_session(self.session_factory)
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    activate_bid = False
 | 
					                    activate_bid = False
 | 
				
			||||||
                    if offer.swap_type == SwapTypes.SELLER_FIRST:
 | 
					                    if offer.swap_type == SwapTypes.SELLER_FIRST:
 | 
				
			||||||
                        if bid.state and bid.state > BidStates.BID_RECEIVED and bid.state < BidStates.SWAP_COMPLETED:
 | 
					                        if bid.state and bid.state > BidStates.BID_RECEIVED and bid.state < BidStates.SWAP_COMPLETED:
 | 
				
			||||||
                            activate_bid = True
 | 
					                            activate_bid = True
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                        raise ValueError('TODO')
 | 
					                        self.log.debug('TODO - determine in-progress for manualBidUpdate')
 | 
				
			||||||
 | 
					                        if offer.swap_type == SwapTypes.XMR_SWAP:
 | 
				
			||||||
 | 
					                            if bid.state and bid.state == BidStates.XMR_SWAP_SECRET_SHARED:
 | 
				
			||||||
 | 
					                                activate_bid = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if activate_bid:
 | 
					                    if activate_bid:
 | 
				
			||||||
                        self.activateBid(session, bid)
 | 
					                        self.activateBid(session, bid)
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                        self.deactivateBid(session, offer, bid)
 | 
					                        self.deactivateBid(session, offer, bid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    self.log.debug('[rm] bid.state %d', bid.state)
 | 
				
			||||||
                    self.saveBidInSession(bid_id, bid, session)
 | 
					                    self.saveBidInSession(bid_id, bid, session)
 | 
				
			||||||
                    session.commit()
 | 
					                    session.commit()
 | 
				
			||||||
                finally:
 | 
					                finally:
 | 
				
			||||||
 | 
				
			|||||||
@ -242,14 +242,13 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            ci = swap_client.ci(k)
 | 
					            ci = swap_client.ci(k)
 | 
				
			||||||
            fee_rate = swap_client.getFeeRateForCoin(k)
 | 
					            fee_rate = swap_client.getFeeRateForCoin(k)
 | 
				
			||||||
            tx_vsize = swap_client.getContractSpendTxVSize(k)
 | 
					            est_fee = swap_client.estimateWithdrawFee(k, fee_rate)
 | 
				
			||||||
            est_fee = (fee_rate * tx_vsize) / 1000
 | 
					 | 
				
			||||||
            wallets_formatted.append({
 | 
					            wallets_formatted.append({
 | 
				
			||||||
                'name': w['name'],
 | 
					                'name': w['name'],
 | 
				
			||||||
                'version': w['version'],
 | 
					                'version': w['version'],
 | 
				
			||||||
                'cid': str(int(k)),
 | 
					                'cid': str(int(k)),
 | 
				
			||||||
                'fee_rate': ci.format_amount(int(fee_rate * ci.COIN())),
 | 
					                'fee_rate': ci.format_amount(int(fee_rate * ci.COIN())),
 | 
				
			||||||
                'est_fee': ci.format_amount(int(est_fee * ci.COIN())),
 | 
					                'est_fee': 'Unknown' if est_fee is None else ci.format_amount(int(est_fee * ci.COIN())),
 | 
				
			||||||
                'balance': w['balance'],
 | 
					                'balance': w['balance'],
 | 
				
			||||||
                'blocks': w['blocks'],
 | 
					                'blocks': w['blocks'],
 | 
				
			||||||
                'synced': w['synced'],
 | 
					                'synced': w['synced'],
 | 
				
			||||||
 | 
				
			|||||||
@ -123,6 +123,7 @@ class BTCInterface(CoinInterface):
 | 
				
			|||||||
        self.txoType = CTxOut
 | 
					        self.txoType = CTxOut
 | 
				
			||||||
        self._network = network
 | 
					        self._network = network
 | 
				
			||||||
        self.blocks_confirmed = coin_settings['blocks_confirmed']
 | 
					        self.blocks_confirmed = coin_settings['blocks_confirmed']
 | 
				
			||||||
 | 
					        self._conf_target = coin_settings['conf_target']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def testDaemonRPC(self):
 | 
					    def testDaemonRPC(self):
 | 
				
			||||||
        self.rpc_callback('getwalletinfo', [])
 | 
					        self.rpc_callback('getwalletinfo', [])
 | 
				
			||||||
@ -881,6 +882,10 @@ class BTCInterface(CoinInterface):
 | 
				
			|||||||
                'vout': utxo['vout']})
 | 
					                'vout': utxo['vout']})
 | 
				
			||||||
        return rv
 | 
					        return rv
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def withdrawCoin(self, value, addr_to, subfee):
 | 
				
			||||||
 | 
					        params = [addr_to, value, '', '', subfee, True, self._conf_target]
 | 
				
			||||||
 | 
					        return self.rpc_callback('sendtoaddress', params)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def testBTCInterface():
 | 
					def testBTCInterface():
 | 
				
			||||||
    print('testBTCInterface')
 | 
					    print('testBTCInterface')
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,7 @@ class PARTInterface(BTCInterface):
 | 
				
			|||||||
        self.txoType = CTxOutPart
 | 
					        self.txoType = CTxOutPart
 | 
				
			||||||
        self._network = network
 | 
					        self._network = network
 | 
				
			||||||
        self.blocks_confirmed = coin_settings['blocks_confirmed']
 | 
					        self.blocks_confirmed = coin_settings['blocks_confirmed']
 | 
				
			||||||
 | 
					        self._conf_target = coin_settings['conf_target']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def knownWalletSeed(self):
 | 
					    def knownWalletSeed(self):
 | 
				
			||||||
        # TODO: Double check
 | 
					        # TODO: Double check
 | 
				
			||||||
@ -47,3 +48,7 @@ class PARTInterface(BTCInterface):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def initialiseWallet(self, key):
 | 
					    def initialiseWallet(self, key):
 | 
				
			||||||
        raise ValueError('TODO')
 | 
					        raise ValueError('TODO')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def withdrawCoin(self, value, addr_to, subfee):
 | 
				
			||||||
 | 
					        params = [addr_to, value, '', '', subfee, '', True, self._conf_target]
 | 
				
			||||||
 | 
					        return self.rpc_callback('sendtoaddress', params)
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@ from coincurve.dleag import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from .util import (
 | 
					from .util import (
 | 
				
			||||||
    dumpj,
 | 
					    dumpj,
 | 
				
			||||||
 | 
					    make_int,
 | 
				
			||||||
    format_amount)
 | 
					    format_amount)
 | 
				
			||||||
from .rpc_xmr import (
 | 
					from .rpc_xmr import (
 | 
				
			||||||
    make_xmr_rpc_func,
 | 
					    make_xmr_rpc_func,
 | 
				
			||||||
@ -55,14 +56,14 @@ class XMRInterface(CoinInterface):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def __init__(self, coin_settings, network):
 | 
					    def __init__(self, coin_settings, network):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], host=coin_settings['rpchost'])
 | 
					        rpc_cb = make_xmr_rpc_func(coin_settings['rpcport'], host=coin_settings.get('rpchost', 'localhost'))
 | 
				
			||||||
        rpc_wallet_cb = make_xmr_wallet_rpc_func(coin_settings['walletrpcport'], coin_settings['walletrpcauth'])
 | 
					        rpc_wallet_cb = make_xmr_wallet_rpc_func(coin_settings['walletrpcport'], coin_settings['walletrpcauth'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.rpc_cb = rpc_cb
 | 
					        self.rpc_cb = rpc_cb
 | 
				
			||||||
        self.rpc_wallet_cb = rpc_wallet_cb
 | 
					        self.rpc_wallet_cb = rpc_wallet_cb
 | 
				
			||||||
        self._network = network
 | 
					        self._network = network
 | 
				
			||||||
        self.blocks_confirmed = coin_settings['blocks_confirmed']
 | 
					        self.blocks_confirmed = coin_settings['blocks_confirmed']
 | 
				
			||||||
        self._restore_height = coin_settings['restore_height']
 | 
					        self._restore_height = coin_settings.get('restore_height', 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setWalletFilename(self, wallet_filename):
 | 
					    def setWalletFilename(self, wallet_filename):
 | 
				
			||||||
        self._wallet_filename = wallet_filename
 | 
					        self._wallet_filename = wallet_filename
 | 
				
			||||||
@ -368,14 +369,26 @@ class XMRInterface(CoinInterface):
 | 
				
			|||||||
                break
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            time.sleep(1 + i)
 | 
					            time.sleep(1 + i)
 | 
				
			||||||
 | 
					        if rv['balance'] < cb_swap_value:
 | 
				
			||||||
 | 
					            logging.error('wallet {} balance {}, expected {}'.format(wallet_filename, rv['balance'], cb_swap_value))
 | 
				
			||||||
 | 
					            raise ValueError('Invalid balance')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {'address': address_to}
 | 
				
			||||||
 | 
					        rv = self.rpc_wallet_cb('sweep_all', params)
 | 
				
			||||||
 | 
					        print('sweep_all', rv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return bytes.fromhex(rv['tx_hash_list'][0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
        # TODO: need a subfee from output option
 | 
					        # TODO: need a subfee from output option
 | 
				
			||||||
        b_fee = b_fee_rate * 10  # Guess
 | 
					        # b_fee = b_fee_rate * 10  # Guess
 | 
				
			||||||
 | 
					        b_fee = b_fee_rate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        num_tries = 20
 | 
					        num_tries = 20
 | 
				
			||||||
        for i in range(1 + num_tries):
 | 
					        for i in range(1 + num_tries):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                params = {'destinations': [{'amount': cb_swap_value - b_fee, 'address': address_to}]}
 | 
					                params = {'destinations': [{'amount': cb_swap_value - b_fee, 'address': address_to}]}
 | 
				
			||||||
 | 
					                logging.debug('params', dumpj(params))
 | 
				
			||||||
                rv = self.rpc_wallet_cb('transfer', params)
 | 
					                rv = self.rpc_wallet_cb('transfer', params)
 | 
				
			||||||
                print('transfer', rv)
 | 
					                print('transfer', rv)
 | 
				
			||||||
                break
 | 
					                break
 | 
				
			||||||
@ -387,3 +400,12 @@ class XMRInterface(CoinInterface):
 | 
				
			|||||||
            logging.info('Raising fee to %d', b_fee)
 | 
					            logging.info('Raising fee to %d', b_fee)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return bytes.fromhex(rv['tx_hash'])
 | 
					        return bytes.fromhex(rv['tx_hash'])
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def withdrawCoin(self, value, addr_to, subfee):
 | 
				
			||||||
 | 
					        self.rpc_wallet_cb('open_wallet', {'filename': self._wallet_filename})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        value_sats = make_int(value, self.exp())
 | 
				
			||||||
 | 
					        params = {'destinations': [{'amount': value_sats, 'address': addr_to}]}
 | 
				
			||||||
 | 
					        rv = self.rpc_wallet_cb('transfer', params)
 | 
				
			||||||
 | 
					        return rv['tx_hash']
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,10 @@ OP_16 = 0x60
 | 
				
			|||||||
COIN = 100000000
 | 
					COIN = 100000000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					decimal_ctx = decimal.Context()
 | 
				
			||||||
 | 
					decimal_ctx.prec = 20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def assert_cond(v, err='Bad opcode'):
 | 
					def assert_cond(v, err='Bad opcode'):
 | 
				
			||||||
    if not v:
 | 
					    if not v:
 | 
				
			||||||
        raise ValueError(err)
 | 
					        raise ValueError(err)
 | 
				
			||||||
@ -224,9 +228,15 @@ def getCompactSizeLen(v):
 | 
				
			|||||||
    raise ValueError('Value too large')
 | 
					    raise ValueError('Value too large')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def float_to_str(f):
 | 
				
			||||||
 | 
					    # stackoverflow.com/questions/38847690
 | 
				
			||||||
 | 
					    d1 = decimal_ctx.create_decimal(repr(f))
 | 
				
			||||||
 | 
					    return format(d1, 'f')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def make_int(v, scale=8, r=0):  # r = 0, no rounding, fail, r > 0 round up, r < 0 floor
 | 
					def make_int(v, scale=8, r=0):  # r = 0, no rounding, fail, r > 0 round up, r < 0 floor
 | 
				
			||||||
    if type(v) == float:
 | 
					    if type(v) == float:
 | 
				
			||||||
        v = str(v)
 | 
					        v = float_to_str(v)
 | 
				
			||||||
    elif type(v) == int:
 | 
					    elif type(v) == int:
 | 
				
			||||||
        return v * 10 ** scale
 | 
					        return v * 10 ** scale
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -239,7 +249,8 @@ def make_int(v, scale=8, r=0):  # r = 0, no rounding, fail, r > 0 round up, r <
 | 
				
			|||||||
            have_dp = True
 | 
					            have_dp = True
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
        if not c.isdigit():
 | 
					        if not c.isdigit():
 | 
				
			||||||
            raise ValueError('Invalid char')
 | 
					
 | 
				
			||||||
 | 
					            raise ValueError('Invalid char: ' + c)
 | 
				
			||||||
        if have_dp:
 | 
					        if have_dp:
 | 
				
			||||||
            ep //= 10
 | 
					            ep //= 10
 | 
				
			||||||
            if ep <= 0:
 | 
					            if ep <= 0:
 | 
				
			||||||
@ -260,7 +271,7 @@ def make_int(v, scale=8, r=0):  # r = 0, no rounding, fail, r > 0 round up, r <
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def validate_amount(amount, scale=8):
 | 
					def validate_amount(amount, scale=8):
 | 
				
			||||||
    str_amount = str(amount)
 | 
					    str_amount = float_to_str(amount) if type(amount) == float else str(amount)
 | 
				
			||||||
    has_decimal = False
 | 
					    has_decimal = False
 | 
				
			||||||
    for c in str_amount:
 | 
					    for c in str_amount:
 | 
				
			||||||
        if c == '.' and not has_decimal:
 | 
					        if c == '.' and not has_decimal:
 | 
				
			||||||
 | 
				
			|||||||
@ -358,7 +358,6 @@ def printHelp():
 | 
				
			|||||||
    logger.info('--htmlhost=              Interface to host on, default:localhost.')
 | 
					    logger.info('--htmlhost=              Interface to host on, default:localhost.')
 | 
				
			||||||
    logger.info('--xmrrestoreheight=n     Block height to restore Monero wallet from, default:{}.'.format(DEFAULT_XMR_RESTORE_HEIGHT))
 | 
					    logger.info('--xmrrestoreheight=n     Block height to restore Monero wallet from, default:{}.'.format(DEFAULT_XMR_RESTORE_HEIGHT))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys()))
 | 
					    logger.info('\n' + 'Known coins: %s', ', '.join(known_coins.keys()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										0
									
								
								bin/basicswap_run.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								bin/basicswap_run.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@ -1,7 +1,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
## Prerequisites
 | 
					## Source code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $ sudo apt-get install git python3-pip protobuf-compiler
 | 
					 | 
				
			||||||
    $ git clone https://github.com/tecnovert/basicswap.git
 | 
					    $ git clone https://github.com/tecnovert/basicswap.git
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -10,46 +9,71 @@
 | 
				
			|||||||
Docker must be installed and started:
 | 
					Docker must be installed and started:
 | 
				
			||||||
    $ sudo systemctl status docker | grep Active
 | 
					    $ sudo systemctl status docker | grep Active
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Should return a line containing:
 | 
					Should return a line containing `active (running)`
 | 
				
			||||||
`active (running)`
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Create the images:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $ cd basicswap/docker
 | 
					    $ cd basicswap/docker
 | 
				
			||||||
    $ docker-compose build
 | 
					    $ docker-compose build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prepare the datadir:
 | 
				
			||||||
 | 
					Set XMR_RPC_HOST and BASE_XMR_RPC_PORT to a public XMR node or exclude to run a local node.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ export SWAP_DATADIR=/var/data/coinswaps
 | 
				
			||||||
 | 
					    $ docker run -e XMR_RPC_HOST="node.xmr.to" -e BASE_XMR_RPC_PORT=18081 -t --name swap_prepare -v $SWAP_DATADIR:/coindata i_swapclient \
 | 
				
			||||||
 | 
					    basicswap-prepare --datadir=/coindata --withcoins=monero --withoutcoins=litecoin --htmlhost="0.0.0.0" --xmrrestoreheight=2245107
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Record the mnemonic from the output of the above command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Remove swap_prepare container (and logs):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ docker rm swap_prepare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start the container
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ export SWAP_DATADIR=/var/data/coinswaps
 | 
				
			||||||
    $ docker-compose up
 | 
					    $ docker-compose up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You may need to run docker-compose with sudo, unless you've setup docker
 | 
					Open in browser: `http://localhost:12700`
 | 
				
			||||||
to be able to run from user accounts.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
By default the data dir will be basicswap/docker/coindata
 | 
					## Run Without Docker:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
To run with a different data directory run:
 | 
					    $ apt-get install -y wget python3-pip gnupg unzip protobuf-compiler automake libtool pkg-config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $ export COINDATA_PATH=/tmp/part_swap_test/coindata
 | 
					    $ export SWAP_DATADIR=/var/data/coinswaps
 | 
				
			||||||
 | 
					    $ mkdirs -p "$SWAP_DATADIR/venv"
 | 
				
			||||||
And copy the initial config there:
 | 
					    $ python3 -m venv "$SWAP_DATADIR/venv"
 | 
				
			||||||
 | 
					    $ . $SWAP_DATADIR/venv/bin/activate && python -V
 | 
				
			||||||
    $ cp -r docker/coindata /tmp/part_swap_test/coindata
 | 
					    $ wget -O coincurve-anonswap.zip https://github.com/tecnovert/coincurve/archive/anonswap.zip
 | 
				
			||||||
 | 
					    $ unzip coincurve-anonswap.zip
 | 
				
			||||||
Before running docker-compose build
 | 
					    $ cd coincurve-anonswap
 | 
				
			||||||
 | 
					    $ python3 setup.py install --force
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Install as Python Module with PIP
 | 
					    $ cd $SWAP_DATADIR
 | 
				
			||||||
 | 
					    $ git clone https://github.com/tecnovert/basicswap.git
 | 
				
			||||||
    $ cd basicswap
 | 
					    $ cd basicswap
 | 
				
			||||||
    $ protoc -I=basicswap --python_out=basicswap basicswap/messages.proto
 | 
					    $ protoc -I=basicswap --python_out=basicswap basicswap/messages.proto
 | 
				
			||||||
    $ pip3 install .
 | 
					    $ pip3 install .
 | 
				
			||||||
    $ basicswap-prepare
 | 
					
 | 
				
			||||||
    $ basicswap-run
 | 
					Prepare the datadir:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    XMR_RPC_HOST="node.xmr.to" BASE_XMR_RPC_PORT=18081 basicswap-prepare --datadir=$SWAP_DATADIR --withcoins=monero --withoutcoins=litecoin --xmrrestoreheight=2245107
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Record the mnemonic from the output of the above command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start the app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $ basicswap-run --datadir=$SWAP_DATADIR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Open in browser: `http://localhost:12700`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
By default the data dir will be `~/.basicswap`
 | 
					Old notes
 | 
				
			||||||
To run in a different directory and on testnet:
 | 
					=============
 | 
				
			||||||
```
 | 
					 | 
				
			||||||
    $ basicswap-prepare -datadir=~/part_swap_test -testnet
 | 
					 | 
				
			||||||
    $ basicswap-run -datadir=~/part_swap_test -testnet
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Run Without Installing
 | 
					## Run Without Installing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										7
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					wheel
 | 
				
			||||||
 | 
					pyzmq
 | 
				
			||||||
 | 
					protobuf
 | 
				
			||||||
 | 
					sqlalchemy
 | 
				
			||||||
 | 
					python-gnupg
 | 
				
			||||||
 | 
					Jinja2
 | 
				
			||||||
 | 
					requests
 | 
				
			||||||
@ -4,7 +4,6 @@ import tests.basicswap.test_other as test_other
 | 
				
			|||||||
import tests.basicswap.test_prepare as test_prepare
 | 
					import tests.basicswap.test_prepare as test_prepare
 | 
				
			||||||
import tests.basicswap.test_run as test_run
 | 
					import tests.basicswap.test_run as test_run
 | 
				
			||||||
import tests.basicswap.test_reload as test_reload
 | 
					import tests.basicswap.test_reload as test_reload
 | 
				
			||||||
import tests.basicswap.test_xmr as test_xmr
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_suite():
 | 
					def test_suite():
 | 
				
			||||||
@ -13,6 +12,6 @@ def test_suite():
 | 
				
			|||||||
    suite.addTests(loader.loadTestsFromModule(test_prepare))
 | 
					    suite.addTests(loader.loadTestsFromModule(test_prepare))
 | 
				
			||||||
    suite.addTests(loader.loadTestsFromModule(test_run))
 | 
					    suite.addTests(loader.loadTestsFromModule(test_run))
 | 
				
			||||||
    suite.addTests(loader.loadTestsFromModule(test_reload))
 | 
					    suite.addTests(loader.loadTestsFromModule(test_reload))
 | 
				
			||||||
    suite.addTests(loader.loadTestsFromModule(test_xmr))
 | 
					    # TODO: Add to ci scripts suite.addTests(loader.loadTestsFromModule(test_xmr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return suite
 | 
					    return suite
 | 
				
			||||||
 | 
				
			|||||||
@ -161,7 +161,7 @@ class Test(unittest.TestCase):
 | 
				
			|||||||
        assert(pubkey == pubkey_test)
 | 
					        assert(pubkey == pubkey_test)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_ecdsa_otves(self):
 | 
					    def test_ecdsa_otves(self):
 | 
				
			||||||
        coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1}
 | 
					        coin_settings = {'rpcport': 0, 'rpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
 | 
				
			||||||
        ci = BTCInterface(coin_settings, 'regtest')
 | 
					        ci = BTCInterface(coin_settings, 'regtest')
 | 
				
			||||||
        vk_sign = i2b(ci.getNewSecretKey())
 | 
					        vk_sign = i2b(ci.getNewSecretKey())
 | 
				
			||||||
        vk_encrypt = i2b(ci.getNewSecretKey())
 | 
					        vk_encrypt = i2b(ci.getNewSecretKey())
 | 
				
			||||||
@ -183,7 +183,7 @@ class Test(unittest.TestCase):
 | 
				
			|||||||
        assert(vk_encrypt == recovered_key)
 | 
					        assert(vk_encrypt == recovered_key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_dleag(self):
 | 
					    def test_dleag(self):
 | 
				
			||||||
        coin_settings = {'rpcport': 0, 'walletrpcport': 0, 'walletrpcauth': 'none', 'blocks_confirmed': 1}
 | 
					        coin_settings = {'rpcport': 0, 'walletrpcport': 0, 'walletrpcauth': 'none', 'blocks_confirmed': 1, 'conf_target': 1}
 | 
				
			||||||
        ci = XMRInterface(coin_settings, 'regtest')
 | 
					        ci = XMRInterface(coin_settings, 'regtest')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        key = i2b(ci.getNewSecretKey())
 | 
					        key = i2b(ci.getNewSecretKey())
 | 
				
			||||||
 | 
				
			|||||||
@ -547,9 +547,9 @@ class Test(unittest.TestCase):
 | 
				
			|||||||
        logging.info('---------- Test PART to XMR')
 | 
					        logging.info('---------- Test PART to XMR')
 | 
				
			||||||
        swap_clients = self.swap_clients
 | 
					        swap_clients = self.swap_clients
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        js_0 = json.loads(urlopen('http://localhost:1801/json/wallets').read())
 | 
					        js_1 = json.loads(urlopen('http://localhost:1801/json/wallets').read())
 | 
				
			||||||
        assert(make_int(js_0[str(int(Coins.XMR))]['balance'], scale=12) > 0)
 | 
					        assert(make_int(js_1[str(int(Coins.XMR))]['balance'], scale=12) > 0)
 | 
				
			||||||
        assert(make_int(js_0[str(int(Coins.XMR))]['unconfirmed'], scale=12) > 0)
 | 
					        assert(make_int(js_1[str(int(Coins.XMR))]['unconfirmed'], scale=12) > 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        offer_id = swap_clients[0].postOffer(Coins.PART, Coins.XMR, 100 * COIN, 0.11 * XMR_COIN, 100 * COIN, SwapTypes.XMR_SWAP)
 | 
					        offer_id = swap_clients[0].postOffer(Coins.PART, Coins.XMR, 100 * COIN, 0.11 * XMR_COIN, 100 * COIN, SwapTypes.XMR_SWAP)
 | 
				
			||||||
        self.wait_for_offer(swap_clients[1], offer_id)
 | 
					        self.wait_for_offer(swap_clients[1], offer_id)
 | 
				
			||||||
@ -725,6 +725,14 @@ class Test(unittest.TestCase):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        self.wait_for_no_offer(swap_clients[1], offer_id)
 | 
					        self.wait_for_no_offer(swap_clients[1], offer_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_08_withdraw(self):
 | 
				
			||||||
 | 
					        logging.info('---------- Test xmr withdrawals')
 | 
				
			||||||
 | 
					        swap_clients = self.swap_clients
 | 
				
			||||||
 | 
					        js_0 = json.loads(urlopen('http://localhost:1800/json/wallets').read())
 | 
				
			||||||
 | 
					        address_to = js_0[str(int(Coins.XMR))]['deposit_address']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        swap_clients[1].withdrawCoin(Coins.XMR, 1.1, address_to, False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    unittest.main()
 | 
					    unittest.main()
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user