aboutsummaryrefslogtreecommitdiff
path: root/src/rpc.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2011-06-01 18:28:20 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2011-06-15 11:05:55 +0200
commit64c7ee7e6b9c059d99aaa493c74a6703c6b0fc80 (patch)
tree5ffafe3c7e4486f7b5ff2594bdbbf67e62560677 /src/rpc.cpp
parente89b9f6a2abaa120ff0fc3cea9ae364e8cbd25e4 (diff)
CWallet class
* A new class CKeyStore manages private keys, and script.cpp depends on access to CKeyStore. * A new class CWallet extends CKeyStore, and contains all former wallet-specific globals; CWallet depends on script.cpp, not the other way around. * Wallet-specific functions in CTransaction/CTxIn/CTxOut (GetDebit, GetCredit, GetChange, IsMine, IsFromMe), are moved to CWallet, taking their former 'this' argument as an explicit parameter * CWalletTx objects know which CWallet they belong to, for convenience, so they have their own direct (and caching) GetDebit/... functions. * Some code was moved from CWalletDB to CWallet, such as handling of reserve keys. * Main.cpp keeps a set of all 'registered' wallets, which should be informed about updates to the block chain, and does not have any notion about any 'main' wallet. Function in main.cpp that require a wallet (such as GenerateCoins), take an explicit CWallet* argument. * The actual CWallet instance used by the application is defined in init.cpp as "CWallet* pwalletMain". rpc.cpp and ui.cpp use this variable. * Functions in main.cpp and db.cpp that are not used by other modules are marked static. * The code for handling the 'submitorder' message is removed, as it not really compatible with the idea that a node is independent from the wallet(s) connected to it, and obsolete anyway.
Diffstat (limited to 'src/rpc.cpp')
-rw-r--r--src/rpc.cpp148
1 files changed, 74 insertions, 74 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp
index ad1abe333e..5b395f9470 100644
--- a/src/rpc.cpp
+++ b/src/rpc.cpp
@@ -264,14 +264,14 @@ Value setgenerate(const Array& params, bool fHelp)
{
int nGenProcLimit = params[1].get_int();
fLimitProcessors = (nGenProcLimit != -1);
- CWalletDB().WriteSetting("fLimitProcessors", fLimitProcessors);
+ WriteSetting("fLimitProcessors", fLimitProcessors);
if (nGenProcLimit != -1)
- CWalletDB().WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
+ WriteSetting("nLimitProcessors", nLimitProcessors = nGenProcLimit);
if (nGenProcLimit == 0)
fGenerate = false;
}
- GenerateBitcoins(fGenerate);
+ GenerateBitcoins(fGenerate, pwalletMain);
return Value::null;
}
@@ -298,7 +298,7 @@ Value getinfo(const Array& params, bool fHelp)
Object obj;
obj.push_back(Pair("version", (int)VERSION));
- obj.push_back(Pair("balance", ValueFromAmount(GetBalance())));
+ obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance())));
obj.push_back(Pair("blocks", (int)nBestHeight));
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("proxy", (fUseProxy ? addrProxy.ToStringIPPort() : string())));
@@ -307,7 +307,7 @@ Value getinfo(const Array& params, bool fHelp)
obj.push_back(Pair("difficulty", (double)GetDifficulty()));
obj.push_back(Pair("hashespersec", gethashespersec(params, false)));
obj.push_back(Pair("testnet", fTestNet));
- obj.push_back(Pair("keypoololdest", (boost::int64_t)GetOldestKeyPoolTime()));
+ obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime()));
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
@@ -329,9 +329,9 @@ Value getnewaddress(const Array& params, bool fHelp)
strAccount = AccountFromValue(params[0]);
// Generate a new key that is added to wallet
- string strAddress = PubKeyToAddress(GetKeyFromKeyPool());
+ string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool());
- SetAddressBookName(strAddress, strAccount);
+ pwalletMain->SetAddressBookName(strAddress, strAccount);
return strAddress;
}
@@ -341,7 +341,7 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
{
string strAddress;
- CWalletDB walletdb;
+ CWalletDB walletdb(pwalletMain->strWalletFile);
walletdb.TxnBegin();
CAccount account;
@@ -352,8 +352,8 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
{
CScript scriptPubKey;
scriptPubKey.SetBitcoinAddress(account.vchPubKey);
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin();
- it != mapWallet.end() && !account.vchPubKey.empty();
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
+ it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty();
++it)
{
const CWalletTx& wtx = (*it).second;
@@ -366,9 +366,9 @@ string GetAccountAddress(string strAccount, bool bForceNew=false)
// Generate a new key
if (account.vchPubKey.empty() || bForceNew)
{
- account.vchPubKey = GetKeyFromKeyPool();
+ account.vchPubKey = pwalletMain->GetKeyFromKeyPool();
string strAddress = PubKeyToAddress(account.vchPubKey);
- SetAddressBookName(strAddress, strAccount);
+ pwalletMain->SetAddressBookName(strAddress, strAccount);
walletdb.WriteAccount(strAccount, account);
}
@@ -391,7 +391,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
Value ret;
CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
ret = GetAccountAddress(strAccount);
}
@@ -421,18 +421,18 @@ Value setaccount(const Array& params, bool fHelp)
// Detect when changing the account of an address that is the 'unused current key' of another account:
CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapWallet)
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
- if (mapAddressBook.count(strAddress))
+ if (pwalletMain->mapAddressBook.count(strAddress))
{
- string strOldAccount = mapAddressBook[strAddress];
+ string strOldAccount = pwalletMain->mapAddressBook[strAddress];
if (strAddress == GetAccountAddress(strOldAccount))
GetAccountAddress(strOldAccount, true);
}
}
- SetAddressBookName(strAddress, strAccount);
+ pwalletMain->SetAddressBookName(strAddress, strAccount);
return Value::null;
}
@@ -447,10 +447,10 @@ Value getaccount(const Array& params, bool fHelp)
string strAddress = params[0].get_str();
string strAccount;
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
- map<string, string>::iterator mi = mapAddressBook.find(strAddress);
- if (mi != mapAddressBook.end() && !(*mi).second.empty())
+ map<string, string>::iterator mi = pwalletMain->mapAddressBook.find(strAddress);
+ if (mi != pwalletMain->mapAddressBook.end() && !(*mi).second.empty())
strAccount = (*mi).second;
}
return strAccount;
@@ -468,9 +468,9 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
// Find all addresses that have the given account
Array ret;
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook)
{
const string& strAddress = item.first;
const string& strName = item.second;
@@ -523,7 +523,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
CRITICAL_BLOCK(cs_main)
{
- string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
+ string strError = pwalletMain->SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
if (strError != "")
throw JSONRPCError(-4, strError);
}
@@ -544,7 +544,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
CScript scriptPubKey;
if (!scriptPubKey.SetBitcoinAddress(strAddress))
throw JSONRPCError(-5, "Invalid bitcoin address");
- if (!IsMine(scriptPubKey))
+ if (!IsMine(*pwalletMain,scriptPubKey))
return (double)0.0;
// Minimum confirmations
@@ -554,9 +554,9 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
// Tally
int64 nAmount = 0;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
if (wtx.IsCoinBase() || !wtx.IsFinal())
@@ -575,9 +575,9 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
{
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook)
{
const string& strAddress = item.first;
const string& strName = item.second;
@@ -586,7 +586,7 @@ void GetAccountPubKeys(string strAccount, set<CScript>& setPubKey)
// We're only counting our own valid bitcoin addresses and not ip addresses
CScript scriptPubKey;
if (scriptPubKey.SetBitcoinAddress(strAddress))
- if (IsMine(scriptPubKey))
+ if (IsMine(*pwalletMain,scriptPubKey))
setPubKey.insert(scriptPubKey);
}
}
@@ -613,9 +613,9 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
// Tally
int64 nAmount = 0;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
if (wtx.IsCoinBase() || !wtx.IsFinal())
@@ -635,10 +635,10 @@ Value getreceivedbyaccount(const Array& params, bool fHelp)
int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinDepth)
{
int64 nBalance = 0;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
// Tally wallet transactions
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
if (!wtx.IsFinal())
@@ -661,7 +661,7 @@ int64 GetAccountBalance(CWalletDB& walletdb, const string& strAccount, int nMinD
int64 GetAccountBalance(const string& strAccount, int nMinDepth)
{
- CWalletDB walletdb;
+ CWalletDB walletdb(pwalletMain->strWalletFile);
return GetAccountBalance(walletdb, strAccount, nMinDepth);
}
@@ -675,7 +675,7 @@ Value getbalance(const Array& params, bool fHelp)
"If [account] is specified, returns the balance in the account.");
if (params.size() == 0)
- return ValueFromAmount(GetBalance());
+ return ValueFromAmount(pwalletMain->GetBalance());
int nMinDepth = 1;
if (params.size() > 1)
@@ -686,7 +686,7 @@ Value getbalance(const Array& params, bool fHelp)
// (GetBalance() sums up all unspent TxOuts)
// getbalance and getbalance '*' should always return the same number.
int64 nBalance = 0;
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
if (!wtx.IsFinal())
@@ -734,9 +734,9 @@ Value movecmd(const Array& params, bool fHelp)
if (params.size() > 4)
strComment = params[4].get_str();
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
- CWalletDB walletdb;
+ CWalletDB walletdb(pwalletMain->strWalletFile);
walletdb.TxnBegin();
int64 nNow = GetAdjustedTime();
@@ -787,7 +787,7 @@ Value sendfrom(const Array& params, bool fHelp)
wtx.mapValue["to"] = params[5].get_str();
CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
// Check funds
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
@@ -795,7 +795,7 @@ Value sendfrom(const Array& params, bool fHelp)
throw JSONRPCError(-6, "Account has insufficient funds");
// Send
- string strError = SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
+ string strError = pwalletMain->SendMoneyToBitcoinAddress(strAddress, nAmount, wtx);
if (strError != "")
throw JSONRPCError(-4, strError);
}
@@ -844,7 +844,7 @@ Value sendmany(const Array& params, bool fHelp)
}
CRITICAL_BLOCK(cs_main)
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
// Check funds
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
@@ -852,16 +852,16 @@ Value sendmany(const Array& params, bool fHelp)
throw JSONRPCError(-6, "Account has insufficient funds");
// Send
- CReserveKey keyChange;
+ CReserveKey keyChange(pwalletMain);
int64 nFeeRequired = 0;
- bool fCreated = CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
+ bool fCreated = pwalletMain->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired);
if (!fCreated)
{
- if (totalAmount + nFeeRequired > GetBalance())
+ if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
throw JSONRPCError(-6, "Insufficient funds");
throw JSONRPCError(-4, "Transaction creation failed");
}
- if (!CommitTransaction(wtx, keyChange))
+ if (!pwalletMain->CommitTransaction(wtx, keyChange))
throw JSONRPCError(-4, "Transaction commit failed");
}
@@ -894,9 +894,9 @@ Value ListReceived(const Array& params, bool fByAccounts)
// Tally
map<uint160, tallyitem> mapTally;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
if (wtx.IsCoinBase() || !wtx.IsFinal())
@@ -923,9 +923,9 @@ Value ListReceived(const Array& params, bool fByAccounts)
// Reply
Array ret;
map<string, tallyitem> mapAccountTally;
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(string, string)& item, mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(string, string)& item, pwalletMain->mapAddressBook)
{
const string& strAddress = item.first;
const string& strAccount = item.second;
@@ -1061,13 +1061,13 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
// Received
if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived)
{
string account;
- if (mapAddressBook.count(r.first))
- account = mapAddressBook[r.first];
+ if (pwalletMain->mapAddressBook.count(r.first))
+ account = pwalletMain->mapAddressBook[r.first];
if (fAllAccounts || (account == strAccount))
{
Object entry;
@@ -1119,16 +1119,16 @@ Value listtransactions(const Array& params, bool fHelp)
nFrom = params[2].get_int();
Array ret;
- CWalletDB walletdb;
+ CWalletDB walletdb(pwalletMain->strWalletFile);
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
// Firs: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap:
typedef pair<CWalletTx*, CAccountingEntry*> TxPair;
typedef multimap<int64, TxPair > TxItems;
TxItems txByTime;
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
CWalletTx* wtx = &((*it).second);
txByTime.insert(make_pair(wtx->GetTxTime(), TxPair(wtx, (CAccountingEntry*)0)));
@@ -1180,16 +1180,16 @@ Value listaccounts(const Array& params, bool fHelp)
nMinDepth = params[0].get_int();
map<string, int64> mapAccountBalances;
- CRITICAL_BLOCK(cs_mapWallet)
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
- BOOST_FOREACH(const PAIRTYPE(string, string)& entry, mapAddressBook) {
+ BOOST_FOREACH(const PAIRTYPE(string, string)& entry, pwalletMain->mapAddressBook) {
uint160 hash160;
if(AddressToHash160(entry.first, hash160) && mapPubKeys.count(hash160)) // This address belongs to me
mapAccountBalances[entry.second] = 0;
}
- for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+ for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); ++it)
{
const CWalletTx& wtx = (*it).second;
int64 nGeneratedImmature, nGeneratedMature, nFee;
@@ -1204,8 +1204,8 @@ Value listaccounts(const Array& params, bool fHelp)
{
mapAccountBalances[""] += nGeneratedMature;
BOOST_FOREACH(const PAIRTYPE(string, int64)& r, listReceived)
- if (mapAddressBook.count(r.first))
- mapAccountBalances[mapAddressBook[r.first]] += r.second;
+ if (pwalletMain->mapAddressBook.count(r.first))
+ mapAccountBalances[pwalletMain->mapAddressBook[r.first]] += r.second;
else
mapAccountBalances[""] += r.second;
}
@@ -1213,7 +1213,7 @@ Value listaccounts(const Array& params, bool fHelp)
}
list<CAccountingEntry> acentries;
- CWalletDB().ListAccountCreditDebit("*", acentries);
+ CWalletDB(pwalletMain->strWalletFile).ListAccountCreditDebit("*", acentries);
BOOST_FOREACH(const CAccountingEntry& entry, acentries)
mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
@@ -1235,11 +1235,11 @@ Value gettransaction(const Array& params, bool fHelp)
hash.SetHex(params[0].get_str());
Object entry;
- CRITICAL_BLOCK(cs_mapWallet)
+ CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
{
- if (!mapWallet.count(hash))
+ if (!pwalletMain->mapWallet.count(hash))
throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
- const CWalletTx& wtx = mapWallet[hash];
+ const CWalletTx& wtx = pwalletMain->mapWallet[hash];
int64 nCredit = wtx.GetCredit();
int64 nDebit = wtx.GetDebit();
@@ -1250,10 +1250,10 @@ Value gettransaction(const Array& params, bool fHelp)
if (wtx.IsFromMe())
entry.push_back(Pair("fee", ValueFromAmount(nFee)));
- WalletTxToJSON(mapWallet[hash], entry);
+ WalletTxToJSON(pwalletMain->mapWallet[hash], entry);
Array details;
- ListTransactions(mapWallet[hash], "*", 0, false, details);
+ ListTransactions(pwalletMain->mapWallet[hash], "*", 0, false, details);
entry.push_back(Pair("details", details));
}
@@ -1269,7 +1269,7 @@ Value backupwallet(const Array& params, bool fHelp)
"Safely copies wallet.dat to destination, which can be a directory or a path with filename.");
string strDest = params[0].get_str();
- BackupWallet(strDest);
+ BackupWallet(*pwalletMain, strDest);
return Value::null;
}
@@ -1295,10 +1295,10 @@ Value validateaddress(const Array& params, bool fHelp)
string currentAddress = Hash160ToAddress(hash160);
ret.push_back(Pair("address", currentAddress));
ret.push_back(Pair("ismine", (mapPubKeys.count(hash160) > 0)));
- CRITICAL_BLOCK(cs_mapAddressBook)
+ CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
{
- if (mapAddressBook.count(currentAddress))
- ret.push_back(Pair("account", mapAddressBook[currentAddress]));
+ if (pwalletMain->mapAddressBook.count(currentAddress))
+ ret.push_back(Pair("account", pwalletMain->mapAddressBook[currentAddress]));
}
}
return ret;
@@ -1325,7 +1325,7 @@ Value getwork(const Array& params, bool fHelp)
static map<uint256, pair<CBlock*, unsigned int> > mapNewBlock;
static vector<CBlock*> vNewBlock;
- static CReserveKey reservekey;
+ static CReserveKey reservekey(pwalletMain);
if (params.size() == 0)
{
@@ -1406,7 +1406,7 @@ Value getwork(const Array& params, bool fHelp)
pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nBits << CBigNum(nExtraNonce);
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
- return CheckWork(pblock, reservekey);
+ return CheckWork(pblock, *pwalletMain, reservekey);
}
}