|
|
@ -24,8 +24,7 @@ |
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************** */ |
|
|
|
/* ************************************************************************** */ |
|
|
|
|
|
|
|
|
|
|
|
UniValue |
|
|
|
UniValue keva_namespace(const JSONRPCRequest& request) |
|
|
|
keva_namespace (const JSONRPCRequest& request) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
CWallet* const pwallet = GetWalletForJSONRPCRequest(request); |
|
|
|
CWallet* const pwallet = GetWalletForJSONRPCRequest(request); |
|
|
|
if (!EnsureWalletIsAvailable (pwallet, request.fHelp)) |
|
|
|
if (!EnsureWalletIsAvailable (pwallet, request.fHelp)) |
|
|
@ -50,9 +49,9 @@ keva_namespace (const JSONRPCRequest& request) |
|
|
|
|
|
|
|
|
|
|
|
ObserveSafeMode (); |
|
|
|
ObserveSafeMode (); |
|
|
|
|
|
|
|
|
|
|
|
const std::string displayNameStr = request.params[0].get_str (); |
|
|
|
const std::string displayNameStr = request.params[0].get_str(); |
|
|
|
const valtype displayName = ValtypeFromString (displayNameStr); |
|
|
|
const valtype displayName = ValtypeFromString (displayNameStr); |
|
|
|
if (displayName.size () > MAX_NAME_LENGTH) |
|
|
|
if (displayName.size () > MAX_NAMESPACE_LENGTH) |
|
|
|
throw JSONRPCError (RPC_INVALID_PARAMETER, "the name is too long"); |
|
|
|
throw JSONRPCError (RPC_INVALID_PARAMETER, "the name is too long"); |
|
|
|
|
|
|
|
|
|
|
|
/* No explicit locking should be necessary. CReserveKey takes care
|
|
|
|
/* No explicit locking should be necessary. CReserveKey takes care
|
|
|
@ -66,7 +65,7 @@ keva_namespace (const JSONRPCRequest& request) |
|
|
|
const bool ok = keyName.GetReservedKey(pubKey, true); |
|
|
|
const bool ok = keyName.GetReservedKey(pubKey, true); |
|
|
|
assert (ok); |
|
|
|
assert (ok); |
|
|
|
|
|
|
|
|
|
|
|
CKeyID keyId = pubKey.GetID() |
|
|
|
CKeyID keyId = pubKey.GetID(); |
|
|
|
|
|
|
|
|
|
|
|
// The namespace is: Hash160(Hash160(keyId) || displayName)
|
|
|
|
// The namespace is: Hash160(Hash160(keyId) || displayName)
|
|
|
|
valtype toHash = ToByteVector(Hash160(ToByteVector(keyId))); |
|
|
|
valtype toHash = ToByteVector(Hash160(ToByteVector(keyId))); |
|
|
@ -79,24 +78,23 @@ keva_namespace (const JSONRPCRequest& request) |
|
|
|
CCoinControl coinControl; |
|
|
|
CCoinControl coinControl; |
|
|
|
CWalletTx wtx; |
|
|
|
CWalletTx wtx; |
|
|
|
SendMoneyToScript(pwallet, newScript, nullptr, |
|
|
|
SendMoneyToScript(pwallet, newScript, nullptr, |
|
|
|
NAME_LOCKED_AMOUNT, false, wtx, coinControl); |
|
|
|
KEVA_LOCKED_AMOUNT, false, wtx, coinControl); |
|
|
|
|
|
|
|
|
|
|
|
keyName.KeepKey(); |
|
|
|
keyName.KeepKey(); |
|
|
|
|
|
|
|
|
|
|
|
const std::string randStr = HexStr(rand); |
|
|
|
|
|
|
|
const std::string txid = wtx.GetHash().GetHex(); |
|
|
|
const std::string txid = wtx.GetHash().GetHex(); |
|
|
|
LogPrintf ("name_new: name=%s, rand=%s, tx=%s\n", |
|
|
|
LogPrintf("keva_namespace: namespace=%s, displayName=%s, tx=%s\n", |
|
|
|
nameStr.c_str(), randStr.c_str(), txid.c_str()); |
|
|
|
namespaceHash.ToString().c_str(), displayNameStr.c_str(), txid.c_str()); |
|
|
|
|
|
|
|
|
|
|
|
UniValue res(UniValue::VARR); |
|
|
|
UniValue res(UniValue::VARR); |
|
|
|
res.push_back(txid); |
|
|
|
res.push_back(txid); |
|
|
|
res.push_back(randStr); |
|
|
|
res.push_back(namespaceHash.ToString()); |
|
|
|
|
|
|
|
|
|
|
|
return res; |
|
|
|
return res; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************** */ |
|
|
|
/* ************************************************************************** */ |
|
|
|
|
|
|
|
#if 0 |
|
|
|
UniValue keva_namespace(const JSONRPCRequest& request) |
|
|
|
UniValue keva_namespace(const JSONRPCRequest& request) |
|
|
|
{ |
|
|
|
{ |
|
|
|
CWallet* const pwallet = GetWalletForJSONRPCRequest(request); |
|
|
|
CWallet* const pwallet = GetWalletForJSONRPCRequest(request); |
|
|
@ -123,20 +121,22 @@ UniValue keva_namespace(const JSONRPCRequest& request) |
|
|
|
|
|
|
|
|
|
|
|
ObserveSafeMode (); |
|
|
|
ObserveSafeMode (); |
|
|
|
|
|
|
|
|
|
|
|
const std::string displayName = request.params[0].get_str(); |
|
|
|
const valtype displayName = ValtypeFromString(request.params[0].get_str()); |
|
|
|
const valtype displayNameVal = ValtypeFromString(displayName); |
|
|
|
if (displayName.size() > MAX_NAMESPACE_LENGTH) { |
|
|
|
if (displayNameVal.size() > MAX_NAMESPACE_LENGTH) |
|
|
|
|
|
|
|
throw JSONRPCError (RPC_INVALID_PARAMETER, "the display name of the namespace is too long"); |
|
|
|
throw JSONRPCError (RPC_INVALID_PARAMETER, "the display name of the namespace is too long"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
/* Reject updates to a name for which the mempool already has
|
|
|
|
/* Reject updates to a name for which the mempool already has
|
|
|
|
a pending update. This is not a hard rule enforced by network |
|
|
|
a pending update. This is not a hard rule enforced by network |
|
|
|
rules, but it is necessary with the current mempool implementation. */ |
|
|
|
rules, but it is necessary with the current mempool implementation. */ |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK (mempool.cs); |
|
|
|
LOCK (mempool.cs); |
|
|
|
if (mempool.updatesName(name)) |
|
|
|
if (mempool.registersNamespace(name)) |
|
|
|
throw JSONRPCError (RPC_TRANSACTION_ERROR, |
|
|
|
throw JSONRPCError (RPC_TRANSACTION_ERROR, |
|
|
|
"there is already a pending update for this name"); |
|
|
|
"there is already a pending update for this name"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/* No more locking required, similarly to name_new. */ |
|
|
|
/* No more locking required, similarly to name_new. */ |
|
|
|
EnsureWalletIsUnlocked (pwallet); |
|
|
|
EnsureWalletIsUnlocked (pwallet); |
|
|
@ -148,36 +148,31 @@ UniValue keva_namespace(const JSONRPCRequest& request) |
|
|
|
bool usedKey = false; |
|
|
|
bool usedKey = false; |
|
|
|
|
|
|
|
|
|
|
|
CScript addrName; |
|
|
|
CScript addrName; |
|
|
|
if (request.params.size () == 3) |
|
|
|
if (request.params.size () == 3) { |
|
|
|
{ |
|
|
|
keyName.ReturnKey(); |
|
|
|
keyName.ReturnKey (); |
|
|
|
const CTxDestination dest = DecodeDestination (request.params[2].get_str ()); |
|
|
|
const CTxDestination dest |
|
|
|
if (!IsValidDestination (dest)) { |
|
|
|
= DecodeDestination (request.params[2].get_str ()); |
|
|
|
|
|
|
|
if (!IsValidDestination (dest)) |
|
|
|
|
|
|
|
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, "invalid address"); |
|
|
|
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, "invalid address"); |
|
|
|
|
|
|
|
|
|
|
|
addrName = GetScriptForDestination (dest); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
addrName = GetScriptForDestination(dest); |
|
|
|
{ |
|
|
|
} else { |
|
|
|
usedKey = true; |
|
|
|
usedKey = true; |
|
|
|
addrName = GetScriptForDestination (pubKeyReserve.GetID ()); |
|
|
|
addrName = GetScriptForDestination(pubKeyReserve.GetID ()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const CScript nameScript |
|
|
|
const CScript kevaScript = CKevaScript::buildKevaNamespace(addrName, name, displayName); |
|
|
|
= CNameScript::buildNameUpdate (addrName, name, value); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CCoinControl coinControl; |
|
|
|
CCoinControl coinControl; |
|
|
|
CWalletTx wtx; |
|
|
|
CWalletTx wtx; |
|
|
|
SendMoneyToScript (pwallet, nameScript, &txIn, |
|
|
|
SendMoneyToScript(pwallet, kevaScript, nullptr, KEVA_LOCKED_AMOUNT, false, wtx, coinControl); |
|
|
|
NAME_LOCKED_AMOUNT, false, wtx, coinControl); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (usedKey) |
|
|
|
if (usedKey) { |
|
|
|
keyName.KeepKey (); |
|
|
|
keyName.KeepKey (); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return wtx.GetHash ().GetHex (); |
|
|
|
return wtx.GetHash ().GetHex (); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
UniValue keva_put(const JSONRPCRequest& request) |
|
|
|
UniValue keva_put(const JSONRPCRequest& request) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -207,8 +202,8 @@ UniValue keva_put(const JSONRPCRequest& request) |
|
|
|
ObserveSafeMode (); |
|
|
|
ObserveSafeMode (); |
|
|
|
|
|
|
|
|
|
|
|
const std::string namespaceStr = request.params[0].get_str (); |
|
|
|
const std::string namespaceStr = request.params[0].get_str (); |
|
|
|
const valtype namespaceVal = ValtypeFromString (namespaceStr); |
|
|
|
const valtype nameSpace = ValtypeFromString (namespaceStr); |
|
|
|
if (namespaceVal.size () > MAX_NAMESPACE_LENGTH) |
|
|
|
if (nameSpace.size () > MAX_NAMESPACE_LENGTH) |
|
|
|
throw JSONRPCError (RPC_INVALID_PARAMETER, "the namespace is too long"); |
|
|
|
throw JSONRPCError (RPC_INVALID_PARAMETER, "the namespace is too long"); |
|
|
|
|
|
|
|
|
|
|
|
const std::string keyStr = request.params[1].get_str (); |
|
|
|
const std::string keyStr = request.params[1].get_str (); |
|
|
@ -231,18 +226,20 @@ UniValue keva_put(const JSONRPCRequest& request) |
|
|
|
rules, but it is necessary with the current mempool implementation. */ |
|
|
|
rules, but it is necessary with the current mempool implementation. */ |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK (mempool.cs); |
|
|
|
LOCK (mempool.cs); |
|
|
|
if (mempool.updatesName (name)) |
|
|
|
if (mempool.updatesKey(nameSpace, key)) { |
|
|
|
throw JSONRPCError (RPC_TRANSACTION_ERROR, |
|
|
|
throw JSONRPCError (RPC_TRANSACTION_ERROR, |
|
|
|
"there is already a pending update for this name"); |
|
|
|
"there is already a pending update for this name"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CNameData oldData; |
|
|
|
CKevaData oldData; |
|
|
|
{ |
|
|
|
{ |
|
|
|
LOCK (cs_main); |
|
|
|
LOCK (cs_main); |
|
|
|
if (!pcoinsTip->GetName (name, oldData) || oldData.isExpired ()) |
|
|
|
if (!pcoinsTip->HasNamespace(nameSpace)) { |
|
|
|
throw JSONRPCError (RPC_TRANSACTION_ERROR, |
|
|
|
throw JSONRPCError (RPC_TRANSACTION_ERROR, |
|
|
|
"this name can not be updated"); |
|
|
|
"this name can not be updated"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const COutPoint outp = oldData.getUpdateOutpoint (); |
|
|
|
const COutPoint outp = oldData.getUpdateOutpoint (); |
|
|
|
const CTxIn txIn(outp); |
|
|
|
const CTxIn txIn(outp); |
|
|
@ -275,12 +272,12 @@ UniValue keva_put(const JSONRPCRequest& request) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const CScript nameScript |
|
|
|
const CScript nameScript |
|
|
|
= CNameScript::buildNameUpdate (addrName, name, value); |
|
|
|
= CKevaScript::buildKevaPut(addrName, nameSpace, key, value); |
|
|
|
|
|
|
|
|
|
|
|
CCoinControl coinControl; |
|
|
|
CCoinControl coinControl; |
|
|
|
CWalletTx wtx; |
|
|
|
CWalletTx wtx; |
|
|
|
SendMoneyToScript (pwallet, nameScript, &txIn, |
|
|
|
SendMoneyToScript(pwallet, nameScript, &txIn, |
|
|
|
NAME_LOCKED_AMOUNT, false, wtx, coinControl); |
|
|
|
KEVA_LOCKED_AMOUNT, false, wtx, coinControl); |
|
|
|
|
|
|
|
|
|
|
|
if (usedKey) |
|
|
|
if (usedKey) |
|
|
|
keyName.KeepKey (); |
|
|
|
keyName.KeepKey (); |
|
|
|