restored nonstandard output on getrawtransaction
attempting to make index pointer problems more obvious reverted strip in Solver synced subtype
This commit is contained in:
parent
920a9b09dc
commit
4da4ab1995
15 changed files with 66 additions and 44 deletions
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue