dashpay / platform

L2 solution for seriously fast decentralized applications for the Dash network
https://dashplatform.readme.io/docs/introduction-what-is-dash-platform
MIT License
72 stars 39 forks source link

Error: 3 INVALID_ARGUMENT: invalid transaction: Missing inputs. Code:-25 #136

Closed cloudwheels closed 2 months ago

cloudwheels commented 4 years ago

Expected Behavior

Spend funds from an account with a balance

Current Behavior

Get error as per title

Possible Solution

Investigate generated transaction inputs / script

Steps to Reproduce (for bugs)

const Dash = require('dash');

const clientOpts = {
    network: 'evonet',
    wallet: {
        mnemonic: "wrist ladder salute build walk other scrap stumble true hotel layer treat"
    }
};

async function sendFunds(amount, toAddress) {
    try {

        const client = new Dash.Client(clientOpts);
        const account = await client.wallet.getAccount();
        console.log(`retrieved account`)
        const accBalTotal = account.getTotalBalance();
        const accBalUnconf = account.getUnconfirmedBalance()
        const accBalConf = account.getConfirmedBalance()
        console.log(`Total balance: ${accBalTotal}`)
        console.log(`Unconfirmed balance: ${accBalUnconf}`)
        console.log(`Confirmed balance: ${accBalConf}`)
        const transaction = account.createTransaction({
            recipients: [
                {
                    recipient: toAddress,
                    satoshis: amount
                }
            ]
        });
        const result = await account.broadcastTransaction(transaction);
        console.log('Transaction broadcast!\nTransaction ID:', result);

        return;
    } catch (e) {
        throw e;
    }

}

(async () => {
    await sendFunds(1000000, 'yMAaR92yKhK7hcKbNGNvAwjRQngx2UR8et')
})()
warn: Running on a NodeJS env without any specified adapter. Data will not persist.
retrieved account
Total balance: 56514754820
Unconfirmed balance: 0
Confirmed balance: 56514754820
(node:243071) UnhandledPromiseRejectionWarning: Error: 3 INVALID_ARGUMENT: invalid transaction: Missing inputs. Code:-25
    at Object.exports.createStatusError (/home/nigel/Dev/autofaucet-express/node_modules/grpc/src/common.js:91:15)
    at Object.onReceiveStatus (/home/nigel/Dev/autofaucet-express/node_modules/grpc/src/client_interceptors.js:1209:28)
    at InterceptingListener._callNext (/home/nigel/Dev/autofaucet-express/node_modules/grpc/src/client_interceptors.js:568:42)
    at InterceptingListener.onReceiveStatus (/home/nigel/Dev/autofaucet-express/node_modules/grpc/src/client_interceptors.js:618:8)
    at InterceptingListener._callNext (/home/nigel/Dev/autofaucet-express/node_modules/grpc/src/client_interceptors.js:574:12)
    at InterceptingListener.onReceiveStatus (/home/nigel/Dev/autofaucet-express/node_modules/grpc/src/client_interceptors.js:618:8)
    at callback (/home/nigel/Dev/autofaucet-express/node_modules/grpc/src/client_interceptors.js:847:24)
(node:243071) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:243071) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Your Environment

nodejs 12.16.2 dash@3.14.1

Schlomon commented 4 years ago

Can confirm, this happens once in a while but not frequently, so if whoever tries to reproduce this bug can't do it in the first run, try e.g. waiting 48 hours and then retry it with the same mnemonics and/or addresses.

dashameter commented 4 years ago

confirmed after running above snippet

cloudwheels commented 4 years ago

see also this https://discordapp.com/channels/670271785974890526/718217459144065045/730357865944055860

cloudwheels commented 4 years ago

Also, all UTXOs are reported as spendbable:

console.log(`all utxos:`)
        console.dir(account.getUTXOS(false))
        console.log(`only spendable utxos:`)
        console.dir(account.getUTXOS(true))
