Skip to content

Commit 9a9ac25

Browse files
committed
genesis block has actual fee issuance in regtest
1 parent 65ed777 commit 9a9ac25

File tree

5 files changed

+69
-39
lines changed

5 files changed

+69
-39
lines changed

qa/rpc-tests/confidential_transactions.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ def run_test(self):
222222

223223
print("Assets tests...")
224224

225+
# Bitcoin is the first issuance
226+
assert_equal(self.nodes[0].listissuances()[0]["assetlabel"], "bitcoin")
227+
assert_equal(len(self.nodes[0].listissuances()), 1)
228+
225229
# Unblinded issuance of asset
226230
issued = self.nodes[0].issueasset(1, 1, False)
227231
assert_equal(self.nodes[0].getwalletinfo()["balance"][issued["asset"]], 1)
@@ -351,13 +355,13 @@ def run_test(self):
351355
addr2 = txdet2[len(txdet2)-1]["address"]
352356
addr3 = txdet3[len(txdet3)-1]["address"]
353357

354-
assert_equal(len(self.nodes[0].listissuances()), 5);
358+
assert_equal(len(self.nodes[0].listissuances()), 6);
355359
self.nodes[0].importaddress(addr1)
356360
self.nodes[0].importaddress(addr2)
357361
self.nodes[0].importaddress(addr3)
358362

359363
issuances = self.nodes[0].listissuances()
360-
assert_equal(len(issuances), 8)
364+
assert_equal(len(issuances), 9)
361365

362366
for issue in issuances:
363367
if issue['txid'] == redata1["txid"] and issue['vin'] == redata1["vin"]:

qa/rpc-tests/wallet.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,15 @@ def setup_network(self, split=False):
3030

3131
def run_test (self):
3232

33-
# Check that there's no UTXO on none of the nodes
34-
assert_equal(len(self.nodes[0].listunspent()), 0)
35-
assert_equal(len(self.nodes[1].listunspent()), 0)
36-
assert_equal(len(self.nodes[2].listunspent()), 0)
33+
# Check that there's 100 UTXOs on each of the nodes
34+
assert_equal(len(self.nodes[0].listunspent()), 100)
35+
assert_equal(len(self.nodes[1].listunspent()), 100)
36+
assert_equal(len(self.nodes[2].listunspent()), 100)
3737

38-
print("Mining blocks...")
39-
40-
self.nodes[0].generate(1)
4138
walletinfo = self.nodes[0].getwalletinfo()
42-
assert_equal(walletinfo['immature_balance']["bitcoin"], 21000000)
43-
assert("bitcoin" not in walletinfo['balance'])
39+
assert_equal(walletinfo['balance']["bitcoin"], 21000000)
4440

45-
self.sync_all()
41+
print("Mining blocks...")
4642
self.nodes[1].generate(101)
4743
self.sync_all()
4844

src/chainparams.cpp

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,15 @@ static CScript StrHexToScriptWithDefault(std::string strScript, const CScript de
4141
return returnScript;
4242
}
4343

44-
static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::string& networkID, const CScript& genesisOutputScript, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion, const CAmount& genesisReward, const uint32_t rewardShards, const CAsset& asset)
44+
static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::string& networkID, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion)
4545
{
46-
// Shards must be evenly divisible
47-
assert(MAX_MONEY % rewardShards == 0);
4846
CMutableTransaction txNew;
4947
txNew.nVersion = 1;
5048
txNew.vin.resize(1);
51-
txNew.vout.resize(rewardShards);
5249
// Any consensus-related values that are command-line set can be added here for anti-footgun
5350
txNew.vin[0].scriptSig = CScript(CommitToArguments(params, networkID, scriptChallenge));
54-
for (unsigned int i = 0; i < rewardShards; i++) {
55-
txNew.vout[i].nValue = genesisReward/rewardShards;
56-
txNew.vout[i].nAsset = asset;
57-
txNew.vout[i].scriptPubKey = genesisOutputScript;
58-
}
51+
txNew.vout.clear();
52+
txNew.vout.push_back(CTxOut(CAsset(), 0, CScript() << OP_RETURN));
5953

6054
CBlock genesis;
6155
genesis.nTime = nTime;
@@ -67,6 +61,41 @@ static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::str
6761
return genesis;
6862
}
6963

