def test_coinjoin_input_account_path_mismatch(self): authorization = CoinJoinAuthorization(self.msg_auth, None, self.coin) tx = SignTx(outputs_count=201, inputs_count=100, coin_name=self.coin.coin_name, lock_time=0) approver = CoinJoinApprover(tx, self.coin, authorization) txi = TxInputType(address_n=[H_(49), H_(0), H_(0), 0, 2], amount=10000000, script_type=InputScriptType.SPENDWITNESS) with self.assertRaises(wire.ProcessError): await_result(approver.add_internal_input(txi, txi.amount))
def test_coinjoin_lots_of_inputs(self): denomination = 10000000 # Other's inputs. inputs = [ TxInputType( amount=denomination + 1000000 * (i + 1), script_type=InputScriptType.EXTERNAL, sequence=0xffffffff, ) for i in range(99) ] # Our input. inputs.insert( 30, TxInputType( address_n=[H_(84), H_(0), H_(0), 0, 1], amount=denomination + 1000000, script_type=InputScriptType.SPENDWITNESS, sequence=0xffffffff, )) # Other's CoinJoined outputs. outputs = [ TxOutputType( amount=denomination, script_type=OutputScriptType.PAYTOWITNESS, ) for i in range(99) ] # Our CoinJoined output. outputs.insert( 40, TxOutputType( address_n=[H_(84), H_(0), H_(0), 0, 2], amount=denomination, script_type=OutputScriptType.PAYTOWITNESS, )) coordinator_fee = self.fee_per_anonymity_percent / 100 * len( outputs) * denomination fees = coordinator_fee + 10000 total_coordinator_fee = coordinator_fee * len(outputs) # Other's change-outputs. outputs.extend( TxOutputType( amount=1000000 * (i + 1) - fees, script_type=OutputScriptType.PAYTOWITNESS, ) for i in range(99)) # Our change-output. outputs.append( TxOutputType( address_n=[H_(84), H_(0), H_(0), 1, 1], amount=1000000 - fees, script_type=OutputScriptType.PAYTOWITNESS, )) # Coordinator's output. outputs.append( TxOutputType( amount=total_coordinator_fee, script_type=OutputScriptType.PAYTOWITNESS, )) authorization = CoinJoinAuthorization(self.msg_auth, None, self.coin) tx = SignTx(outputs_count=len(outputs), inputs_count=len(inputs), coin_name=self.coin.coin_name, lock_time=0) approver = CoinJoinApprover(tx, self.coin, authorization) for txi in inputs: if txi.script_type == InputScriptType.EXTERNAL: approver.add_external_input(txi) else: await_result(approver.add_internal_input(txi, txi.amount)) for txo in outputs: if txo.address_n: approver.add_change_output(txo, script_pubkey=bytes(22)) else: await_result( approver.add_external_output(txo, script_pubkey=bytes(22))) await_result(approver.approve_tx())
def test_coinjoin_lots_of_inputs(self): denomination = 10000000 coordinator_fee = int(self.max_fee_rate_percent / 100 * denomination) fees = coordinator_fee + 500 # Other's inputs. inputs = [ TxInput( prev_hash=b"", prev_index=0, amount=denomination, script_pubkey=bytes(22), script_type=InputScriptType.EXTERNAL, sequence=0xffffffff, witness="", ) for i in range(99) ] # Our input. inputs.insert( 30, TxInput( prev_hash=b"", prev_index=0, address_n=[H_(84), H_(0), H_(0), 0, 1], amount=denomination, script_type=InputScriptType.SPENDWITNESS, sequence=0xffffffff, )) # Other's CoinJoined outputs. outputs = [ TxOutput( address="", amount=denomination - fees, script_type=OutputScriptType.PAYTOWITNESS, payment_req_index=0, ) for i in range(99) ] # Our CoinJoined output. outputs.insert( 40, TxOutput( address="", address_n=[H_(84), H_(0), H_(0), 0, 2], amount=denomination - fees, script_type=OutputScriptType.PAYTOWITNESS, payment_req_index=0, )) # Coordinator's output. outputs.append( TxOutput( address="", amount=coordinator_fee * len(outputs), script_type=OutputScriptType.PAYTOWITNESS, payment_req_index=0, )) authorization = CoinJoinAuthorization(self.msg_auth) tx = SignTx(outputs_count=len(outputs), inputs_count=len(inputs), coin_name=self.coin.coin_name, lock_time=0) approver = CoinJoinApprover(tx, self.coin, authorization) signer = Bitcoin(tx, None, self.coin, approver) # Compute payment request signature. # Private key of m/0h for "all all ... all" seed. private_key = b'?S\ti\x8b\xc5o{,\xab\x03\x194\xea\xa8[_:\xeb\xdf\xce\xef\xe50\xf17D\x98`\xb9dj' h_pr = HashWriter(sha256()) writers.write_bytes_fixed(h_pr, b"SL\x00\x24", 4) writers.write_bytes_prefixed(h_pr, b"") # Empty nonce. writers.write_bytes_prefixed(h_pr, self.coordinator_name.encode()) writers.write_compact_size(h_pr, 0) # No memos. writers.write_uint32(h_pr, self.coin.slip44) h_outputs = HashWriter(sha256()) for txo in outputs: writers.write_uint64(h_outputs, txo.amount) writers.write_bytes_prefixed(h_outputs, txo.address.encode()) writers.write_bytes_fixed(h_pr, h_outputs.get_digest(), 32) signature = secp256k1.sign(private_key, h_pr.get_digest()) tx_ack_payment_req = TxAckPaymentRequest( recipient_name=self.coordinator_name, signature=signature, ) for txi in inputs: if txi.script_type == InputScriptType.EXTERNAL: approver.add_external_input(txi) else: await_result(approver.add_internal_input(txi)) await_result(approver.add_payment_request(tx_ack_payment_req, None)) for txo in outputs: if txo.address_n: approver.add_change_output(txo, script_pubkey=bytes(22)) else: await_result( approver.add_external_output(txo, script_pubkey=bytes(22))) await_result(approver.approve_tx(TxInfo(signer, tx), []))