all utxos:
[
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: '98e33837b7a307112a12eb6bdb6cdd49ce962047084bb6ce39444a2cd58db974',
    outputIndex: 1,
    script: Script { chunks: [Array] },
    satoshis: 18512150000
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'f7b10cc87a6ce84f17e22ff679e655f83c5a91aa7707e5b1776a4c3406e683e3',
    outputIndex: 1,
    script: Script { chunks: [Array] },
    satoshis: 16682540000
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'fe9d2b99a63cebaa8fa48e0caba631cbe7ec16925033d05d9eb5eb33615dbc36',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 11590914663
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'e324e98073d7b2ece5114760bc3635769fa5a2d90cfd8d8d6c0793a71d8ec1c7',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 4732968748
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'd15323bddadbb15ac4ca9b704dc7da0df018d4d6af9019c47b5757483cc306eb',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 2709837809
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'dd0975fc4b05fef8fd97961d9bf7feba48e25626340ad3248a34440eab5fff32',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 1716915370
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: '5a04d7c5e60625f1a4105ab0a327a7d48540179bcbf754fde95a6003a587a971',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 469428435
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: '74d4ddcd1caf2a234c7bd31a284668075252ee8855cab350dad4a099a0a1f188',
    outputIndex: 0,
    script: Script { chunks: [Array] },
    satoshis: 99999795
  }
]
only spendable utxos:
[
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: '98e33837b7a307112a12eb6bdb6cdd49ce962047084bb6ce39444a2cd58db974',
    outputIndex: 1,
    script: Script { chunks: [Array] },
    satoshis: 18512150000
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'f7b10cc87a6ce84f17e22ff679e655f83c5a91aa7707e5b1776a4c3406e683e3',
    outputIndex: 1,
    script: Script { chunks: [Array] },
    satoshis: 16682540000
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'fe9d2b99a63cebaa8fa48e0caba631cbe7ec16925033d05d9eb5eb33615dbc36',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 11590914663
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'e324e98073d7b2ece5114760bc3635769fa5a2d90cfd8d8d6c0793a71d8ec1c7',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 4732968748
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'd15323bddadbb15ac4ca9b704dc7da0df018d4d6af9019c47b5757483cc306eb',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 2709837809
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: 'dd0975fc4b05fef8fd97961d9bf7feba48e25626340ad3248a34440eab5fff32',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 1716915370
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: '5a04d7c5e60625f1a4105ab0a327a7d48540179bcbf754fde95a6003a587a971',
    outputIndex: 3,
    script: Script { chunks: [Array] },
    satoshis: 469428435
  },
  UnspentOutput {
    address: Address {
      hashBuffer: [Buffer [Uint8Array]],
      network: [Network],
      type: 'pubkeyhash'
    },
    txId: '74d4ddcd1caf2a234c7bd31a284668075252ee8855cab350dad4a099a0a1f188',
    outputIndex: 0,
    script: Script { chunks: [Array] },
    satoshis: 99999795
  }
]
dashameter commented 3 years ago

I have a script running right now with a mnemonic that throws this error.

Feel free to use this mnemonic to reproduce and triage this issue:

https://github.com/dashameter/dash-dapp-autofaucet/blob/sendTest/sendTx1.js#L36

https://github.com/dashameter/dash-dapp-autofaucet/blob/sendTest/logs/sendTx1-out.log#L7687

dash-maverick commented 3 years ago

please try retesting it

dashameter commented 3 years ago

failed retest:

InvalidRequestError: invalid transaction: Missing inputs
    at GrpcTransport.createGrpcTransportError (dash-dapp-autofaucet/node_modules/@dashevo/dapi-client/lib/transport/GrpcTransport/createGrpcTransportError.js:96:12)
    at GrpcTransport.request (dash-dapp-autofaucet/node_modules/@dashevo/dapi-client/lib/transport/GrpcTransport/GrpcTransport.js:86:34)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5) {
  code: 3,
  data: {},
  dapiAddress: DAPIAddress {
    host: '34.219.93.145',
    httpPort: 3000,
    grpcPort: 3010,
    proRegTxHash: '4eb2e565f1df2bc390c813149c86771f69809a83549440e70343289b605e6208',
    banCount: 0,
    banStartTime: undefined
  }
}
SamKirby22 commented 3 years ago

Triage sheet updated. Thanks

dash-maverick commented 2 years ago

