Browse Source

Added main and infrastructure.

cl-refactor
Gav Wood 11 years ago
parent
commit
9c891a7c3b
  1. 1
      CMakeLists.txt
  2. 13
      eth/CMakeLists.txt
  3. 76
      eth/main.cpp
  4. 14
      libethereum/BlockChain.cpp
  5. 24
      libethereum/BlockChain.h
  6. 31
      libethereum/PeerNetwork.cpp
  7. 37
      libethereum/PeerNetwork.h
  8. 4
      libethereum/State.cpp
  9. 36
      libethereum/State.h

1
CMakeLists.txt

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

13
eth/CMakeLists.txt

@ -0,0 +1,13 @@
cmake_policy(SET CMP0015 NEW)
aux_source_directory(. SRC_LIST)
include_directories(../../secp256k1/include)
include_directories(../libethereum)
link_directories(../libethereum)
link_directories(../../secp256k1)
add_executable(eth ${SRC_LIST})
target_link_libraries(eth secp256k1)
target_link_libraries(eth ethereum)
target_link_libraries(eth gmp)

76
eth/main.cpp

@ -0,0 +1,76 @@
/*
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 main.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
* Ethereum client.
*/
#include "PeerNetwork.h"
#include "BlockChain.h"
#include "State.h"
using namespace std;
using namespace eth;
int main()
{
// Our address.
Address us; // TODO: should be loaded from config file/set at command-line.
BlockChain bc; // TODO: Implement - should look for block database.
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);
PeerNetwork net; // TODO: Implement - should run in background and send us events when blocks found and allow us to send blocks as required.
while (true)
{
// Process network events.
net.process();
// Synchronise block chain with network.
net.sync(bc, tq);
// Synchronise state to block chain.
// This should remove any transactions on our queue that are included in the block chain.
s.sync(bc, tq); // Resynchronise state with block chain & trans
if (s.mine(100))
{
// Mined block
bytes b = s.blockData();
bc.import(b);
}
}
return 0;
}
/*
while (net.incomingTransaction())
{
bytes const& tx = net.incomingTransaction();
s.execute(tx);
net.popIncomingTransaction();
}
*/

14
libethereum/BlockChain.cpp

@ -0,0 +1,14 @@
#include "Common.h"
#include "BlockChain.h"
using namespace std;
using namespace eth;
BlockChain::BlockChain()
{
}
BlockChain::~BlockChain()
{
}

24
libethereum/BlockChain.h

@ -0,0 +1,24 @@
#pragma once
#include "Common.h"
namespace eth
{
/**
* @brief Models the blockchain database.
*/
class BlockChain
{
public:
BlockChain();
~BlockChain();
void import(bytes const& _block) {}
private:
};
}

31
libethereum/PeerNetwork.cpp

@ -0,0 +1,31 @@
#include "Common.h"
#include "PeerNetwork.h"
using namespace std;
using namespace eth;
PeerNetwork::PeerNetwork()
{
}
PeerNetwork::~PeerNetwork()
{
}
void PeerNetwork::process()
{
}
void PeerNetwork::sync(BlockChain& _bc, TransactionQueue const&)
{
/* while (incomingBlock())
{
// import new block
bytes const& block = net.incomingBlock();
bc.import(block);
net.popIncomingBlock();
// check block chain and make longest given all available blocks.
bc.rejig();
}*/
}

37
libethereum/PeerNetwork.h

@ -0,0 +1,37 @@
#pragma once
#include "Common.h"
namespace eth
{
class BlockChain;
class TransactionQueue;
static const bytes NullBytes;
class PeerNetwork
{
public:
PeerNetwork();
~PeerNetwork();
/// Conduct I/O, polling, syncing, whatever.
/// Ideally all time-consuming I/O is done in a background thread, but you get this call every 100ms or so anyway.
void process();
/// Sync with the BlockChain. It might contain one of our mined blocks, we might have new candidates from the network.
void sync(BlockChain& _bc, TransactionQueue const&);
/// Get an incoming transaction from the queue. @returns bytes() if nothing waiting.
bytes const& incomingTransaction() { return NullBytes; }
/// Remove incoming transaction from the queue. Make sure you've finished with the data from any previous incomingTransaction() calls.
void popIncomingTransaction() {}
private:
};
}

4
libethereum/State.cpp

@ -118,7 +118,7 @@ void State::execute(Transaction const& _t, Address _sender)
if (_t.receiveAddress)
{
assert(subBalance(_sender, _t.value + _t.fee));
subBalance(_sender, _t.value + _t.fee);
addBalance(_t.receiveAddress, _t.value);
addBalance(m_minerAddress, _t.fee);
@ -141,7 +141,7 @@ void State::execute(Transaction const& _t, Address _sender)
auto& mem = m_current[newAddress].memory();
for (uint i = 0; i < _t.data.size(); ++i)
mem[i] = _t.data[i];
assert(subBalance(_sender, _t.value + _t.fee));
subBalance(_sender, _t.value + _t.fee);
addBalance(newAddress, _t.value);
addBalance(m_minerAddress, _t.fee);
}

36
libethereum/State.h

@ -34,6 +34,21 @@
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).
@ -49,30 +64,47 @@ public:
/// Verify a given block.
bool verify(bytes const& _block, uint _number = 0);
/// 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; }
/// Get the complete current block, including valid nonce.
bytes blockData() const { return bytes(); }
/// 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) {}
/// Execute a given transaction.
bool execute(bytes const& _rlp) { try { Transaction t(_rlp); execute(t, t.sender()); } catch (...) { return false; } }
/// Check if the address is a valid normal (non-contract) account address.
bool isNormalAddress(Address _address) const;
/// Check if the address is a valid contract's address.
bool isContractAddress(Address _address) const;
/// Get an account's balance.
/// @returns 0 if the address has never been used.
u256 balance(Address _id) const;
/// Add some amount to balance.
/// Will initialise the address if it has never been used.
void addBalance(Address _id, u256 _amount);
/** Subtract some amount from balance.
* @throws NotEnoughCash if balance of @a _id is less than @a _value.
* @throws NotEnoughCash if balance of @a _id is less than @a _value (or has never been used).
* @note We use bigint here as we don't want any accidental problems with negative numbers.
*/
void subBalance(Address _id, bigint _value);
/// Get the value of a memory position of a contract.
/// @returns 0 if no contract exists at that address.
u256 contractMemory(Address _contract, u256 _memory) const;
/// Get the number of transactions a particular address has sent (used for the transaction nonce).
/// @returns 0 if the address has never been used.
u256 transactionsFrom(Address _address) const;
private:
@ -93,6 +125,8 @@ private:
// TODO: std::hash<Address> and then move to unordered_map.
// Will need to sort on hash construction.
std::map<Address, AddressState> m_current; ///< The current state. We work with a C++ hash map rather than a Trie.
std::vector<Transaction> m_transactions; ///< The current list of transactions that we've included in the state.
BlockInfo m_previousBlock; ///< The previous block's information.
BlockInfo m_currentBlock; ///< The current block's information.

Loading…
Cancel
Save