Emurgo / cardano-serialization-lib

This is a library, written in Rust, for serialization & deserialization of data structures used in Cardano's Haskell implementation of Alonzo along with useful utility functions.
Other
236 stars 125 forks source link

UTXO Balance Insufficient error when using RandomImproveMultiAsset #467

Closed raamb closed 2 years ago

raamb commented 2 years ago

We have integrated with Cardano web wallet in our DApp built using ReactJS.

While attempting to transfer tokens we get the error "UTXO Balance Insufficient". We are passing in all the UTXOs of the user wallet to the transaction body. In our case, the user has around ~81 ADA and 100 tokens in the wallet, so the user has sufficient funds to make a transfer operation. But when we do a transfer we get the UTXO Balance Insufficient Error

Here is the code from our DApp

`
const txBuilder = await initTransactionBuilder(); const changeAddress = await getChangeAddress(); const shelleyOutputAddress = Address.from_bech32(transferWalletAddress); const shelleyChangeAddress = Address.from_bech32(changeAddress); let txOutputBuilder = TransactionOutputBuilder.new(); txOutputBuilder = await txOutputBuilder.with_address(shelleyOutputAddress); txOutputBuilder = await txOutputBuilder.next();

  const multiAsset = MultiAsset.new();
  const assets = Assets.new();
  assets.insert(
    AssetName.new(Buffer.from(assetNameHex, 'hex')), // Asset Name
    BigNum.from_str(assetQuantity) // How much to send
  );
  multiAsset.insert(
    ScriptHash.from_bytes(Buffer.from(assetPolicyIdHex, 'hex')), // PolicyID
    assets
  );

  txOutputBuilder = txOutputBuilder.with_asset_and_min_required_coin(multiAsset, BigNum.from_str(protocolParams.coinsPerUtxoWord));
  const txOutput = txOutputBuilder.build();

  await txBuilder.add_output(txOutput);

  // Find the available UTXOs in the wallet and
  // use them as Inputs
  const txUnspentOutputs = await getTxUnspentOutputs();
  txBuilder.add_inputs_from(txUnspentOutputs, 3);

  // calculate the min fee required and send any change to an address
  txBuilder.add_change_if_needed(shelleyChangeAddress);

  // once the transaction is ready, we build it to get the tx body without witnesses
  const txBody = await txBuilder.build();

` In the add_inputs_from method we are using the strategy RandomImproveMultiAsset Our expectation is that this will pick the best UTXO (combination of UTXOs) to service the request, however we occassionally get the error UTxO Balance Insufficient What could be going wrong?

AdamMachera commented 2 years ago

We are using version CSL 11.0.1. I'm having same issue while locking two NFTs + additional asset in smart contract (it is working for marketplace if we lock only one token).

The code that we are using:

    const amount = parseInt(breedingParams.serviceFee) + parseInt(nftMoveFixedPrice) + parseInt(mintingFee)

    //fixed ends in 5 min
    const breedingDatum = createBreedingDatum(pkh, breedingParams);
    const breedingDatumHash = hash_plutus_data(toPlutusData(breedingDatum));

    let txOutputBuilder = TransactionOutputBuilder.new();
    txOutputBuilder = txOutputBuilder
        .with_address(scriptAddress)
        .with_data_hash(breedingDatumHash);
    const txOutputAmountBuilder = txOutputBuilder.next();
    const lovelaceWithAsset = getBreedingContractOutput(amount.toString(), breedingParams)
    const txOutputAmountBuilderWithCoins = txOutputAmountBuilder.with_value(lovelaceWithAsset)

    const aux_data: AuxiliaryData = await addBreedingMetadata(txBuilder, selfAddress, breedingParams, "start")

    const txOutput = txOutputAmountBuilderWithCoins.build();
    const txOutVal = txOutput.to_json()
    console.log(txOutVal)
    txBuilder.add_output(txOutput)

    console.log('after add_output')
    // Find the available UTXOs in the wallet and
    const txUnspentOutputs  = TransactionUnspentOutputs.new();
    const walletOutputs  = await cardano.getUtxos();
    walletOutputs.forEach(utxo => txUnspentOutputs.add(utxo))
    walletOutputs.forEach(utxo => {
        console.log(utxo.input().to_json())
        console.log(utxo.output().to_json())
    });
    console.log('before add_inputs_from')
    txBuilder.add_inputs_from(txUnspentOutputs, 3)
    console.log('after add_inputs_from')

    txBuilder.add_change_if_needed(selfAddress)

it never gets into console.log('after add_inputs_from') I'm getting "UTxO Balance Insufficient"

This is the output that we want to lock in the SC - two NFTs 1000 coins of custom asset and 20ADA:

