/* 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. cpp-ethereum 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 cpp-ethereum. If not, see . */ /** @file main.cpp * @author Gav Wood * @date 2014 * Ethereum client. */ #if ETH_ETHASHCL #define __CL_ENABLE_EXCEPTIONS #define CL_USE_DEPRECATED_OPENCL_2_0_APIS #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" #include #pragma clang diagnostic pop #else #include #endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace dev; using namespace dev::eth; using namespace dev::p2p; using namespace dev::shh; namespace js = json_spirit; namespace fs = boost::filesystem; #if 1 int main() { cdebug << pbkdf2("password", asBytes("salt"), 1, 32); cdebug << pbkdf2("password", asBytes("salt"), 1, 16); cdebug << pbkdf2("password", asBytes("salt"), 2, 16); cdebug << pbkdf2("testpassword", fromHex("de5742f1f1045c402296422cee5a8a9ecf0ac5bf594deca1170d22aef33a79cf"), 262144, 16); return 0; } #elif 0 int main() { cdebug << "EXP"; vector data; for (unsigned i = 0; i < 10000; ++i) data.push_back(rlp(i)); h256 ret; DEV_TIMED("triedb") { MemoryDB mdb; GenericTrieDB t(&mdb); t.init(); unsigned i = 0; for (auto const& d: data) t.insert(rlp(i++), d); ret = t.root(); } cdebug << ret; DEV_TIMED("hash256") ret = orderedTrieRoot(data); cdebug << ret; } #elif 0 int main() { KeyManager keyman; if (keyman.exists()) keyman.load("foo"); else keyman.create("foo"); Address a("9cab1cc4e8fe528267c6c3af664a1adbce810b5f"); // keyman.importExisting(fromUUID("441193ae-a767-f1c3-48ba-dd6610db5ed0"), "{\"name\":\"Gavin Wood - Main identity\"}", "bar", "{\"hint\":\"Not foo.\"}"); // Address a2 = keyman.address(keyman.import(Secret::random(), "Key with no additional security.")); // cdebug << toString(a2); Address a2("19c486071651b2650449ba3c6a807f316a73e8fe"); cdebug << keyman.accountDetails(); cdebug << "Secret key for " << a << "is" << keyman.secret(a, [](){ return "bar"; }); cdebug << "Secret key for " << a2 << "is" << keyman.secret(a2); } #elif 0 int main() { DownloadMan man; DownloadSub s0(man); DownloadSub s1(man); DownloadSub s2(man); man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}), 0); assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8})); assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6})); assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4})); s0.noteBlock(u256(8)); s0.doneFetch(); assert((s0.nextFetch(2) == h256Set{(u256)2, (u256)7})); s1.noteBlock(u256(6)); s1.noteBlock(u256(5)); s1.doneFetch(); assert((s1.nextFetch(2) == h256Set{(u256)0, (u256)1})); s0.doneFetch(); // TODO: check exact semantics of doneFetch & nextFetch. Not sure if they're right -> doneFetch calls resetFetch which kills all the info of past fetches. cdebug << s0.nextFetch(2); assert((s0.nextFetch(2) == h256Set{(u256)3, (u256)4})); /* RangeMask m(0, 100); cnote << m; m += UnsignedRange(3, 10); cnote << m; m += UnsignedRange(11, 16); cnote << m; m += UnsignedRange(10, 11); cnote << m; cnote << ~m; cnote << (~m).lowest(10); for (auto i: (~m).lowest(10)) cnote << i;*/ return 0; } #elif 0 int main() { KeyPair u = KeyPair::create(); KeyPair cb = KeyPair::create(); OverlayDB db; State s(cb.address(), db, BaseState::Empty); cnote << s.rootHash(); s.addBalance(u.address(), 1 * ether); Address c = s.newContract(1000 * ether, compileLLL("(suicide (caller))")); s.commit(); State before = s; cnote << "State before transaction: " << before; Transaction t(0, 10000, 10000, c, bytes(), 0, u.secret()); cnote << "Transaction: " << t; cnote << s.balance(c); s.execute(LastHashes(), t.rlp()); cnote << "State after transaction: " << s; cnote << before.diff(s); } #elif 0 int main() { GenericFarm f; BlockInfo genesis = CanonBlockChain::genesis(); genesis.difficulty = 1 << 18; cdebug << genesis.boundary(); auto mine = [](GenericFarm& f, BlockInfo const& g, unsigned timeout) { BlockInfo bi = g; bool completed = false; f.onSolutionFound([&](ProofOfWork::Solution sol) { ProofOfWork::assignResult(sol, bi); return completed = true; }); f.setWork(bi); for (unsigned i = 0; !completed && i < timeout * 10; ++i, cout << f.miningProgress() << "\r" << flush) this_thread::sleep_for(chrono::milliseconds(100)); cout << endl << flush; cdebug << bi.mixHash << bi.nonce << (Ethash::verify(bi) ? "GOOD" : "bad"); }; Ethash::prep(genesis); genesis.difficulty = u256(1) << 40; genesis.noteDirty(); f.startCPU(); mine(f, genesis, 10); f.startGPU(); cdebug << "Good:"; genesis.difficulty = 1 << 18; genesis.noteDirty(); mine(f, genesis, 30); cdebug << "Bad:"; genesis.difficulty = (u256(1) << 40); genesis.noteDirty(); mine(f, genesis, 30); f.stop(); return 0; } #elif 0 void mine(State& s, BlockChain const& _bc) { s.commitToMine(_bc); GenericFarm f; bool completed = false; f.onSolutionFound([&](ProofOfWork::Solution sol) { return completed = s.completeMine(sol); }); f.setWork(s.info()); f.startCPU(); while (!completed) this_thread::sleep_for(chrono::milliseconds(20)); } #elif 0 int main() { cnote << "Testing State..."; KeyPair me = sha3("Gav Wood"); KeyPair myMiner = sha3("Gav's Miner"); // KeyPair you = sha3("123"); Defaults::setDBPath(boost::filesystem::temp_directory_path().string() + "/" + toString(chrono::system_clock::now().time_since_epoch().count())); OverlayDB stateDB = State::openDB(); CanonBlockChain bc; cout << bc; State s(stateDB, BaseState::CanonGenesis, myMiner.address()); cout << s; // Sync up - this won't do much until we use the last state. s.sync(bc); cout << s; // Mine to get some ether! mine(s, bc); bc.attemptImport(s.blockData(), stateDB); cout << bc; s.sync(bc); cout << s; // Inject a transaction to transfer funds from miner to me. Transaction t(1000, 10000, 30000, me.address(), bytes(), s.transactionsFrom(myMiner.address()), myMiner.secret()); assert(t.sender() == myMiner.address()); s.execute(bc.lastHashes(), t); cout << s; // Mine to get some ether and set in stone. s.commitToMine(bc); s.commitToMine(bc); mine(s, bc); bc.attemptImport(s.blockData(), stateDB); cout << bc; s.sync(bc); cout << s; return 0; } #else int main() { string tempDir = boost::filesystem::temp_directory_path().string() + "/" + toString(chrono::system_clock::now().time_since_epoch().count()); KeyPair myMiner = sha3("Gav's Miner"); p2p::Host net("Test"); cdebug << "Path:" << tempDir; Client c(&net, tempDir); c.setAddress(myMiner.address()); this_thread::sleep_for(chrono::milliseconds(1000)); c.startMining(); this_thread::sleep_for(chrono::milliseconds(6000)); c.stopMining(); return 0; } #endif