64+
/** Add an issuance transaction to the genesis block. Typically used to pre-issue
65+
* the policyAsset of a blockchain. The genesis block is not actually validated,
66+
* so this transaction simply has to match issuance structure. */
67+
static void AppendInitialIssuance(CBlock& genesis_block, const COutPoint& prevout, const uint256& contract, const int64_t asset_outputs, const int64_t asset_values, const int64_t reissuance_outputs, const int64_t reissuance_values, const CScript& issuance_destination) {
68+
69+
uint256 entropy;
70+
GenerateAssetEntropy(entropy, prevout, contract);
71+
72+
CAsset asset;
73+
CalculateAsset(asset, entropy);
74+
75+
// Re-issuance of policyAsset is always unblinded
76+
CAsset reissuance;
77+
CalculateReissuanceToken(reissuance, entropy, false);
78+
79+
// Note: Genesis block isn't actually validated, outputs are entered into utxo db only
80+
CMutableTransaction txNew;
81+
txNew.nVersion = 1;
82+
txNew.vin.resize(1);
83+
txNew.vin[0].prevout = prevout;
84+
txNew.vin[0].assetIssuance.assetEntropy = contract;
85+
txNew.vin[0].assetIssuance.nAmount = asset_values*asset_outputs;
86+
txNew.vin[0].assetIssuance.nInflationKeys = reissuance_values*reissuance_outputs;
87+
88+
for (unsigned int i = 0; i < asset_outputs; i++) {
89+
txNew.vout.push_back(CTxOut(asset, asset_values, issuance_destination));
90+
}
91+
for (unsigned int i = 0; i < reissuance_outputs; i++) {
92+
txNew.vout.push_back(CTxOut(reissuance, reissuance_values, issuance_destination));
93+
}
94+
95+
genesis_block.vtx.push_back(MakeTransactionRef(std::move(txNew)));
96+
genesis_block.hashMerkleRoot = BlockMerkleRoot(genesis_block);
97+
}
98+
7099
void CChainParams::UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
71100
{
72101
consensus.vDeployments[d].nStartTime = nStartTime;
@@ -149,7 +178,7 @@ class CElementsParams : public CChainParams {
149178
CalculateAsset(consensus.pegged_asset, entropy);
150179

151180
CScript scriptDestination(CScript() << std::vector<unsigned char>(parentGenesisBlockHash.begin(), parentGenesisBlockHash.end()) << OP_WITHDRAWPROOFVERIFY);
152-
genesis = CreateGenesisBlock(consensus, strNetworkID, scriptDestination, 1231006505, genesisChallengeScript, 1, MAX_MONEY, 100, consensus.pegged_asset);
181+
genesis = CreateGenesisBlock(consensus, strNetworkID, 1231006505, genesisChallengeScript, 1);
153182
consensus.hashGenesisBlock = genesis.GetHash();
154183

155184
scriptCoinbaseDestination = CScript() << ParseHex("0229536c4c83789f59c30b93eb40d4abbd99b8dcc99ba8bd748f29e33c1d279e3c") << OP_CHECKSIG;
@@ -259,7 +288,8 @@ class CRegTestParams : public CChainParams {
259288
GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash);
260289
CalculateAsset(consensus.pegged_asset, entropy);
261290

262-
genesis = CreateGenesisBlock(consensus, strNetworkID, defaultRegtestScript, 1296688602, genesisChallengeScript, 1, MAX_MONEY, 100, consensus.pegged_asset);
291+
genesis = CreateGenesisBlock(consensus, strNetworkID, 1296688602, genesisChallengeScript, 1);
292+
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), parentGenesisBlockHash, 100, 21000000000000, 0, 0, CScript() << OP_TRUE);
263293
consensus.hashGenesisBlock = genesis.GetHash();
264294

