Browse Source

Various fixes.

cl-refactor
Gav Wood 11 years ago
parent
commit
4347cfc4fc
  1. 1
      CMakeLists.txt
  2. 2
      eth/CMakeLists.txt
  3. 2
      eth/main.cpp
  4. 14
      libethereum/BlockChain.cpp
  5. 2
      libethereum/BlockChain.h
  6. 2
      libethereum/BlockInfo.cpp
  7. 2
      libethereum/CMakeLists.txt
  8. 2
      libethereum/Common.cpp
  9. 29
      libethereum/Common.h
  10. 84
      libethereum/State.cpp
  11. 9
      libethereum/State.h
  12. 9
      libethereum/Transaction.cpp
  13. 2
      libethereum/Transaction.h
  14. 8
      libethereum/TrieDB.h
  15. 2
      test/CMakeLists.txt
  16. 17
      test/crypto.cpp
  17. 2
      test/main.cpp
  18. 31
      test/state.cpp

1
CMakeLists.txt

@ -26,4 +26,3 @@ endif ()
add_subdirectory(libethereum) add_subdirectory(libethereum)
add_subdirectory(test) add_subdirectory(test)
add_subdirectory(eth) add_subdirectory(eth)

2
eth/CMakeLists.txt

@ -18,3 +18,5 @@ target_link_libraries(eth leveldb)
target_link_libraries(eth secp256k1) target_link_libraries(eth secp256k1)
target_link_libraries(eth cryptopp) target_link_libraries(eth cryptopp)
target_link_libraries(eth gmp) target_link_libraries(eth gmp)
target_link_libraries(eth boost_system)
target_link_libraries(eth boost_filesystem)

2
eth/main.cpp

