Browse Source

Fixed KEVA_PUT checking.

cn
Jianping Wu 6 years ago
parent
commit
d3e92247d7
  1. 46
      src/keva/main.cpp

46
src/keva/main.cpp

@ -384,11 +384,11 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
if (nameOpOut.getNameOp () == OP_NAME_NEW) if (nameOpOut.getNameOp () == OP_NAME_NEW)
{ {
if (nameIn != -1) if (nameIn != -1)
return state.Invalid (error ("CheckNameTransaction: NAME_NEW with" return state.Invalid (error ("CheckKevaTransaction: NAME_NEW with"
" previous name input")); " previous name input"));
if (nameOpOut.getOpHash ().size () != 20) if (nameOpOut.getOpHash ().size () != 20)
return state.Invalid (error ("CheckNameTransaction: NAME_NEW's hash" return state.Invalid (error ("CheckKevaTransaction: NAME_NEW's hash"
" has wrong size")); " has wrong size"));
return true; return true;
@ -400,31 +400,30 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
if (nameOpOut.isNamespaceRegistration()) { if (nameOpOut.isNamespaceRegistration()) {
if (nameOpOut.getOpNamespaceDisplayName().size () > MAX_VALUE_LENGTH) { if (nameOpOut.getOpNamespaceDisplayName().size () > MAX_VALUE_LENGTH) {
return state.Invalid (error ("CheckNameTransaction: display name value too long")); return state.Invalid (error ("CheckKevaTransaction: display name value too long"));
} }
return true; return true;
} }
assert (nameOpOut.isAnyUpdate()); assert (nameOpOut.isAnyUpdate());
if (nameIn == -1) { if (nameIn == -1) {
return state.Invalid(error("CheckNameTransaction: update without previous keva input")); return state.Invalid(error("CheckKevaTransaction: update without previous keva input"));
} }
const valtype& key = nameOpOut.getOpKey(); const valtype& key = nameOpOut.getOpKey();
if (key.size() > MAX_KEY_LENGTH) { if (key.size() > MAX_KEY_LENGTH) {
return state.Invalid (error ("CheckNameTransaction: key too long")); return state.Invalid (error ("CheckKevaTransaction: key too long"));
} }
if (nameOpOut.getOpValue().size () > MAX_VALUE_LENGTH) { if (nameOpOut.getOpValue().size () > MAX_VALUE_LENGTH) {
return state.Invalid (error ("CheckNameTransaction: value too long")); return state.Invalid (error ("CheckKevaTransaction: value too long"));
} }
/* Process KEVA_PUT next. */ /* Process KEVA_PUT next. */
const valtype& nameSpace = nameOpOut.getOpNamespace(); const valtype& nameSpace = nameOpOut.getOpNamespace();
if (nameOpOut.getKevaOp() == OP_KEVA_PUT) { if (nameOpOut.getKevaOp() == OP_KEVA_PUT) {
if (!nameOpIn.isAnyUpdate ()) { if (!nameOpIn.isAnyUpdate() && !nameOpIn.isNamespaceRegistration()) {
return state.Invalid(error("CheckNameTransaction: KEVA_PUT with" return state.Invalid(error("CheckKevaTransaction: KEVA_PUT with prev input that is no update"));
" prev input that is no update"));
} }
if (nameSpace != nameOpIn.getOpNamespace()) { if (nameSpace != nameOpIn.getOpNamespace()) {
@ -432,6 +431,21 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
" found in %s", __func__, txid)); " found in %s", __func__, txid));
} }
CKevaData oldName;
const valtype& namespaceIn = nameOpIn.getOpNamespace();
if (nameOpIn.isNamespaceRegistration()) {
if (!view.GetNamespace(namespaceIn, oldName)) {
return state.Invalid (error ("%s: KEVA_PUT name does not exist in namespace registration", __func__));
}
} else if (nameOpIn.isAnyUpdate()) {
const valtype& keyIn = nameOpIn.getOpKey();
if (!view.GetName(namespaceIn, keyIn, oldName)) {
return state.Invalid (error ("%s: KEVA_PUT name does not exist", __func__));
}
}
assert (tx.vin[nameIn].prevout == oldName.getUpdateOutpoint());
#if 0
/* This is actually redundant, since expired names are removed /* This is actually redundant, since expired names are removed
from the UTXO set and thus not available to be spent anyway. from the UTXO set and thus not available to be spent anyway.
But it does not hurt to enforce this here, too. It is also But it does not hurt to enforce this here, too. It is also
@ -443,17 +457,15 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
return state.Invalid (error ("%s: KEVA_PUT name does not exist", return state.Invalid (error ("%s: KEVA_PUT name does not exist",
__func__)); __func__));
} }
#if 0
if (oldName.isExpired (nHeight)) if (oldName.isExpired (nHeight))
return state.Invalid (error ("%s: trying to update expired name", return state.Invalid (error ("%s: trying to update expired name",
__func__)); __func__));
#endif
/* This is an internal consistency check. If everything is fine, /* This is an internal consistency check. If everything is fine,
the input coins from the UTXO database should match the the input coins from the UTXO database should match the
name database. */ name database. */
assert (static_cast<unsigned> (coinIn.nHeight) == oldName.getHeight()); assert (static_cast<unsigned> (coinIn.nHeight) == oldName.getHeight());
assert (tx.vin[nameIn].prevout == oldName.getUpdateOutpoint()); assert (tx.vin[nameIn].prevout == oldName.getUpdateOutpoint());
#endif
return true; return true;
} }
@ -462,7 +474,7 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
assert(nameOpOut.getNameOp () == OP_NAME_FIRSTUPDATE); assert(nameOpOut.getNameOp () == OP_NAME_FIRSTUPDATE);
if (nameOpIn.getNameOp () != OP_NAME_NEW) if (nameOpIn.getNameOp () != OP_NAME_NEW)
return state.Invalid (error ("CheckNameTransaction: NAME_FIRSTUPDATE" return state.Invalid (error ("CheckKevaTransaction: NAME_FIRSTUPDATE"
" with non-NAME_NEW prev tx")); " with non-NAME_NEW prev tx"));
/* Maturity of NAME_NEW is checked only if we're not adding /* Maturity of NAME_NEW is checked only if we're not adding
@ -471,12 +483,12 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
{ {
assert (static_cast<unsigned> (coinIn.nHeight) != MEMPOOL_HEIGHT); assert (static_cast<unsigned> (coinIn.nHeight) != MEMPOOL_HEIGHT);
if (coinIn.nHeight + MIN_FIRSTUPDATE_DEPTH > nHeight) if (coinIn.nHeight + MIN_FIRSTUPDATE_DEPTH > nHeight)
return state.Invalid (error ("CheckNameTransaction: NAME_NEW" return state.Invalid (error ("CheckKevaTransaction: NAME_NEW"
" is not mature for FIRST_UPDATE")); " is not mature for FIRST_UPDATE"));
} }
if (nameOpOut.getOpRand ().size () > 20) if (nameOpOut.getOpRand ().size () > 20)
return state.Invalid (error ("CheckNameTransaction: NAME_FIRSTUPDATE" return state.Invalid (error ("CheckKevaTransaction: NAME_FIRSTUPDATE"
" rand too large, %d bytes", " rand too large, %d bytes",
nameOpOut.getOpRand ().size ())); nameOpOut.getOpRand ().size ()));
@ -485,13 +497,13 @@ CheckKevaTransaction (const CTransaction& tx, unsigned nHeight,
toHash.insert (toHash.end (), name.begin (), name.end ()); toHash.insert (toHash.end (), name.begin (), name.end ());
const uint160 hash = Hash160 (toHash); const uint160 hash = Hash160 (toHash);
if (hash != uint160 (nameOpIn.getOpHash ())) if (hash != uint160 (nameOpIn.getOpHash ()))
return state.Invalid (error ("CheckNameTransaction: NAME_FIRSTUPDATE" return state.Invalid (error ("CheckKevaTransaction: NAME_FIRSTUPDATE"
" hash mismatch")); " hash mismatch"));
} }
CNameData oldName; CNameData oldName;
if (view.GetName (name, oldName) && !oldName.isExpired (nHeight)) if (view.GetName (name, oldName) && !oldName.isExpired (nHeight))
return state.Invalid (error ("CheckNameTransaction: NAME_FIRSTUPDATE" return state.Invalid (error ("CheckKevaTransaction: NAME_FIRSTUPDATE"
" on an unexpired name")); " on an unexpired name"));
/* We don't have to specifically check that miners don't create blocks with /* We don't have to specifically check that miners don't create blocks with

Loading…
Cancel
Save