def sign_using_output(self, id, seq_no, op: Dict = None, request: Request = None): assert lxor(op, request) if op: request = Request(reqId=Request.gen_req_id(), operation=op, protocolVersion=CURRENT_PROTOCOL_VERSION) # existing_inputs = request.operation.get(INPUTS, []) # request.operation[INPUTS] = [[id, seq_no], ] # payload = deepcopy(request.signingState(id)) # # TEMPORARY # payload[OPERATION].pop(SIGS) # payload.pop(f.IDENTIFIER.nm) # # signature = self.addresses[id].signer.sign(payload) # request.operation[INPUTS] = existing_inputs + [[id, seq_no], ] # TODO: Account for `extra` field payload = [[ { "address": id, "seqNo": seq_no }, ], request.operation[OUTPUTS]] signature = self.addresses[id].signer.sign(payload) request.operation[INPUTS] = request.operation.get(INPUTS, []) + [ { "address": id, "seqNo": seq_no }, ] request.operation[SIGS].append(signature) return request
def hasProdable(self, prodable: Prodable=None, name: str=None): assert lxor(prodable, name), \ "One and only one of prodable or name must be provided" for p in self.prodables: if (prodable and p == prodable) or (name and name == p.name): return True return False
def hasProdable(self, prodable: Prodable = None, name: str = None): assert lxor(prodable, name), \ "One and only one of prodable or name must be provided" for p in self.prodables: if (prodable and p == prodable) or (name and name == p.name): return True return False
def sign_using_multi_sig(self, op: Dict=None, request: Request=None, identifier=None) -> Request: # One and only 1 of `op` and `request` must be provided. # If `request` is provided it must have `reqId` assert lxor(op, request) identifier = identifier or self.defaultId if op: request = Request(reqId=Request.gen_req_id(), operation=op, protocolVersion=CURRENT_PROTOCOL_VERSION) self.do_multi_sig_on_req(request, identifier) return request
def test_seller_xfer_double_spend_attempt(looper, sdk_pool_handle, # noqa nodeSetWithIntegratedTokenPlugin, public_minting, sdk_wallet_client, seller_address, seller_token_wallet, user1_address, user2_address): """ An address tries to send to send to transactions using the same UTXO, one of the txn gets rejected even though the amount held by the UTXO is greater than the sum of outputs in both txns, since one UTXO can be used only once """ # ============= # Declaration of helper functions. # ============= def succeeded(req_resp): try: sdk_check_reply(req_resp) return True except Exception: return False def check_output_val(address, amount): return check_output_val_on_all_nodes( nodeSetWithIntegratedTokenPlugin, address, amount ) def check_no_output_val(address, amount): with pytest.raises(AssertionError): check_output_val(address, amount) def get_seq_no_first_utxo(address): get_utxo_resp = send_get_utxo( looper, address, sdk_wallet_client, sdk_pool_handle ) return get_utxo_resp[OUTPUTS][0]["seqNo"] # ============= # Form the two xfer requests. Each request will try to spend the same UTXO. # ============= user1_gets = 3 user2_gets = 5 seq_no = get_seq_no_first_utxo(seller_address) inputs = [[seller_token_wallet, seller_address, seq_no]] outputs1 = [ {"address": user1_address, "amount": user1_gets}, {"address": seller_address, "amount": seller_gets - user1_gets} ] outputs2 = [ {"address": user2_address, "amount": user2_gets}, {"address": seller_address, "amount": seller_gets - user2_gets} ] r1 = xfer_request(inputs, outputs1) r2 = xfer_request(inputs, outputs2) requests = [json.dumps(r.as_dict) for r in [r1, r2]] # ============= # Send the two requests and wait for replies. Only one request # should succeed. # ============= req_resp = sdk_send_signed_requests(sdk_pool_handle, requests) req_resp = sdk_get_replies(looper, req_resp) success1 = succeeded(req_resp[0]) success2 = succeeded(req_resp[1]) assert lxor(success1, success2) # ============= # Check that the seller, user1, and user2, have the output or not. # ============= if success1: check_output_val(seller_address, seller_gets - user1_gets) check_output_val(user1_address, user1_gets) check_no_output_val(user2_address, 0) else: check_output_val(seller_address, seller_gets - user2_gets) check_output_val(user2_address, user2_gets) check_no_output_val(user1_address, 0)