@@ -648,10 +648,6 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
648
648
649
649
ptx.collateralOutpoint = COutPoint (collateralHash, (uint32_t )collateralIndex);
650
650
paramIdx += 2 ;
651
-
652
- // TODO unlock on failure
653
- LOCK (wallet->cs_wallet );
654
- wallet->LockCoin (ptx.collateralOutpoint );
655
651
}
656
652
657
653
if (request.params [paramIdx].get_str () != " " ) {
@@ -721,15 +717,14 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
721
717
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, std::string (" Invalid Dash address: " ) + request.params [paramIdx + 6 ].get_str ());
722
718
}
723
719
724
- FundSpecialTx (wallet.get (), tx, ptx, fundDest);
725
- UpdateSpecialTxInputsHash (tx, ptx);
726
-
727
720
bool fSubmit {true };
728
721
if ((isExternalRegister || isFundRegister) && !request.params [paramIdx + 7 ].isNull ()) {
729
722
fSubmit = ParseBoolV (request.params [paramIdx + 7 ], " submit" );
730
723
}
731
724
732
725
if (isFundRegister) {
726
+ FundSpecialTx (wallet.get (), tx, ptx, fundDest);
727
+ UpdateSpecialTxInputsHash (tx, ptx);
733
728
CAmount fundCollateral = GetMnType (mnType).collat_amount ;
734
729
uint32_t collateralIndex = (uint32_t ) -1 ;
735
730
for (uint32_t i = 0 ; i < tx.vout .size (); i++) {
@@ -746,41 +741,57 @@ static UniValue protx_register_common_wrapper(const JSONRPCRequest& request,
746
741
} else {
747
742
// referencing external collateral
748
743
749
- Coin coin;
750
- if (!GetUTXOCoin (ptx.collateralOutpoint , coin)) {
751
- throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, strprintf (" collateral not found: %s" , ptx.collateralOutpoint .ToStringShort ()));
752
- }
753
- CTxDestination txDest;
754
- ExtractDestination (coin.out .scriptPubKey , txDest);
755
- const PKHash *pkhash = std::get_if<PKHash>(&txDest);
756
- if (!pkhash) {
757
- throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, strprintf (" collateral type not supported: %s" , ptx.collateralOutpoint .ToStringShort ()));
758
- }
759
-
760
- if (isPrepareRegister) {
761
- // external signing with collateral key
762
- ptx.vchSig .clear ();
763
- SetTxPayload (tx, ptx);
764
-
765
- UniValue ret (UniValue::VOBJ);
766
- ret.pushKV (" tx" , EncodeHexTx (CTransaction (tx)));
767
- ret.pushKV (" collateralAddress" , EncodeDestination (txDest));
768
- ret.pushKV (" signMessage" , ptx.MakeSignString ());
769
- return ret;
770
- } else {
771
- // lets prove we own the collateral
772
- LegacyScriptPubKeyMan* spk_man = wallet->GetLegacyScriptPubKeyMan ();
773
- if (!spk_man) {
774
- throw JSONRPCError (RPC_WALLET_ERROR, " This type of wallet does not support this command" );
744
+ const bool unlockOnError = [&]() {
745
+ if (LOCK (wallet->cs_wallet ); !wallet->IsLockedCoin (ptx.collateralOutpoint .hash , ptx.collateralOutpoint .n )) {
746
+ wallet->LockCoin (ptx.collateralOutpoint );
747
+ return true ;
748
+ }
749
+ return false ;
750
+ }();
751
+ try {
752
+ FundSpecialTx (wallet.get (), tx, ptx, fundDest);
753
+ UpdateSpecialTxInputsHash (tx, ptx);
754
+ Coin coin;
755
+ if (!GetUTXOCoin (ptx.collateralOutpoint , coin)) {
756
+ throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, strprintf (" collateral not found: %s" , ptx.collateralOutpoint .ToStringShort ()));
757
+ }
758
+ CTxDestination txDest;
759
+ ExtractDestination (coin.out .scriptPubKey , txDest);
760
+ const PKHash* pkhash = std::get_if<PKHash>(&txDest);
761
+ if (!pkhash) {
762
+ throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, strprintf (" collateral type not supported: %s" , ptx.collateralOutpoint .ToStringShort ()));
775
763
}
776
764
777
- CKey key;
778
- if (!spk_man->GetKey (ToKeyID (*pkhash), key)) {
779
- throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, strprintf (" collateral key not in wallet: %s" , EncodeDestination (txDest)));
765
+ if (isPrepareRegister) {
766
+ // external signing with collateral key
767
+ ptx.vchSig .clear ();
768
+ SetTxPayload (tx, ptx);
769
+
770
+ UniValue ret (UniValue::VOBJ);
771
+ ret.pushKV (" tx" , EncodeHexTx (CTransaction (tx)));
772
+ ret.pushKV (" collateralAddress" , EncodeDestination (txDest));
773
+ ret.pushKV (" signMessage" , ptx.MakeSignString ());
774
+ return ret;
775
+ } else {
776
+ // lets prove we own the collateral
777
+ LegacyScriptPubKeyMan* spk_man = wallet->GetLegacyScriptPubKeyMan ();
778
+ if (!spk_man) {
779
+ throw JSONRPCError (RPC_WALLET_ERROR, " This type of wallet does not support this command" );
780
+ }
781
+
782
+ CKey key;
783
+ if (!spk_man->GetKey (ToKeyID (*pkhash), key)) {
784
+ throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, strprintf (" collateral key not in wallet: %s" , EncodeDestination (txDest)));
785
+ }
786
+ SignSpecialTxPayloadByString (tx, ptx, key);
787
+ SetTxPayload (tx, ptx);
788
+ return SignAndSendSpecialTx (request, chainman, tx, fSubmit );
789
+ }
790
+ } catch (...) {
791
+ if (unlockOnError) {
792
+ WITH_LOCK (wallet->cs_wallet , wallet->UnlockCoin (ptx.collateralOutpoint ));
780
793
}
781
- SignSpecialTxPayloadByString (tx, ptx, key);
782
- SetTxPayload (tx, ptx);
783
- return SignAndSendSpecialTx (request, chainman, tx, fSubmit );
794
+ throw ;
784
795
}
785
796
}
786
797
}
0 commit comments