Skip to content

Commit

Permalink
[BROKEN] Introduce CA in data structures
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenroose committed Mar 20, 2019
1 parent 04d0691 commit d53479c
Show file tree
Hide file tree
Showing 17 changed files with 333 additions and 132 deletions.
25 changes: 3 additions & 22 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ static CBlock CreateGenesisBlock(const Consensus::Params& params, const CScript&
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = genesisScriptSig;
txNew.vout[0].nValue = genesisReward;
txNew.vout[0].scriptPubKey = genesisOutputScript;
txNew.vout.push_back(CTxOut(CAsset(), genesisReward, genesisOutputScript));

CBlock genesis;
genesis.nTime = nTime;
Expand Down Expand Up @@ -86,23 +84,6 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
return CreateGenesisBlock(params, genesisScriptSig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}

/** Add an issuance transaction to the genesis block. Typically used to pre-issue
* the policyAsset of a blockchain. The genesis block is not actually validated,
* so this transaction simply has to match issuance structure. */
static void AppendInitialIssuance(CBlock& genesis_block, const COutPoint& prevout, const int64_t asset_values, const CScript& issuance_destination) {

// Note: Genesis block isn't actually validated, outputs are entered into utxo db only
CMutableTransaction txNew;
txNew.nVersion = 1;
txNew.vin.resize(1);
txNew.vin[0].prevout = prevout;

txNew.vout.push_back(CTxOut(asset_values, issuance_destination));

genesis_block.vtx.push_back(MakeTransactionRef(std::move(txNew)));
genesis_block.hashMerkleRoot = BlockMerkleRoot(genesis_block);
}

/**
* Main network
*/
Expand Down Expand Up @@ -623,8 +604,8 @@ class CCustomParams : public CRegTestParams {
// Intended compatibility with Liquid v1 and elements-0.14.1
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID);
genesis = CreateGenesisBlock(consensus, CScript(commit), CScript(OP_RETURN), 1296688602, 2, 0x207fffff, 1, 0);
if (initialFreeCoins != 0) {
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), initialFreeCoins, CScript() << OP_TRUE);
if (initialFreeCoins != 0 || initial_reissuance_tokens != 0) {
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), parentGenesisBlockHash, (initialFreeCoins > 0) ? 1 : 0, initialFreeCoins, (initial_reissuance_tokens > 0) ? 1 : 0, initial_reissuance_tokens, CScript() << OP_TRUE);
}
} else {
throw std::runtime_error(strprintf("Invalid -genesis_style (%s)", consensus.genesis_style));
Expand Down
14 changes: 12 additions & 2 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,16 @@ bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
return true;
}

static const Coin coinEmpty;
// ELEMENTS:
// Because g_con_elementsmode is only set after the moment coinEmpty is initialized,
// we have to force set it to an empty coin without the default asset commitment.
Coin generateEmptyCoin() {
Coin coin;
coin.out.nValue.vchCommitment.clear();
coin.out.nAsset.vchCommitment.clear();
return coin;
}
static const Coin coinEmpty = generateEmptyCoin();

