// This is a good implementation. Dots all the i's, so to speak. // client-side. // The basket ONLY stores closing numbers, so this means "harvest 'em all." // void OTBasket::HarvestClosingNumbers(OTPseudonym & theNym, const OTIdentifier & theServerID, const bool bSave/*=true*/) { const OTString strServerID(theServerID); bool bNeedToSave = false; // ************************************************************************* // The SUB-CURRENCIES first... // const unsigned int nCount = static_cast<unsigned int>(this->Count()); for (unsigned int i = 0; i < nCount; i++) { BasketItem * pRequestItem = this->At(i); OT_ASSERT(NULL != pRequestItem); // -------------------------------- const long lClosingTransNo = pRequestItem->lClosingTransactionNo; // -------------------------------- // This function will only "add it back" if it was really there in the first place. // (Verifies it is on issued list first, before adding to available list.) // const bool bClawedBack = theNym.ClawbackTransactionNumber(theServerID, lClosingTransNo, false); // bSave=false if (bClawedBack) bNeedToSave = true; // else // OTLog::vError("OTBasket::HarvestClosingNumbers: Number (%ld) failed as issued. (Thus didn't bother 'adding it back'.)\n", // lClosingTransNo); } // for // ************************************************************************* // Then the BASKET currency itself... // const long lClosingTransNo = this->GetClosingNum(); // -------------------------------- // This function will only "add it back" if it was really there in the first place. // (Verifies it is on issued list first, before adding to available list.) // const bool bClawedBack = theNym.ClawbackTransactionNumber(theServerID, lClosingTransNo, false); // bSave=false if (bClawedBack) bNeedToSave = true; // ************************************************************************* // Until I put this down here, there were subtle cases where the Nym wouldn't get saved. // Therefore another vote for my "dirty instances" theory. // if (bSave && bNeedToSave) { OTPseudonym * pSignerNym = &theNym;// probably unnecessary. theNym.SaveSignedNymfile(*pSignerNym); } }
// You usually wouldn't want to use this, since if the transaction failed, the opening number // is already burned and gone. But there might be cases where it's not, and you want to retrieve it. // So I added this function. // void OTAgreement::HarvestOpeningNumber(OTPseudonym & theNym) { // since we overrode the parent, we give it a chance to harvest also. // IF theNym is the original sender, the opening number will be harvested // inside this call. // OTCronItem::HarvestOpeningNumber(theNym); // The Nym is the original recipient. (If Compares true). // IN CASES where GetTransactionNum() isn't already burned, we can harvest it here. // if (theNym.CompareID(GetRecipientUserID())) { // This function will only "add it back" if it was really there in the first place. // (Verifies it is on issued list first, before adding to available list.) // theNym.ClawbackTransactionNumber(GetServerID(), GetRecipientOpeningNum(), true); //bSave=true } // NOTE: if the message failed (transaction never actually ran) then the sender AND recipient // can both reclaim their opening numbers. But if the message SUCCEEDED and the transaction FAILED, // then only the recipient can claim his opening number -- the sender's is already burned. So then, // what if you mistakenly call this function and pass the sender, when that number is already burned? // There's nothing this function can do, because we have no way of telling, from inside here, // whether the message succeeded or not, and whether the transaction succeeded or not. Therefore, // ==> we MUST rely on the CALLER to know this, and to avoid calling this function in the first place, // if he's sitting on a sender with a failed transaction. }
// Used for adding transaction numbers back to a Nym, after deciding not to use this agreement // or failing in trying to use it. Client side. // void OTAgreement::HarvestClosingNumbers(OTPseudonym & theNym) { // Since we overrode the parent, we give it a chance to harvest also. // If theNym is the sender, then his closing numbers will be harvested // inside here. But what if the transaction was a success? The numbers // will still be harvested, since they are still on the sender's issued // list, but they should not have been harvested, regardless, since the // transaction was a success and the server therefore has them marked as // "used." So clearly you cannot just blindly call this function unless // you know beforehand whether the message and transaction were a success. // OTCronItem::HarvestClosingNumbers(theNym); // The Nym is the original recipient. (If Compares true). // FYI, if Nym is the original sender, then the above call will handle him. // // GetTransactionNum() is burned, but we can harvest the closing // numbers from the "Closing" list, which is only for the sender's numbers. // Subclasses will have to override this function for recipients, etc. // if (theNym.CompareID(GetRecipientUserID())) { for (int i = 0; i < GetRecipientCountClosingNumbers(); i++) { // This function will only "add it back" if it was really there in the first place. // (Verifies it is on issued list first, before adding to available list.) // const bool bClawedBack = theNym.ClawbackTransactionNumber(GetServerID(), GetRecipientClosingTransactionNoAt(i), (i == (GetRecipientCountClosingNumbers()-1) ? true : false)); // bSave=true only on the last iteration. if (!bClawedBack) { // OTLog::vError("OTAgreement::HarvestClosingNumbers: Number (%ld) failed as issued. (Thus didn't bother 'adding it back'.)\n", // GetRecipientClosingTransactionNoAt(i)); } } } }