@@ -50,7 +50,6 @@ bool bSpendZeroConfChange = true;
5050bool bdisableSystemnotifications = false ; // Those bubbles can be annoying and slow down the UI when you get lots of trx
5151bool fSendFreeTransactions = false ;
5252bool fPayAtLeastCustomFee = true ;
53- bool fGlobalUnlockSpendCache = false ;
5453int64_t nStartupTime = GetTime(); // !< Client startup time for use with automint
5554
5655/* *
@@ -2788,21 +2787,16 @@ bool CWallet::CreateCoinStake(
27882787 // Masternode payment
27892788 FillBlockPayee (txNew, nMinFee, true , stakeInput->IsZPIV ());
27902789
2791- {
2792- TRY_LOCK (zpivTracker->cs_spendcache , fLocked );
2793- if (!fLocked )
2794- continue ;
2795-
2796- uint256 hashTxOut = txNew.GetHash ();
2797- CTxIn in;
2798- if (!stakeInput->CreateTxIn (this , in, hashTxOut)) {
2799- LogPrintf (" %s : failed to create TxIn\n " , __func__);
2800- txNew.vin .clear ();
2801- txNew.vout .clear ();
2802- continue ;
2803- }
2804- txNew.vin .emplace_back (in);
2790+ uint256 hashTxOut = txNew.GetHash ();
2791+ CTxIn in;
2792+ if (!stakeInput->CreateTxIn (this , in, hashTxOut)) {
2793+ LogPrintf (" %s : failed to create TxIn\n " , __func__);
2794+ txNew.vin .clear ();
2795+ txNew.vout .clear ();
2796+ continue ;
28052797 }
2798+ txNew.vin .emplace_back (in);
2799+
28062800
28072801 // Mark mints as spent
28082802 if (stakeInput->IsZPIV ()) {
@@ -4314,93 +4308,71 @@ bool CWallet::MintsToInputVector(std::map<CBigNum, CZerocoinMint>& mapMintsSelec
43144308 AccumulatorMap mapAccumulators (paramsAccumulator);
43154309 int64_t nTimeStart = GetTimeMicros ();
43164310
4317- int nLockAttempts = 0 ;
4318- while (nLockAttempts < 100 ) {
4319- TRY_LOCK (zpivTracker->cs_spendcache , lockSpendcache);
4320- if (!lockSpendcache) {
4321- fGlobalUnlockSpendCache = true ;
4322- MilliSleep (100 );
4323- ++nLockAttempts;
4324- continue ;
4311+ for (auto &it : mapMintsSelected) {
4312+ CZerocoinMint mint = it.second ;
4313+ CMintMeta meta = zpivTracker->Get (GetSerialHash (mint.GetSerialNumber ()));
4314+ CoinWitnessData coinWitness = CoinWitnessData (mint);
4315+ coinWitness.SetHeightMintAdded (mint.GetHeight ());
4316+
4317+ // Generate the witness for each mint being spent
4318+ if (!GenerateAccumulatorWitness (&coinWitness, mapAccumulators, pindexCheckpoint)) {
4319+ receipt.SetStatus (_ (" Couldn't generate the accumulator witness" ),
4320+ ZPIV_FAILED_ACCUMULATOR_INITIALIZATION);
4321+ return error (" %s : %s" , __func__, receipt.GetStatusMessage ());
43254322 }
43264323
4327- for (auto &it : mapMintsSelected) {
4328- CZerocoinMint mint = it.second ;
4329- CMintMeta meta = zpivTracker->Get (GetSerialHash (mint.GetSerialNumber ()));
4330- CoinWitnessData *coinWitness = zpivTracker->GetSpendCache (meta.hashStake );
4331-
4332- if (!coinWitness->nHeightAccEnd ) {
4333- *coinWitness = CoinWitnessData (mint);
4334- coinWitness->SetHeightMintAdded (mint.GetHeight ());
4335- }
4336-
4337- // Generate the witness for each mint being spent
4338- if (!GenerateAccumulatorWitness (coinWitness, mapAccumulators, pindexCheckpoint)) {
4339- receipt.SetStatus (_ (" Couldn't generate the accumulator witness" ),
4340- ZPIV_FAILED_ACCUMULATOR_INITIALIZATION);
4341- return error (" %s : %s" , __func__, receipt.GetStatusMessage ());
4342- }
4343-
4344- // Construct the CoinSpend object. This acts like a signature on the transaction.
4345- int64_t nTime1 = GetTimeMicros ();
4346- libzerocoin::ZerocoinParams *paramsCoin = Params ().Zerocoin_Params (coinWitness->isV1 );
4347- libzerocoin::PrivateCoin privateCoin (paramsCoin, coinWitness->denom );
4348- privateCoin.setPublicCoin (*coinWitness->coin );
4349- privateCoin.setRandomness (mint.GetRandomness ());
4350- privateCoin.setSerialNumber (mint.GetSerialNumber ());
4351- int64_t nTime2 = GetTimeMicros ();
4352- LogPrint (" bench" , " - CoinSpend constructed in %.2fms\n " , 0.001 * (nTime2 - nTime1));
4353-
4354- // Version 2 zerocoins have a privkey associated with them
4355- uint8_t nVersion = mint.GetVersion ();
4356- privateCoin.setVersion (mint.GetVersion ());
4357- if (nVersion >= libzerocoin::PrivateCoin::PUBKEY_VERSION) {
4358- CKey key;
4359- if (!mint.GetKeyPair (key))
4360- return error (" %s: failed to set zPIV privkey mint version=%d" , __func__, nVersion);
4361- privateCoin.setPrivKey (key.GetPrivKey ());
4362- }
4363- int64_t nTime3 = GetTimeMicros ();
4364- LogPrint (" bench" , " - Signing key set in %.2fms\n " , 0.001 * (nTime3 - nTime2));
4365-
4366- libzerocoin::Accumulator accumulator = mapAccumulators.GetAccumulator (coinWitness->denom );
4367- uint32_t nChecksum = GetChecksum (accumulator.getValue ());
4368- CBigNum bnValue;
4369- if (!GetAccumulatorValueFromChecksum (nChecksum, false , bnValue) || bnValue == 0 )
4370- return error (" %s: could not find checksum used for spend\n " , __func__);
4371-
4372- int64_t nTime4 = GetTimeMicros ();
4373- LogPrint (" bench" , " - Accumulator value fetched in %.2fms\n " , 0.001 * (nTime4 - nTime3));
4324+ // Construct the CoinSpend object. This acts like a signature on the transaction.
4325+ int64_t nTime1 = GetTimeMicros ();
4326+ libzerocoin::ZerocoinParams *paramsCoin = Params ().Zerocoin_Params (coinWitness.isV1 );
4327+ libzerocoin::PrivateCoin privateCoin (paramsCoin, coinWitness.denom );
4328+ privateCoin.setPublicCoin (*coinWitness.coin );
4329+ privateCoin.setRandomness (mint.GetRandomness ());
4330+ privateCoin.setSerialNumber (mint.GetSerialNumber ());
4331+ int64_t nTime2 = GetTimeMicros ();
4332+ LogPrint (" bench" , " - CoinSpend constructed in %.2fms\n " , 0.001 * (nTime2 - nTime1));
4333+
4334+ // Version 2 zerocoins have a privkey associated with them
4335+ uint8_t nVersion = mint.GetVersion ();
4336+ privateCoin.setVersion (mint.GetVersion ());
4337+ if (nVersion >= libzerocoin::PrivateCoin::PUBKEY_VERSION) {
4338+ CKey key;
4339+ if (!mint.GetKeyPair (key))
4340+ return error (" %s: failed to set zPIV privkey mint version=%d" , __func__, nVersion);
4341+ privateCoin.setPrivKey (key.GetPrivKey ());
4342+ }
4343+ int64_t nTime3 = GetTimeMicros ();
4344+ LogPrint (" bench" , " - Signing key set in %.2fms\n " , 0.001 * (nTime3 - nTime2));
43744345
4375- try {
4376- libzerocoin::CoinSpend spend (paramsCoin, paramsAccumulator, privateCoin, accumulator, nChecksum,
4377- *coinWitness->pWitness , hashTxOut, spendType);
4346+ libzerocoin::Accumulator accumulator = mapAccumulators.GetAccumulator (coinWitness.denom );
4347+ uint32_t nChecksum = GetChecksum (accumulator.getValue ());
4348+ CBigNum bnValue;
4349+ if (!GetAccumulatorValueFromChecksum (nChecksum, false , bnValue) || bnValue == 0 )
4350+ return error (" %s: could not find checksum used for spend\n " , __func__);
43784351
4379- if (!CheckCoinSpend (spend, accumulator, receipt)) {
4380- receipt.SetStatus (_ (" CoinSpend: failed check" ), ZPIV_SPEND_ERROR);
4381- return error (" %s : %s" , __func__, receipt.GetStatusMessage ());
4382- }
4352+ int64_t nTime4 = GetTimeMicros ();
4353+ LogPrint (" bench" , " - Accumulator value fetched in %.2fms\n " , 0.001 * (nTime4 - nTime3));
43834354
4384- vin.emplace_back (CTxIn (spend, coinWitness->denom ));
4385- CZerocoinSpend zcSpend (spend.getCoinSerialNumber (), 0 , mint.GetValue (), mint.GetDenomination (),
4386- GetChecksum (accumulator.getValue ()));
4387- zcSpend.SetMintCount (coinWitness->nMintsAdded );
4388- receipt.AddSpend (zcSpend);
4355+ try {
4356+ libzerocoin::CoinSpend spend (paramsCoin, paramsAccumulator, privateCoin, accumulator, nChecksum,
4357+ *coinWitness.pWitness , hashTxOut, spendType);
43894358
4390- int64_t nTime5 = GetTimeMicros ();
4391- LogPrint (" bench" , " - CoinSpend verified in %.2fms\n " , 0.001 * (nTime5 - nTime4));
4392- } catch (const std::exception&) {
4393- receipt.SetStatus (_ (" CoinSpend: Accumulator witness does not verify" ), ZPIV_INVALID_WITNESS);
4359+ if (!CheckCoinSpend (spend, accumulator, receipt)) {
4360+ receipt.SetStatus (_ (" CoinSpend: failed check" ), ZPIV_SPEND_ERROR);
43944361 return error (" %s : %s" , __func__, receipt.GetStatusMessage ());
43954362 }
4396- }
4397- break ;
4398- }
43994363
4400- if (nLockAttempts == 100 ) {
4401- LogPrintf (" %s : could not get lock on cs_spendcache\n " , __func__);
4402- receipt.SetStatus (_ (" could not get lock on cs_spendcache" ), ZPIV_TXMINT_GENERAL);
4403- return false ;
4364+ vin.emplace_back (CTxIn (spend, coinWitness.denom ));
4365+ CZerocoinSpend zcSpend (spend.getCoinSerialNumber (), 0 , mint.GetValue (), mint.GetDenomination (),
4366+ GetChecksum (accumulator.getValue ()));
4367+ zcSpend.SetMintCount (coinWitness.nMintsAdded );
4368+ receipt.AddSpend (zcSpend);
4369+
4370+ int64_t nTime5 = GetTimeMicros ();
4371+ LogPrint (" bench" , " - CoinSpend verified in %.2fms\n " , 0.001 * (nTime5 - nTime4));
4372+ } catch (const std::exception&) {
4373+ receipt.SetStatus (_ (" CoinSpend: Accumulator witness does not verify" ), ZPIV_INVALID_WITNESS);
4374+ return error (" %s : %s" , __func__, receipt.GetStatusMessage ());
4375+ }
44044376 }
44054377
44064378 int64_t nTimeFinished = GetTimeMicros ();
@@ -4428,69 +4400,51 @@ bool CWallet::MintsToInputVectorPublicSpend(std::map<CBigNum, CZerocoinMint>& ma
44284400
44294401 int spendVersion = CurrentPublicCoinSpendVersion ();
44304402
4431- int nLockAttempts = 0 ;
4432- while (nLockAttempts < 100 ) {
4433- TRY_LOCK (zpivTracker->cs_spendcache , lockSpendcache);
4434- if (!lockSpendcache) {
4435- fGlobalUnlockSpendCache = true ;
4436- MilliSleep (100 );
4437- ++nLockAttempts;
4438- continue ;
4439- }
4440-
4441- for (auto &it : mapMintsSelected) {
4442- CZerocoinMint mint = it.second ;
4403+ for (auto &it : mapMintsSelected) {
4404+ CZerocoinMint mint = it.second ;
44434405
4444- // Create the simple input and the scriptSig -> Serial + Randomness + Private key signature of both.
4445- // As the mint doesn't have the output index search it..
4446- CTransaction txMint;
4447- uint256 hashBlock;
4448- if (!GetTransaction (mint.GetTxHash (), txMint, hashBlock)) {
4449- receipt.SetStatus (strprintf (_ (" Unable to find transaction containing mint %s" ), mint.GetTxHash ().GetHex ()), ZPIV_TXMINT_GENERAL);
4450- return false ;
4451- } else if (mapBlockIndex.count (hashBlock) < 1 ) {
4452- // check that this mint made it into the blockchain
4453- receipt.SetStatus (_ (" Mint did not make it into blockchain" ), ZPIV_TXMINT_GENERAL);
4454- return false ;
4455- }
4406+ // Create the simple input and the scriptSig -> Serial + Randomness + Private key signature of both.
4407+ // As the mint doesn't have the output index search it..
4408+ CTransaction txMint;
4409+ uint256 hashBlock;
4410+ if (!GetTransaction (mint.GetTxHash (), txMint, hashBlock)) {
4411+ receipt.SetStatus (strprintf (_ (" Unable to find transaction containing mint %s" ), mint.GetTxHash ().GetHex ()), ZPIV_TXMINT_GENERAL);
4412+ return false ;
4413+ } else if (mapBlockIndex.count (hashBlock) < 1 ) {
4414+ // check that this mint made it into the blockchain
4415+ receipt.SetStatus (_ (" Mint did not make it into blockchain" ), ZPIV_TXMINT_GENERAL);
4416+ return false ;
4417+ }
44564418
4457- int outputIndex = -1 ;
4458- for (unsigned long i = 0 ; i < txMint.vout .size (); ++i) {
4459- CTxOut out = txMint.vout [i];
4460- if (out.scriptPubKey .IsZerocoinMint ()){
4461- libzerocoin::PublicCoin pubcoin (Params ().Zerocoin_Params (false ));
4462- CValidationState state;
4463- if (!TxOutToPublicCoin (out, pubcoin, state))
4464- return error (" %s: extracting pubcoin from txout failed" , __func__);
4465-
4466- if (pubcoin.getValue () == mint.GetValue ()){
4467- outputIndex = i;
4468- break ;
4469- }
4419+ int outputIndex = -1 ;
4420+ for (unsigned long i = 0 ; i < txMint.vout .size (); ++i) {
4421+ CTxOut out = txMint.vout [i];
4422+ if (out.scriptPubKey .IsZerocoinMint ()){
4423+ libzerocoin::PublicCoin pubcoin (Params ().Zerocoin_Params (false ));
4424+ CValidationState state;
4425+ if (!TxOutToPublicCoin (out, pubcoin, state))
4426+ return error (" %s: extracting pubcoin from txout failed" , __func__);
4427+
4428+ if (pubcoin.getValue () == mint.GetValue ()){
4429+ outputIndex = i;
4430+ break ;
44704431 }
44714432 }
4433+ }
44724434
4473- if (outputIndex == -1 ) {
4474- receipt.SetStatus (_ (" Pubcoin not found in mint tx" ), ZPIV_TXMINT_GENERAL);
4475- return false ;
4476- }
4477-
4478- mint.SetOutputIndex (outputIndex);
4479- CTxIn in;
4480- if (!ZPIVModule::createInput (in, mint, hashTxOut, spendVersion)) {
4481- receipt.SetStatus (_ (" Cannot create public spend input" ), ZPIV_TXMINT_GENERAL);
4482- return false ;
4483- }
4484- vin.emplace_back (in);
4485- receipt.AddSpend (CZerocoinSpend (mint.GetSerialNumber (), 0 , mint.GetValue (), mint.GetDenomination (), 0 ));
4435+ if (outputIndex == -1 ) {
4436+ receipt.SetStatus (_ (" Pubcoin not found in mint tx" ), ZPIV_TXMINT_GENERAL);
4437+ return false ;
44864438 }
4487- break ;
4488- }
44894439
4490- if (nLockAttempts == 100 ) {
4491- LogPrintf (" %s : could not get lock on cs_spendcache\n " , __func__);
4492- receipt.SetStatus (_ (" could not get lock on cs_spendcache" ), ZPIV_TXMINT_GENERAL);
4493- return false ;
4440+ mint.SetOutputIndex (outputIndex);
4441+ CTxIn in;
4442+ if (!ZPIVModule::createInput (in, mint, hashTxOut, spendVersion)) {
4443+ receipt.SetStatus (_ (" Cannot create public spend input" ), ZPIV_TXMINT_GENERAL);
4444+ return false ;
4445+ }
4446+ vin.emplace_back (in);
4447+ receipt.AddSpend (CZerocoinSpend (mint.GetSerialNumber (), 0 , mint.GetValue (), mint.GetDenomination (), 0 ));
44944448 }
44954449
44964450 receipt.SetStatus (_ (" Spend Valid" ), ZPIV_SPEND_OKAY); // Everything okay
0 commit comments