Skip to content

Commit d53479c

Browse files
committed
[BROKEN] Introduce CA in data structures
1 parent 04d0691 commit d53479c

File tree

17 files changed

+333
-132
lines changed

17 files changed

+333
-132
lines changed

src/chainparams.cpp

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,8 @@ static CBlock CreateGenesisBlock(const Consensus::Params& params, const CScript&
4848
CMutableTransaction txNew;
4949
txNew.nVersion = 1;
5050
txNew.vin.resize(1);
51-
txNew.vout.resize(1);
5251
txNew.vin[0].scriptSig = genesisScriptSig;
53-
txNew.vout[0].nValue = genesisReward;
54-
txNew.vout[0].scriptPubKey = genesisOutputScript;
52+
txNew.vout.push_back(CTxOut(CAsset(), genesisReward, genesisOutputScript));
5553

5654
CBlock genesis;
5755
genesis.nTime = nTime;
@@ -86,23 +84,6 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
8684
return CreateGenesisBlock(params, genesisScriptSig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
8785
}
8886

89-
/** Add an issuance transaction to the genesis block. Typically used to pre-issue
90-
* the policyAsset of a blockchain. The genesis block is not actually validated,
91-
* so this transaction simply has to match issuance structure. */
92-
static void AppendInitialIssuance(CBlock& genesis_block, const COutPoint& prevout, const int64_t asset_values, const CScript& issuance_destination) {
93-
94-
// Note: Genesis block isn't actually validated, outputs are entered into utxo db only
95-
CMutableTransaction txNew;
96-
txNew.nVersion = 1;
97-
txNew.vin.resize(1);
98-
txNew.vin[0].prevout = prevout;
99-
100-
txNew.vout.push_back(CTxOut(asset_values, issuance_destination));
101-
102-
genesis_block.vtx.push_back(MakeTransactionRef(std::move(txNew)));
103-
genesis_block.hashMerkleRoot = BlockMerkleRoot(genesis_block);
104-
}
105-
10687
/**
10788
* Main network
10889
*/
@@ -623,8 +604,8 @@ class CCustomParams : public CRegTestParams {
623604
// Intended compatibility with Liquid v1 and elements-0.14.1
624605
std::vector<unsigned char> commit = CommitToArguments(consensus, strNetworkID);
625606
genesis = CreateGenesisBlock(consensus, CScript(commit), CScript(OP_RETURN), 1296688602, 2, 0x207fffff, 1, 0);
626-
if (initialFreeCoins != 0) {
627-
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), initialFreeCoins, CScript() << OP_TRUE);
607+
if (initialFreeCoins != 0 || initial_reissuance_tokens != 0) {
608+
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), parentGenesisBlockHash, (initialFreeCoins > 0) ? 1 : 0, initialFreeCoins, (initial_reissuance_tokens > 0) ? 1 : 0, initial_reissuance_tokens, CScript() << OP_TRUE);
628609
}
629610
} else {
630611
throw std::runtime_error(strprintf("Invalid -genesis_style (%s)", consensus.genesis_style));

src/coins.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,16 @@ bool CCoinsViewCache::SpendCoin(const COutPoint &outpoint, Coin* moveout) {
124124
return true;
125125
}
126126

127-
static const Coin coinEmpty;
127+
// ELEMENTS:
128+
// Because g_con_elementsmode is only set after the moment coinEmpty is initialized,
129+
// we have to force set it to an empty coin without the default asset commitment.
130+
Coin generateEmptyCoin() {
131+
Coin coin;
132+
coin.out.nValue.vchCommitment.clear();
133+
coin.out.nAsset.vchCommitment.clear();
134+
return coin;
135+
}
136+
static const Coin coinEmpty = generateEmptyCoin();
128137

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

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

311321
return nResult;
312322
}

src/compressor.h

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,42 @@ class CTxOutCompressor
9595

