Browse Source

Repotting and big-picture stuff.

cl-refactor
Gav Wood 11 years ago
parent
commit
6c72a021d7
  1. 2
      CMakeLists.txt
  2. 8
      README.md
  3. 14
      eth/main.cpp
  4. 25
      libethereum/BlockChain.cpp
  5. 49
      libethereum/BlockChain.h
  6. 15
      libethereum/BlockInfo.cpp
  7. 9
      libethereum/BlockInfo.h
  8. 109
      libethereum/Common.cpp
  9. 42
      libethereum/Common.h
  10. 1
      libethereum/Exceptions.h
  11. 21
      libethereum/PeerNetwork.cpp
  12. 23
      libethereum/PeerNetwork.h
  13. 16
      libethereum/RLP.h
  14. 50
      libethereum/State.cpp
  15. 22
      libethereum/State.h
  16. 24
      libethereum/TransactionQueue.cpp
  17. 45
      libethereum/TransactionQueue.h

2
CMakeLists.txt

@ -25,5 +25,5 @@ endif ()
add_subdirectory(libethereum)
add_subdirectory(test)
#add_subdirectory(eth)
add_subdirectory(eth)

8
README.md

@ -9,14 +9,16 @@ Gav Wood, 2014.
secp256k1 implementation: https://github.com/sipa/secp256k1.git
Expects secp256k1 directory to be in same path as cpp-ethereum.
(NOTE: secp256k1 requires a development installation of the GMP library and
apparently libcrypto.)
(NOTE: secp256k1 requires a development installation of the GMP library, libssl and
apparently libcrypto++.)
A decent C++11 compiler (I use GNU GCC 4.8.1) and a recent version of Boost (I use version 1.53).
CMake, version 2.8 or greater.
sudo apt-get install libgmp3-dev libcrypto++-dev libboost-all-dev cmake
On Ubuntu:
sudo apt-get install libgmp3-dev libcrypto++-dev libssl-dev libboost-all-dev cmake
## Building

14
eth/main.cpp

@ -32,12 +32,10 @@ int main()
Address us; // TODO: should be loaded from config file/set at command-line.
BlockChain bc; // TODO: Implement - should look for block database.
TransactionQueue tq; // TODO: Implement.
State s(us);
// s.restore(); // TODO: Implement - key optimisation.
TransactionQueue tq; // TODO: Implement.
// Synchronise the state according to the block chain - i.e. replay all transactions, in order. Will take a while if the state isn't restored.
s.sync(bc, tq);
@ -48,16 +46,24 @@ int main()
net.process();
// Synchronise block chain with network.
// Will broadcast any of our (new) transactions and blocks, and collect & add any of their (new) transactions and blocks.
net.sync(bc, tq);
// Synchronise state to block chain.
// This should remove any transactions on our queue that are included in the block chain.
// This should remove any transactions on our queue that are included within our state.
// It also guarantees that the state reflects the longest (valid!) chain on the block chain.
// This might mean reverting to an earlier state and replaying some blocks, or, (worst-case:
// if there are no checkpoints before our fork) reverting to the genesis block and replaying
// all blocks.
s.sync(bc, tq); // Resynchronise state with block chain & trans
// Mine for a while.
if (s.mine(100))
{
// Mined block
bytes b = s.blockData();
// Import block.
bc.import(b);
}
}

25
libethereum/BlockChain.cpp

@ -1,3 +1,24 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file BlockChain.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Common.h"
#include "BlockChain.h"
using namespace std;
@ -11,4 +32,6 @@ BlockChain::~BlockChain()
{
}
void BlockChain::import(bytes const& _block)
{
}

49
libethereum/BlockChain.h

@ -1,3 +1,24 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file BlockChain.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include "Common.h"
@ -5,6 +26,19 @@
namespace eth
{
class MappedBlock
{
public:
MappedBlock() {}
MappedBlock(u256 _hash) {} // TODO: map memory from disk.
~MappedBlock() {} // TODO: unmap memory from disk
bytesConstRef data() const { return bytesConstRef(); }
private:
// TODO: memory mapping.
};
/**
* @brief Models the blockchain database.
*/
@ -14,9 +48,22 @@ public:
BlockChain();
~BlockChain();
void import(bytes const& _block) {}
/// Import block into disk-backed DB
void import(bytes const& _block);
/// Get the last block of the longest chain.
bytesConstRef lastBlock() const { return bytesConstRef(); }
/// Get the number of the last block of the longest chain.
u256 lastBlockNumber() const { return Invalid256; }
private:
// Get fully populated from disk DB.
mutable std::map<u256, std::pair<u256, u256>> m_numberAndParent;
mutable std::multimap<u256, u256> m_children;
// Gets populated on demand and reduced after a while.
mutable std::map<u256, std::shared_ptr<MappedBlock>> m_cache;
};
}