265295

src/test/test_bitcoin.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,15 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
6565

6666
RegisterAllCoreRPCCommands(tableRPC);
6767

68-
// Make genesis coinbase use out spend-key
68+
int gen_size = Params().GenesisBlock().vtx.size();
69+
70+
// Make genesis second transaction(with spendable outputs) use out spend-key
6971
coinbaseKey.MakeNewKey(true);
7072
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
71-
CMutableTransaction newCoinbase(*(Params().GenesisBlock().vtx[0]));
72-
for (unsigned int i = 0; i < Params().GenesisBlock().vtx[0]->vout.size(); i++)
73-
newCoinbase.vout[i].scriptPubKey = scriptPubKey;
74-
const_cast<CBlock&>(Params().GenesisBlock()).vtx[0] = MakeTransactionRef(newCoinbase);
73+
CMutableTransaction newTransaction(*(Params().GenesisBlock().vtx[gen_size-1]));
74+
for (unsigned int i = 0; i < Params().GenesisBlock().vtx[gen_size-1]->vout.size(); i++)
75+
newTransaction.vout[i].scriptPubKey = scriptPubKey;
76+
const_cast<CBlock&>(Params().GenesisBlock()).vtx[gen_size-1] = MakeTransactionRef(newTransaction);
7577
const_cast<CBlock&>(Params().GenesisBlock()).hashMerkleRoot = BlockMerkleRoot(Params().GenesisBlock());
7678
const_cast<CBlock&>(Params().GenesisBlock()).proof = CProof(CScript()<<OP_TRUE, CScript());
7779
const_cast<Consensus::Params&>(Params().GetConsensus()).hashGenesisBlock = Params().GenesisBlock().GetHash();
@@ -114,8 +116,9 @@ TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
114116
{
115117
// Generate a 100-block chain:
116118
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
117-
assert(Params().GenesisBlock().vtx[0]->vout[0].scriptPubKey == scriptPubKey);
118-
coinbaseTxns.push_back(*(Params().GenesisBlock().vtx[0]));
119+
assert(Params().GenesisBlock().vtx[Params().GenesisBlock().vtx.size()-1]->vout[0].scriptPubKey == scriptPubKey);
120+
// Get spendable outputs from genesis block, which is non-coinbase for regtest
121+
coinbaseTxns.push_back(*(Params().GenesisBlock().vtx[Params().GenesisBlock().vtx.size()-1]));
119122
for (int i = 0; i < COINBASE_MATURITY; i++)
120123
{
121124
std::vector<CMutableTransaction> noTxns;

src/validation.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,19 +2267,16 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
22672267
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
22682268
assert(hashPrevBlock == view.GetBestBlock());
22692269

2270-
// Gesesis coinbase *is* spendable
2270+
// Add genesis outputs. The assumption made here is that there are no real spends
2271+
// occurring in this block.
22712272
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
22722273
if (!fJustCheck) {
2273-
assert(block.vtx.size() == 1);
22742274
assert(block.nHeight == 0);
2275+
for (const auto& tx : block.vtx) {
22752276

2276-
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2277-
std::multimap<uint256, std::pair<COutPoint, CAmount> > mLocksCreated;
2278-
const CTransaction tx = *(block.vtx[0]);
2279-
2280-
CTxUndo undoDummy;
2281-
UpdateCoins(tx, view, undoDummy, pindex->nHeight);
2282-
2277+
// Directly add new coins to DB
2278+
view.ModifyNewCoins(tx->GetHash(), tx->IsCoinBase())->FromTx(*tx, pindex->nHeight);
2279+
}
22832280
view.SetBestBlock(pindex->GetBlockHash());
22842281
}
22852282
return true;

0 commit comments

Comments
 (0)