Signature concurrency issue

+2 votes


I'm developing web application using Multichain's multisig. End user receives list of partially signed transactions and he able to sign them. Once he clicks "Sign" button on the UI my application performs signrawtransaction and sendrawtransaction

The problem is that if user clicks "Sign" multiple times in row (for different transactions), multiple requests start executing sendrawtransaction and some of them fail with RPC_TRANSACTION_ALREADY_IN_CHAIN error code.

I tried to re-execute signature for failed transactions via multichain-cli but got the same error RPC_TRANSACTION_ALREADY_IN_CHAIN 

Getting failed transaction by txid via getrawtransaction results in RPC_TX_NOT_FOUND .

If user keep some delay (confirmation delay I guess) between signatures then everything is fine.

So concurrency should be handled in application and Multichain doesn't do that for us, right?




asked Jan 29, 2018 by Dmitry
edited Jan 29, 2018 by Dmitry

1 Answer

+2 votes
Best answer
Alongside that RPC_TRANSACTION_ALREADY_IN_CHAIN error, can you please post the textual error explanation you see? Looking in the source code it seems like this may be the wrong error code for a "missing inputs" error. If so, the explanation is that some of the transaction inputs are missing. But this still looks like an error we should check into.
answered Jan 29, 2018 by MultiChain
selected Feb 6, 2018 by Dmitry
Hi. Thanks for your help on this. Could you point me to some documentation (perhaps bitcoin docs?) regarding this issue and how best to solve for it?
Please explain how you would like things to work, then perhaps we can provide some pointers.
Seems locks are kept in memory and not persistent. In case node goes down and then starts again all locked UTXO becomes available for spending. Is there any way to create transaction from multisig address specifying input txid ?
Found most viable solution - do not rely on existing inputs and always create new one.

1. Create transaction with zero assets

createrawsendfrom <local_node_address> '{"<multisig_address>": 0}' '[]' send

returns txid e.g. e88aa877600e418453e1efba870d3f237f061889ab98c75f7244bcf0456a7440

2. Create multisig transactions

createrawtransaction '[{"txid":"e88aa877600e418453e1efba870d3f237f061889ab98c75f7244bcf0456a7440", "vout":0}]' '{}' '[{"for":"multisig_stream", "key":"test_key", "data":"abcd"}]' sign

Transaction created on the first step contains two outputs in the following order:
  vout: 0 for a <multisig_address>
  vout: 1 for a <local_node_address>
Is it safe to rely on that order or it could be changed and we should lookup vout index by address?
What your thoughts about this approach?
Yes, this works absolutely fine if you're using transactions to write stream data and not to move assets. (The problem with doing this with assets is that the assets can only be in one place at once.) We were not aware you were using MultiChain in this way or we would have suggested this solution ourselves!

In any event you can rely on the output order being fixed because createrawsendfrom takes the order you give it, then adds a change output at the end.