@ -30,7 +30,7 @@ int main()
{ {
// Our address. // Our address.
h256 privkey = sha3("123"); h256 privkey = sha3("123");
Address us = toPublic(privkey); // TODO: should be loaded from config file/set at command-line. Address us = toAddress(privkey); // TODO: should be loaded from config file/set at command-line.
BlockChain bc; // Maintains block database. BlockChain bc; // Maintains block database.
TransactionQueue tq; // Maintains list of incoming transactions not yet on the block chain. TransactionQueue tq; // Maintains list of incoming transactions not yet on the block chain.

14
libethereum/BlockChain.cpp

@ -19,6 +19,7 @@
* @date 2014 * @date 2014
*/ */
#include <boost/filesystem.hpp>
#include "Common.h" #include "Common.h"
#include "RLP.h" #include "RLP.h"
#include "Exceptions.h" #include "Exceptions.h"
@ -29,10 +30,17 @@
using namespace std; using namespace std;
using namespace eth; using namespace eth;
BlockChain::BlockChain() BlockChain::BlockChain(std::string _path, bool _killExisting)
{ {
if (_path.empty())
_path = string(getenv("HOME")) + "/.ethereum";
boost::filesystem::create_directory(_path);
if (_killExisting)
boost::filesystem::remove_all(_path + "/blocks");
ldb::Options o; ldb::Options o;
auto s = ldb::DB::Open(o, "blockchain", &m_db); o.create_if_missing = true;
auto s = ldb::DB::Open(o, _path + "/blocks", &m_db);
// Initialise with the genesis as the last block on the longest chain. // Initialise with the genesis as the last block on the longest chain.
m_lastBlockHash = m_genesisHash = BlockInfo::genesis().hash; m_lastBlockHash = m_genesisHash = BlockInfo::genesis().hash;
@ -91,7 +99,7 @@ void BlockChain::import(bytes const& _block)
BlockInfo biGrandParent; BlockInfo biGrandParent;
if (it->second.number) if (it->second.number)
biGrandParent.populate(block(it->second.parent)); biGrandParent.populate(block(it->second.parent));
u256 td = it->second.totalDifficulty + s.playback(&_block, bi, biParent, biGrandParent); u256 td = it->second.totalDifficulty + s.playback(&_block, bi, biParent, biGrandParent, true);
// All ok - insert into DB // All ok - insert into DB
m_details[newHash] = BlockDetails{(uint)it->second.number + 1, bi.parentHash, td}; m_details[newHash] = BlockDetails{(uint)it->second.number + 1, bi.parentHash, td};

2
libethereum/BlockChain.h

@ -44,7 +44,7 @@ static const h256s NullH256s;
class BlockChain class BlockChain
{ {
public: public:
BlockChain(); BlockChain(std::string _path = std::string(), bool _killExisting = false);
~BlockChain(); ~BlockChain();
/// (Potentially) renders invalid existing bytesConstRef returned by lastBlock. /// (Potentially) renders invalid existing bytesConstRef returned by lastBlock.

2
libethereum/BlockInfo.cpp

@ -121,6 +121,6 @@ void BlockInfo::verifyParent(BlockInfo const& _parent) const
throw InvalidDifficulty(); throw InvalidDifficulty();
// Check timestamp is after previous timestamp. // Check timestamp is after previous timestamp.
if (parentHash && _parent.timestamp <= _parent.timestamp) if (parentHash && _parent.timestamp >= timestamp)
throw InvalidTimestamp(); throw InvalidTimestamp();
} }

2
libethereum/CMakeLists.txt

@ -13,3 +13,5 @@ target_link_libraries(ethereum secp256k1)
target_link_libraries(ethereum leveldb) target_link_libraries(ethereum leveldb)
target_link_libraries(ethereum cryptopp) target_link_libraries(ethereum cryptopp)
target_link_libraries(ethereum gmp) target_link_libraries(ethereum gmp)
target_link_libraries(ethereum boost_system)
target_link_libraries(ethereum boost_filesystem)

2
libethereum/Common.cpp

@ -144,7 +144,7 @@ h256 eth::sha3(bytesConstRef _input)
return ret; return ret;
} }
Address eth::toPublic(PrivateKey _private) Address eth::toAddress(Secret _private)
{ {
secp256k1_start(); secp256k1_start();

29
libethereum/Common.h

@ -83,6 +83,14 @@ public:
bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; } bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; }
bool operator<(FixedHash const& _c) const { return m_data < _c.m_data; } bool operator<(FixedHash const& _c) const { return m_data < _c.m_data; }
FixedHash& operator^=(FixedHash const& _c) { for (auto i = 0; i < N; ++i) m_data[i] ^= _c.m_data[i]; return *this; }
FixedHash operator^(FixedHash const& _c) const { return FixedHash(*this) ^= _c; }
FixedHash& operator|=(FixedHash const& _c) { for (auto i = 0; i < N; ++i) m_data[i] |= _c.m_data[i]; return *this; }
FixedHash operator|(FixedHash const& _c) const { return FixedHash(*this) |= _c; }
FixedHash& operator&=(FixedHash const& _c) { for (auto i = 0; i < N; ++i) m_data[i] &= _c.m_data[i]; return *this; }
FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; }
FixedHash& operator~() { for (auto i = 0; i < N; ++i) m_data[i] = ~m_data[i]; return *this; }
byte& operator[](unsigned _i) { return m_data[_i]; } byte& operator[](unsigned _i) { return m_data[_i]; }
byte operator[](unsigned _i) const { return m_data[_i]; } byte operator[](unsigned _i) const { return m_data[_i]; }
@ -98,8 +106,9 @@ private:
template <unsigned N> template <unsigned N>
inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h) inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)
{ {
_out << std::noshowbase << std::hex << std::setfill('0');
for (unsigned i = 0; i < N; ++i) for (unsigned i = 0; i < N; ++i)
_out << std::hex << std::setfill('0') << std::setw(2) << (int)_h[i]; _out << std::setw(2) << (int)_h[i];
return _out; return _out;
} }
@ -110,7 +119,7 @@ using h160s = std::vector<h160>;
using h256Set = std::set<h256>; using h256Set = std::set<h256>;
using h160Set = std::set<h160>; using h160Set = std::set<h160>;
using PrivateKey = h256; using Secret = h256;
using Address = h160; using Address = h160;
using Addresses = h160s; using Addresses = h160s;
@ -317,6 +326,20 @@ inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input))
/// Convert a private key into the public key equivalent. /// Convert a private key into the public key equivalent.
/// @returns 0 if it's not a valid private key. /// @returns 0 if it's not a valid private key.
Address toPublic(h256 _private); Address toAddress(h256 _private);
class KeyPair
{
public:
KeyPair() {}
KeyPair(Secret _k): m_secret(_k), m_address(toAddress(_k)) {}
Secret secret() const { return m_secret; }
Address address() const { return m_address; }
private:
Secret m_secret;
Address m_address;
};
} }