{
  "address": "addr_test1wpv93hm9sqx0ar7pgxwl9jn3xt6lwmxxy27zd932slzvghqg8fe0n",
  "amount": {
    "coin": "20000000",
    "multiasset": {
      "07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28": {
        "44696e6f436f696e": "1000"
      },
      "ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3": {
        "43727970746f44696e6f2d312d3030303030": "1",
        "43727970746f44696e6f2d312d3030303032": "1"
      }
    }
  },
  "plutus_data": {
    "DataHash": "979f68de9e070e75779f80ce5e6cc74f8d77661d65f2895c01d0a6f66eceb791"
  },
  "script_ref": null
}

Here are the inputs that are available in my wallet:

{
  "transaction_id": "96631bf40bc2ae1e10b3c9157a4c711562c664b9744ed1f580b725e0589efcd0",
  "index": 1
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "661308571",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "89da149fa162eca7212493f2bcc8415ed070832e053ac0ec335d3501f901ad77",
  "index": 1
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "555975153",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "0124993c20ea0fe626d96a644773225202fb442238c38206242d26a1131e0a6e",
  "index": 1
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "1899495",
    "multiasset": {
      "07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28": {
        "44696e6f436f696e": "750"
      }
    }
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "c15c423d624b3af3f032c079a1b390c472b8ba889b48dd581d0ea28f96a36875",
  "index": 0
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "1804315",
    "multiasset": {
      "07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28": {
        "44696e6f436f696e": "2000"
      }
    }
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "5894bf9c9125859d29770bf43e4018f4f34a69edee49a7c9488c6707ab523c9b",
  "index": 1
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "440573428",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "168404afd4e9927d7775c8f40c0f749fc7634832d6931c5d51a507724cf44420",
  "index": 0
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "1804315",
    "multiasset": {
      "07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28": {
        "44696e6f436f696e": "1000"
      }
    }
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "3e6138498b721ee609a4c289768b2accad39cd4f00448540a95ba3362578a2f7",
  "index": 4
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "1508500",
    "multiasset": {
      "07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28": {
        "44696e6f436f696e": "750"
      }
    }
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "3e6138498b721ee609a4c289768b2accad39cd4f00448540a95ba3362578a2f7",
  "index": 5
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "664935092",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "046cf1bc21c23c59975714b520dd7ed22b63dab592cb0449e0ee6cc96eefde69",
  "index": 2
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "7094915",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "e16f195105db5f84621af4f7ea57c7156b8699cba94d4fdb72a6fb09e31db7a8",
  "index": 1
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "78400000",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "e16f195105db5f84621af4f7ea57c7156b8699cba94d4fdb72a6fb09e31db7a8",
  "index": 2
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "2000000",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "006697ef0c9285b7001ebe5a9e356fb50441e0af803773a99b7cbb0e9b728570",
  "index": 1
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "15054830",
    "multiasset": {
      "07e8df329b724e4be48ee32738125c06000de5448aaf93ed46d59e28": {
        "44696e6f436f696e": "56250"
      },
      "3320679b145d683b9123f0626360699fcd7408b4d3ec3bd9cc79398c": {
        "44696e6f436f696e": "287000"
      },
      "57fca08abbaddee36da742a839f7d83a7e1d2419f1507fcbf3916522": {
        "4d494e54": "91051638",
        "534245525259": "27198732"
      },
      "e61bfc106338ed4aeba93036324fbea8150fd9750fcffca1cd9f1a19": {
        "44696e6f536176696f723030303639": "1",
        "44696e6f536176696f723030303936": "1",
        "44696e6f536176696f723030313737": "1",
        "44696e6f536176696f723030333033": "1",
        "44696e6f536176696f723030333531": "1",
        "44696e6f536176696f723030333931": "1",
        "44696e6f536176696f723030343336": "1",
        "44696e6f536176696f723030343434": "1",
        "44696e6f536176696f723030353232": "1",
        "44696e6f536176696f723030353337": "1",
        "44696e6f536176696f723030363334": "1",
        "44696e6f536176696f723030373332": "1",
        "44696e6f536176696f723030373430": "1",
        "44696e6f536176696f723030373435": "1",
        "44696e6f536176696f723031303139": "1",
        "44696e6f536176696f723031303631": "1",
        "44696e6f536176696f723031333432": "1",
        "44696e6f536176696f723031333832": "1",
        "44696e6f536176696f723031353333": "1",
        "44696e6f536176696f723031353732": "1",
        "44696e6f536176696f723031363337": "1",
        "44696e6f536176696f723031363430": "1",
        "44696e6f536176696f723031373631": "1",
        "44696e6f536176696f723031393436": "1",
        "44696e6f536176696f723032313237": "1",
        "44696e6f536176696f723032323232": "1",
        "44696e6f536176696f723032333230": "1",
        "44696e6f536176696f723032333239": "1",
        "44696e6f536176696f723032333534": "1",
        "44696e6f536176696f723032333631": "1",
        "44696e6f536176696f723032333935": "1",
        "44696e6f536176696f723032333938": "1",
        "44696e6f536176696f723032343037": "1",
        "44696e6f536176696f723032343434": "1",
        "44696e6f536176696f723032353039": "1",
        "44696e6f536176696f723032363334": "1",
        "44696e6f536176696f723032363430": "1",
        "44696e6f536176696f723032373537": "1",
        "44696e6f536176696f723032373832": "1",
        "44696e6f536176696f723032383933": "1",
        "44696e6f536176696f723033323430": "1",
        "44696e6f536176696f723033343937": "1",
        "44696e6f536176696f723033353437": "1",
        "44696e6f536176696f723033353738": "1",
        "44696e6f536176696f723033363638": "1",
        "44696e6f536176696f723033363836": "1",
        "44696e6f536176696f723033363930": "1",
        "44696e6f536176696f723033383638": "1",
        "44696e6f536176696f723033383731": "1",
        "44696e6f536176696f723033383931": "1",
        "44696e6f536176696f723034313936": "1",
        "44696e6f536176696f723034323538": "1",
        "44696e6f536176696f723034323733": "1",
        "44696e6f536176696f723034363235": "1",
        "44696e6f536176696f723034373132": "1",
        "44696e6f536176696f723034373932": "1",
        "44696e6f536176696f723034383831": "1",
        "44696e6f536176696f723034393936": "1",
        "44696e6f536176696f723035303432": "1",
        "44696e6f536176696f723035313539": "1",
        "44696e6f536176696f723035333138": "1",
        "44696e6f536176696f723035333532": "1",
        "44696e6f536176696f723035343433": "1",
        "44696e6f536176696f723035343639": "1",
        "44696e6f536176696f723035373434": "1",
        "44696e6f536176696f723035373638": "1",
        "44696e6f536176696f723035373830": "1",
        "44696e6f536176696f723035383435": "1",
        "44696e6f536176696f723035383538": "1",
        "44696e6f536176696f723035393632": "1",
        "44696e6f536176696f723036303032": "1",
        "44696e6f536176696f723036303337": "1",
        "44696e6f536176696f723036303738": "1",
        "44696e6f536176696f723036323033": "1",
        "44696e6f536176696f723036323036": "1",
        "44696e6f536176696f723036323236": "1",
        "44696e6f536176696f723036333130": "1",
        "44696e6f536176696f723036333935": "1",
        "44696e6f536176696f723036343932": "1",
        "44696e6f536176696f723036353532": "1",
        "44696e6f536176696f723036363735": "1",
        "44696e6f536176696f723036363839": "1",
        "44696e6f536176696f723036373233": "1",
        "44696e6f536176696f723036383731": "1",
        "44696e6f536176696f723036383830": "1",
        "44696e6f536176696f723036393137": "1",
        "44696e6f536176696f723037303339": "1",
        "44696e6f536176696f723037323638": "1",
        "44696e6f536176696f723037333434": "1",
        "44696e6f536176696f723037343232": "1",
        "44696e6f536176696f723037343731": "1",
        "44696e6f536176696f723037353431": "1",
        "44696e6f536176696f723037363032": "1",
        "44696e6f536176696f723037363136": "1",
        "44696e6f536176696f723037363430": "1",
        "44696e6f536176696f723037373635": "1",
        "44696e6f536176696f723037373732": "1",
        "44696e6f536176696f723037393039": "1",
        "44696e6f536176696f723037393234": "1",
        "44696e6f536176696f723037393430": "1",
        "44696e6f536176696f723037393632": "1",
        "44696e6f536176696f723038303130": "1",
        "44696e6f536176696f723038303338": "1",
        "44696e6f536176696f723038303339": "1",
        "44696e6f536176696f723038303636": "1",
        "44696e6f536176696f723038313735": "1",
        "44696e6f536176696f723038323032": "1",
        "44696e6f536176696f723038323131": "1",
        "44696e6f536176696f723038323536": "1",
        "44696e6f536176696f723038333532": "1",
        "44696e6f536176696f723038333536": "1",
        "44696e6f536176696f723038333538": "1",
        "44696e6f536176696f723038333539": "1",
        "44696e6f536176696f723038333830": "1",
        "44696e6f536176696f723038343932": "1",
        "44696e6f536176696f723038353231": "1",
        "44696e6f536176696f723038353736": "1",
        "44696e6f536176696f723038353836": "1",
        "44696e6f536176696f723038363130": "1",
        "44696e6f536176696f723039303231": "1",
        "44696e6f536176696f723039303735": "1",
        "44696e6f536176696f723039313039": "1",
        "44696e6f536176696f723039313231": "1",
        "44696e6f536176696f723039323238": "1",
        "44696e6f536176696f723039333138": "1",
        "44696e6f536176696f723039333731": "1",
        "44696e6f536176696f723039343035": "1",
        "44696e6f536176696f723039343136": "1",
        "44696e6f536176696f723039353039": "1",
        "44696e6f536176696f723039353635": "1",
        "44696e6f536176696f723039363331": "1",
        "44696e6f536176696f723039363932": "1",
        "44696e6f536176696f723039383839": "1",
        "44696e6f536176696f723039393038": "1",
        "44696e6f536176696f723039393935": "1"
      },
      "ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3": {
        "43727970746f44696e6f3030303135": "1",
        "43727970746f44696e6f3030313335": "1",
        "43727970746f44696e6f3030323634": "1",
        "43727970746f44696e6f3030333932": "1",
        "43727970746f44696e6f3030353834": "1",
        "43727970746f44696e6f3030373136": "1",
        "43727970746f44696e6f3030373837": "1",
        "43727970746f44696e6f3030383438": "1",
        "43727970746f44696e6f3031303537": "1",
        "43727970746f44696e6f3031313134": "1",
        "43727970746f44696e6f3031323237": "1",
        "43727970746f44696e6f3031323330": "1",
        "43727970746f44696e6f3031343031": "1",
        "43727970746f44696e6f3031353138": "1",
        "43727970746f44696e6f3031353734": "1",
        "43727970746f44696e6f3031373635": "1",
        "43727970746f44696e6f3031383037": "1",
        "43727970746f44696e6f3031383231": "1",
        "43727970746f44696e6f3032303830": "1",
        "43727970746f44696e6f3032313133": "1",
        "43727970746f44696e6f3032323835": "1",
        "43727970746f44696e6f3032343238": "1",
        "43727970746f44696e6f3032363738": "1",
        "43727970746f44696e6f3032393034": "1",
        "43727970746f44696e6f3032393333": "1",
        "43727970746f44696e6f3032393537": "1",
        "43727970746f44696e6f3032393632": "1",
        "43727970746f44696e6f3032393735": "1",
        "43727970746f44696e6f3033303434": "1",
        "43727970746f44696e6f3033333338": "1",
        "43727970746f44696e6f3033393535": "1",
        "43727970746f44696e6f3034303630": "1",
        "43727970746f44696e6f3034313939": "1",
        "43727970746f44696e6f3034373439": "1",
        "43727970746f44696e6f3034383134": "1",
        "43727970746f44696e6f3034393530": "1",
        "43727970746f44696e6f3035303630": "1",
        "43727970746f44696e6f3035333230": "1",
        "43727970746f44696e6f2d312d3030303030": "1",
        "43727970746f44696e6f2d312d3030303032": "1"
      }
    }
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "006697ef0c9285b7001ebe5a9e356fb50441e0af803773a99b7cbb0e9b728570",
  "index": 2
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "2279450",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "017962634cf8fa87835256a80b8374c6f75687c34d8694480cb071648551c3a7",
  "index": 0
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "2000000",
    "multiasset": {
      "ee8e37676f6ebb8e031dff493f88ff711d24aa68666a09d61f1d3fb3": {
        "43727970746f44696e6f3031353039": "1"
      }
    }
  },
  "plutus_data": null,
  "script_ref": null
}
{
  "transaction_id": "017962634cf8fa87835256a80b8374c6f75687c34d8694480cb071648551c3a7",
  "index": 1
}
{
  "address": "addr_test1qp03v9yeg0vcfdhyn65ets2juearxpc3pmdhr0sxs0w6wh3sjf67h3yhrpxpv00zqfc7rtmr6mnmrcplfdkw5zhnl49qmyf0q5",
  "amount": {
    "coin": "725669617",
    "multiasset": null
  },
  "plutus_data": null,
  "script_ref": null
}
AdamMachera commented 2 years ago

when I have changed strategy to: txBuilder.add_inputs_from(txUnspentOutputs, 2) it helped.

dynamicstrategies commented 2 years ago

I see a similar issue here when using a fresh wallet. My hunch is that when the wallet has only 1 utxo the random improve gets confused. Try adding a few more UTXO to the wallet and checking if random improve works?

nicolasayotte commented 2 years ago

The coin selection does not account for the fact that you are returning NFTs in the change output and can sometimes fail because of that. This needs to be filed and addressed.

lisicky commented 2 years ago

Thanks @AdamMachera ! Your utoxs were very helpful, fix for RandomImproveMultiAsset will be in the next CSL release.