Skip to content

Commit

Permalink
treat snapshot balances as genesis block transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
sfultong committed Dec 10, 2015
1 parent d02d31c commit bbc60f0
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 40 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,6 @@ qa/pull-tester/test.*/*
!src/leveldb*/Makefile

/doc/doxygen/

# clion
.idea
13 changes: 12 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ $(LIBLEVELDB) $(LIBMEMENV):
OPT="$(CXXFLAGS) $(CPPFLAGS)"
endif

SNAPSHOT_INCLUDES = -I/home/sfultong/bitcoin-spinoff-toolkit/include

BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)

BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
BITCOIN_INCLUDES += $(SNAPSHOT_INCLUDES)

LIBBITCOIN_SERVER=libbitcoin_server.a
LIBBITCOIN_WALLET=libbitcoin_wallet.a
Expand All @@ -35,6 +38,10 @@ LIBSECP256K1=secp256k1/libsecp256k1.la
$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)

LIBBST = /home/sfultong/bitcoin-spinoff-toolkit/libspinoff_toolkit.so
LIBBITCOIN2 = /nix/store/x7g501xv9inzriw999g2xksfsbzm966d-libbitcoin-2.9.0/lib/libbitcoin.so
LIBBST_ALL = $(LIBBST) $(LIBBITCOIN2)

# Make is not made aware of per-object dependencies to avoid limiting building parallelization
# But to build the less dependent modules first, we manually select their order here:
EXTRA_LIBRARIES = \
Expand Down Expand Up @@ -187,6 +194,7 @@ libbitcoin_server_a_SOURCES = \
txmempool.cpp \
$(JSON_H) \
$(BITCOIN_CORE_H)
# libbitcoin_server_a_LIBADD = $(LIBBST_ALL)

# wallet: shared between bitcoind and bitcoin-qt, but only linked
# when wallet enabled
Expand Down Expand Up @@ -257,6 +265,8 @@ libbitcoin_common_a_SOURCES = \
script/standard.cpp \
script/script_error.cpp \
$(BITCOIN_CORE_H)
libbitcoin_common_a_LIBADD = $(LIBBST_ALL)


# util: shared between all executables.
# This library *must* be included to make sure that the glibc
Expand Down Expand Up @@ -301,6 +311,7 @@ litecoind_LDADD = \
$(LIBBITCOIN_CRYPTO) \
$(LIBLEVELDB) \
$(LIBMEMENV) \
$(LIBBST_ALL) \
$(LIBSECP256K1)

if ENABLE_WALLET
Expand Down Expand Up @@ -378,7 +389,7 @@ endif

libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj $(SNAPSHOT_INCLUDES) -DBUILD_BITCOIN_INTERNAL
if USE_LIBSECP256K1
libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la
endif
Expand Down
107 changes: 77 additions & 30 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <assert.h>

#include <boost/assign/list_of.hpp>
#include <bitcoin/bst/claim.h>
#include <boost/foreach.hpp>

using namespace std;
using namespace boost::assign;
Expand Down Expand Up @@ -101,6 +103,58 @@ static const Checkpoints::CCheckpointData dataRegtest = {
0
};