84
libethereum/State.cpp

@ -44,30 +44,35 @@
using namespace std; using namespace std;
using namespace eth; using namespace eth;
u256 const State::c_stepFee = 0; u256 const State::c_stepFee = 10000;
u256 const State::c_dataFee = 0; u256 const State::c_dataFee = 20000;
u256 const State::c_memoryFee = 0; u256 const State::c_memoryFee = 30000;
u256 const State::c_extroFee = 0; u256 const State::c_extroFee = 40000;
u256 const State::c_cryptoFee = 0; u256 const State::c_cryptoFee = 50000;
u256 const State::c_newContractFee = 0; u256 const State::c_newContractFee = 60000;
u256 const State::c_txFee = 0; u256 const State::c_txFee = 0;
u256 const State::c_blockReward = 0; u256 const State::c_blockReward = 1000000000;
State::State(Address _coinbaseAddress): m_state(&m_db), m_ourAddress(_coinbaseAddress) State::State(Address _coinbaseAddress, std::string _path, bool _killExisting): m_state(&m_db), m_ourAddress(_coinbaseAddress)
{ {
secp256k1_start(); secp256k1_start();
m_previousBlock = BlockInfo::genesis();
m_currentBlock.coinbaseAddress = m_ourAddress;
boost::filesystem::create_directory(string(getenv("HOME")) + "/.ethereum/"); if (_path.empty())
_path = string(getenv("HOME")) + "/.ethereum";
boost::filesystem::create_directory(_path);
if (_killExisting)
boost::filesystem::remove_all(_path + "/state");
ldb::Options o; ldb::Options o;
o.create_if_missing = true;
ldb::DB* db = nullptr; ldb::DB* db = nullptr;
ldb::DB::Open(o, string(getenv("HOME")) + "/.ethereum/state", &db); ldb::DB::Open(o, _path + "/state", &db);
m_db.setDB(db); m_db.setDB(db);
m_state.init(); m_state.init();
m_state.setRoot(m_currentBlock.stateRoot);
m_previousBlock = BlockInfo::genesis();
resetCurrent();
} }
void State::ensureCached(Address _a, bool _requireMemory) const void State::ensureCached(Address _a, bool _requireMemory) const
@ -79,7 +84,9 @@ void State::ensureCached(Address _a, bool _requireMemory) const
string stateBack = m_state.at(_a); string stateBack = m_state.at(_a);
RLP state(stateBack); RLP state(stateBack);
AddressState s; AddressState s;
if (state.itemCount() == 2) if (state.isNull())
s = AddressState(0, 0);
else if (state.itemCount() == 2)
s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>()); s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>());
else else
s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>()); s = AddressState(state[0].toInt<u256>(), state[1].toInt<u256>(), state[2].toHash<h256>());
@ -104,7 +111,7 @@ void State::commit()
m_state.remove(i.first); m_state.remove(i.first);
else else
{ {
RLPStream s; RLPStream s(i.second.type() == AddressType::Contract ? 3 : 2);
s << i.second.balance() << i.second.nonce(); s << i.second.balance() << i.second.nonce();
if (i.second.type() == AddressType::Contract) if (i.second.type() == AddressType::Contract)
{ {
@ -114,7 +121,7 @@ void State::commit()
memdb.init(); memdb.init();
for (auto const& j: i.second.memory()) for (auto const& j: i.second.memory())
if (j.second) if (j.second)
memdb.insert(j.first, rlp(j.second)); // TODO: CHECK: check this isn't RLP or compact memdb.insert(j.first, rlp(j.second));
s << memdb.root(); s << memdb.root();
} }
else else
@ -179,7 +186,7 @@ void State::sync(BlockChain const& _bc, h256 _block)
// Iterate through in reverse, playing back each of the blocks. // Iterate through in reverse, playing back each of the blocks.
for (auto it = next(l.cbegin()); it != l.cend(); ++it) for (auto it = next(l.cbegin()); it != l.cend(); ++it)
playback(_bc.block(*it)); playback(_bc.block(*it), true);
m_currentNumber = _bc.details(_bc.currentHash()).number + 1; m_currentNumber = _bc.details(_bc.currentHash()).number + 1;
resetCurrent(); resetCurrent();
@ -193,6 +200,8 @@ void State::resetCurrent()
m_currentBlock = BlockInfo(); m_currentBlock = BlockInfo();
m_currentBlock.coinbaseAddress = m_ourAddress; m_currentBlock.coinbaseAddress = m_ourAddress;
m_currentBlock.stateRoot = m_previousBlock.stateRoot; m_currentBlock.stateRoot = m_previousBlock.stateRoot;
m_currentBlock.parentHash = m_previousBlock.hash;
m_state.setRoot(m_currentBlock.stateRoot);
} }
void State::sync(TransactionQueue& _tq) void State::sync(TransactionQueue& _tq)
@ -224,13 +233,13 @@ void State::sync(TransactionQueue& _tq)
} }
} }
u256 State::playback(bytesConstRef _block) u256 State::playback(bytesConstRef _block, bool _fullCommit)
{ {
try try
{ {
m_currentBlock.populate(_block); m_currentBlock.populate(_block);
m_currentBlock.verifyInternals(_block); m_currentBlock.verifyInternals(_block);
return playback(_block, BlockInfo()); return playback(_block, BlockInfo(), _fullCommit);
} }
catch (...) catch (...)
{ {
@ -240,14 +249,14 @@ u256 State::playback(bytesConstRef _block)
} }
} }
u256 State::playback(bytesConstRef _block, BlockInfo const& _bi, BlockInfo const& _parent, BlockInfo const& _grandParent) u256 State::playback(bytesConstRef _block, BlockInfo const& _bi, BlockInfo const& _parent, BlockInfo const& _grandParent, bool _fullCommit)
{ {
m_currentBlock = _bi; m_currentBlock = _bi;
m_previousBlock = _parent; m_previousBlock = _parent;
return playback(_block, _grandParent); return playback(_block, _grandParent, _fullCommit);
} }
u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent) u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent, bool _fullCommit)
{ {
if (m_currentBlock.parentHash != m_previousBlock.hash) if (m_currentBlock.parentHash != m_previousBlock.hash)
throw InvalidParentHash(); throw InvalidParentHash();
@ -279,16 +288,27 @@ u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent)
// Hash the state trie and check against the state_root hash in m_currentBlock. // Hash the state trie and check against the state_root hash in m_currentBlock.
if (m_currentBlock.stateRoot != rootHash()) if (m_currentBlock.stateRoot != rootHash())
{ {
cout << m_state;
cout << TrieDB<Address, Overlay>(&m_db, m_state.root());
cout << TrieDB<Address, Overlay>(&m_db, m_currentBlock.stateRoot) << endl;
// Rollback the trie. // Rollback the trie.
m_db.rollback(); m_db.rollback();
throw InvalidStateRoot(); throw InvalidStateRoot();
} }
// Commit the new trie to disk. if (_fullCommit)
m_db.commit(); {
// Commit the new trie to disk.
m_db.commit();
m_previousBlock = m_currentBlock; m_previousBlock = m_currentBlock;
resetCurrent(); resetCurrent();
}
else
{
m_db.rollback();
resetCurrent();
}
return tdIncrease; return tdIncrease;
} }
@ -298,17 +318,25 @@ u256 State::playback(bytesConstRef _block, BlockInfo const& _grandParent)
void State::commitToMine(BlockChain const& _bc) void State::commitToMine(BlockChain const& _bc)
{ {
RLPStream uncles; RLPStream uncles;
Addresses uncleAddresses;
if (m_previousBlock != BlockInfo::genesis()) if (m_previousBlock != BlockInfo::genesis())
{ {
// Find uncles if we're not a direct child of the genesis. // Find uncles if we're not a direct child of the genesis.
auto us = _bc.details(m_previousBlock.parentHash).children; auto us = _bc.details(m_previousBlock.parentHash).children;
uncles.appendList(us.size()); uncles.appendList(us.size());
for (auto const& u: us) for (auto const& u: us)
BlockInfo(_bc.block(u)).fillStream(uncles, true); {
BlockInfo ubi(_bc.block(u));
ubi.fillStream(uncles, true);
uncleAddresses.push_back(ubi.coinbaseAddress);
}
} }
else else
uncles.appendList(0); uncles.appendList(0);
applyRewards(uncleAddresses);
RLPStream txs(m_transactions.size()); RLPStream txs(m_transactions.size());
for (auto const& i: m_transactions) for (auto const& i: m_transactions)
i.second.fillStream(txs); i.second.fillStream(txs);
@ -321,7 +349,9 @@ void State::commitToMine(BlockChain const& _bc)
// Commit any and all changes to the trie that are in the cache, then update the state root accordingly. // Commit any and all changes to the trie that are in the cache, then update the state root accordingly.
commit(); commit();
cout << m_state;
m_currentBlock.stateRoot = m_state.root(); m_currentBlock.stateRoot = m_state.root();
m_currentBlock.parentHash = m_previousBlock.hash;
} }
bool State::mine(uint _msTimeout) bool State::mine(uint _msTimeout)

