Skip to content

Commit

Permalink
Merge pull request #532 from syscoin/dev-4.x-spt-clean
Browse files Browse the repository at this point in the history
wip spt clean
  • Loading branch information
sidhujag committed Aug 17, 2023
2 parents c8a24cd + 63855de commit dbb4f66
Show file tree
Hide file tree
Showing 64 changed files with 979 additions and 7,664 deletions.
20 changes: 11 additions & 9 deletions src/Makefile.am
Expand Up @@ -127,9 +127,8 @@ endif
# syscoin core #
SYSCOIN_CORE_H = \
addresstype.h \
services/asset.h \
services/assetconsensus.h \
services/rpc/assetrpc.h \
services/nevmconsensus.h \
services/rpc/nevmrpc.h \
spork.h \
dsnotificationinterface.h \
governance/governance.h \
Expand Down Expand Up @@ -186,6 +185,7 @@ SYSCOIN_CORE_H = \
compat/compat.h \
compat/cpuid.h \
compat/endian.h \
compressor.h \
common/settings.h \
common/system.h \
node/connection_types.h \
Expand Down Expand Up @@ -464,9 +464,8 @@ libsyscoin_util_a-clientversion.$(OBJEXT): obj/build.h
libsyscoin_node_a_CPPFLAGS = $(AM_CPPFLAGS) $(SYSCOIN_INCLUDES) $(LEVELDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(MINIUPNPC_CPPFLAGS) $(NATPMP_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS)
libsyscoin_node_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libsyscoin_node_a_SOURCES = \
services/asset.cpp \
services/assetconsensus.cpp \
services/rpc/assetrpc.cpp \
services/nevmconsensus.cpp \
services/rpc/nevmrpc.cpp \
core_write.cpp \
dsnotificationinterface.cpp \
governance/governance.cpp \
Expand Down Expand Up @@ -658,7 +657,7 @@ libsyscoin_wallet_a_SOURCES = \
rpc/rpcevo.cpp \
rpc/masternode.cpp \
rpc/auxpow_miner.cpp \
services/rpc/wallet/assetwalletrpc.cpp \
services/rpc/wallet/nevmwalletrpc.cpp \
wallet/rpcevo.cpp \
wallet/rpcgovernance.cpp \
wallet/rpcmasternode.cpp \
Expand Down Expand Up @@ -807,8 +806,7 @@ libsyscoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(SYSCOIN_INCLUDES) $(LEVELDB_CPPF
libsyscoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libsyscoin_common_a_SOURCES = \
addresstype.cpp \
services/asset.cpp \
services/assetconsensus.cpp \
services/nevmconsensus.cpp \
auxpow.cpp \
base58.cpp \
bech32.cpp \
Expand All @@ -820,6 +818,7 @@ libsyscoin_common_a_SOURCES = \
common/init.cpp \
common/interfaces.cpp \
common/run_command.cpp \
compressor.cpp \
common/settings.cpp \
common/system.cpp \
core_read.cpp \
Expand Down Expand Up @@ -1079,6 +1078,9 @@ libsyscoinkernel_la_SOURCES = \
chain.cpp \
clientversion.cpp \
coins.cpp \
common/args.cpp \
common/config.cpp \
compressor.cpp \
consensus/merkle.cpp \
consensus/tx_check.cpp \
consensus/tx_verify.cpp \
Expand Down
1 change: 0 additions & 1 deletion src/Makefile.test.include
Expand Up @@ -26,7 +26,6 @@ JSON_TEST_FILES = \
test/data/tx_invalid.json \
test/data/tx_valid.json \
test/data/utxo.json \
test/data/assetbalances.json \
test/data/nevmspv_valid.json \
test/data/nevmspv_invalid.json \
test/data/tx_valid.json
Expand Down
6 changes: 3 additions & 3 deletions src/addresstype.h
Expand Up @@ -2,8 +2,8 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or https://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_ADDRESSTYPE_H
#define BITCOIN_ADDRESSTYPE_H
#ifndef SYSCOIN_ADDRESSTYPE_H
#define SYSCOIN_ADDRESSTYPE_H

#include <pubkey.h>
#include <script/script.h>
Expand Down Expand Up @@ -118,4 +118,4 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
*/
CScript GetScriptForDestination(const CTxDestination& dest);

#endif // BITCOIN_ADDRESSTYPE_H
#endif // SYSCOIN_ADDRESSTYPE_H
1 change: 1 addition & 0 deletions src/coins.h
Expand Up @@ -6,6 +6,7 @@
#ifndef SYSCOIN_COINS_H
#define SYSCOIN_COINS_H

#include <compressor.h>
#include <primitives/transaction.h>
#include <core_memusage.h>
#include <memusage.h>
Expand Down
2 changes: 1 addition & 1 deletion src/compressor.cpp
Expand Up @@ -189,4 +189,4 @@ uint64_t DecompressAmount(uint64_t x)
e--;
}
return n;
}
}
118 changes: 118 additions & 0 deletions src/compressor.h
@@ -0,0 +1,118 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef SYSCOIN_COMPRESSOR_H
#define SYSCOIN_COMPRESSOR_H