15
libethereum/BlockInfo.cpp

@ -27,7 +27,12 @@
using namespace std;
using namespace eth;
void BlockInfo::populateAndVerify(bytesConstRef _block, u256 _number)
BlockInfo::BlockInfo()
{
number = Invalid256;
}
void BlockInfo::populate(bytesConstRef _block, u256 _number)
{
number = _number;
@ -48,7 +53,13 @@ void BlockInfo::populateAndVerify(bytesConstRef _block, u256 _number)
{
throw InvalidBlockFormat();
}
}
void BlockInfo::verify(bytesConstRef _block, u256 _number)
{
populate(_block, _number);
RLP root(_block);
if (sha256Transactions != sha256(root[1].data()))
throw InvalidTransactionsHash();
@ -59,5 +70,5 @@ void BlockInfo::populateAndVerify(bytesConstRef _block, u256 _number)
// TODO: check difficulty against timestamp.
// TODO: check proof of work.
// TODO: check each transaction.
// TODO: check each transaction - allow any destination for the miner fees, but everything else must be exactly how we would do it.
}

9
libethereum/BlockInfo.h

@ -39,7 +39,14 @@ public:
u256 nonce;
u256 number;
void populateAndVerify(bytesConstRef _block, u256 _number);
BlockInfo();
explicit operator bool() { return number != Invalid256; }
bool operator==(BlockInfo const& _cmp) const { return hash == _cmp.hash && parentHash == _cmp.parentHash && nonce == _cmp.nonce && number == _cmp.number; }
void populate(bytesConstRef _block, u256 _number);
void verify(bytesConstRef _block, u256 _number);
};
}

109
libethereum/Common.cpp

@ -19,62 +19,13 @@
* @date 2014
*/
#include <random>
#include "Common.h"
#include "Exceptions.h"
#include "rmd160.h"
using namespace std;
using namespace eth;
/* collect four bytes into one word: */
#define BYTES_TO_DWORD(strptr) \
(((uint32_t) *((strptr)+3) << 24) | \
((uint32_t) *((strptr)+2) << 16) | \
((uint32_t) *((strptr)+1) << 8) | \
((uint32_t) *(strptr)))
u256 eth::ripemd160(bytesConstRef _message)
/*
* returns RMD(message)
* message should be a string terminated by '\0'
*/
{
static const uint RMDsize = 160;
uint32_t MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */
static byte hashcode[RMDsize/8]; /* for final hash-value */
uint32_t X[16]; /* current 16-word chunk */
unsigned int i; /* counter */
uint32_t length; /* length in bytes of message */
uint32_t nbytes; /* # of bytes not yet processed */
/* initialize */
MDinit(MDbuf);
length = _message.size();
auto message = _message.data();
/* process message in 16-word chunks */
for (nbytes=length; nbytes > 63; nbytes-=64) {
for (i=0; i<16; i++) {
X[i] = BYTES_TO_DWORD(message);
message += 4;
}
compress(MDbuf, X);
} /* length mod 64 bytes left */
/* finish: */
MDfinish(MDbuf, message, length, 0);
for (i=0; i<RMDsize/8; i+=4) {
hashcode[i] = MDbuf[i>>2]; /* implicit cast to byte */
hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */
hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */
hashcode[i+3] = (MDbuf[i>>2] >> 24);
}
u256 ret = 0;
for (i = 0; i < RMDsize / 8; ++i)
ret = (ret << 8) | hashcode[i];
return ret;
}
std::string eth::escaped(std::string const& _s, bool _all)
{
std::string ret;
@ -108,7 +59,6 @@ std::string eth::randomWord()
return ret;
}
int eth::fromHex(char _i)
{
if (_i >= '0' && _i <= '9')
@ -144,3 +94,58 @@ bytes eth::toHex(std::string const& _s)
}
return ret;
}
// /////////////////////////////////////////////////
// RIPEMD-160 stuff. Leave well alone.
// /////////////////////////////////////////////////
/* collect four bytes into one word: */
#define BYTES_TO_DWORD(strptr) \
(((uint32_t) *((strptr)+3) << 24) | \
((uint32_t) *((strptr)+2) << 16) | \
((uint32_t) *((strptr)+1) << 8) | \
((uint32_t) *(strptr)))
u256 eth::ripemd160(bytesConstRef _message)
/*
* returns RMD(message)
* message should be a string terminated by '\0'
*/
{
static const uint RMDsize = 160;
uint32_t MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */
static byte hashcode[RMDsize/8]; /* for final hash-value */
uint32_t X[16]; /* current 16-word chunk */
unsigned int i; /* counter */
uint32_t length; /* length in bytes of message */
uint32_t nbytes; /* # of bytes not yet processed */
/* initialize */
MDinit(MDbuf);
length = _message.size();
auto message = _message.data();
/* process message in 16-word chunks */
for (nbytes=length; nbytes > 63; nbytes-=64) {
for (i=0; i<16; i++) {
X[i] = BYTES_TO_DWORD(message);
message += 4;
}
compress(MDbuf, X);
} /* length mod 64 bytes left */
/* finish: */
MDfinish(MDbuf, message, length, 0);
for (i=0; i<RMDsize/8; i+=4) {
hashcode[i] = MDbuf[i>>2]; /* implicit cast to byte */
hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */
hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */
hashcode[i+3] = (MDbuf[i>>2] >> 24);
}
u256 ret = 0;
for (i = 0; i < RMDsize / 8; ++i)
ret = (ret << 8) | hashcode[i];
return ret;
}