static bool generateGenesis(CBlock& genesis) {
/**
* Build the genesis block. Note that the output of the genesis coinbase cannot
* be spent as it did not originally exist in the database.
*
* CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
* CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
* CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
bst::snapshot_reader snapshot_reader;
ifstream stream;
if (! bst::openSnapshot(stream, snapshot_reader)) return false;
bst::SnapshotEntryCollection p2pkhEntries = bst::getP2PKHCollection(snapshot_reader);
bst::SnapshotEntryCollection p2shEntries = bst::getP2SHCollection(snapshot_reader);

const char* pszTimestamp = "NY Times 05/Oct/2011 Steve Jobs, Apple’s Visionary, Dies at 56";
CMutableTransaction txNew;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG;
genesis.vtx.push_back(txNew);

CScript fakeSign = CScript() << 486604799;
BOOST_FOREACH(bst::snapshot_entry& entry, p2pkhEntries) {
txNew.vin[0].scriptSig = fakeSign;
txNew.vout[0].nValue = entry.amount;
txNew.vout[0].scriptPubKey = CScript() << OP_DUP << OP_HASH160 << entry.hash << OP_EQUALVERIFY << OP_CHECKSIG;
genesis.vtx.push_back(txNew);
}

BOOST_FOREACH(bst::snapshot_entry& entry, p2shEntries) {
txNew.vin[0].scriptSig = fakeSign;
txNew.vout[0].nValue = entry.amount;
txNew.vout[0].scriptPubKey = CScript() << OP_HASH160 << entry.hash << OP_EQUAL;
genesis.vtx.push_back(txNew);
}


genesis.hashPrevBlock = 0;
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
genesis.nVersion = 1;
genesis.nTime = 1317972665;
genesis.nBits = 0x8e0ffff0;
genesis.nNonce = 2084524493;

return true;
}

class CMainParams : public CChainParams {
public:
CMainParams() {
Expand All @@ -126,43 +180,23 @@ class CMainParams : public CChainParams {
nTargetTimespan = 3.5 * 24 * 60 * 60; // 3.5 days
nTargetSpacing = 2.5 * 60; // 2.5 minutes

/**
* Build the genesis block. Note that the output of the genesis coinbase cannot
* be spent as it did not originally exist in the database.
*
* CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
* CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
* CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
* CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
* vMerkleTree: 4a5e1e
*/
const char* pszTimestamp = "NY Times 05/Oct/2011 Steve Jobs, Apple’s Visionary, Dies at 56";
CMutableTransaction txNew;
txNew.vin.resize(1);
txNew.vout.resize(1);
txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << vector<unsigned char>((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp));
txNew.vout[0].nValue = 50 * COIN;
txNew.vout[0].scriptPubKey = CScript() << ParseHex("040184710fa689ad5023690c80f3a49c8f13f8d45b8c857fbcbc8bc4a8e4d3eb4b10f4d4604fa08dce601aaf0f470216fe1b51850b4acf21b179c45070ac7b03a9") << OP_CHECKSIG;
genesis.vtx.push_back(txNew);
genesis.hashPrevBlock = 0;
genesis.hashMerkleRoot = genesis.BuildMerkleTree();
genesis.nVersion = 1;
genesis.nTime = 1317972665;
genesis.nBits = 0x1e0ffff0;
genesis.nNonce = 2084524493;
assert(true == generateGenesis(genesis));

//TODO uncomment and fix
/*
hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0x12a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2"));
assert(genesis.hashMerkleRoot == uint256("0x97ddfbbae6be97fd6cdf3e7ca13232a3afff2353e29badfab7f73011edd4ced9"));
*/

vSeeds.push_back(CDNSSeedData("litecointools.com", "dnsseed.litecointools.com"));
vSeeds.push_back(CDNSSeedData("litecoinpool.org", "dnsseed.litecoinpool.org"));
vSeeds.push_back(CDNSSeedData("xurious.com", "dnsseed.ltc.xurious.com"));
vSeeds.push_back(CDNSSeedData("koin-project.com", "dnsseed.koin-project.com"));
vSeeds.push_back(CDNSSeedData("weminemnc.com", "dnsseed.weminemnc.com"));

base58Prefixes[PUBKEY_ADDRESS] = list_of(48);
base58Prefixes[SCRIPT_ADDRESS] = list_of(5);
base58Prefixes[PUBKEY_ADDRESS] = list_of(52);
base58Prefixes[SCRIPT_ADDRESS] = list_of(9);
base58Prefixes[SECRET_KEY] = list_of(176);
base58Prefixes[EXT_PUBLIC_KEY] = list_of(0x04)(0x88)(0xB2)(0x1E);
base58Prefixes[EXT_SECRET_KEY] = list_of(0x04)(0x88)(0xAD)(0xE4);
Expand Down Expand Up @@ -214,7 +248,7 @@ class CTestNetParams : public CMainParams {
genesis.nTime = 1317798646;
genesis.nNonce = 385270584;
hashGenesisBlock = genesis.GetHash();
assert(hashGenesisBlock == uint256("0xf5ae71e26c74beacc88382716aced69cddf3dffff24f384e1808905e0188f68f"));
//assert(hashGenesisBlock == uint256("0xf5ae71e26c74beacc88382716aced69cddf3dffff24f384e1808905e0188f68f"));

vFixedSeeds.clear();
vSeeds.clear();
Expand All @@ -241,7 +275,7 @@ class CTestNetParams : public CMainParams {
// Litecoin: Testnet v2 enforced as of block 400k
nEnforceV2AfterHeight = 400000;
}
const Checkpoints::CCheckpointData& Checkpoints() const
const Checkpoints::CCheckpointData& Checkpoints() const
{
return dataTestnet;
}
Expand Down Expand Up @@ -270,10 +304,23 @@ class CRegTestParams : public CTestNetParams {
bnProofOfWorkLimit = ~uint256(0) >> 1;
genesis.nTime = 1296688602;
genesis.nBits = 0x207fffff;
genesis.nNonce = 0;
/*
bool fNegative;
bool fOverflow;
uint256 bnTarget;
bnTarget.SetCompact(genesis.nBits, &fNegative, &fOverflow);
for (unsigned int i = 0; true; i++) {
genesis.nNonce = i;
uint256 powHash = genesis.GetPoWHash();
if (powHash <= bnTarget) break;
}
cout << "nonce is " << genesis.nNonce << endl;
*/
genesis.nNonce = 2;
hashGenesisBlock = genesis.GetHash();
nDefaultPort = 19444;
assert(hashGenesisBlock == uint256("0x530827f38f93b43ed12af0b3ad25a288dc02ed74d6d7857862df51fc56c416f9"));
cout << "hashGenesisBlock " << hashGenesisBlock.ToString() << endl;
assert(hashGenesisBlock == uint256("91a4d6becff084cd8bbffc48721358acb5a80e7888dc780d034b50b859a001f0"));

vFixedSeeds.clear(); //! Regtest mode doesn't have any fixed seeds.
vSeeds.clear(); //! Regtest mode doesn't have any DNS seeds.
Expand Down
18 changes: 14 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1659,18 +1659,25 @@ static int64_t nTimeTotal = 0;

bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck)
{
bool isGenesis = block.GetHash() == Params().HashGenesisBlock() && pindex->nHeight == 0;
AssertLockHeld(cs_main);
// Check it again in case a previous version let a bad block in
if (!CheckBlock(block, state, !fJustCheck, !fJustCheck))
if (!isGenesis && !CheckBlock(block, state, !fJustCheck, !fJustCheck))
return false;

// verify that the view's current state corresponds to the previous block
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256(0) : pindex->pprev->GetBlockHash();
assert(hashPrevBlock == view.GetBestBlock());

// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if (block.GetHash() == Params().HashGenesisBlock()) {
// if this is the genesis, we just want to add in all transactions without checking them
if (isGenesis) {
CTxUndo undoDummy;
// skip first coinbase in genesis
for (unsigned int i = 1; i < block.vtx.size(); i++) {
const CTransaction &tx = block.vtx[i];
UpdateCoins(tx, state, view, undoDummy, pindex->nHeight);
}

view.SetBestBlock(pindex->GetBlockHash());
return true;
}
Expand Down Expand Up @@ -2457,6 +2464,9 @@ bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool f

bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot)
{
// don't check genesis... it has multiple coinbases
if (block.GetHash() == Params().HashGenesisBlock()) return true;

// These are checks that are independent of context.

// Check that the header is valid (particularly PoW). This is mostly
Expand Down
5 changes: 0 additions & 5 deletions src/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -938,11 +938,6 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
{
LOCK2(cs_main, cs_wallet);

// no need to read and scan block, if block was created before
// our wallet birthday (as adjusted for block time variability)
while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
pindex = chainActive.Next(pindex);

ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
double dProgressStart = Checkpoints::GuessVerificationProgress(pindex, false);
double dProgressTip = Checkpoints::GuessVerificationProgress(chainActive.Tip(), false);
Expand Down

0 comments on commit bbc60f0

Please sign in to comment.