#include <prevector.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <serialize.h>
#include <span.h>

/**
* This saves us from making many heap allocations when serializing
* and deserializing compressed scripts.
*
* This prevector size is determined by the largest .resize() in the
* CompressScript function. The largest compressed script format is a
* compressed public key, which is 33 bytes.
*/
using CompressedScript = prevector<33, unsigned char>;


bool CompressScript(const CScript& script, CompressedScript& out);
unsigned int GetSpecialScriptSize(unsigned int nSize);
bool DecompressScript(CScript& script, unsigned int nSize, const CompressedScript& in);

/**
* Compress amount.
*
* nAmount is of type uint64_t and thus cannot be negative. If you're passing in
* a CAmount (int64_t), make sure to properly handle the case where the amount
* is negative before calling CompressAmount(...).
*
* @pre Function defined only for 0 <= nAmount <= MAX_MONEY.
*/
uint64_t CompressAmount(uint64_t nAmount);

uint64_t DecompressAmount(uint64_t nAmount);

/** Compact serializer for scripts.
*
* It detects common cases and encodes them much more efficiently.
* 3 special cases are defined:
* * Pay to pubkey hash (encoded as 21 bytes)
* * Pay to script hash (encoded as 21 bytes)
* * Pay to pubkey starting with 0x02, 0x03 or 0x04 (encoded as 33 bytes)
*
* Other scripts up to 121 bytes require 1 byte + script length. Above
* that, scripts up to 16505 bytes require 2 bytes + script length.
*/
struct ScriptCompression
{
/**
* make this static for now (there are only 6 special scripts defined)
* this can potentially be extended together with a new nVersion for
* transactions, in which case this value becomes dependent on nVersion
* and nHeight of the enclosing transaction.
*/
static const unsigned int nSpecialScripts = 6;

template<typename Stream>
void Ser(Stream &s, const CScript& script) {
CompressedScript compr;
if (CompressScript(script, compr)) {
s << Span{compr};
return;
}
unsigned int nSize = script.size() + nSpecialScripts;
s << VARINT(nSize);
s << Span{script};
}

template<typename Stream>
void Unser(Stream &s, CScript& script) {
unsigned int nSize = 0;
s >> VARINT(nSize);
if (nSize < nSpecialScripts) {
CompressedScript vch(GetSpecialScriptSize(nSize), 0x00);
s >> Span{vch};
DecompressScript(script, nSize, vch);
return;
}
nSize -= nSpecialScripts;
if (nSize > MAX_SCRIPT_SIZE) {
// Overly long script, replace with a short invalid one
script << OP_RETURN;
s.ignore(nSize);
} else {
script.resize(nSize);
s >> Span{script};
}
}
};

