Browse Source

Mostly-working Hush full node sans Verus!!!

Every line of Verus-specific code has been removed from the codebase.
This code compiles on Linux and can do a partial sync. A full sync
and other extensive tests need to be done before it's merged into
the duke branch.

BUGS:

One known bug is that the node starts to CPU mine by default, lol.
pull/43/head
Duke Leto 5 years ago
parent
commit
e87d029968
  1. 1
      src/Makefile.am
  2. 11
      src/cc/CCinclude.h
  3. 116
      src/cc/COptCCParams.cpp
  4. 1
      src/keystore.h
  5. 1
      src/main.cpp
  6. 1
      src/main.h
  7. 33
      src/miner.cpp
  8. 137
      src/script/script_ext.cpp
  9. 65
      src/script/script_ext.h
  10. 7
      src/wallet/rpcwallet.cpp
  11. 8
      src/wallet/wallet.cpp

1
src/Makefile.am

@ -457,7 +457,6 @@ libbitcoin_common_a_SOURCES = \
script/cc.cpp \
script/interpreter.cpp \
script/script.cpp \
script/script_ext.cpp \
script/script_error.cpp \
script/sign.cpp \
script/standard.cpp \

11
src/cc/CCinclude.h

@ -103,17 +103,6 @@ struct CC_utxo
int32_t vout;
};
// these are the parameters stored after Verus crypto-condition vouts. new versions may change
// the format
struct CC_meta
{
std::vector<unsigned char> version;
uint8_t evalCode;
bool is1of2;
uint8_t numDestinations;
// followed by address destinations
};
struct CCcontract_info
{
// this is for spending from 'unspendable' CC address

116
src/cc/COptCCParams.cpp

@ -1,116 +0,0 @@
/*Descriptson and examples of COptCCParams class found in:
script/standard.h/cpp
class COptCCParams
structure of data in vData payload attached to end of CCvout:
param
OP_1
param
OP_2 ... etc until OP_16
OP_PUSHDATA4 is the last OP code to tell things its at the end.
taken from standard.cpp line 22: COptCCParams::COptCCParams(std::vector<unsigned char> &vch)
EXAMPLE taken from Verus how to create scriptPubKey from COptCCParams class:
EXAMPLE taken from Verus how to decode scriptPubKey from COptCCParams class:
*/
bool MakeGuardedOutput(CAmount value, CPubKey &dest, CTransaction &stakeTx, CTxOut &vout)
{
CCcontract_info *cp, C;
cp = CCinit(&C,EVAL_STAKEGUARD);
CPubKey ccAddress = CPubKey(ParseHex(cp->CChexstr));
// return an output that is bound to the stake transaction and can be spent by presenting either a signed condition by the original
// destination address or a properly signed stake transaction of the same utxo on a fork
vout = MakeCC1of2vout(EVAL_STAKEGUARD, value, dest, ccAddress);
std::vector<CPubKey> vPubKeys = std::vector<CPubKey>();
vPubKeys.push_back(dest);
vPubKeys.push_back(ccAddress);
std::vector<std::vector<unsigned char>> vData = std::vector<std::vector<unsigned char>>();
CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
hw << stakeTx.vin[0].prevout.hash;
hw << stakeTx.vin[0].prevout.n;
uint256 utxo = hw.GetHash();
vData.push_back(std::vector<unsigned char>(utxo.begin(), utxo.end())); // Can we use any data here to construct vector?
CStakeParams p;
if (GetStakeParams(stakeTx, p))
{
// prev block hash and height is here to make validation easy
vData.push_back(std::vector<unsigned char>(p.prevHash.begin(), p.prevHash.end()));
std::vector<unsigned char> height = std::vector<unsigned char>(4);
for (int i = 0; i < 4; i++)
{
height[i] = (p.blkHeight >> (8 * i)) & 0xff;
}
vData.push_back(height);
COptCCParams ccp = COptCCParams(COptCCParams::VERSION, EVAL_STAKEGUARD, 1, 2, vPubKeys, vData);
vout.scriptPubKey << ccp.AsVector() << OP_DROP;
return true;
}
return false;
}
bool ValidateMatchingStake(const CTransaction &ccTx, uint32_t voutNum, const CTransaction &stakeTx, bool &cheating)
{
// an invalid or non-matching stake transaction cannot cheat
cheating = false;
//printf("ValidateMatchingStake: ccTx.vin[0].prevout.hash: %s, ccTx.vin[0].prevout.n: %d\n", ccTx.vin[0].prevout.hash.GetHex().c_str(), ccTx.vin[0].prevout.n);
if (ccTx.IsCoinBase())
{
CStakeParams p;
if (ValidateStakeTransaction(stakeTx, p))
{
std::vector<std::vector<unsigned char>> vParams = std::vector<std::vector<unsigned char>>();
CScript dummy;
if (ccTx.vout[voutNum].scriptPubKey.IsPayToCryptoCondition(&dummy, vParams) && vParams.size() > 0)
{
COptCCParams ccp = COptCCParams(vParams[0]);
if (ccp.IsValid() & ccp.vData.size() >= 3 && ccp.vData[2].size() <= 4)
{
CVerusHashWriter hw = CVerusHashWriter(SER_GETHASH, PROTOCOL_VERSION);
hw << stakeTx.vin[0].prevout.hash;
hw << stakeTx.vin[0].prevout.n;
uint256 utxo = hw.GetHash();
uint32_t height = 0;
int i, dataLen = ccp.vData[2].size();
for (i = dataLen - 1; i >= 0; i--)
{
height = (height << 8) + ccp.vData[2][i];
}
// for debugging strange issue
// printf("iterator: %d, height: %d, datalen: %d\n", i, height, dataLen);
if (utxo == uint256(ccp.vData[0]))
{
if (p.prevHash != uint256(ccp.vData[1]) && p.blkHeight >= height)
{
cheating = true;
return true;
}
// if block height is equal and we are at the else, prevHash must have been equal
else if (p.blkHeight == height)
{
return true;
}
}
}
}
}
}
return false;
}

1
src/keystore.h

@ -25,7 +25,6 @@
#include "pubkey.h"
#include "script/script.h"
#include "script/standard.h"
#include "script/script_ext.h"
#include "sync.h"
#include "zcash/Address.hpp"
#include "zcash/NoteEncryption.hpp"

1
src/main.cpp

@ -4122,7 +4122,6 @@ bool static DisconnectTip(CValidationState &state, bool fBare = false) {
for (int i = 0; i < block.vtx.size(); i++)
{
CTransaction &tx = block.vtx[i];
//if ((i == (block.vtx.size() - 1)) && ((ASSETCHAINS_LWMAPOS && block.IsVerusPOSBlock()) || (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block) != 0))))
if ((i == (block.vtx.size() - 1)) && (ASSETCHAINS_STAKED != 0 && (komodo_isPoS((CBlock *)&block,pindexDelete->GetHeight(),true) != 0)))
{
#ifdef ENABLE_WALLET

1
src/main.h

@ -37,7 +37,6 @@
#include "script/script.h"
#include "script/serverchecker.h"
#include "script/standard.h"
#include "script/script_ext.h"
#include "spentindex.h"
#include "sync.h"
#include "tinyformat.h"

33
src/miner.cpp

@ -691,31 +691,10 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
}
else if ( (uint64_t)(txNew.vout[0].nValue) >= ASSETCHAINS_TIMELOCKGTE)
{
int32_t opretlen, p2shlen, scriptlen;
CScriptExt opretScript = CScriptExt();
txNew.vout.resize(2);
// prepend time lock to original script unless original script is P2SH, in which case, we will leave the coins
// protected only by the time lock rather than 100% inaccessible
opretScript.AddCheckLockTimeVerify(komodo_block_unlocktime(nHeight));
if (scriptPubKeyIn.IsPayToScriptHash() || scriptPubKeyIn.IsPayToCryptoCondition())
{
fprintf(stderr,"CreateNewBlock: attempt to add timelock to pay2sh or pay2cc\n");
if ( ASSETCHAINS_SYMBOL[0] == 0 || (ASSETCHAINS_SYMBOL[0] != 0 && !isStake) )
{
LEAVE_CRITICAL_SECTION(cs_main);
LEAVE_CRITICAL_SECTION(mempool.cs);
}
return 0;
}
opretScript += scriptPubKeyIn;
txNew.vout[0].scriptPubKey = CScriptExt().PayToScriptHash(CScriptID(opretScript));
txNew.vout[1].scriptPubKey = CScriptExt().OpReturnScript(opretScript, OPRETTYPE_TIMELOCK);
txNew.vout[1].nValue = 0;
// timelocks and commissions are currently incompatible due to validation complexity of the combination
fprintf(stderr,"timelocked chains not supported in this code!\n");
LEAVE_CRITICAL_SECTION(cs_main);
LEAVE_CRITICAL_SECTION(mempool.cs);
return(0);
}
else if ( fNotarisationBlock && ASSETCHAINS_NOTARY_PAY[0] != 0 && pblock->vtx[1].vout.size() == 2 && pblock->vtx[1].vout[1].nValue == 0 )
{
@ -749,7 +728,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
pblock->vtx[0] = txNew;
pblocktemplate->vTxFees[0] = -nFees;
// if not Verus stake, setup nonce, otherwise, leave it alone
// if not staking, setup nonce, otherwise, leave it alone
if (!isStake || ASSETCHAINS_LWMAPOS == 0)
{
// Randomise nonce
@ -765,7 +744,7 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
pblock->hashPrevBlock = pindexPrev->GetBlockHash();
pblock->hashFinalSaplingRoot = sapling_tree.root();
// all Verus PoS chains need this data in the block at all times
// all PoS chains need this data in the block at all times
if ( ASSETCHAINS_LWMAPOS || ASSETCHAINS_SYMBOL[0] == 0 || ASSETCHAINS_STAKED == 0 || KOMODO_MININGTHREADS > 0 )
{
UpdateTime(pblock, Params().GetConsensus(), pindexPrev);

137
src/script/script_ext.cpp

@ -1,137 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Verus developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#include "script_ext.h"
using namespace std;
bool CScriptExt::IsPayToScriptHash(CScriptID *scriptID) const
{
if (((CScript *)this)->IsPayToScriptHash())
{
*scriptID = CScriptID(uint160(std::vector<unsigned char>(this->begin() + 2, this->end() - 1)));
return true;
}
return false;
}
// P2PKH script, adds to whatever is already in the script (for example CLTV)
const CScriptExt &CScriptExt::AddPayToPubKeyHash(const CKeyID &key) const
{
*((CScript *)this) << OP_DUP;
*((CScript *)this) << OP_HASH160;
*((CScript *)this) << ToByteVector(key);
*((CScript *)this) << OP_EQUALVERIFY;
*((CScript *)this) << OP_CHECKSIG;
return *this;
}
// push data into an op_return script with an opret type indicator, fails if the op_return is too large
const CScriptExt &CScriptExt::OpReturnScript(const vector<unsigned char> &data, unsigned char opretType) const
{
((CScript *)this)->clear();
if (data.size() < MAX_SCRIPT_ELEMENT_SIZE)
{
vector<unsigned char> scratch = vector<unsigned char>(data);
scratch.insert(scratch.begin(), opretType);
*((CScript *)this) << OP_RETURN;
*((CScript *)this) << scratch;
}
return *this;
}
// push data into an op_return script with an opret type indicator, fails if the op_return is too large
const CScriptExt &CScriptExt::OpReturnScript(const CScript &src, unsigned char opretType) const
{
vector<unsigned char> vch = vector<unsigned char>(src.begin(), src.end());
return OpReturnScript(vch, opretType);
}
// P2SH script, adds to whatever is already in the script (for example CLTV)
const CScriptExt &CScriptExt::PayToScriptHash(const CScriptID &scriptID) const
{
((CScript *)this)->clear();
*((CScript *)this) << OP_HASH160;
*((CScript *)this) << ToByteVector(scriptID);
*((CScript *)this) << OP_EQUAL;
return *this;
}
// P2SH script, adds to whatever is already in the script (for example CLTV)
const CScriptExt &CScriptExt::AddCheckLockTimeVerify(int64_t unlocktime) const
{
if (unlocktime > 0)
{
*((CScript *)this) << CScriptNum::serialize(unlocktime);
*((CScript *)this) << OP_CHECKLOCKTIMEVERIFY;
*((CScript *)this) << OP_DROP;
return *this;
}
return *this;
}
// combined CLTV script and P2PKH
const CScriptExt &CScriptExt::TimeLockSpend(const CKeyID &key, int64_t unlocktime) const
{
((CScript *)this)->clear();
this->AddCheckLockTimeVerify(unlocktime);
this->AddPayToPubKeyHash(key);
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.IsOpReturn())
{
opcodetype op;
std::vector<uint8_t> opretData = std::vector<uint8_t>();
CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
{
if (opretData.size() > 0 && opretData[0] == OPRETTYPE_TIMELOCK)
{
int64_t unlocktime;
CScriptExt se = CScriptExt(&opretData[1], &opretData[opretData.size()]);
if (CScriptID(se) == scriptHash &&
se.IsCheckLockTimeVerify(&unlocktime))
{
spk = se;
}
}
}
}
return ExtractDestination(spk, addressRet);
}

65
src/script/script_ext.h

@ -1,65 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2018 The Verus developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
/******************************************************************************
* Copyright © 2014-2019 The SuperNET Developers. *
* *
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* SuperNET software, including this file may be copied, modified, propagated *
* or distributed except according to the terms contained in the LICENSE file *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
#ifndef BITCOIN_SCRIPT_SCRIPT_EXT_H
#define BITCOIN_SCRIPT_SCRIPT_EXT_H
#include "script.h"
#include "standard.h"
#include "pubkey.h"
#include <vector>
class CScriptExt : public CScript
{
public:
CScriptExt() { }
CScriptExt(const CScript& b) : CScript(b) { }
CScriptExt(const_iterator pbegin, const_iterator pend) : CScript(pbegin, pend) { }
CScriptExt(const unsigned char* pbegin, const unsigned char* pend) : CScript(pbegin, pend) { }
// overload to return the hash of the referenced script
bool IsPayToScriptHash(CScriptID *scriptID) const;
// P2PKH script, adds to whatever is already in the script (for example CLTV)
const CScriptExt &AddPayToPubKeyHash(const CKeyID &key) const;
// push data into an op_return script with an opret type indicator, fails if the op_return is too large
const CScriptExt &OpReturnScript(const std::vector<unsigned char> &data, unsigned char opretType) const;
// push data into an op_return script with an opret type indicator, fails if the op_return is too large
const CScriptExt &OpReturnScript(const CScript &src, unsigned char opretType) const;
// P2SH script
const CScriptExt &PayToScriptHash(const CScriptID &scriptID) const;
// P2SH script, adds to whatever is already in the script (for example CLTV)
const CScriptExt &AddCheckLockTimeVerify(int64_t unlocktime) const;
// 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

7
src/wallet/rpcwallet.cpp

@ -1,5 +1,6 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -1858,11 +1859,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe
entry.push_back(Pair("involvesWatchonly", true));
entry.push_back(Pair("account", account));
CTxDestination dest;
if (CScriptExt::ExtractVoutDestination(wtx, r.vout, dest))
MaybePushAddress(entry, dest);
else
MaybePushAddress(entry, r.destination);
MaybePushAddress(entry, r.destination);
if (bIsCoinbase)
{

8
src/wallet/wallet.cpp

@ -1,5 +1,6 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Copyright (c) 2019 The Hush developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -2084,13 +2085,13 @@ bool CWallet::IsMine(const CTransaction& tx)
return false;
}
// special case handling for non-standard/Verus OP_RETURN script outputs, which need the transaction
// special case handling for non-standard OP_RETURN script outputs, which need the transaction
// to determine ownership
isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
{
vector<valtype> vSolutions;
txnouttype whichType;
const CScriptExt scriptPubKey = CScriptExt(tx.vout[voutNum].scriptPubKey);
const CScript scriptPubKey = CScript(tx.vout[voutNum].scriptPubKey);
if (!Solver(scriptPubKey, whichType, vSolutions)) {
if (this->HaveWatchOnly(scriptPubKey))
@ -2100,7 +2101,7 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
CKeyID keyID;
CScriptID scriptID;
CScriptExt subscript;
CScript subscript;
int voutNext = voutNum + 1;
switch (whichType)
@ -2134,6 +2135,7 @@ isminetype CWallet::IsMine(const CTransaction& tx, uint32_t voutNum)
case TX_SCRIPTHASH:
scriptID = CScriptID(uint160(vSolutions[0]));
//TODO: remove CLTV stuff not relevant to Hush
if (this->GetCScript(scriptID, subscript))
{
// if this is a CLTV, handle it differently

Loading…
Cancel
Save