const Coin& CCoinsViewCache::AccessCoin(const COutPoint &outpoint) const {
CCoinsMap::const_iterator it = FetchCoin(outpoint);
Expand Down Expand Up @@ -306,7 +315,8 @@ CAmount CCoinsViewCache::GetValueIn(const CTransaction& tx) const

CAmount nResult = 0;
for (unsigned int i = 0; i < tx.vin.size(); i++)
nResult += AccessCoin(tx.vin[i].prevout).out.nValue;
// ELEMENTS: this method is for tests only, just naively add amounts
nResult += AccessCoin(tx.vin[i].prevout).out.nValue.GetAmount();

return nResult;
}
Expand Down
40 changes: 34 additions & 6 deletions src/compressor.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,42 @@ class CTxOutCompressor

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action) {
if (!ser_action.ForRead()) {
uint64_t nVal = CompressAmount(txout.nValue);
READWRITE(VARINT(nVal));
if (g_con_elementsmode) {
if (!ser_action.ForRead()) {
if (txout.nValue.IsExplicit()) {
uint8_t b = 0;
READWRITE(b);
uint64_t nVal = CompressAmount(txout.nValue.GetAmount());
READWRITE(VARINT(nVal));
} else {
uint8_t b = 1;
READWRITE(b);
READWRITE(txout.nValue);
}
} else {
uint8_t type = 0;
READWRITE(type);
if (type == 0) {
uint64_t nVal = 0;
READWRITE(VARINT(nVal));
txout.nValue = DecompressAmount(nVal);
} else {
READWRITE(txout.nValue);
}
}
READWRITE(txout.nAsset);
} else {
uint64_t nVal = 0;
READWRITE(VARINT(nVal));
txout.nValue = DecompressAmount(nVal);
if (!ser_action.ForRead()) {
assert(txout.nValue.IsExplicit());
uint64_t nVal = CompressAmount(txout.nValue.GetAmount());
READWRITE(VARINT(nVal));
} else {
uint64_t nVal = 0;
READWRITE(VARINT(nVal));
txout.nValue = DecompressAmount(nVal);
}
}

CScriptCompressor cscript(REF(txout.scriptPubKey));
READWRITE(cscript);
}
Expand Down
14 changes: 9 additions & 5 deletions src/consensus/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,17 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
{
std::vector<uint256> leaves;
leaves.resize(block.vtx.size());
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
for (size_t s = 1; s < block.vtx.size(); s++) {
if (g_con_elementsmode) {
if (g_con_elementsmode) {
// Coinbase witness hash for inputs is just CTxInWitness().GetHash()
for (size_t s = 0; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetWitnessOnlyHash();
} else {
}
return ComputeFastMerkleRoot(std::move(leaves));
} else {
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
for (size_t s = 1; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetWitnessHash();
}
return ComputeMerkleRoot(std::move(leaves), mutated);
}
return ComputeMerkleRoot(std::move(leaves), mutated);
}
1 change: 1 addition & 0 deletions src/core_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define BITCOIN_CORE_IO_H

#include <amount.h>
#include <asset.h>

#include <string>
#include <vector>
Expand Down
129 changes: 111 additions & 18 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <consensus/consensus.h>
#include <consensus/validation.h>
#include <issuance.h>
#include <key_io.h>
#include <script/script.h>
#include <script/standard.h>
Expand All @@ -16,6 +17,32 @@
#include <utilmoneystr.h>
#include <utilstrencodings.h>

#include <secp256k1_rangeproof.h>

static secp256k1_context* secp256k1_blind_context = NULL;

class RPCRawTransaction_ECC_Init {
public:
RPCRawTransaction_ECC_Init() {
assert(secp256k1_blind_context == NULL);

secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
assert(ctx != NULL);

secp256k1_blind_context = ctx;
}

~RPCRawTransaction_ECC_Init() {
secp256k1_context *ctx = secp256k1_blind_context;
secp256k1_blind_context = NULL;

if (ctx) {
secp256k1_context_destroy(ctx);
}
}
};
static RPCRawTransaction_ECC_Init ecc_init_on_load;

UniValue ValueFromAmount(const CAmount& amount)
{
bool sign = amount < 0;
Expand Down Expand Up @@ -223,29 +250,65 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
in.pushKV("scriptSig", o);
in.pushKV("is_pegin", txin.m_is_pegin);
}
in.pushKV("sequence", (int64_t)txin.nSequence);

if (tx.witness.vtxinwit.size() > i) {
const CScriptWitness &scriptWitness = tx.witness.vtxinwit[i].scriptWitness;
if (!scriptWitness.IsNull()) {
UniValue txinwitness(UniValue::VARR);
for (const auto &item : scriptWitness.stack) {
txinwitness.push_back(HexStr(item.begin(), item.end()));
}
in.pushKV("txinwitness", txinwitness);
if (tx.witness.vtxinwit.size() > i) {
const CScriptWitness &scriptWitness = tx.witness.vtxinwit[i].scriptWitness;
if (!scriptWitness.IsNull()) {
UniValue txinwitness(UniValue::VARR);
for (const auto &item : scriptWitness.stack) {
txinwitness.push_back(HexStr(item.begin(), item.end()));
}
in.pushKV("txinwitness", txinwitness);
}
}

// ELEMENTS:
in.pushKV("is_pegin", txin.m_is_pegin);
if (tx.witness.vtxinwit.size() > i && !tx.witness.vtxinwit[i].m_pegin_witness.IsNull()) {
UniValue pegin_witness(UniValue::VARR);
for (const auto& item : tx.witness.vtxinwit[i].m_pegin_witness.stack) {
pegin_witness.push_back(HexStr(item.begin(), item.end()));
}
in.pushKV("pegin_witness", pegin_witness);
// ELEMENTS:
if (tx.witness.vtxinwit.size() > i && !tx.witness.vtxinwit[i].m_pegin_witness.IsNull()) {
UniValue pegin_witness(UniValue::VARR);
for (const auto& item : tx.witness.vtxinwit[i].m_pegin_witness.stack) {
pegin_witness.push_back(HexStr(item.begin(), item.end()));
}
in.pushKV("pegin_witness", pegin_witness);
}
in.pushKV("sequence", (int64_t)txin.nSequence);
const CAssetIssuance& issuance = txin.assetIssuance;
if (!issuance.IsNull()) {
UniValue issue(UniValue::VOBJ);
issue.pushKV("assetBlindingNonce", issuance.assetBlindingNonce.GetHex());
CAsset asset;
CAsset token;
uint256 entropy;
if (issuance.assetBlindingNonce.IsNull()) {
GenerateAssetEntropy(entropy, txin.prevout, issuance.assetEntropy);
issue.pushKV("assetEntropy", entropy.GetHex());
CalculateAsset(asset, entropy);
CalculateReissuanceToken(token, entropy, issuance.nAmount.IsCommitment());
issue.pushKV("isreissuance", false);
issue.pushKV("token", token.GetHex());
}
else {
issue.pushKV("assetEntropy", issuance.assetEntropy.GetHex());
issue.pushKV("isreissuance", true);
CalculateAsset(asset, issuance.assetEntropy);
}
issue.pushKV("asset", asset.GetHex());

if (issuance.nAmount.IsExplicit()) {
issue.pushKV("assetamount", ValueFromAmount(issuance.nAmount.GetAmount()));
} else if (issuance.nAmount.IsCommitment()) {
issue.pushKV("assetamountcommitment", HexStr(issuance.nAmount.vchCommitment));
}
if (issuance.nInflationKeys.IsExplicit()) {
issue.pushKV("tokenamount", ValueFromAmount(issuance.nInflationKeys.GetAmount()));
} else if (issuance.nInflationKeys.IsCommitment()) {
issue.pushKV("tokenamountcommitment", HexStr(issuance.nInflationKeys.vchCommitment));
}
in.pushKV("issuance", issue);
}
// END ELEMENTS

vin.push_back(in);
}
entry.pushKV("vin", vin);
Expand All @@ -256,7 +319,37 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,

UniValue out(UniValue::VOBJ);

out.pushKV("value", ValueFromAmount(txout.nValue));
if (txout.nValue.IsExplicit()) {
out.pushKV("value", ValueFromAmount(txout.nValue.GetAmount()));
} else {
int exp;
int mantissa;
uint64_t minv;
uint64_t maxv;
const CTxOutWitness* ptxoutwit = tx.witness.vtxoutwit.size() <= i? NULL: &tx.witness.vtxoutwit[i];
if (ptxoutwit && secp256k1_rangeproof_info(secp256k1_blind_context, &exp, &mantissa, &minv, &maxv, &ptxoutwit->vchRangeproof[0], ptxoutwit->vchRangeproof.size())) {
if (exp == -1) {
out.pushKV("value", ValueFromAmount((CAmount)minv));
} else {
out.pushKV("value-minimum", ValueFromAmount((CAmount)minv));
out.pushKV("value-maximum", ValueFromAmount((CAmount)maxv));
}
out.pushKV("ct-exponent", exp);
out.pushKV("ct-bits", mantissa);
}
out.pushKV("valuecommitment", txout.nValue.GetHex());
}
if (g_con_elementsmode) {
if (txout.nAsset.IsExplicit()) {
out.pushKV("asset", txout.nAsset.GetAsset().GetHex());
} else {
out.pushKV("assetcommitment", txout.nAsset.GetHex());
}

out.pushKV("commitmentnonce", txout.nNonce.GetHex());
CPubKey pubkey(txout.nNonce.vchCommitment);
out.pushKV("commitmentnonce_fully_valid", pubkey.IsFullyValid());
}
out.pushKV("n", (int64_t)i);

UniValue o(UniValue::VOBJ);
Expand Down
8 changes: 4 additions & 4 deletions src/interfaces/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,8 @@ class WalletImpl : public Wallet
num_blocks = ::chainActive.Height();
return true;
}
CAmount getBalance() override { return m_wallet.GetBalance(); }
CAmount getAvailableBalance(const CCoinControl& coin_control) override
CAmountMap getBalance() override { return m_wallet.GetBalance(); }
CAmountMap getAvailableBalance(const CCoinControl& coin_control) override
{
return m_wallet.GetAvailableBalance(&coin_control);
}
Expand All @@ -370,12 +370,12 @@ class WalletImpl : public Wallet
LOCK2(::cs_main, m_wallet.cs_wallet);
return m_wallet.IsMine(txout);
}
CAmount getDebit(const CTxIn& txin, isminefilter filter) override
CAmountMap getDebit(const CTxIn& txin, isminefilter filter) override
{
LOCK2(::cs_main, m_wallet.cs_wallet);
return m_wallet.GetDebit(txin, filter);
}
CAmount getCredit(const CTxOut& txout, isminefilter filter) override
CAmountMap getCredit(const CTxOut& txout, isminefilter filter) override
{
LOCK2(::cs_main, m_wallet.cs_wallet);
return m_wallet.GetCredit(txout, filter);
Expand Down
Loading

0 comments on commit d53479c

Please sign in to comment.