struct AmountCompression
{
template<typename Stream, typename I> void Ser(Stream& s, I val)
{
s << VARINT(CompressAmount(val));
}
template<typename Stream, typename I> void Unser(Stream& s, I& val)
{
uint64_t v;
s >> VARINT(v);
val = DecompressAmount(v);
}
};

/** wrapper for CTxOut that provides a more compact serialization */
struct TxOutCompression
{
FORMATTER_METHODS(CTxOut, obj) { READWRITE(Using<AmountCompression>(obj.nValue), Using<ScriptCompression>(obj.scriptPubKey)); }
};

#endif // SYSCOIN_COMPRESSOR_H
26 changes: 0 additions & 26 deletions src/consensus/amount.h
Expand Up @@ -5,9 +5,6 @@

#ifndef SYSCOIN_CONSENSUS_AMOUNT_H
#define SYSCOIN_CONSENSUS_AMOUNT_H
// SYSCOIN
#include <unordered_map>
#include <unordered_set>
#include <cstdint>

/** Amount in satoshis (Can be negative) */
Expand All @@ -26,28 +23,5 @@ static constexpr CAmount COIN = 100000000;
* for the creation of coins out of thin air modification could lead to a fork.
* */
static const CAmount MAX_MONEY = 1000000000000000000LL - 1LL;
// SYSCOIN
static const CAmount MAX_ASSET = 1000000000000000000LL - 1LL; // 10^18 - 1 max decimal value that will fit in CAmount
static const CAmount COST_ASSET = COIN;
inline bool MoneyRange(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }
inline bool MoneyRangeAsset(const CAmount& nValue) { return (nValue >= 0 && nValue <= MAX_ASSET); }
struct AssetMapOutput {
bool bZeroVal;
// satoshi amount of all outputs
CAmount nAmount;
AssetMapOutput(const bool &bZeroValIn, const CAmount &nAmountIn): bZeroVal(bZeroValIn), nAmount(nAmountIn) {}
// this is consensus critical, it will ensure input assets and output assets are equal
friend bool operator==(const AssetMapOutput& a, const AssetMapOutput& b)
{
return (a.bZeroVal == b.bZeroVal &&
a.nAmount == b.nAmount);
}

friend bool operator!=(const AssetMapOutput& a, const AssetMapOutput& b)
{
return !(a == b);
}
};
typedef std::unordered_map<uint64_t, AssetMapOutput> CAssetsMap;
typedef std::unordered_set<uint64_t> CAssetsSet;
#endif // SYSCOIN_CONSENSUS_AMOUNT_H
2 changes: 1 addition & 1 deletion src/consensus/params.h
Expand Up @@ -151,7 +151,6 @@ struct LLMQParams {
struct Params {
uint256 hashGenesisBlock;
// SYSCOIN
uint64_t nSYSXAsset;
uint32_t nNEVMChainID;
std::vector<unsigned char> vchSYSXBurnMethodSignature;
std::vector<unsigned char> vchSYSXERC20Manager;
Expand All @@ -164,6 +163,7 @@ struct Params {
int nBridgeStartBlock;
int nNEVMStartBlock;
int nPODAStartBlock;
int nRolluxStartBlock;
int nV19StartBlock;
int nUTXOAssetsBlock;
int nUTXOAssetsBlockProvisioning;
Expand Down
52 changes: 20 additions & 32 deletions src/consensus/tx_verify.cpp
Expand Up @@ -14,7 +14,7 @@
#include <util/check.h>
#include <util/moneystr.h>
// SYSCOIN
#include <services/asset.h>
#include <services/nevmconsensus.h>
bool IsFinalTx(const CTransaction &tx, int nBlockHeight, int64_t nBlockTime)
{
if (tx.nLockTime == 0)
Expand Down Expand Up @@ -167,13 +167,15 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i
}
return nSigOps;
}
bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache &inputs, int nSpendHeight, CAmount& txfee, CAssetsMap &mapAssetIn, CAssetsMap &mapAssetOut)
// SYSCOIN
bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, bool fJustCheck, NEVMMintTxMap &mapMintKeys)
{
// are the actual inputs available?
if (!inputs.HaveInputs(tx)) {
return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
strprintf("%s: inputs missing/spent", __func__));
}

