Fix CLTV mode.
This commit is contained in:
		
							parent
							
								
									307b8ab8bf
								
							
						
					
					
						commit
						aedfe796b8
					
				@ -632,7 +632,7 @@ class BasicSwap():
 | 
			
		||||
                self.callcoinrpc(coin_type, 'getwalletinfo', [], self.wallet)
 | 
			
		||||
                return
 | 
			
		||||
            except Exception as ex:
 | 
			
		||||
                logging.warning('Can\'t connect to %s RPC: %s.  Trying again in %d second/s.', coin_type, str(ex), (1 + i))
 | 
			
		||||
                self.log.warning('Can\'t connect to %s RPC: %s.  Trying again in %d second/s.', coin_type, str(ex), (1 + i))
 | 
			
		||||
                time.sleep(1 + i)
 | 
			
		||||
        self.log.error('Can\'t connect to %s RPC, exiting.', coin_type)
 | 
			
		||||
        self.stopRunning(1)  # systemd will try restart if fail_code != 0
 | 
			
		||||
@ -724,9 +724,11 @@ class BasicSwap():
 | 
			
		||||
            assert(self.coin_clients[coin_from]['use_csv'] and self.coin_clients[coin_to]['use_csv']), 'Both coins need CSV activated.'
 | 
			
		||||
        elif lock_type == ABS_LOCK_TIME:
 | 
			
		||||
            # TODO: range?
 | 
			
		||||
            assert(not self.coin_clients[coin_from]['use_csv'] or not self.coin_clients[coin_to]['use_csv']), 'Should use CSV.'
 | 
			
		||||
            assert(lock_value >= 4 * 60 * 60 and lock_value <= 96 * 60 * 60), 'Invalid lock_value time'
 | 
			
		||||
        elif lock_type == ABS_LOCK_BLOCKS:
 | 
			
		||||
            # TODO: range?
 | 
			
		||||
            assert(not self.coin_clients[coin_from]['use_csv'] or not self.coin_clients[coin_to]['use_csv']), 'Should use CSV.'
 | 
			
		||||
            assert(lock_value >= 10 and lock_value <= 1000), 'Invalid lock_value blocks'
 | 
			
		||||
        else:
 | 
			
		||||
            raise ValueError('Unknown locktype')
 | 
			
		||||
@ -1153,7 +1155,7 @@ class BasicSwap():
 | 
			
		||||
                lock_value = self.callcoinrpc(coin_from, 'getblockchaininfo')['blocks'] + offer.lock_value
 | 
			
		||||
            else:
 | 
			
		||||
                lock_value = int(time.time()) + offer.lock_value
 | 
			
		||||
            logging.debug('initiate %s lock_value %d %d', coin_from, offer.lock_value, lock_value)
 | 
			
		||||
            self.log.debug('initiate %s lock_value %d %d', coin_from, offer.lock_value, lock_value)
 | 
			
		||||
            script = buildContractScript(lock_value, secret_hash, bid.pkhash_buyer, pkhash_refund, OpCodes.OP_CHECKLOCKTIMEVERIFY)
 | 
			
		||||
 | 
			
		||||
        p2sh = self.callcoinrpc(Coins.PART, 'decodescript', [script.hex()])['p2sh']
 | 
			
		||||