42
libethereum/Common.h

@ -26,7 +26,6 @@
#include <map>
#include <string>
#include <cassert>
#include <random>
#include <sstream>
#include <cstdint>
#include <type_traits>
@ -56,11 +55,24 @@ using StringMap = std::map<std::string, std::string>;
using u256Map = std::map<u256, u256>;
using HexMap = std::map<bytes, std::string>;
template <class _T> std::string toString(_T const& _t) { std::ostringstream o; o << _t; return o.str(); }
static const u256 Invalid256 = ~(u256)0;
static const bytes NullBytes;
inline std::string asString(bytes const& _b) { return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size())); }
template <class _T>
std::string toString(_T const& _t)
{
std::ostringstream o;
o << _t;
return o.str();
}
template <class _T> inline std::string asHex(_T const& _data, int _w = 2)
inline std::string asString(bytes const& _b)
{
return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
}
template <class _T>
std::string asHex(_T const& _data, int _w = 2)
{
std::ostringstream ret;
for (auto i: _data)
@ -68,21 +80,21 @@ template <class _T> inline std::string asHex(_T const& _data, int _w = 2)
return ret.str();
}
template <class _T> void trimFront(_T& _t, uint _elements)
template <class _T>
void trimFront(_T& _t, uint _elements)
{
memmove(_t.data(), _t.data() + _elements, (_t.size() - _elements) * sizeof(_t[0]));
_t.resize(_t.size() - _elements);
}
template <class _T, class _U> void pushFront(_T& _t, _U _e)
template <class _T, class _U>
void pushFront(_T& _t, _U _e)
{
_t.push_back(_e);
memmove(_t.data() + 1, _t.data(), (_t.size() - 1) * sizeof(_e));
_t[0] = _e;
}
class BadHexCharacter: public std::exception {};
std::string randomWord();
std::string escaped(std::string const& _s, bool _all = true);
int fromHex(char _i);
@ -122,7 +134,8 @@ inline std::string toCompactBigEndianString(_T _val)
return ret;
}
template <class _T, class _U> uint commonPrefix(_T const& _t, _U const& _u)
template <class _T, class _U>
uint commonPrefix(_T const& _t, _U const& _u)
{
uint s = std::min<uint>(_t.size(), _u.size());
for (uint i = 0;; ++i)
@ -145,7 +158,8 @@ inline u160 as160(_T const& _t)
return (u160)(_t & ((((_T)1) << 160) - 1));
}
template <class _T> inline std::vector<_T>& operator+=(std::vector<_T>& _a, std::vector<_T> const& _b)
template <class _T>
inline std::vector<_T>& operator+=(std::vector<_T>& _a, std::vector<_T> const& _b)
{
auto s = _a.size();
_a.resize(_a.size() + _b.size());
@ -153,6 +167,12 @@ template <class _T> inline std::vector<_T>& operator+=(std::vector<_T>& _a, std:
return _a;
}
template <class _T> inline std::vector<_T> operator+(std::vector<_T> const& _a, std::vector<_T> const& _b) { std::vector<_T> ret(_a); return ret += _b; }
template <class _T>
inline std::vector<_T> operator+(std::vector<_T> const& _a, std::vector<_T> const& _b)
{
std::vector<_T> ret(_a);
return ret += _b;
}
}

