Browse Source

Fast block hash from number.

cl-refactor
Gav Wood 10 years ago
parent
commit
b5c2e82b19
  1. 9
      libethcore/Common.cpp
  2. 23
      libethereum/BlockChain.cpp
  3. 32
      libethereum/BlockChain.h
  4. 11
      libethereum/BlockDetails.h

9
libethcore/Common.cpp

@ -33,13 +33,14 @@ namespace eth
{ {
const unsigned c_protocolVersion = 56; const unsigned c_protocolVersion = 56;
const unsigned c_databaseVersion = 6 + const unsigned c_databaseBaseVersion = 7;
#if ETH_FATDB #if ETH_FATDB
1000 const unsigned c_databaseVersionModifier = 1000;
#else #else
0 const unsigned c_databaseVersionModifier = 0;
#endif #endif
;
const unsigned c_databaseVersion = c_databaseBaseVersion + c_databaseVersionModifier;
vector<pair<u256, string>> const& units() vector<pair<u256, string>> const& units()
{ {

23
libethereum/BlockChain.cpp

@ -46,7 +46,7 @@ namespace js = json_spirit;
std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc) std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc)
{ {
string cmp = toBigEndianString(_bc.currentHash()); string cmp = toBigEndianString(_bc.currentHash());
auto it = _bc.m_db->NewIterator(_bc.m_readOptions); auto it = _bc.m_blocksDB->NewIterator(_bc.m_readOptions);
for (it->SeekToFirst(); it->Valid(); it->Next()) for (it->SeekToFirst(); it->Valid(); it->Next())
if (it->key().ToString() != "best") if (it->key().ToString() != "best")
{ {
@ -346,17 +346,14 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
m_receipts[newHash] = br; m_receipts[newHash] = br;
} }
m_extrasDB->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)dev::ref(m_details[newHash].rlp())); m_blocksDB->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block));
m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(newHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[newHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 3), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(h256(bi.number), ExtraBlockHash), (ldb::Slice)dev::ref(m_blockHashes[h256(bi.number)].rlp()));
m_extrasDB->Put(m_writeOptions, toSlice(newHash, 4), (ldb::Slice)dev::ref(m_receipts[newHash].rlp())); for (auto const& h: tas)
m_db->Put(m_writeOptions, toSlice(newHash), (ldb::Slice)ref(_block)); m_extrasDB->Put(m_writeOptions, toSlice(h, ExtraTransactionAddress), (ldb::Slice)dev::ref(m_transactionAddresses[h].rlp()));
RLP blockRLP(_block); m_extrasDB->Put(m_writeOptions, toSlice(newHash, ExtraLogBlooms), (ldb::Slice)dev::ref(m_logBlooms[newHash].rlp()));
TransactionAddress ta; m_extrasDB->Put(m_writeOptions, toSlice(newHash, ExtraReceipts), (ldb::Slice)dev::ref(m_receipts[newHash].rlp()));
ta.blockHash = newHash;
for (ta.index = 0; ta.index < blockRLP[1].itemCount(); ++ta.index)
m_extrasDB->Put(m_writeOptions, toSlice(sha3(blockRLP[1][ta.index].data()), 5), (ldb::Slice)dev::ref(ta.rlp()));
#if ETH_PARANOIA #if ETH_PARANOIA
checkConsistency(); checkConsistency();
@ -636,7 +633,5 @@ bytes BlockChain::block(h256 _hash) const
m_blocks[_hash].resize(d.size()); m_blocks[_hash].resize(d.size());
memcpy(m_blocks[_hash].data(), d.data(), d.size()); memcpy(m_blocks[_hash].data(), d.data(), d.size());
noteUsed(_hash);
return m_blocks[_hash]; return m_blocks[_hash];
} }

32
libethereum/BlockChain.h

