Browse Source

Merge branch 'bc' of https://github.com/arkpar/cpp-ethereum into arkpar-bc

cl-refactor
Gav Wood 10 years ago
parent
commit
182a88e721
  1. 3
      libdevcore/Common.h
  2. 2
      libdevcore/CommonData.cpp
  3. 2
      libdevcore/CommonData.h
  4. 58
      libdevcore/TrieHash.cpp
  5. 15
      libdevcore/TrieHash.h
  6. 12
      libethcore/BlockInfo.cpp
  7. 20
      libethereum/State.cpp
  8. 54
      test/libdevcrypto/trie.cpp

3
libdevcore/Common.h

@ -86,8 +86,9 @@ extern const u256 UndefinedU256;
// Map types. // Map types.
using StringMap = std::map<std::string, std::string>; using StringMap = std::map<std::string, std::string>;
using BytesMap = std::map<bytes, bytes>;
using u256Map = std::map<u256, u256>; using u256Map = std::map<u256, u256>;
using HexMap = std::map<bytes, std::string>; using HexMap = std::map<bytes, bytes>;
// Hash types. // Hash types.
using StringHashMap = std::unordered_map<std::string, std::string>; using StringHashMap = std::unordered_map<std::string, std::string>;

2
libdevcore/CommonData.cpp

@ -115,7 +115,7 @@ bytes dev::fromHex(std::string const& _s, WhenError _throw)
return ret; return ret;
} }
bytes dev::asNibbles(std::string const& _s) bytes dev::asNibbles(bytesConstRef const& _s)
{ {
std::vector<uint8_t> ret; std::vector<uint8_t> ret;
ret.reserve(_s.size() * 2); ret.reserve(_s.size() * 2);

2
libdevcore/CommonData.h

@ -95,7 +95,7 @@ inline bytes asBytes(std::string const& _b)
/// Converts a string into the big-endian base-16 stream of integers (NOT ASCII). /// Converts a string into the big-endian base-16 stream of integers (NOT ASCII).
/// @example asNibbles("A")[0] == 4 && asNibbles("A")[1] == 1 /// @example asNibbles("A")[0] == 4 && asNibbles("A")[1] == 1
bytes asNibbles(std::string const& _s); bytes asNibbles(bytesConstRef const& _s);
// Big-endian to/from host endian conversion functions. // Big-endian to/from host endian conversion functions.

58
libdevcore/TrieHash.cpp

@ -158,74 +158,40 @@ void hash256aux(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_i
} }
} }
h256 hash256(StringMap const& _s) bytes rlp256(BytesMap const& _s)
{
// build patricia tree.
if (_s.empty())
return sha3(rlp(""));
HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(i->first)] = i->second;
RLPStream s;
hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s);
return sha3(s.out());
}
bytes rlp256(StringMap const& _s)
{ {
// build patricia tree. // build patricia tree.
if (_s.empty()) if (_s.empty())
return rlp(""); return rlp("");
HexMap hexMap; HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i) for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(i->first)] = i->second; hexMap[asNibbles(bytesConstRef(&i->first))] = i->second;
RLPStream s; RLPStream s;
hash256aux(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s); hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s);
return s.out(); return s.out();
} }
h256 hash256(u256Map const& _s) h256 hash256(BytesMap const& _s)
{ {
// build patricia tree. return sha3(rlp256(_s));
if (_s.empty())
return sha3(rlp(""));
HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(toBigEndianString(i->first))] = asString(rlp(i->second));
RLPStream s;
hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s);
return sha3(s.out());
} }
/*h256 orderedTrieRoot(std::vector<bytes> const& _data) h256 orderedTrieRoot(std::vector<bytes> const& _data)
{ {
StringMap m; BytesMap m;
unsigned j = 0; unsigned j = 0;
for (auto i: _data) for (auto i: _data)
m[asString(rlp(j++))] = asString(i); m[rlp(j++)] = i;
return hash256(m); return hash256(m);
}*/
h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data)
{
MemoryDB db;
GenericTrieDB<MemoryDB> t(&db);
t.init();
unsigned j = 0;
for (auto i: _data)
t.insert(rlp(j++), i.toBytes());
return t.root();
} }
h256 orderedTrieRoot(std::vector<bytes> const& _data) h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data)
{ {
MemoryDB db; BytesMap m;
GenericTrieDB<MemoryDB> t(&db);
t.init();
unsigned j = 0; unsigned j = 0;
for (auto i: _data) for (auto i: _data)
t.insert(rlp(j++), i); m[rlp(j++)] = i.toBytes();
return t.root(); return hash256(m);
} }
} }

15
libdevcore/TrieHash.h