CAmount nValueIn = 0;
for (unsigned int i = 0; i < tx.vin.size(); ++i) {
const COutPoint &prevout = tx.vin[i].prevout;
Expand All @@ -185,47 +187,33 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state,
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
}
if (!coin.out.assetInfo.IsNull()) {
const bool &zeroVal = coin.out.assetInfo.nValue == 0;
auto inRes = mapAssetIn.try_emplace(coin.out.assetInfo.nAsset, zeroVal, coin.out.assetInfo.nValue);
if (!inRes.second) {
inRes.first->second.nAmount += coin.out.assetInfo.nValue;
if (!inRes.first->second.bZeroVal) {
inRes.first->second.bZeroVal = zeroVal;
}
// sanity, should never have multiple zero val inputs for an asset
else if (zeroVal) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-asset-multiple-zero-val-input");
}
if(!MoneyRangeAsset(inRes.first->second.nAmount) || !MoneyRangeAsset(coin.out.assetInfo.nValue)) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-asset-inputvalues-outofrange");
}
}
}

// Check for negative or overflow input values
nValueIn += coin.out.nValue;
if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
}

}
// SYSCOIN
if(tx.IsMintTx()) {
CAmount nMintAmount;
if(!CheckSyscoinMint(tx, state, fJustCheck, nSpendHeight, mapMintKeys, nMintAmount)) {
// state filled by CheckSyscoinMint
return false;
}
// nMintAmount is range checked already because it is compared against an output and outputs are checked in GetValueOut()
// but we do need to check for overflow before adding it
if (!MoneyRange(nValueIn + nMintAmount))
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-mint-outofrange", strprintf("value out of range value_in (%s) value_in+mint (%s)", FormatMoney(nValueIn), FormatMoney(nValueIn + nMintAmount)));
nValueIn += nMintAmount;
assert(MoneyRange(nValueIn));
}
const CAmount &value_out = tx.GetValueOut();
if (nValueIn < value_out) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
}
// SYSCOIN
if(tx.HasAssets()) {
std::string err;
if(!tx.GetAssetValueOut(mapAssetOut, err)) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, err);
}
// if input was used, validate it against output (note, no fees for assets in == out)
if(!CheckTxInputsAssets(tx, state, GetBaseAssetID(tx.voutAssets.begin()->key), mapAssetIn, mapAssetOut)) {
return false; // state filled by CheckTxInputsAssets
}
}


// Tally transaction fees
const CAmount txfee_aux = nValueIn - value_out;
if (!MoneyRange(txfee_aux)) {
Expand Down
8 changes: 6 additions & 2 deletions src/consensus/tx_verify.h
Expand Up @@ -9,11 +9,15 @@

#include <stdint.h>
#include <vector>

// SYSCOIN
#include <unordered_map>
class CBlockIndex;
class CCoinsViewCache;
class CTransaction;
class TxValidationState;
// SYSCOIN
class uint256;
typedef std::unordered_map<uint256, uint256> NEVMMintTxMap;
/** Transaction validation functions */

namespace Consensus {
Expand All @@ -23,7 +27,7 @@ namespace Consensus {
* @param[out] txfee Set to the transaction fee if successful.
* Preconditions: tx.IsCoinBase() is false.
*/
[[nodiscard]] bool CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, CAssetsMap &mapAssetIn, CAssetsMap &mapAssetOut);
[[nodiscard]] bool CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmount& txfee, bool fJustCheck, NEVMMintTxMap &mapMintKeys);
} // namespace Consensus

/** Auxiliary functions for transaction validation (ideally should not be exposed) */
Expand Down

0 comments on commit dbb4f66

Please sign in to comment.