restored nonstandard output on getrawtransaction

attempting to make index pointer problems more obvious


reverted strip in Solver


synced subtype
This commit is contained in:
Brannon King 2019-09-13 11:01:43 -06:00
parent 920a9b09dc
commit 4da4ab1995
15 changed files with 66 additions and 44 deletions

View file

@ -15,6 +15,7 @@
#include <util.h>
#include <utilmoneystr.h>
#include <utilstrencodings.h>
#include <nameclaim.h>
UniValue ValueFromAmount(const CAmount& amount)
{
@ -147,12 +148,20 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
out.pushKV("hex", HexStr(script.begin(), script.end()));
std::vector<std::vector<unsigned char>> solns;
txnouttype type;
Solver(script, type, solns);
out.pushKV("type", GetTxnOutputType(type));
txnouttype type; int claimOp;
auto stripped = StripClaimScriptPrefix(script, claimOp);
Solver(stripped, type, solns);
if (claimOp >= 0) {
out.pushKV("isclaim", UniValue(claimOp == OP_CLAIM_NAME || claimOp == OP_UPDATE_CLAIM));
out.pushKV("issupport", UniValue(claimOp == OP_SUPPORT_CLAIM));
out.pushKV("subtype", GetTxnOutputType(type));
out.pushKV("type", GetTxnOutputType(TX_NONSTANDARD)); // trying to keep backwards compatibility
}
else
out.pushKV("type", GetTxnOutputType(type)); // trying to keep backwards compatibility
CTxDestination address;
if (include_address && ExtractDestination(script, address)) {
if (include_address && ExtractDestination(stripped, address)) {
out.pushKV("address", EncodeDestination(address));
}
}
@ -168,19 +177,27 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
if (fIncludeHex)
out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) {
int claimOp;
auto stripped = StripClaimScriptPrefix(scriptPubKey, claimOp);
auto extracted = ExtractDestinations(stripped, type, addresses, nRequired);
if (claimOp >= 0) {
out.pushKV("isclaim", UniValue(claimOp == OP_CLAIM_NAME || claimOp == OP_UPDATE_CLAIM));
out.pushKV("issupport", UniValue(claimOp == OP_SUPPORT_CLAIM));
out.pushKV("subtype", GetTxnOutputType(type));
out.pushKV("type", GetTxnOutputType(TX_NONSTANDARD));
}
else
out.pushKV("type", GetTxnOutputType(type));
return;
}
out.pushKV("reqSigs", nRequired);
out.pushKV("type", GetTxnOutputType(type));
UniValue a(UniValue::VARR);
for (const CTxDestination& addr : addresses) {
a.push_back(EncodeDestination(addr));
if (extracted) {
out.pushKV("reqSigs", nRequired);
UniValue a(UniValue::VARR);
for (const CTxDestination &addr : addresses) {
a.push_back(EncodeDestination(addr));
}
out.pushKV("addresses", a);
}
out.pushKV("addresses", a);
}
void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry, bool include_hex, int serialize_flags)

View file

