mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
genesis block has actual fee issuance in regtest
This commit is contained in:
parent
65ed777e6e
commit
9a9ac25ee1
5 changed files with 70 additions and 40 deletions
|
|
@ -222,6 +222,10 @@ class CTTest (BitcoinTestFramework):
|
|||
|
||||
print("Assets tests...")
|
||||
|
||||
# Bitcoin is the first issuance
|
||||
assert_equal(self.nodes[0].listissuances()[0]["assetlabel"], "bitcoin")
|
||||
assert_equal(len(self.nodes[0].listissuances()), 1)
|
||||
|
||||
# Unblinded issuance of asset
|
||||
issued = self.nodes[0].issueasset(1, 1, False)
|
||||
assert_equal(self.nodes[0].getwalletinfo()["balance"][issued["asset"]], 1)
|
||||
|
|
@ -351,13 +355,13 @@ class CTTest (BitcoinTestFramework):
|
|||
addr2 = txdet2[len(txdet2)-1]["address"]
|
||||
addr3 = txdet3[len(txdet3)-1]["address"]
|
||||
|
||||
assert_equal(len(self.nodes[0].listissuances()), 5);
|
||||
assert_equal(len(self.nodes[0].listissuances()), 6);
|
||||
self.nodes[0].importaddress(addr1)
|
||||
self.nodes[0].importaddress(addr2)
|
||||
self.nodes[0].importaddress(addr3)
|
||||
|
||||
issuances = self.nodes[0].listissuances()
|
||||
assert_equal(len(issuances), 8)
|
||||
assert_equal(len(issuances), 9)
|
||||
|
||||
for issue in issuances:
|
||||
if issue['txid'] == redata1["txid"] and issue['vin'] == redata1["vin"]:
|
||||
|
|
|
|||
|
|
@ -30,19 +30,15 @@ class WalletTest (BitcoinTestFramework):
|
|||
|
||||
def run_test (self):
|
||||
|
||||
# Check that there's no UTXO on none of the nodes
|
||||
assert_equal(len(self.nodes[0].listunspent()), 0)
|
||||
assert_equal(len(self.nodes[1].listunspent()), 0)
|
||||
assert_equal(len(self.nodes[2].listunspent()), 0)
|
||||
# Check that there's 100 UTXOs on each of the nodes
|
||||
assert_equal(len(self.nodes[0].listunspent()), 100)
|
||||
assert_equal(len(self.nodes[1].listunspent()), 100)
|
||||
assert_equal(len(self.nodes[2].listunspent()), 100)
|
||||
|
||||
walletinfo = self.nodes[0].getwalletinfo()
|
||||
assert_equal(walletinfo['balance']["bitcoin"], 21000000)
|
||||
|
||||
print("Mining blocks...")
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
walletinfo = self.nodes[0].getwalletinfo()
|
||||
assert_equal(walletinfo['immature_balance']["bitcoin"], 21000000)
|
||||
assert("bitcoin" not in walletinfo['balance'])
|
||||
|
||||
self.sync_all()
|
||||
self.nodes[1].generate(101)
|
||||
self.sync_all()
|
||||
|
||||
|
|
|
|||
|
|
@ -41,21 +41,15 @@ static CScript StrHexToScriptWithDefault(std::string strScript, const CScript de
|
|||
return returnScript;
|
||||
}
|
||||
|
||||
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)
|
||||
static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::string& networkID, uint32_t nTime, const CScript& scriptChallenge, int32_t nVersion)
|
||||
{
|
||||
// Shards must be evenly divisible
|
||||
assert(MAX_MONEY % rewardShards == 0);
|
||||
CMutableTransaction txNew;
|
||||
txNew.nVersion = 1;
|
||||
txNew.vin.resize(1);
|
||||
txNew.vout.resize(rewardShards);
|
||||
// Any consensus-related values that are command-line set can be added here for anti-footgun
|
||||
txNew.vin[0].scriptSig = CScript(CommitToArguments(params, networkID, scriptChallenge));
|
||||
for (unsigned int i = 0; i < rewardShards; i++) {
|
||||
txNew.vout[i].nValue = genesisReward/rewardShards;
|
||||
txNew.vout[i].nAsset = asset;
|
||||
txNew.vout[i].scriptPubKey = genesisOutputScript;
|
||||
}
|
||||
txNew.vout.clear();
|
||||
txNew.vout.push_back(CTxOut(CAsset(), 0, CScript() << OP_RETURN));
|
||||
|
||||
CBlock genesis;
|
||||
genesis.nTime = nTime;
|
||||
|
|
@ -67,6 +61,41 @@ static CBlock CreateGenesisBlock(const Consensus::Params& params, const std::str
|
|||
return genesis;
|
||||
}
|
||||
|
||||
/** 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 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) {
|
||||
|
||||
uint256 entropy;
|
||||
GenerateAssetEntropy(entropy, prevout, contract);
|
||||
|
||||
CAsset asset;
|
||||
CalculateAsset(asset, entropy);
|
||||
|
||||
// Re-issuance of policyAsset is always unblinded
|
||||
CAsset reissuance;
|
||||
CalculateReissuanceToken(reissuance, entropy, false);
|
||||
|
||||
// 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.vin[0].assetIssuance.assetEntropy = contract;
|
||||
txNew.vin[0].assetIssuance.nAmount = asset_values*asset_outputs;
|
||||
txNew.vin[0].assetIssuance.nInflationKeys = reissuance_values*reissuance_outputs;
|
||||
|
||||
for (unsigned int i = 0; i < asset_outputs; i++) {
|
||||
txNew.vout.push_back(CTxOut(asset, asset_values, issuance_destination));
|
||||
}
|
||||
for (unsigned int i = 0; i < reissuance_outputs; i++) {
|
||||
txNew.vout.push_back(CTxOut(reissuance, reissuance_values, issuance_destination));
|
||||
}
|
||||
|
||||
genesis_block.vtx.push_back(MakeTransactionRef(std::move(txNew)));
|
||||
genesis_block.hashMerkleRoot = BlockMerkleRoot(genesis_block);
|
||||
}
|
||||
|
||||
void CChainParams::UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
|
||||
{
|
||||
consensus.vDeployments[d].nStartTime = nStartTime;
|
||||
|
|
@ -149,7 +178,7 @@ public:
|
|||
CalculateAsset(consensus.pegged_asset, entropy);
|
||||
|
||||
CScript scriptDestination(CScript() << std::vector<unsigned char>(parentGenesisBlockHash.begin(), parentGenesisBlockHash.end()) << OP_WITHDRAWPROOFVERIFY);
|
||||
genesis = CreateGenesisBlock(consensus, strNetworkID, scriptDestination, 1231006505, genesisChallengeScript, 1, MAX_MONEY, 100, consensus.pegged_asset);
|
||||
genesis = CreateGenesisBlock(consensus, strNetworkID, 1231006505, genesisChallengeScript, 1);
|
||||
consensus.hashGenesisBlock = genesis.GetHash();
|
||||
|
||||
scriptCoinbaseDestination = CScript() << ParseHex("0229536c4c83789f59c30b93eb40d4abbd99b8dcc99ba8bd748f29e33c1d279e3c") << OP_CHECKSIG;
|
||||
|
|
@ -259,7 +288,8 @@ public:
|
|||
GenerateAssetEntropy(entropy, COutPoint(uint256(commit), 0), parentGenesisBlockHash);
|
||||
CalculateAsset(consensus.pegged_asset, entropy);
|
||||
|
||||
genesis = CreateGenesisBlock(consensus, strNetworkID, defaultRegtestScript, 1296688602, genesisChallengeScript, 1, MAX_MONEY, 100, consensus.pegged_asset);
|
||||
genesis = CreateGenesisBlock(consensus, strNetworkID, 1296688602, genesisChallengeScript, 1);
|
||||
AppendInitialIssuance(genesis, COutPoint(uint256(commit), 0), parentGenesisBlockHash, 100, 21000000000000, 0, 0, CScript() << OP_TRUE);
|
||||
consensus.hashGenesisBlock = genesis.GetHash();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -65,13 +65,15 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
|||
|
||||
RegisterAllCoreRPCCommands(tableRPC);
|
||||
|
||||
// Make genesis coinbase use out spend-key
|
||||
int gen_size = Params().GenesisBlock().vtx.size();
|
||||
|
||||
// Make genesis second transaction(with spendable outputs) use out spend-key
|
||||
coinbaseKey.MakeNewKey(true);
|
||||
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
|
||||
CMutableTransaction newCoinbase(*(Params().GenesisBlock().vtx[0]));
|
||||
for (unsigned int i = 0; i < Params().GenesisBlock().vtx[0]->vout.size(); i++)
|
||||
newCoinbase.vout[i].scriptPubKey = scriptPubKey;
|
||||
const_cast<CBlock&>(Params().GenesisBlock()).vtx[0] = MakeTransactionRef(newCoinbase);
|
||||
CMutableTransaction newTransaction(*(Params().GenesisBlock().vtx[gen_size-1]));
|
||||
for (unsigned int i = 0; i < Params().GenesisBlock().vtx[gen_size-1]->vout.size(); i++)
|
||||
newTransaction.vout[i].scriptPubKey = scriptPubKey;
|
||||
const_cast<CBlock&>(Params().GenesisBlock()).vtx[gen_size-1] = MakeTransactionRef(newTransaction);
|
||||
const_cast<CBlock&>(Params().GenesisBlock()).hashMerkleRoot = BlockMerkleRoot(Params().GenesisBlock());
|
||||
const_cast<CBlock&>(Params().GenesisBlock()).proof = CProof(CScript()<<OP_TRUE, CScript());
|
||||
const_cast<Consensus::Params&>(Params().GetConsensus()).hashGenesisBlock = Params().GenesisBlock().GetHash();
|
||||
|
|
@ -114,8 +116,9 @@ TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
|
|||
{
|
||||
// Generate a 100-block chain:
|
||||
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
|
||||
assert(Params().GenesisBlock().vtx[0]->vout[0].scriptPubKey == scriptPubKey);
|
||||
coinbaseTxns.push_back(*(Params().GenesisBlock().vtx[0]));
|
||||
assert(Params().GenesisBlock().vtx[Params().GenesisBlock().vtx.size()-1]->vout[0].scriptPubKey == scriptPubKey);
|
||||
// Get spendable outputs from genesis block, which is non-coinbase for regtest
|
||||
coinbaseTxns.push_back(*(Params().GenesisBlock().vtx[Params().GenesisBlock().vtx.size()-1]));
|
||||
for (int i = 0; i < COINBASE_MATURITY; i++)
|
||||
{
|
||||
std::vector<CMutableTransaction> noTxns;
|
||||
|
|
|
|||
|
|
@ -2267,19 +2267,16 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
|
||||
assert(hashPrevBlock == view.GetBestBlock());
|
||||
|
||||
// Gesesis coinbase *is* spendable
|
||||
// Add genesis outputs. The assumption made here is that there are no real spends
|
||||
// occurring in this block.
|
||||
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
|
||||
if (!fJustCheck) {
|
||||
assert(block.vtx.size() == 1);
|
||||
assert(block.nHeight == 0);
|
||||
for (const auto& tx : block.vtx) {
|
||||
|
||||
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
|
||||
std::multimap<uint256, std::pair<COutPoint, CAmount> > mLocksCreated;
|
||||
const CTransaction tx = *(block.vtx[0]);
|
||||
|
||||
CTxUndo undoDummy;
|
||||
UpdateCoins(tx, view, undoDummy, pindex->nHeight);
|
||||
|
||||
// Directly add new coins to DB
|
||||
view.ModifyNewCoins(tx->GetHash(), tx->IsCoinBase())->FromTx(*tx, pindex->nHeight);
|
||||
}
|
||||
view.SetBestBlock(pindex->GetBlockHash());
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue