Browse Source

PoC-6 : 12 second blocks, allow multi-level uncles, rejig rewards.

cl-refactor
Gav Wood 11 years ago
parent
commit
4fe8075365
  1. 2
      libethcore/BlockInfo.cpp
  2. 3
      libethcore/Exceptions.h
  3. 14
      libethereum/BlockChain.cpp
  4. 5
      libethereum/BlockChain.h
  5. 26
      libethereum/State.cpp
  6. 4
      libethereum/State.h

2
libethcore/BlockInfo.cpp

@ -166,7 +166,7 @@ u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const
if (!parentHash)
return c_genesisDifficulty;
else
return timestamp >= _parent.timestamp + 42 ? _parent.difficulty - (_parent.difficulty >> 10) : (_parent.difficulty + (_parent.difficulty >> 10));
return timestamp >= _parent.timestamp + 9 ? _parent.difficulty - (_parent.difficulty >> 10) : (_parent.difficulty + (_parent.difficulty >> 10));
}
void BlockInfo::verifyParent(BlockInfo const& _parent) const

3
libethcore/Exceptions.h

@ -20,7 +20,8 @@ class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f,
class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"; } };
class InvalidUnclesHash: public Exception {};
class InvalidUncle: public Exception {};
class UncleNotAnUncle: public Exception {};
class UncleTooOld: public Exception {};
class UncleInChain: public Exception {};
class DuplicateUncleNonce: public Exception {};
class InvalidStateRoot: public Exception {};
class InvalidTransactionsHash: public Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } };

14
libethereum/BlockChain.cpp

@ -386,6 +386,20 @@ void BlockChain::checkConsistency()
delete it;
}
h256Set BlockChain::allUnclesFrom(h256 _parent) const
{
// Get all uncles cited given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5).
h256Set ret;
h256 p = _parent;
for (unsigned i = 0; i < 6 && p != m_genesisHash; ++i, p = details(p).parent)
{
ret.insert(sha3(RLP(block(p))[0].data()));
for (auto i: RLP(block(p))[2])
ret.insert(sha3(i.data()));
}
return ret;
}
bytes BlockChain::block(h256 _hash) const
{
if (_hash == m_genesisHash)

5
libethereum/BlockChain.h

@ -107,6 +107,11 @@ public:
/// Get the hash of a block of a given number. Slow; try not to use it too much.
h256 numberHash(unsigned _n) const;
/// Get all blocks not allowed as uncles given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5).
/// @returns set including the header-hash of every parent (including @a _parent) up to and including generation +5
/// togther with all their quoted uncles.
h256Set allUnclesFrom(h256 _parent) const;
/// @returns the genesis block header.
static BlockInfo const& genesis() { UpgradableGuard l(x_genesis); if (!s_genesis) { auto gb = createGenesisBlock(); UpgradeGuard ul(l); (s_genesis = new BlockInfo)->populate(&gb); } return *s_genesis; }

26
libethereum/State.cpp

@ -390,7 +390,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const
sync(_bc, _bi.parentHash);
resetCurrent();
m_previousBlock = biParent;
return enact(_block, biGrandParent);
return enact(_block, &_bc);
}
map<Address, u256> State::addresses() const
@ -499,7 +499,7 @@ h256s State::sync(TransactionQueue& _tq, bool* o_transactionQueueChanged)
return ret;
}
u256 State::enact(bytesConstRef _block, BlockInfo const& _grandParent, bool _checkNonce)
u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
{
// m_currentBlock is assumed to be prepopulated and reset.
@ -558,16 +558,21 @@ u256 State::enact(bytesConstRef _block, BlockInfo const& _grandParent, bool _che
// Check uncles & apply their rewards to state.
set<h256> nonces = { m_currentBlock.nonce };
Addresses rewarded;
set<h256> knownUncles = _bc ? _bc->allUnclesFrom(m_currentBlock.parentHash) : set<h256>();
for (auto const& i: RLP(_block)[2])
{
BlockInfo uncle = BlockInfo::fromHeader(i.data());
if (m_previousBlock.parentHash != uncle.parentHash)
throw UncleNotAnUncle();
if (nonces.count(uncle.nonce))
throw DuplicateUncleNonce();
if (_grandParent)
uncle.verifyParent(_grandParent);
if (_bc)
{
BlockInfo uncleParent(_bc->block(uncle.parentHash));
if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 6) // TODO: check 6. might be 7 or something...
throw UncleTooOld();
if (knownUncles.count(uncle.hash))
throw UncleInChain();
uncle.verifyParent(uncleParent);
}
nonces.insert(uncle.nonce);
tdIncrease += uncle.difficulty;
@ -651,7 +656,7 @@ bool State::amIJustParanoid(BlockChain const& _bc)
cnote << "PARANOIA root:" << s.rootHash();
// s.m_currentBlock.populate(&block.out(), false);
// s.m_currentBlock.verifyInternals(&block.out());
s.enact(&block.out(), BlockInfo(), false); // don't check nonce for this since we haven't mined it yet.
s.enact(&block.out(), &_bc, false); // don't check nonce for this since we haven't mined it yet.
s.cleanup(false);
return true;
}
@ -694,6 +699,7 @@ void State::commitToMine(BlockChain const& _bc)
if (m_previousBlock != BlockChain::genesis())
{
// TODO: find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations.
// Find uncles if we're not a direct child of the genesis.
// cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl;
auto us = _bc.details(m_previousBlock.parentHash).children;
@ -1181,8 +1187,8 @@ void State::applyRewards(Addresses const& _uncleAddresses)
u256 r = m_blockReward;
for (auto const& i: _uncleAddresses)
{
addBalance(i, m_blockReward * 3 / 4);
r += m_blockReward / 8;
addBalance(i, m_blockReward * 15 / 16);
r += m_blockReward / 32;
}
addBalance(m_currentBlock.coinbaseAddress, r);
}

4
libethereum/State.h

@ -299,9 +299,9 @@ private:
/// Commit all changes waiting in the address cache to the DB.
void commit();
/// Execute the given block, assuming it corresponds to m_currentBlock. If _grandParent is passed, it will be used to check the uncles.
/// Execute the given block, assuming it corresponds to m_currentBlock. If _bc is passed, it will be used to check the uncles.
/// Throws on failure.
u256 enact(bytesConstRef _block, BlockInfo const& _grandParent = BlockInfo(), bool _checkNonce = true);
u256 enact(bytesConstRef _block, BlockChain const* _bc = nullptr, bool _checkNonce = true);
// Two priviledged entry points for the VM (these don't get added to the Transaction lists):
// We assume all instrinsic fees are paid up before this point.

Loading…
Cancel
Save