@ -27,21 +27,18 @@
namespace dev namespace dev
{ {
bytes rlp256(StringMap const& _s); bytes rlp256(BytesMap const& _s);
h256 hash256(StringMap const& _s); h256 hash256(BytesMap const& _s);
h256 hash256(u256Map const& _s);
/*h256 orderedTrieRoot(std::vector<bytes> const& _data); h256 orderedTrieRoot(std::vector<bytes> const& _data);
template <class T, class U> inline h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue) template <class T, class U> inline h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue)
{ {
StringMap m; BytesMap m;
for (unsigned i = 0; i < _itemCount; ++i) for (unsigned i = 0; i < _itemCount; ++i)
m[asString(_getKey(i))] = asString(_getValue(i)); m[_getKey(i)] = _getValue(i);
return hash256(m); return hash256(m);
}*/ }
using bytesMap = std::unordered_map<bytes, bytes>;
h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data); h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data);
h256 orderedTrieRoot(std::vector<bytes> const& _data); h256 orderedTrieRoot(std::vector<bytes> const& _data);

12
libethcore/BlockInfo.cpp

@ -191,22 +191,12 @@ void BlockInfo::populate(bytesConstRef _block, Strictness _s, h256 const& _h)
struct BlockInfoDiagnosticsChannel: public LogChannel { static const char* name() { return EthBlue "" EthWhite ""; } static const int verbosity = 9; }; struct BlockInfoDiagnosticsChannel: public LogChannel { static const char* name() { return EthBlue "" EthWhite ""; } static const int verbosity = 9; };
template <class T, class U> h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue)
{
MemoryDB db;
GenericTrieDB<MemoryDB> t(&db);
t.init();
for (unsigned i = 0; i < _itemCount; ++i)
t.insert(_getKey(i), _getValue(i));
return t.root();
}
void BlockInfo::verifyInternals(bytesConstRef _block) const void BlockInfo::verifyInternals(bytesConstRef _block) const
{ {
RLP root(_block); RLP root(_block);
auto txList = root[1]; auto txList = root[1];
auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data(); }); auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data().toBytes(); });
clog(BlockInfoDiagnosticsChannel) << "Expected trie root:" << toString(expectedRoot); clog(BlockInfoDiagnosticsChannel) << "Expected trie root:" << toString(expectedRoot);
if (transactionsRoot != expectedRoot) if (transactionsRoot != expectedRoot)

20
libethereum/State.cpp

@ -840,16 +840,8 @@ void State::commitToMine(BlockChain const& _bc)
} }
} }
// TODO: move over to using TrieHash BytesMap transactionsMap;
BytesMap receiptsMap;
MemoryDB tm;
GenericTrieDB<MemoryDB> transactionsTrie(&tm);
transactionsTrie.init();
MemoryDB rm;
GenericTrieDB<MemoryDB> receiptsTrie(&rm);
receiptsTrie.init();
RLPStream txs; RLPStream txs;
txs.appendList(m_transactions.size()); txs.appendList(m_transactions.size());
@ -861,11 +853,11 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream receiptrlp; RLPStream receiptrlp;
m_receipts[i].streamRLP(receiptrlp); m_receipts[i].streamRLP(receiptrlp);
receiptsTrie.insert(&k.out(), &receiptrlp.out()); receiptsMap.insert(std::make_pair(k.out(), receiptrlp.out()));
RLPStream txrlp; RLPStream txrlp;
m_transactions[i].streamRLP(txrlp); m_transactions[i].streamRLP(txrlp);
transactionsTrie.insert(&k.out(), &txrlp.out()); transactionsMap.insert(std::make_pair(k.out(), txrlp.out()));
txs.appendRaw(txrlp.out()); txs.appendRaw(txrlp.out());
} }
@ -874,8 +866,8 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles);
m_currentBlock.transactionsRoot = transactionsTrie.root(); m_currentBlock.transactionsRoot = hash256(transactionsMap);
m_currentBlock.receiptsRoot = receiptsTrie.root(); m_currentBlock.receiptsRoot = hash256(receiptsMap);
m_currentBlock.logBloom = logBloom(); m_currentBlock.logBloom = logBloom();
m_currentBlock.sha3Uncles = sha3(m_currentUncles); m_currentBlock.sha3Uncles = sha3(m_currentUncles);

54
test/libdevcrypto/trie.cpp