@dashameter @SamKirby22 should be solved from now - please double check (have a look at https://github.com/dashevo/wallet-lib/issues/232)

dashameter commented 2 years ago

retest failed:

1|sendTx1  | InvalidRequestError: invalid transaction: Missing inputs
1|sendTx1  |     at GrpcTransport.createGrpcTransportError (/root/dash-dapp-autofaucet/node_modules/@dashevo/dapi-client/lib/transport/GrpcTransport/createGrpcTransportError.js:96:12)
1|sendTx1  |     at GrpcTransport.request (/root/dash-dapp-autofaucet/node_modules/@dashevo/dapi-client/lib/transport/GrpcTransport/GrpcTransport.js:86:34)
1|sendTx1  |     at runMicrotasks (<anonymous>)
1|sendTx1  |     at processTicksAndRejections (internal/process/task_queues.js:97:5) {
1|sendTx1  |   code: 3,
1|sendTx1  |   data: {},
1|sendTx1  |   dapiAddress: DAPIAddress {
1|sendTx1  |     host: '34.220.41.134',
1|sendTx1  |     httpPort: 3000,
1|sendTx1  |     grpcPort: 3010,
1|sendTx1  |     proRegTxHash: undefined,
1|sendTx1  |     banCount: 0,
1|sendTx1  |     banStartTime: undefined
1|sendTx1  |   }
1|sendTx1  | }
1|sendTx1  | retryCounter :>>  0
1|sendTx1  | Waiting 10 seconds until retry...
1|sendTx1  | Total balance: 846999385
1|sendTx1  | Unconfirmed balance: 0
1|sendTx1  | Confirmed balance: 846999385
dash-maverick commented 2 years ago

Hey @Alex-Werner @markin-io , chaining of transactions was supposed to help here. Could you please refer?

markin-io commented 2 years ago

Hey @dash-maverick @dashameter

This seems to be the same situation like the one we debugged this week with @thephez The node 34.220.41.134 somehow seems to be out of sync and does not provide a complete set of transactions to the SDK.

As a result, we have a situation where the wallet tries to spend already spent UTXOs, because of the gaps in the TX list.

My suggestion to @dashameter would be to choose a different set of dapiAddresses, or remove it completely.

@dash-maverick It would've been good to improve the error message, and instead of saying "Missing inputs", say something like "Attempt to spend already spent UTXO". However, this lies in the field of dash core, and I'm not sure it's easily doable.

Also, it is worth investigating why the node which is out of sync is still considered a valid source of truth. I believe this might require help from someone from the platform protocol team.

dashameter commented 2 years ago

@markin-io thanks for the hint. I actually haven't been using the dapiAddresses for the last test. I just re-ran the test a few times with and without the unsafeOptions and this is the error log I get now:

https://gist.github.com/dashameter/7996c104ca3271c446b57d4ab3b04e97

Were you able to run the script successfully and have it send txs?

markin-io commented 2 years ago

@dashameter hey! Apologies for the late response. Just finished checking out these: https://github.com/dashameter/dash-dapp-autofaucet/blob/master/sendTx1.js https://github.com/dashameter/dash-dapp-autofaucet/blob/master/sendTx2.js

I managed to reproduce the Merkle diff error a couple of times, but it does not happen all the time. However, both mnemonics produce Missing inputs or Transaction already in chain errors every time I run the scripts.

Those are "heavy" wallets with around 500 transactions, so I assume some of them are not making it to the wallet store, and hence we have incorrect UTXO selection.

So, no matter what DAPI addresses are chosen, it will still be the same. Please, discard my original assumption about the node being out of sync.

We are continuing to narrow down this problem. In the meantime, I'd suggest using a fresh wallet, because, from my current experience, problems start appearing if the wallet has more than 300 transactions in it.

dash-maverick commented 2 years ago

This is even a known workaround connected to the state of having > 300 transactions - that way metadata can be obtained without having the light client fully implemented.

dashameter commented 2 years ago

There is even a know workaround connected to the state of having > 300 transactions

@dash-maverick can you share the known workaround ?

dash-maverick commented 2 years ago

@dash-maverick can you share the known workaround ?

I made a mistake in my previous comment and fixed that right now with a bit of more explanation

SamKirby22 commented 2 years ago

As per triage, unable to reproduce. Agreed to retest.

dashameter commented 2 years ago

waiting for testnet to be online for retest