1
libethereum/Exceptions.h

@ -6,6 +6,7 @@
namespace eth
{
class BadHexCharacter: public std::exception {};
class NotEnoughCash: public std::exception {};
class BadInstruction: public std::exception {};
class StackTooSmall: public std::exception { public: StackTooSmall(u256 _req, u256 _got): req(_req), got(_got) {} u256 req; u256 got; };

21
libethereum/PeerNetwork.cpp

@ -1,3 +1,24 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file PeerNetwork.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Common.h"
#include "PeerNetwork.h"
using namespace std;

23
libethereum/PeerNetwork.h

@ -1,3 +1,24 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file PeerNetwork.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include "Common.h"
@ -8,8 +29,6 @@ namespace eth
class BlockChain;
class TransactionQueue;
static const bytes NullBytes;
class PeerNetwork
{
public:

16
libethereum/RLP.h

@ -75,28 +75,28 @@ public:
bool isNull() const { return m_data.size() == 0; }
/// Contains a zero-length string or zero-length list.
bool isEmpty() const { return m_data[0] == 0x40 || m_data[0] == 0x80; }
bool isEmpty() const { return !isNull() && (m_data[0] == 0x40 || m_data[0] == 0x80); }
/// String value.
bool isString() const { assert(!isNull()); return m_data[0] >= 0x40 && m_data[0] < 0x80; }
bool isString() const { return !isNull() && m_data[0] >= 0x40 && m_data[0] < 0x80; }
/// List value.
bool isList() const { assert(!isNull()); return m_data[0] >= 0x80 && m_data[0] < 0xc0; }
bool isList() const { return !isNull() && m_data[0] >= 0x80 && m_data[0] < 0xc0; }
/// Integer value. Either isSlimInt(), isFatInt() or isBigInt().
bool isInt() const { assert(!isNull()); return m_data[0] < 0x40; }
bool isInt() const { return !isNull() && m_data[0] < 0x40; }
/// Fits into eth::uint type. Can use toSlimInt() to read (as well as toFatInt() or toBigInt() ).
bool isSlimInt() const { assert(!isNull()); return m_data[0] < 0x20; }
bool isSlimInt() const { return !isNull() && m_data[0] < 0x20; }
/// Fits into eth::u256 or eth::bigint type. Use only toFatInt() or toBigInt() to read.
bool isFatInt() const { assert(!isNull()); return m_data[0] >= 0x20 && m_data[0] < 0x38; }
bool isFatInt() const { return !isNull() && m_data[0] >= 0x20 && m_data[0] < 0x38; }
/// Fits into eth::u256 type, though might fit into eth::uint type.
bool isFixedInt() const { assert(!isNull()); return m_data[0] < 0x38; }
bool isFixedInt() const { return !isNull() && m_data[0] < 0x38; }
/// Fits only into eth::bigint type. Use only toBigInt() to read.
bool isBigInt() const { assert(!isNull()); return m_data[0] >= 0x38 && m_data[0] < 0x40; }
bool isBigInt() const { return !isNull() && m_data[0] >= 0x38 && m_data[0] < 0x40; }
/// @returns the number of items in the list, or zero if it isn't a list.
uint itemCount() const { return isList() ? items() : 0; }

50
libethereum/State.cpp

@ -22,6 +22,7 @@
#include <secp256k1.h>
#include <random>
#include "Trie.h"
#include "BlockChain.h"
#include "Instruction.h"
#include "Exceptions.h"
#include "sha256.h"
@ -40,6 +41,52 @@ u256 const State::c_txFee = 0;
State::State(Address _minerAddress): m_minerAddress(_minerAddress)
{
secp256k1_start();
// TODO: Initialise current block/previous block, ready for sync.
}
void State::sync(BlockChain const& _bc, TransactionQueue const& _tq)
{
BlockInfo bi;
try
{
bi.verify(_bc.lastBlock(), _bc.lastBlockNumber());
}
catch (...)
{
cerr << "ERROR: Corrupt block-chain! Delete your block-chain DB and restart." << endl;
exit(1);
}
if (bi == m_currentBlock)
{
// We mined the last block.
// Our state is good - we just need to move on to next.
m_previousBlock = m_currentBlock;
m_current.clear();
m_transactions.clear();
m_currentBlock = BlockInfo();
m_currentBlock.number = m_previousBlock.number + 1;
}
else if (bi == m_previousBlock)
{
// No change since last sync.
// Carry on as we were.
}
else
{
// 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.)
}
}
bool State::mine(uint _msTimeout) const
{
// TODO: update timestamp according to clock.
// TODO: update difficulty according to timestamp.
// TODO: look for a nonce that makes a good hash.
// ...but don't take longer than _msTimeout ms.
return false;
}
bool State::isNormalAddress(Address _address) const
@ -97,7 +144,7 @@ bool State::verify(bytes const& _block, uint _number)
BlockInfo bi;
try
{
bi.populateAndVerify(bytesConstRef((bytes*)&_block), _number);
bi.verify(bytesConstRef((bytes*)&_block), _number);
}
catch (...)
{
@ -109,6 +156,7 @@ bool State::verify(bytes const& _block, uint _number)
void State::execute(Transaction const& _t, Address _sender)
{
// Entry point for a contract-originated transaction.
m_transactions.push_back(_t);
if (_t.nonce != transactionsFrom(_sender))
throw InvalidNonce();

22
libethereum/State.h

@ -26,6 +26,7 @@
#include <unordered_map>
#include "Common.h"
#include "RLP.h"
#include "TransactionQueue.h"
#include "Exceptions.h"
#include "BlockInfo.h"
#include "AddressState.h"
@ -36,19 +37,6 @@ namespace eth
class BlockChain;
// TODO: Repot.
/**
* @brief A queue of Transactions, each stored as RLP.
*/
class TransactionQueue
{
public:
void sync(BlockChain const& _bc) {}
private:
std::vector<bytes> m_data;
};
/**
* @brief Model of the current state of the ledger.
* Maintains current ledger (m_current) as a fast hash-map. This is hashed only when required (i.e. to create or verify a block).
@ -67,14 +55,14 @@ public:
/// Attempt to find valid nonce for block that this state represents.
/// @param _msTimeout Timeout before return in milliseconds.
/// @returns true if it got lucky.
bool mine(uint _msTimeout = 1000) const { (void)_msTimeout; return false; }
bool mine(uint _msTimeout = 1000) const;
/// Get the complete current block, including valid nonce.
bytes blockData() const { return bytes(); }
bytes const& blockData() const { return m_currentBytes; }
/// Sync our state with the block chain.
/// This basically involves wiping ourselves if we've been superceded and rebuilding from the transaction queue.
void sync(BlockChain const& _bc, TransactionQueue const& _tq) {}
void sync(BlockChain const& _bc, TransactionQueue const& _tq);
/// Execute a given transaction.
bool execute(bytes const& _rlp) { try { Transaction t(_rlp); execute(t, t.sender()); } catch (...) { return false; } }
@ -117,6 +105,7 @@ private:
};
/// Execute a decoded transaction object, given a sender.
/// This will append @a _t to the transaction list and change the state accordingly.
void execute(Transaction const& _t, Address _sender);
/// Execute a contract transaction.
@ -129,6 +118,7 @@ private:
BlockInfo m_previousBlock; ///< The previous block's information.
BlockInfo m_currentBlock; ///< The current block's information.
bytes m_currentBytes; ///< The current block.
Address m_minerAddress; ///< Our address (i.e. the address to which fees go).

24
libethereum/TransactionQueue.cpp

@ -0,0 +1,24 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file TransactionQueue.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "TransactionQueue.h"
using namespace std;
using namespace eth;

45
libethereum/TransactionQueue.h

@ -0,0 +1,45 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file TransactionQueue.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include "Common.h"
namespace eth
{
class BlockChain;
/**
* @brief A queue of Transactions, each stored as RLP.
*/
class TransactionQueue
{
public:
void sync(BlockChain const& _bc) {}
private:
std::vector<bytes> m_data;
};
}
Loading…
Cancel
Save