Browse Source

More verification stuff.

cl-refactor
Gav Wood 11 years ago
parent
commit
b3db8f3980
  1. 21
      libethereum/BlockChain.cpp
  2. 4
      libethereum/BlockChain.h
  3. 31
      libethereum/BlockInfo.cpp
  4. 5
      libethereum/BlockInfo.h
  5. 4
      libethereum/State.cpp

21
libethereum/BlockChain.cpp

@ -42,12 +42,16 @@ BlockChain::~BlockChain()
{
}
u256s BlockChain::blockChain() const
u256s BlockChain::blockChain(u256Set const& _earlyExit) const
{
// TODO: return the current valid block chain from most recent to genesis.
// TODO: arguments for specifying a set of early-ends
u256s ret;
ret.reserve(m_numberAndParent[m_lastBlockHash].first + 1);
auto i = m_lastBlockHash;
for (; i != m_genesisHash && !_earlyExit.count(i); i = m_numberAndParent[i].second)
ret.push_back(i);
ret.push_back(i);
return ret;
}
@ -73,13 +77,9 @@ void BlockChain::import(bytes const& _block)
return;
bi.number = it->second.first + 1;
// Check Ancestry:
// Check timestamp is after previous timestamp.
if (bi.timestamp <= BlockInfo(block(bi.parentHash)).timestamp)
throw InvalidTimestamp();
// TODO: check difficulty is correct given the two timestamps.
// if (bi.timestamp )
// Check family:
BlockInfo bip(block(bi.parentHash));
bi.verifyParent(bip);
// TODO: check transactions are valid and that they result in a state equivalent to our state_root.
// this saves us from an embarrassing exit later.
@ -95,13 +95,14 @@ void BlockChain::import(bytes const& _block)
}
// Insert into DB
m_numberAndParent[newHash] = make_pair(bi.number, bi.parentHash);
m_numberAndParent[newHash] = make_pair((uint)bi.number, bi.parentHash);
m_children.insert(make_pair(bi.parentHash, newHash));
ldb::WriteOptions o;
m_db->Put(o, ldb::Slice(toBigEndianString(newHash)), (ldb::Slice)ref(_block));
// This might be the new last block; count back through ancestors to common shared ancestor and compare to current.
// TODO: Use GHOST algorithm.
}
catch (...)
{

4
libethereum/BlockChain.h

@ -51,7 +51,7 @@ public:
bytesConstRef lastBlock() const { return block(m_lastBlockHash); }
/// Get the full block chain, according to the GHOST algo and the blocks available in the db.
u256s blockChain() const;
u256s blockChain(u256Set const& _earlyExit) const;
/// Get the number of the last block of the longest chain.
u256 lastBlockNumber() const;
@ -60,7 +60,7 @@ public:
private:
/// Get fully populated from disk DB.
mutable std::map<u256, std::pair<u256, u256>> m_numberAndParent;
mutable std::map<u256, std::pair<uint, u256>> m_numberAndParent;
mutable std::multimap<u256, u256> m_children;
ldb::DB* m_db;

31
libethereum/BlockInfo.cpp

@ -84,7 +84,7 @@ void BlockInfo::populate(bytesConstRef _block, u256 _number)
}
}
void BlockInfo::verifyInternals(bytesConstRef _block)
void BlockInfo::verifyInternals(bytesConstRef _block) const
{
RLP root(_block);
@ -99,3 +99,32 @@ void BlockInfo::verifyInternals(bytesConstRef _block)
if (d.eval(nonce) >= difficulty)
throw InvalidNonce();
}
u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const
{
/*
D(genesis_block) = 2^36
D(block) =
if block.timestamp >= block.parent.timestamp + 42: D(block.parent) - floor(D(block.parent) / 1024)
else: D(block.parent) + floor(D(block.parent) / 1024)
*/
if (number == 0)
return (u256)1 << 36;
else
return timestamp >= _parent.timestamp + 42 ? _parent.difficulty - (_parent.difficulty >> 10) : (_parent.difficulty + (_parent.difficulty >> 10));
}
void BlockInfo::verifyParent(BlockInfo const& _parent) const
{
if (number == 0)
// Genesis block - no parent.
return;
// Check timestamp is after previous timestamp.
if (_parent.timestamp <= _parent.timestamp)
throw InvalidTimestamp();
// Check difficulty is correct given the two timestamps.
if (difficulty != calculateDifficulty(_parent))
throw InvalidDifficulty();
}

5
libethereum/BlockInfo.h

@ -49,7 +49,10 @@ public:
static BlockInfo const& genesis() { if (!s_genesis) (s_genesis = new BlockInfo)->populateGenesis(); return *s_genesis; }
void populate(bytesConstRef _block, u256 _number = 0);
void verifyInternals(bytesConstRef _block);
void verifyInternals(bytesConstRef _block) const;
void verifyParent(BlockInfo const& _parent) const;
u256 calculateDifficulty(BlockInfo const& _bi) const;
/// No-nonce sha3 of the header only.
u256 headerHashWithoutNonce() const;

4
libethereum/State.cpp

@ -83,7 +83,7 @@ void State::sync(BlockChain const& _bc, TransactionQueue& _tq)
// New blocks available, or we've switched to a different branch. All change.
// TODO: Find most recent state dump and replay what's left.
// (Most recent state dump might end up being genesis.)
std::vector<u256> l = _bc.blockChain(); // TODO: take u256Set "restorePoints" argument so it needs only give us the chain up until some restore point in the past where we stored the state.
std::vector<u256> l = _bc.blockChain(u256Set()); // TODO: take u256Set "restorePoints" argument so it needs only give us the chain up until some restore point in the past where we stored the state.
if (l.back() == BlockInfo::genesis().hash)
{
@ -125,6 +125,8 @@ void State::sync(BlockChain const& _bc, TransactionQueue& _tq)
}
catch (...)
{
// Something else went wrong - drop it.
_tq.drop(i.first);
}
}

Loading…
Cancel
Save