@ -1302,11 +1304,35 @@ class BasicSwap():
 | 
			
		||||
            sequence = getExpectedSequence(offer.lock_type, lock_value, coin_to)
 | 
			
		||||
            bid.participate_script = buildContractScript(sequence, secret_hash, pkhash_seller, pkhash_buyer_refund)
 | 
			
		||||
        else:
 | 
			
		||||
            # Lock from the height or time of the block containing the initiate txn
 | 
			
		||||
            coin_from = Coins(offer.coin_from)
 | 
			
		||||
            initiate_tx_block_hash = self.callcoinrpc(coin_from, 'getblockhash', [bid.initiate_txn_height,])
 | 
			
		||||
            initiate_tx_block_time = int(self.callcoinrpc(coin_from, 'getblock', [initiate_tx_block_hash,])['time'])
 | 
			
		||||
            if offer.lock_type == ABS_LOCK_BLOCKS:
 | 
			
		||||
                contract_lock_value = self.callcoinrpc(coin_to, 'getblockchaininfo')['blocks'] + lock_value
 | 
			
		||||
                # Walk the coin_to chain back until block time matches
 | 
			
		||||
                blockchaininfo = self.callcoinrpc(coin_to, 'getblockchaininfo')
 | 
			
		||||
                cblock_hash = blockchaininfo['bestblockhash']
 | 
			
		||||
                cblock_height = blockchaininfo['blocks']
 | 
			
		||||
                max_tries = 1000
 | 
			
		||||
                for i in range(max_tries):
 | 
			
		||||
                    self.log.debug('wtf %d', i)
 | 
			
		||||
                    prev_block = self.callcoinrpc(coin_to, 'getblock', [cblock_hash,])
 | 
			
		||||
                    self.log.debug('prev_block %s', str(prev_block))
 | 
			
		||||
 | 
			
		||||
                    if prev_block['time'] <= initiate_tx_block_time:
 | 
			
		||||
                        break
 | 
			
		||||
                    # cblock_hash and height are out of step unless loop breaks
 | 
			
		||||
                    cblock_hash = prev_block['previousblockhash']
 | 
			
		||||
                    cblock_height = prev_block['height']
 | 
			
		||||
 | 
			
		||||
                assert(prev_block['time'] <= initiate_tx_block_time), 'Block not found for lock height'
 | 
			
		||||
 | 
			
		||||
                self.log.debug('Setting lock value from height of block %s %s', coin_to, cblock_hash)
 | 
			
		||||
                contract_lock_value = cblock_height + lock_value
 | 
			
		||||
            else:
 | 
			
		||||
                contract_lock_value = int(time.time()) + lock_value
 | 
			
		||||
            logging.debug('participate %s lock_value %d %d', coin_to, lock_value, contract_lock_value)
 | 
			
		||||
                self.log.debug('Setting lock value from time of block %s %s', coin_from, initiate_tx_block_hash)
 | 
			
		||||
                contract_lock_value = initiate_tx_block_time + lock_value
 | 
			
		||||
            self.log.debug('participate %s lock_value %d %d', coin_to, lock_value, contract_lock_value)
 | 
			
		||||
            bid.participate_script = buildContractScript(contract_lock_value, secret_hash, pkhash_seller, pkhash_buyer_refund, OpCodes.OP_CHECKLOCKTIMEVERIFY)
 | 
			
		||||
 | 
			
		||||
    def createParticipateTxn(self, bid_id, bid, offer):
 | 
			
		||||
