diff --git a/src/komodo_bitcoind.h b/src/komodo_bitcoind.h index e87bf3727..2fb4b74c1 100644 --- a/src/komodo_bitcoind.h +++ b/src/komodo_bitcoind.h @@ -1325,12 +1325,12 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height) } else if ( ExtractDestination(pblock->vtx[txn_count-1].vout[0].scriptPubKey, voutaddress) && ExtractDestination(tx.vout[voutNum].scriptPubKey, destaddress) && - ExtractDestination(tx.vout[voutNum].scriptPubKey, cbaddress) ) + CScriptExt::ExtractVoutDestination(pblock->vtx[0], 0, cbaddress) ) { strcpy(voutaddr, CBitcoinAddress(voutaddress).ToString().c_str()); strcpy(destaddr, CBitcoinAddress(destaddress).ToString().c_str()); strcpy(cbaddr, CBitcoinAddress(cbaddress).ToString().c_str()); - if ( !strcmp(destaddr,voutaddr) && ( !strcmp(destaddr,cbaddr) || (height < 12800)) ) + if ( !strcmp(destaddr,voutaddr) && ( !strcmp(destaddr,cbaddr) || (height < 17840)) ) { isPOS = true; } diff --git a/src/script/script_ext.cpp b/src/script/script_ext.cpp index 8c74426a6..a43036556 100644 --- a/src/script/script_ext.cpp +++ b/src/script/script_ext.cpp @@ -74,3 +74,42 @@ const CScriptExt &CScriptExt::TimeLockSpend(const CKeyID &key, int64_t unlocktim return *this; } +/** + * provide destination extraction for non-standard, timelocked coinbase transactions + * as well as other transactions + */ +bool CScriptExt::ExtractVoutDestination(const CTransaction& tx, int32_t voutNum, CTxDestination& addressRet) +{ + if (tx.vout.size() <= voutNum) + return false; + + CScriptID scriptHash; + CScriptExt spk = tx.vout[voutNum].scriptPubKey; + + // if this is a timelocked transaction, get the destination behind the time lock + if (tx.IsCoinBase() && tx.vout.size() == 2 && voutNum == 0 && + spk.IsPayToScriptHash(&scriptHash) && + tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds + tx.vout[1].scriptPubKey.data()[0] == OP_RETURN) + { + opcodetype op; + std::vector opretData = std::vector(); + CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1; + if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData)) + { + if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK) + { + int64_t unlocktime; + CScriptExt se = CScriptExt(opretData.begin() + 1, opretData.end()); + + if (CScriptID(se) == scriptHash && + se.IsCheckLockTimeVerify(&unlocktime)) + { + spk = se; + } + } + } + } + return ExtractDestination(spk, addressRet); +} + diff --git a/src/script/script_ext.h b/src/script/script_ext.h index a42616669..738ffdd09 100644 --- a/src/script/script_ext.h +++ b/src/script/script_ext.h @@ -36,6 +36,9 @@ class CScriptExt : public CScript // combined CLTV script and P2PKH const CScriptExt &TimeLockSpend(const CKeyID &key, int64_t unlocktime) const; + + // lookup for destinations that includes non-standard destinations for time locked coinbases + static bool ExtractVoutDestination(const CTransaction& tx, int32_t voutNum, CTxDestination& addressRet); }; #endif diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 49ea9270d..029730cb3 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1606,7 +1606,13 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", account)); - MaybePushAddress(entry, r.destination); + + CTxDestination dest; + if (CScriptExt::ExtractVoutDestination(wtx, r.vout, dest)) + MaybePushAddress(entry, dest); + else + MaybePushAddress(entry, r.destination); + if (wtx.IsCoinBase()) { int btm;