@ -193,6 +193,7 @@ bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync)
if (log_memory) {
mem_before = DynamicMemoryUsage() / 1024.0 / 1024;
}
assert(pdb);
leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
dbwrapper_private::HandleError(status);
if (log_memory) {

View file

@ -151,7 +151,7 @@ public:
* with a zero'd byte array.
*/
CDBWrapper(const fs::path& path, size_t nCacheSize, bool fMemory = false, bool fWipe = false, bool obfuscate = false);
~CDBWrapper();
virtual ~CDBWrapper();
CDBWrapper(const CDBWrapper&) = delete;
/* CDBWrapper& operator=(const CDBWrapper&) = delete; */
@ -159,6 +159,7 @@ public:
template <typename K, typename V>
bool Read(const K& key, V& value) const
{
assert(ssKey.empty());
ssKey << key;
leveldb::Slice slKey(ssKey.data(), ssKey.size());

View file

@ -28,6 +28,8 @@ protected:
DB(const fs::path& path, size_t n_cache_size,
bool f_memory = false, bool f_wipe = false, bool f_obfuscate = false);
~DB() override {}
/// Read block locator of the chain that the txindex is in sync with.
bool ReadBestBlock(CBlockLocator& locator) const;

View file

@ -29,6 +29,7 @@ class TxIndex::DB : public BaseIndex::DB
{
public:
explicit DB(size_t n_cache_size, bool f_memory = false, bool f_wipe = false);
~DB() override {}
/// Read the disk location of the transaction data with the given hash. Returns false if the
/// transaction hash is not indexed.

View file

@ -115,7 +115,7 @@ bool IsStandardTx(const CTransaction& tx, std::string& reason)
unsigned int nDataOut = 0;
txnouttype whichType;
for (const CTxOut& txout : tx.vout) {
if (!::IsStandard(txout.scriptPubKey, whichType)) {
if (!::IsStandard(StripClaimScriptPrefix(txout.scriptPubKey), whichType)) {
reason = "scriptpubkey";
return false;
}

View file

@ -45,7 +45,7 @@ static const unsigned int MAX_STANDARD_P2WSH_SCRIPT_SIZE = 3600;
* standard and should be done with care and ideally rarely. It makes sense to
* only increase the dust limit after prior releases were already not creating
* outputs below the new threshold */
static const unsigned int DUST_RELAY_TX_FEE = 3000;
static const unsigned int DUST_RELAY_TX_FEE = 1000;
/**
* Standard script verification flags that standard transactions will comply
* with. However scripts violating these flags may still be present in valid

View file

@ -111,7 +111,7 @@ std::string escapeNonUtf8(const std::string& name)
static bool extractValue(const CScript& scriptPubKey, std::string& sValue)
{
int op;
std::vector<std::vector<unsigned char> > vvchParams;
std::vector<std::vector<unsigned char>> vvchParams;
if (!DecodeClaimScript(scriptPubKey, op, vvchParams))
return false;

View file

@ -549,14 +549,15 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
" ],\n"
" \"vout\" : [ (array of json objects)\n"
" {\n"
" \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
" \"n\" : n, (numeric) index\n"
" \"scriptPubKey\" : { (json object)\n"
" \"asm\" : \"asm\", (string) the asm\n"
" \"hex\" : \"hex\", (string) the hex\n"
" \"reqSigs\" : n, (numeric) The required sigs\n"
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
" \"addresses\" : [ (json array of string)\n"
" \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n"
" \"n\" : n, (numeric) index\n"
" \"scriptPubKey\" : { (json object)\n"
" \"asm\" : \"asm\", (string) the asm\n"
" \"hex\" : \"hex\", (string) the hex\n"
" \"reqSigs\" : n, (numeric) The required sigs\n"
" \"subtype\" : \"pubkeyhash\", (numeric) For claims and supports, this represents the type of suffix\n"
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n"
" \"addresses\" : [ (json array of string)\n"
" \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) lbry address\n"
" ,...\n"
" ]\n"

View file

@ -6,6 +6,7 @@
#include <script/sign.h>
#include <key.h>
#include <nameclaim.h>
#include <policy/policy.h>
#include <primitives/transaction.h>
#include <script/standard.h>
@ -183,7 +184,7 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
std::vector<valtype> result;
txnouttype whichType;
bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata);
bool solved = SignStep(provider, creator, StripClaimScriptPrefix(fromPubKey), result, whichType, SigVersion::BASE, sigdata);
bool P2SH = false;
CScript subscript;
sigdata.scriptWitness.stack.clear();
@ -349,7 +350,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
// Get scripts
txnouttype script_type;
std::vector<std::vector<unsigned char>> solutions;
Solver(txout.scriptPubKey, script_type, solutions);
Solver(StripClaimScriptPrefix(txout.scriptPubKey), script_type, solutions);
SigVersion sigversion = SigVersion::BASE;
CScript next_script = txout.scriptPubKey;

View file

@ -91,21 +91,19 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
{
vSolutionsRet.clear();
auto strippedPubKey = StripClaimScriptPrefix(scriptPubKey);
// Shortcut for pay-to-script-hash, which are more constrained than the other types:
// it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
if (strippedPubKey.IsPayToScriptHash())
if (scriptPubKey.IsPayToScriptHash())
{
typeRet = TX_SCRIPTHASH;
std::vector<unsigned char> hashBytes(strippedPubKey.begin()+2, strippedPubKey.begin()+22);
std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
vSolutionsRet.push_back(hashBytes);
return true;
}
int witnessversion;
std::vector<unsigned char> witnessprogram;
if (strippedPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
typeRet = TX_WITNESS_V0_KEYHASH;
vSolutionsRet.push_back(witnessprogram);
@ -131,19 +129,19 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
// So long as script passes the IsUnspendable() test and all but the first
// byte passes the IsPushOnly() test we don't care what exactly is in the
// script.
if (strippedPubKey.size() >= 1 && strippedPubKey[0] == OP_RETURN && strippedPubKey.IsPushOnly(strippedPubKey.begin()+1)) {
if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
typeRet = TX_NULL_DATA;
return true;
}
std::vector<unsigned char> data;
if (MatchPayToPubkey(strippedPubKey, data)) {
if (MatchPayToPubkey(scriptPubKey, data)) {
typeRet = TX_PUBKEY;
vSolutionsRet.push_back(std::move(data));
return true;
}
if (MatchPayToPubkeyHash(strippedPubKey, data)) {
if (MatchPayToPubkeyHash(scriptPubKey, data)) {
typeRet = TX_PUBKEYHASH;
vSolutionsRet.push_back(std::move(data));
return true;
@ -151,7 +149,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::v
unsigned int required;
std::vector<std::vector<unsigned char>> keys;
if (MatchMultisig(strippedPubKey, required, keys)) {
if (MatchMultisig(scriptPubKey, required, keys)) {
typeRet = TX_MULTISIG;
vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16
vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
@ -168,7 +166,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
{
std::vector<valtype> vSolutions;
txnouttype whichType;
if (!Solver(scriptPubKey, whichType, vSolutions))
if (!Solver(StripClaimScriptPrefix(scriptPubKey), whichType, vSolutions))
return false;
if (whichType == TX_PUBKEY)
@ -216,9 +214,8 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::
addressRet.clear();
typeRet = TX_NONSTANDARD;
std::vector<valtype> vSolutions;
if (!Solver(scriptPubKey, typeRet, vSolutions))
return false;
if (typeRet == TX_NULL_DATA){
auto solved = Solver(scriptPubKey, typeRet, vSolutions);
if (!solved || typeRet == TX_NULL_DATA){
// This is data, not addresses
return false;
}

View file

@ -224,6 +224,7 @@ CMutableTransaction ClaimTrieChainFixture::MakeSupport(const CTransaction &prev,
uint32_t prevout = prev.vout.size() - 1;
while (prevout > 0 && prev.vout[prevout].nValue < quantity)
--prevout;
CMutableTransaction tx = BuildTransaction(prev, prevout, prev.vout[prevout].nValue > quantity ? 2 : 1);
tx.vout[0].scriptPubKey = SupportClaimScript(name, ClaimIdHash(claimtx.GetHash(), 0));
tx.vout[0].nValue = quantity;

View file

@ -701,7 +701,7 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
// Check dust with default relay fee:
CAmount nDustThreshold = 182 * dustRelayFee.GetFeePerK()/1000;
BOOST_CHECK_EQUAL(nDustThreshold, 546);
BOOST_CHECK_EQUAL(nDustThreshold, 182);
// dust:
t.vout[0].nValue = nDustThreshold - 1;
BOOST_CHECK(!IsStandardTx(t, reason));

View file

@ -918,7 +918,7 @@ UniValue supportclaim(const JSONRPCRequest& request)
CClaimTrieCache trieCache(pclaimTrie);
auto csToName = trieCache.getClaimsForName(sName);
if (csToName.claimsNsupports.empty())
return NullUniValue;
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unable to find a claim named %s", sName));
auto& claimNsupports = !sClaimId.empty() ? csToName.find(sClaimId) : csToName.claimsNsupports[0];
if (claimNsupports.IsNull())
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unable to find a claimid that starts with %s", sClaimId));

View file

@ -166,7 +166,7 @@ public:
txnouttype type;
std::vector<CTxDestination> vDest;
int nRequired;
if (ExtractDestinations(script, type, vDest, nRequired)) {
if (ExtractDestinations(StripClaimScriptPrefix(script), type, vDest, nRequired)) {
for (const CTxDestination &dest : vDest)
boost::apply_visitor(*this, dest);
}