@ -62,8 +62,17 @@ std::map<Address, Account> const& genesisState();
ldb::Slice toSlice(h256 _h, unsigned _sub = 0); ldb::Slice toSlice(h256 _h, unsigned _sub = 0);
using BlocksHash = std::map<h256, bytes>;
using TransactionHashes = h256s; using TransactionHashes = h256s;
enum {
ExtraDetails = 0,
ExtraBlockHash,
ExtraTransactionAddress,
ExtraLogBlooms,
ExtraReceipts
};
/** /**
* @brief Implements the blockchain database. All data this gives is disk-backed. * @brief Implements the blockchain database. All data this gives is disk-backed.
* @threadsafe * @threadsafe
@ -119,12 +128,11 @@ public:
TransactionHashes transactionHashes(h256 _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t: rlp[1]) ret.push_back(sha3(t.data())); return ret; } TransactionHashes transactionHashes(h256 _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t: rlp[1]) ret.push_back(sha3(t.data())); return ret; }
TransactionHashes transactionHashes() const { return transactionHashes(currentHash()); } TransactionHashes transactionHashes() const { return transactionHashes(currentHash()); }
/// Get a block (RLP format) for the given hash (or the most recent mined if none given). Thread-safe. /// Get a list of transaction hashes for a given block. Thread-safe.
bytes block(h256 _hash) const; h256 numberHash(u256 _index) const { if (!_index) return genesisHash(); return queryExtras<BlockHash, ExtraBlockHash>(h256(_index), m_blockHashes, x_blockHashes, NullBlockHash).value; }
bytes block() const { return block(currentHash()); }
/// Get a transaction from its hash. Thread-safe. /// Get a transaction from its hash. Thread-safe.
bytes transaction(h256 _transactionHash) const { TransactionAddress ta = queryExtras<TransactionAddress, 5>(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytes(); return transaction(ta.blockHash, ta.index); } bytes transaction(h256 _transactionHash) const { TransactionAddress ta = queryExtras<TransactionAddress, ExtraTransactionAddress>(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytes(); return transaction(ta.blockHash, ta.index); }
/// Get a block's transaction (RLP format) for the given block hash (or the most recent mined if none given) & index. Thread-safe. /// Get a block's transaction (RLP format) for the given block hash (or the most recent mined if none given) & index. Thread-safe.
bytes transaction(h256 _blockHash, unsigned _i) const { bytes b = block(_blockHash); return RLP(b)[1][_i].data().toBytes(); } bytes transaction(h256 _blockHash, unsigned _i) const { bytes b = block(_blockHash); return RLP(b)[1][_i].data().toBytes(); }
@ -163,20 +171,18 @@ public:
struct Statistics struct Statistics
{ {
unsigned memBlocks;
unsigned memDetails; unsigned memDetails;
unsigned memLogBlooms; unsigned memLogBlooms;
unsigned memReceipts; unsigned memReceipts;
unsigned memTransactionAddresses; unsigned memTransactionAddresses;
unsigned memBlockHashes; unsigned memCache;
unsigned memTotal() const { return memBlocks + memDetails + memLogBlooms + memReceipts + memTransactionAddresses + memBlockHashes; }
}; };
/// @returns statistics about memory usage. /// @returns statistics about memory usage.
Statistics usage(bool _freshen = false) const { if (_freshen) updateStats(); return m_lastStats; } Statistics usage() const;
/// Deallocate unused data. /// Deallocate unused data.
void garbageCollect(bool _force = false); void garbageCollect();
private: private:
void open(std::string _path, bool _killExisting = false); void open(std::string _path, bool _killExisting = false);
@ -209,9 +215,9 @@ private:
void checkConsistency(); void checkConsistency();
/// The caches of the disk DB and their locks. /// The caches of the disk DB and their locks.
mutable SharedMutex x_blocks; mutable boost::shared_mutex x_blocks;
mutable BlocksHash m_blocks; mutable BlocksHash m_blocks;
mutable SharedMutex x_details; mutable boost::shared_mutex x_details;
mutable BlockDetailsHash m_details; mutable BlockDetailsHash m_details;
mutable SharedMutex x_logBlooms; mutable SharedMutex x_logBlooms;
mutable BlockLogBloomsHash m_logBlooms; mutable BlockLogBloomsHash m_logBlooms;
@ -219,8 +225,8 @@ private:
mutable BlockReceiptsHash m_receipts; mutable BlockReceiptsHash m_receipts;
mutable boost::shared_mutex x_transactionAddresses; mutable boost::shared_mutex x_transactionAddresses;
mutable TransactionAddressHash m_transactionAddresses; mutable TransactionAddressHash m_transactionAddresses;
mutable boost::shared_mutex x_cache; mutable boost::shared_mutex x_blockHashes;
mutable std::map<h256, bytes> m_cache; mutable BlockHashHash m_blockHashes;
/// The disk DBs. Thread-safe, so no need for locks. /// The disk DBs. Thread-safe, so no need for locks.
ldb::DB* m_blocksDB; ldb::DB* m_blocksDB;

11
libethereum/BlockDetails.h

@ -97,6 +97,15 @@ struct TransactionAddress
static const unsigned size = 67; static const unsigned size = 67;
}; };
struct BlockHash
{
BlockHash() {}
BlockHash(RLP const& _r) { value = _r.toHash<h256>(); }
bytes rlp() const { return dev::rlp(value); }
h256 value;
};
struct TransactionAddress struct TransactionAddress
{ {
TransactionAddress() {} TransactionAddress() {}
@ -113,11 +122,13 @@ using BlockDetailsHash = std::map<h256, BlockDetails>;
using BlockLogBloomsHash = std::map<h256, BlockLogBlooms>; using BlockLogBloomsHash = std::map<h256, BlockLogBlooms>;
using BlockReceiptsHash = std::map<h256, BlockReceipts>; using BlockReceiptsHash = std::map<h256, BlockReceipts>;
using TransactionAddressHash = std::map<h256, TransactionAddress>; using TransactionAddressHash = std::map<h256, TransactionAddress>;
using BlockHashHash = std::map<h256, BlockHash>;
static const BlockDetails NullBlockDetails; static const BlockDetails NullBlockDetails;
static const BlockLogBlooms NullBlockLogBlooms; static const BlockLogBlooms NullBlockLogBlooms;
static const BlockReceipts NullBlockReceipts; static const BlockReceipts NullBlockReceipts;
static const TransactionAddress NullTransactionAddress; static const TransactionAddress NullTransactionAddress;
static const BlockHash NullBlockHash;
} }
} }

Loading…
Cancel
Save