@ -2156,11 +2182,16 @@ class BasicSwap():
 | 
			
		||||
        assert(len(scriptvalues[0]) == 64), 'Bad secret_hash length'
 | 
			
		||||
        assert(bytes.fromhex(scriptvalues[1]) == bid.pkhash_buyer), 'pkhash_buyer mismatch'
 | 
			
		||||
 | 
			
		||||
        script_lock_value = int(scriptvalues[2])
 | 
			
		||||
        if use_csv:
 | 
			
		||||
            expect_sequence = getExpectedSequence(offer.lock_type, offer.lock_value, coin_from)
 | 
			
		||||
            assert(int(scriptvalues[2]) == expect_sequence), 'sequence mismatch'
 | 
			
		||||
            assert(script_lock_value == expect_sequence), 'sequence mismatch'
 | 
			
		||||
        else:
 | 
			
		||||
            if offer.lock_type == ABS_LOCK_BLOCKS:
 | 
			
		||||
                self.log.warning('TODO: validate absolute lock values')
 | 
			
		||||
            else:
 | 
			
		||||
                assert(script_lock_value <= bid.created_at + offer.lock_value + INITIATE_TX_TIMEOUT), 'script lock time too high'
 | 
			
		||||
                assert(script_lock_value >= bid.created_at + offer.lock_value), 'script lock time too low'
 | 
			
		||||
 | 
			
		||||
        assert(len(scriptvalues[3]) == 40), 'pkhash_refund bad length'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -23,6 +23,7 @@ chainparams = {
 | 
			
		||||
        'name': 'particl',
 | 
			
		||||
        'ticker': 'PART',
 | 
			
		||||
        'message_magic': 'Bitcoin Signed Message:\n',
 | 
			
		||||
        'blocks_target': 60 * 2,
 | 
			
		||||
        'mainnet': {
 | 
			
		||||
            'rpcport': 51735,
 | 
			
		||||
            'pubkey_address': 0x38,
 | 
			
		||||
@ -58,6 +59,7 @@ chainparams = {
 | 
			
		||||
        'name': 'bitcoin',
 | 
			
		||||
        'ticker': 'BTC',
 | 
			
		||||
        'message_magic': 'Bitcoin Signed Message:\n',
 | 
			
		||||
        'blocks_target': 60 * 10,
 | 
			
		||||
        'mainnet': {
 | 
			
		||||
            'rpcport': 8332,
 | 
			
		||||
            'pubkey_address': 0,
 | 
			
		||||
@ -91,6 +93,7 @@ chainparams = {
 | 
			
		||||
        'name': 'litecoin',
 | 
			
		||||
        'ticker': 'LTC',
 | 
			
		||||
        'message_magic': 'Litecoin Signed Message:\n',
 | 
			
		||||
        'blocks_target': 60 * 1,
 | 
			
		||||
        'mainnet': {
 | 
			
		||||
            'rpcport': 9332,
 | 
			
		||||
            'pubkey_address': 48,
 | 
			
		||||
@ -124,6 +127,7 @@ chainparams = {
 | 
			
		||||
        'name': 'namecoin',
 | 
			
		||||
        'ticker': 'NMC',
 | 
			
		||||
        'message_magic': 'Namecoin Signed Message:\n',
 | 
			
		||||
        'blocks_target': 60 * 10,
 | 
			
		||||
        'mainnet': {
 | 
			
		||||
            'rpcport': 8336,
 | 
			
		||||
            'pubkey_address': 52,
 | 
			
		||||
 | 
			
		||||
@ -187,7 +187,13 @@ class HttpHandler(BaseHTTPRequestHandler):
 | 
			
		||||
                lock_seconds = int(form_data[b'lockhrs'][0]) * 60 * 60
 | 
			
		||||
                # TODO: More accurate rate
 | 
			
		||||
                # assert(value_to == (value_from * rate) // COIN)
 | 
			
		||||
                offer_id = swap_client.postOffer(coin_from, coin_to, value_from, rate, min_bid, SwapTypes.SELLER_FIRST, auto_accept_bids=autoaccept, lock_value=lock_seconds)
 | 
			
		||||
 | 
			
		||||
                if swap_client.coin_clients[coin_from]['use_csv'] and swap_client.coin_clients[coin_to]['use_csv']:
 | 
			
		||||
                    lock_type = SEQUENCE_LOCK_TIME
 | 
			
		||||
                else:
 | 
			
		||||
                    lock_type = ABS_LOCK_TIME
 | 
			
		||||
 | 
			
		||||
                offer_id = swap_client.postOffer(coin_from, coin_to, value_from, rate, min_bid, SwapTypes.SELLER_FIRST, auto_accept_bids=autoaccept, lock_type=lock_type, lock_value=lock_seconds)
 | 
			
		||||
                content += '<p><a href="/offer/' + offer_id.hex() + '">Sent Offer ' + offer_id.hex() + '</a><br/>Rate: ' + format8(rate) + '</p>'
 | 
			
		||||
 | 
			
		||||
        coins = []
 | 
			
		||||
 | 
			
		||||
@ -374,7 +374,7 @@ class Test(unittest.TestCase):
 | 
			
		||||
               and (participate_state is None or bid.participate_txn_state == participate_state):
 | 
			
		||||
                return
 | 
			
		||||
        raise ValueError('wait_for_bid_tx_state timed out.')
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    def test_02_part_ltc(self):
 | 
			
		||||
        swap_clients = self.swap_clients
 | 
			
		||||
 | 
			
		||||
@ -454,16 +454,14 @@ class Test(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
        assert(js_0['num_swapping'] == 0 and js_0['num_watched_outputs'] == 0)
 | 
			
		||||
        assert(js_1['num_swapping'] == 0 and js_1['num_watched_outputs'] == 0)
 | 
			
		||||
 | 
			
		||||
    """
 | 
			
		||||
    def test_05_refund(self):
 | 
			
		||||
        # Seller submits initiate txn, buyer doesn't respond
 | 
			
		||||
        swap_clients = self.swap_clients
 | 
			
		||||
 | 
			
		||||
        logging.info('---------- Test refund, NMC to BTC')
 | 
			
		||||
 | 
			
		||||
        # Note the lock value is absolute.
 | 
			
		||||
        offer_id = swap_clients[0].postOffer(Coins.NMC, Coins.BTC, 10 * COIN, 0.1 * COIN, 10 * COIN, SwapTypes.SELLER_FIRST,
 | 
			
		||||
                                             ABS_LOCK_BLOCKS, 20)
 | 
			
		||||
                                             ABS_LOCK_BLOCKS, 10)
 | 
			
		||||
 | 
			
		||||
        self.wait_for_offer(swap_clients[1], offer_id)
 | 
			
		||||
        offers = swap_clients[1].listOffers()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user