9696
template <typename Stream, typename Operation>
9797
inline void SerializationOp(Stream& s, Operation ser_action) {
98-
if (!ser_action.ForRead()) {
99-
uint64_t nVal = CompressAmount(txout.nValue);
100-
READWRITE(VARINT(nVal));
98+
if (g_con_elementsmode) {
99+
if (!ser_action.ForRead()) {
100+
if (txout.nValue.IsExplicit()) {
101+
uint8_t b = 0;
102+
READWRITE(b);
103+
uint64_t nVal = CompressAmount(txout.nValue.GetAmount());
104+
READWRITE(VARINT(nVal));
105+
} else {
106+
uint8_t b = 1;
107+
READWRITE(b);
108+
READWRITE(txout.nValue);
109+
}
110+
} else {
111+
uint8_t type = 0;
112+
READWRITE(type);
113+
if (type == 0) {
114+
uint64_t nVal = 0;
115+
READWRITE(VARINT(nVal));
116+
txout.nValue = DecompressAmount(nVal);
117+
} else {
118+
READWRITE(txout.nValue);
119+
}
120+
}
121+
READWRITE(txout.nAsset);
101122
} else {
102-
uint64_t nVal = 0;
103-
READWRITE(VARINT(nVal));
104-
txout.nValue = DecompressAmount(nVal);
123+
if (!ser_action.ForRead()) {
124+
assert(txout.nValue.IsExplicit());
125+
uint64_t nVal = CompressAmount(txout.nValue.GetAmount());
126+
READWRITE(VARINT(nVal));
127+
} else {
128+
uint64_t nVal = 0;
129+
READWRITE(VARINT(nVal));
130+
txout.nValue = DecompressAmount(nVal);
131+
}
105132
}
133+
106134
CScriptCompressor cscript(REF(txout.scriptPubKey));
107135
READWRITE(cscript);
108136
}

src/consensus/merkle.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,17 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
7777
{
7878
std::vector<uint256> leaves;
7979
leaves.resize(block.vtx.size());
80-
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
81-
for (size_t s = 1; s < block.vtx.size(); s++) {
82-
if (g_con_elementsmode) {
80+
if (g_con_elementsmode) {
81+
// Coinbase witness hash for inputs is just CTxInWitness().GetHash()
82+
for (size_t s = 0; s < block.vtx.size(); s++) {
8383
leaves[s] = block.vtx[s]->GetWitnessOnlyHash();
84-
} else {
84+
}
85+
return ComputeFastMerkleRoot(std::move(leaves));
86+
} else {
87+
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
88+
for (size_t s = 1; s < block.vtx.size(); s++) {
8589
leaves[s] = block.vtx[s]->GetWitnessHash();
8690
}
91+
return ComputeMerkleRoot(std::move(leaves), mutated);
8792
}
88-
return ComputeMerkleRoot(std::move(leaves), mutated);
8993
}

src/core_io.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_CORE_IO_H
77

88
#include <amount.h>
9+
#include <asset.h>
910

1011
#include <string>
1112
#include <vector>

src/core_write.cpp

Lines changed: 111 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <consensus/consensus.h>
88
#include <consensus/validation.h>
9+
#include <issuance.h>
910
#include <key_io.h>
1011
#include <script/script.h>
1112
#include <script/standard.h>
@@ -16,6 +17,32 @@
1617
#include <utilmoneystr.h>
1718
#include <utilstrencodings.h>
1819

20+
#include <secp256k1_rangeproof.h>
21+
22+
static secp256k1_context* secp256k1_blind_context = NULL;
23+
24+
class RPCRawTransaction_ECC_Init {
25+
public:
26+
RPCRawTransaction_ECC_Init() {
27+
assert(secp256k1_blind_context == NULL);
28+
29+
secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
30+
assert(ctx != NULL);
31+
32+
secp256k1_blind_context = ctx;
33+
}
34+
35+
~RPCRawTransaction_ECC_Init() {
36+
secp256k1_context *ctx = secp256k1_blind_context;
37+
secp256k1_blind_context = NULL;
38+
39+
if (ctx) {
40+
secp256k1_context_destroy(ctx);
41+
}
42+
}
43+
};
44+
static RPCRawTransaction_ECC_Init ecc_init_on_load;
45+
1946
UniValue ValueFromAmount(const CAmount& amount)
2047
{
2148
bool sign = amount < 0;
@@ -223,29 +250,65 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
223250
o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));
224251
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
225252
in.pushKV("scriptSig", o);
253+
in.pushKV("is_pegin", txin.m_is_pegin);
254+
}
255+
in.pushKV("sequence", (int64_t)txin.nSequence);
226256

227-
if (tx.witness.vtxinwit.size() > i) {
228-
const CScriptWitness &scriptWitness = tx.witness.vtxinwit[i].scriptWitness;
229-
if (!scriptWitness.IsNull()) {
230-
UniValue txinwitness(UniValue::VARR);
231-
for (const auto &item : scriptWitness.stack) {
232-
txinwitness.push_back(HexStr(item.begin(), item.end()));
233-
}
234-
in.pushKV("txinwitness", txinwitness);
257+
if (tx.witness.vtxinwit.size() > i) {
258+
const CScriptWitness &scriptWitness = tx.witness.vtxinwit[i].scriptWitness;
259+
if (!scriptWitness.IsNull()) {
260+
UniValue txinwitness(UniValue::VARR);
261+
for (const auto &item : scriptWitness.stack) {
262+
txinwitness.push_back(HexStr(item.begin(), item.end()));
235263
}
264+
in.pushKV("txinwitness", txinwitness);
236265
}
266+
}
237267

238-
// ELEMENTS:
239-
in.pushKV("is_pegin", txin.m_is_pegin);
240-
if (tx.witness.vtxinwit.size() > i && !tx.witness.vtxinwit[i].m_pegin_witness.IsNull()) {
241-
UniValue pegin_witness(UniValue::VARR);
242-
for (const auto& item : tx.witness.vtxinwit[i].m_pegin_witness.stack) {
243-
pegin_witness.push_back(HexStr(item.begin(), item.end()));
244-
}
245-
in.pushKV("pegin_witness", pegin_witness);
268+
// ELEMENTS:
269+
if (tx.witness.vtxinwit.size() > i && !tx.witness.vtxinwit[i].m_pegin_witness.IsNull()) {
270+
UniValue pegin_witness(UniValue::VARR);
271+
for (const auto& item : tx.witness.vtxinwit[i].m_pegin_witness.stack) {
272+
pegin_witness.push_back(HexStr(item.begin(), item.end()));
246273
}
274+
in.pushKV("pegin_witness", pegin_witness);
247275
}
248-
in.pushKV("sequence", (int64_t)txin.nSequence);
276+
const CAssetIssuance& issuance = txin.assetIssuance;
277+
if (!issuance.IsNull()) {
278+
UniValue issue(UniValue::VOBJ);
279+
issue.pushKV("assetBlindingNonce", issuance.assetBlindingNonce.GetHex());
280+
CAsset asset;
281+
CAsset token;
282+
uint256 entropy;
283+
if (issuance.assetBlindingNonce.IsNull()) {
284+
GenerateAssetEntropy(entropy, txin.prevout, issuance.assetEntropy);
285+
issue.pushKV("assetEntropy", entropy.GetHex());
286+
CalculateAsset(asset, entropy);
287+
CalculateReissuanceToken(token, entropy, issuance.nAmount.IsCommitment());
288+
issue.pushKV("isreissuance", false);
289+
issue.pushKV("token", token.GetHex());
290+
}
291+
else {
292+
issue.pushKV("assetEntropy", issuance.assetEntropy.GetHex());
293+
issue.pushKV("isreissuance", true);
294+
CalculateAsset(asset, issuance.assetEntropy);
295+
}
296+
issue.pushKV("asset", asset.GetHex());
297+
298+
if (issuance.nAmount.IsExplicit()) {
299+
issue.pushKV("assetamount", ValueFromAmount(issuance.nAmount.GetAmount()));
300+
} else if (issuance.nAmount.IsCommitment()) {
301+
issue.pushKV("assetamountcommitment", HexStr(issuance.nAmount.vchCommitment));
302+
}
303+
if (issuance.nInflationKeys.IsExplicit()) {
304+
issue.pushKV("tokenamount", ValueFromAmount(issuance.nInflationKeys.GetAmount()));
305+
} else if (issuance.nInflationKeys.IsCommitment()) {
306+
issue.pushKV("tokenamountcommitment", HexStr(issuance.nInflationKeys.vchCommitment));
307+
}
308+
in.pushKV("issuance", issue);
309+
}
310+
// END ELEMENTS
311+
249312
vin.push_back(in);
250313
}
251314
entry.pushKV("vin", vin);
@@ -256,7 +319,37 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
256319

257320
UniValue out(UniValue::VOBJ);
258321

259-
out.pushKV("value", ValueFromAmount(txout.nValue));
322+
if (txout.nValue.IsExplicit()) {
323+
out.pushKV("value", ValueFromAmount(txout.nValue.GetAmount()));
324+
} else {
325+
int exp;
326+
int mantissa;
327+
uint64_t minv;
328+
uint64_t maxv;
329+
const CTxOutWitness* ptxoutwit = tx.witness.vtxoutwit.size() <= i? NULL: &tx.witness.vtxoutwit[i];
330+
if (ptxoutwit && secp256k1_rangeproof_info(secp256k1_blind_context, &exp, &mantissa, &minv, &maxv, &ptxoutwit->vchRangeproof[0], ptxoutwit->vchRangeproof.size())) {
331+
if (exp == -1) {
332+
out.pushKV("value", ValueFromAmount((CAmount)minv));
333+
} else {
334+
out.pushKV("value-minimum", ValueFromAmount((CAmount)minv));
335+
out.pushKV("value-maximum", ValueFromAmount((CAmount)maxv));
336+
}
337+
out.pushKV("ct-exponent", exp);
338+
out.pushKV("ct-bits", mantissa);
339+
}
340+
out.pushKV("valuecommitment", txout.nValue.GetHex());
341+
}
342+
if (g_con_elementsmode) {
343+
if (txout.nAsset.IsExplicit()) {
344+
out.pushKV("asset", txout.nAsset.GetAsset().GetHex());
345+
} else {
346+
out.pushKV("assetcommitment", txout.nAsset.GetHex());
347+
}
348+
349+
out.pushKV("commitmentnonce", txout.nNonce.GetHex());
350+
CPubKey pubkey(txout.nNonce.vchCommitment);
351+
out.pushKV("commitmentnonce_fully_valid", pubkey.IsFullyValid());
352+
}
260353
out.pushKV("n", (int64_t)i);
261354

262355
UniValue o(UniValue::VOBJ);

src/interfaces/wallet.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,8 @@ class WalletImpl : public Wallet
355355
num_blocks = ::chainActive.Height();
356356
return true;
357357
}
358-
CAmount getBalance() override { return m_wallet.GetBalance(); }
359-
CAmount getAvailableBalance(const CCoinControl& coin_control) override
358+
CAmountMap getBalance() override { return m_wallet.GetBalance(); }
359+
CAmountMap getAvailableBalance(const CCoinControl& coin_control) override
360360
{
361361
return m_wallet.GetAvailableBalance(&coin_control);
362362
}
@@ -370,12 +370,12 @@ class WalletImpl : public Wallet
370370
LOCK2(::cs_main, m_wallet.cs_wallet);
371371
return m_wallet.IsMine(txout);
372372
}
373-
CAmount getDebit(const CTxIn& txin, isminefilter filter) override
373+
CAmountMap getDebit(const CTxIn& txin, isminefilter filter) override
374374
{
375375
LOCK2(::cs_main, m_wallet.cs_wallet);
376376
return m_wallet.GetDebit(txin, filter);
377377
}
378-
CAmount getCredit(const CTxOut& txout, isminefilter filter) override
378+
CAmountMap getCredit(const CTxOut& txout, isminefilter filter) override
379379
{
380380
LOCK2(::cs_main, m_wallet.cs_wallet);
381381
return m_wallet.GetCredit(txout, filter);

0 commit comments

Comments
 (0)