9
libethereum/State.h

@ -49,7 +49,7 @@ class State
{ {
public: public:
/// Construct state object. /// Construct state object.
explicit State(Address _coinbaseAddress); explicit State(Address _coinbaseAddress, std::string _path = std::string(), bool _killExisting = false);
/// Cancels transactions and rolls back the state to the end of the previous block. /// Cancels transactions and rolls back the state to the end of the previous block.
/// @warning This will only work for on any transactions after you called the last commitToMine(). /// @warning This will only work for on any transactions after you called the last commitToMine().
@ -60,6 +60,7 @@ public:
/// Commits all transactions into the trie, compiles uncles and transactions list, applies all /// Commits all transactions into the trie, compiles uncles and transactions list, applies all
/// rewards and populates the current block header with the appropriate hashes. /// rewards and populates the current block header with the appropriate hashes.
/// The only thing left to do after this is to actually mine(). /// The only thing left to do after this is to actually mine().
/// @warning Only call this once!
void commitToMine(BlockChain const& _bc); void commitToMine(BlockChain const& _bc);
/// Attempt to find valid nonce for block that this state represents. /// Attempt to find valid nonce for block that this state represents.
@ -127,7 +128,7 @@ public:
/// @returns the additional total difficulty. /// @returns the additional total difficulty.
/// If the _grandParent is passed, it will check the validity of each of the uncles. /// If the _grandParent is passed, it will check the validity of each of the uncles.
/// This might throw. /// This might throw.
u256 playback(bytesConstRef _block, BlockInfo const& _bi, BlockInfo const& _parent, BlockInfo const& _grandParent); u256 playback(bytesConstRef _block, BlockInfo const& _bi, BlockInfo const& _parent, BlockInfo const& _grandParent, bool _fullCommit);
private: private:
/// Fee-adder on destruction RAII class. /// Fee-adder on destruction RAII class.
@ -146,11 +147,11 @@ private:
/// Execute the given block on our previous block. This will set up m_currentBlock first, then call the other playback(). /// Execute the given block on our previous block. This will set up m_currentBlock first, then call the other playback().
/// Any failure will be critical. /// Any failure will be critical.
u256 playback(bytesConstRef _block); u256 playback(bytesConstRef _block, bool _fullCommit);
/// 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 _grandParent is passed, it will be used to check the uncles.
/// Throws on failure. /// Throws on failure.
u256 playback(bytesConstRef _block, BlockInfo const& _grandParent); u256 playback(bytesConstRef _block, BlockInfo const& _grandParent, bool _fullCommit);
/// Execute a decoded transaction object, given a sender. /// Execute a decoded transaction object, given a sender.
/// This will append @a _t to the transaction list and change the state accordingly. /// This will append @a _t to the transaction list and change the state accordingly.

9
libethereum/Transaction.cpp

@ -54,13 +54,16 @@ Address Transaction::sender() const
return right160(eth::sha3(bytesConstRef(&(pubkey[1]), 64))); return right160(eth::sha3(bytesConstRef(&(pubkey[1]), 64)));
} }
void Transaction::sign(PrivateKey _priv) void Transaction::sign(Secret _priv)
{ {
int v = 0; int v = 0;
secp256k1_start();
h256 msg = sha3(false); h256 msg = sha3(false);
byte sig[64]; byte sig[64];
if (!secp256k1_ecdsa_sign_compact(msg.data(), 32, sig, _priv.data(), kFromMessage(msg, _priv).data(), &v)) h256 nonce = kFromMessage(msg, _priv);
if (!secp256k1_ecdsa_sign_compact(msg.data(), 32, sig, _priv.data(), nonce.data(), &v))
throw InvalidSignature(); throw InvalidSignature();
vrs.v = (byte)(v + 27); vrs.v = (byte)(v + 27);
@ -91,6 +94,6 @@ h256 Transaction::kFromMessage(h256 _msg, h256 _priv)
v = hmac.new(k, v, hashlib.sha256).digest() v = hmac.new(k, v, hashlib.sha256).digest()
return decode(hmac.new(k, v, hashlib.sha256).digest(),256) return decode(hmac.new(k, v, hashlib.sha256).digest(),256)
*/ */
return h256(); return _msg ^ _priv;
} }