@ -294,15 +294,25 @@ BOOST_AUTO_TEST_CASE(trie_tests_ordered)
} }
} }
inline h256 stringMapHash256(StringMap const& _s) h256 stringMapHash256(StringMap const& _s)
{ {
return hash256(_s); BytesMap bytesMap;
for (auto const& _v: _s)
bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end())));
return hash256(bytesMap);
}
bytes stringMapRlp256(StringMap const& _s)
{
BytesMap bytesMap;
for (auto const& _v: _s)
bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end())));
return rlp256(bytesMap);
} }
BOOST_AUTO_TEST_CASE(moreTrieTests) BOOST_AUTO_TEST_CASE(moreTrieTests)
{ {
cnote << "Testing Trie more..."; cnote << "Testing Trie more...";
#if 0
// More tests... // More tests...
{ {
MemoryDB m; MemoryDB m;
@ -311,7 +321,7 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
cout << t; cout << t;
cout << m; cout << m;
cout << t.root() << endl; cout << t.root() << endl;
cout << hash256(StringMap()) << endl; cout << stringMapHash256(StringMap()) << endl;
t.insert(string("tesz"), string("test")); t.insert(string("tesz"), string("test"));
cout << t; cout << t;
@ -336,7 +346,7 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
t.remove(string("test")); t.remove(string("test"));
cout << m; cout << m;
cout << t.root() << endl; cout << t.root() << endl;
cout << hash256(StringMap()) << endl; cout << stringMapHash256(StringMap()) << endl;
} }
{ {
MemoryDB m; MemoryDB m;
@ -348,20 +358,23 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
cout << m; cout << m;
cout << t.root() << endl; cout << t.root() << endl;
cout << stringMapHash256({{"b", "B"}, {"a", "A"}}) << endl; cout << stringMapHash256({{"b", "B"}, {"a", "A"}}) << endl;
cout << RLP(rlp256({{"b", "B"}, {"a", "A"}})) << endl; bytes r(stringMapRlp256({{"b", "B"}, {"a", "A"}}));
cout << RLP(r) << endl;
} }
{ {
MemTrie t; MemTrie t;
t.insert("dog", "puppy"); t.insert("dog", "puppy");
cout << hex << t.hash256() << endl; cout << hex << t.hash256() << endl;
cout << RLP(t.rlp()) << endl; bytes r(t.rlp());
cout << RLP(r) << endl;
} }
{ {
MemTrie t; MemTrie t;
t.insert("bed", "d"); t.insert("bed", "d");
t.insert("be", "e"); t.insert("be", "e");
cout << hex << t.hash256() << endl; cout << hex << t.hash256() << endl;
cout << RLP(t.rlp()) << endl; bytes r(t.rlp());
cout << RLP(r) << endl;
} }
{ {
cout << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl; cout << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl;
@ -369,10 +382,10 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
t.insert("dog", "puppy"); t.insert("dog", "puppy");
t.insert("doe", "reindeer"); t.insert("doe", "reindeer");
cout << hex << t.hash256() << endl; cout << hex << t.hash256() << endl;
cout << RLP(t.rlp()) << endl; bytes r(t.rlp());
cout << RLP(r) << endl;
cout << toHex(t.rlp()) << endl; cout << toHex(t.rlp()) << endl;
} }
#endif
{ {
MemoryDB m; MemoryDB m;
EnforceRefs r(m, true); EnforceRefs r(m, true);
@ -387,16 +400,16 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
t.insert(a, b); t.insert(a, b);
s[a] = b; s[a] = b;
/*cout << endl << "-------------------------------" << endl; cout << endl << "-------------------------------" << endl;
cout << a << " -> " << b << endl; cout << a << " -> " << b << endl;
cout << d; cout << d;
cout << m; cout << m;
cout << d.root() << endl; cout << d.root() << endl;
cout << hash256(s) << endl;*/ cout << stringMapHash256(s) << endl;
BOOST_REQUIRE(d.check(true)); BOOST_REQUIRE(d.check(true));
BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s));
BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s));
for (auto const& i: s) for (auto const& i: s)
{ {
(void)i; (void)i;
@ -421,8 +434,8 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
BOOST_REQUIRE(d.check(true)); BOOST_REQUIRE(d.check(true));
BOOST_REQUIRE(t.at(a).empty()); BOOST_REQUIRE(t.at(a).empty());
BOOST_REQUIRE(d.at(string(a)).empty()); BOOST_REQUIRE(d.at(string(a)).empty());
BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s));
BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s));
for (auto const& i: s) for (auto const& i: s)
{ {
(void)i; (void)i;
@ -493,7 +506,6 @@ BOOST_AUTO_TEST_CASE(trieLowerBound)
BOOST_AUTO_TEST_CASE(trieStess) BOOST_AUTO_TEST_CASE(trieStess)
{ {
cnote << "Stress-testing Trie..."; cnote << "Stress-testing Trie...";
if (0)
{ {
MemoryDB m; MemoryDB m;
MemoryDB dm; MemoryDB dm;
@ -512,8 +524,8 @@ BOOST_AUTO_TEST_CASE(trieStess)
m[k] = v; m[k] = v;
t.insert(k, v); t.insert(k, v);
d.insert(k, v); d.insert(k, v);
BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256());
BOOST_REQUIRE_EQUAL(hash256(m), d.root()); BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root());
BOOST_REQUIRE(d.check(true)); BOOST_REQUIRE(d.check(true));
} }
while (!m.empty()) while (!m.empty())
@ -557,8 +569,8 @@ BOOST_AUTO_TEST_CASE(trieStess)
cwarn << "Good?" << d2.root(); cwarn << "Good?" << d2.root();
} }
BOOST_REQUIRE(d.check(true)); BOOST_REQUIRE(d.check(true));
BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256());
BOOST_REQUIRE_EQUAL(hash256(m), d.root()); BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root());
} }
} }
} }

Loading…
Cancel
Save