2
libethereum/Transaction.h

@ -49,7 +49,7 @@ struct Transaction
Signature vrs; Signature vrs;
Address sender() const; Address sender() const;
void sign(PrivateKey _priv); void sign(Secret _priv);
static h256 kFromMessage(h256 _msg, h256 _priv); static h256 kFromMessage(h256 _msg, h256 _priv);

8
libethereum/TrieDB.h

@ -95,7 +95,7 @@ private:
/** /**
* @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree. * @brief Merkle Patricia Tree "Trie": a modifed base-16 Radix tree.
* This version uses an LDB backend - TODO: split off m_db & m_over into opaque key/value map layer and allow caching & testing without DB. * This version uses an LDB backend
*/ */
template <class DB> template <class DB>
class GenericTrieDB class GenericTrieDB
@ -365,8 +365,8 @@ public:
{ {
auto p = Super::at(); auto p = Super::at();
value_type ret; value_type ret;
assert(p.first.size() == sizeof(ret)); assert(p.first.size() == sizeof(KeyType));
memcpy(&ret.first, p.first.data(), sizeof(ret)); memcpy(&ret.first, p.first.data(), sizeof(KeyType));
ret.second = p.second; ret.second = p.second;
return ret; return ret;
} }
@ -415,7 +415,7 @@ template <class DB> std::string GenericTrieDB<DB>::at(bytesConstRef _key) const
template <class DB> std::string GenericTrieDB<DB>::atAux(RLP const& _here, NibbleSlice _key) const template <class DB> std::string GenericTrieDB<DB>::atAux(RLP const& _here, NibbleSlice _key) const
{ {
if (_here.isEmpty()) if (_here.isEmpty() || _here.isNull())
// not found. // not found.
return std::string(); return std::string();
assert(_here.isList() && (_here.itemCount() == 2 || _here.itemCount() == 17)); assert(_here.isList() && (_here.itemCount() == 2 || _here.itemCount() == 17));

2
test/CMakeLists.txt

@ -17,3 +17,5 @@ target_link_libraries(testeth ethereum)
target_link_libraries(testeth cryptopp) target_link_libraries(testeth cryptopp)
target_link_libraries(testeth secp256k1) target_link_libraries(testeth secp256k1)
target_link_libraries(testeth gmp) target_link_libraries(testeth gmp)
target_link_libraries(testeth boost_system)
target_link_libraries(testeth boost_filesystem)

17
test/crypto.cpp

@ -34,8 +34,16 @@ int cryptoTest()
bytes tx = fromUserHex("88005401010101010101010101010101010101010101011f0de0b6b3a76400001ce8d4a5100080181c373130a009ba1f10285d4e659568bfcfec85067855c5a3c150100815dad4ef98fd37cf0593828c89db94bd6c64e210a32ef8956eaa81ea9307194996a3b879441f5d"); bytes tx = fromUserHex("88005401010101010101010101010101010101010101011f0de0b6b3a76400001ce8d4a5100080181c373130a009ba1f10285d4e659568bfcfec85067855c5a3c150100815dad4ef98fd37cf0593828c89db94bd6c64e210a32ef8956eaa81ea9307194996a3b879441f5d");
cout << "TX: " << RLP(tx) << endl; cout << "TX: " << RLP(tx) << endl;
Transaction t(tx); Transaction t2(tx);
cout << "SENDER: " << hex << t.sender() << endl; cout << "SENDER: " << hex << t2.sender() << endl;
secp256k1_start();
Transaction t;
t.nonce = 0;
t.fee = 0;
t.value = 1; // 1 wei.
t.receiveAddress = toAddress(sha3("123"));
bytes sig64 = toBigEndian(t.vrs.r) + toBigEndian(t.vrs.s); bytes sig64 = toBigEndian(t.vrs.r) + toBigEndian(t.vrs.s);
cout << "SIG: " << sig64.size() << " " << asHex(sig64) << " " << t.vrs.v << endl; cout << "SIG: " << sig64.size() << " " << asHex(sig64) << " " << t.vrs.v << endl;
@ -48,8 +56,6 @@ int cryptoTest()
bytes privkey = sha3Bytes("123"); bytes privkey = sha3Bytes("123");
secp256k1_start();
{ {
bytes pubkey(65); bytes pubkey(65);
int pubkeylen = 65; int pubkeylen = 65;
@ -68,6 +74,9 @@ int cryptoTest()
bytes sig(64); bytes sig(64);
u256 nonce = 0; u256 nonce = 0;
int v = 0; int v = 0;
cout << asHex(hmsg) << endl;
cout << asHex(privkey) << endl;
cout << hex << nonce << endl;
int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v); int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v);
cout << "MYSIG: " << dec << ret << " " << sig.size() << " " << asHex(sig) << " " << v << endl; cout << "MYSIG: " << dec << ret << " " << sig.size() << " " << asHex(sig) << " " << v << endl;

2
test/main.cpp

@ -35,7 +35,7 @@ int main()
rlpTest(); rlpTest();
trieTest(); trieTest();
// daggerTest(); // daggerTest();
// cryptoTest(); cryptoTest();
stateTest(); stateTest();
return 0; return 0;
} }

31
test/state.cpp

@ -20,43 +20,44 @@
* State test functions. * State test functions.
*/ */
#include <secp256k1.h>
#include <BlockChain.h>
#include <State.h> #include <State.h>
using namespace std; using namespace std;
using namespace eth; using namespace eth;
struct KeyPair
{
KeyPair() {}
KeyPair(PrivateKey _k): priv(_k), addr(toPublic(_k)) {}
PrivateKey priv;
Address addr;
};
int stateTest() int stateTest()
{ {
KeyPair me = sha3("Gav Wood"); KeyPair me = sha3("Gav Wood");
KeyPair myMiner = sha3("Gav's Miner"); KeyPair myMiner = sha3("Gav's Miner");
// KeyPair you = sha3("123"); // KeyPair you = sha3("123");
State s(myMiner.addr); BlockChain bc("/tmp");
State s(myMiner.address(), "/tmp");
// Mine to get some ether! // Mine to get some ether!
s.mine(); s.commitToMine(bc);
while (!s.mine(100)) {}
bc.attemptImport(s.blockData());
s.sync(bc);
bytes tx; bytes tx;
{ {
Transaction t; Transaction t;
t.nonce = s.transactionsFrom(myMiner.addr); t.nonce = s.transactionsFrom(myMiner.address());
t.fee = 0; t.fee = 0;
t.value = 1; // 1 wei. t.value = 1000000000; // 1e9 wei.
t.receiveAddress = me.addr; t.receiveAddress = me.address();
t.sign(myMiner.priv); t.sign(myMiner.secret());
tx = t.rlp(); tx = t.rlp();
} }
cout << RLP(tx) << endl; cout << RLP(tx) << endl;
s.execute(tx); s.execute(tx);
// TODO: Mine to set in stone. s.commitToMine(bc);
while (!s.mine(100)) {}
bc.attemptImport(s.blockData());
s.sync(bc);
return 0; return 0;
} }

Loading…
Cancel
Save