Last active
August 29, 2015 13:57
-
-
Save caktux/9615529 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/eth/main.cpp b/eth/main.cpp | |
index 499a43b..54c7409 100644 | |
--- a/eth/main.cpp | |
+++ b/eth/main.cpp | |
@@ -34,6 +34,7 @@ | |
#include "FileSystem.h" | |
#include "Instruction.h" | |
#include "BuildInfo.h" | |
+#include <boost/filesystem.hpp> | |
using namespace std; | |
using namespace eth; | |
using eth::Instruction; | |
@@ -58,6 +59,8 @@ void help() | |
<< " -c,--client-name <name> Add a name to your client's version string (default: blank)." << endl | |
<< " -d,--db-path <path> Load database from path (default: ~/.ethereum " << endl | |
<< " <APPDATA>/Etherum or Library/Application Support/Ethereum)." << endl | |
+ << " -e, --export <path> Continously exports the block chain " << endl | |
+ << " to the provided directory within <APPDATA>/<path> in CSV format " << endl | |
<< " -h,--help Show this help message and exit." << endl | |
<< " -i,--interactive Enter interactive mode (default: non-interactive)." << endl | |
<< " -l,--listen <port> Listen on the given port for incoming connected (default: 30303)." << endl | |
@@ -259,6 +262,9 @@ int main(int argc, char** argv) | |
string remoteHost; | |
unsigned short remotePort = 30303; | |
bool interactive = false; | |
+ bool exportBlockChain = false; | |
+ unsigned int maxNumber = 0; | |
+ string exportPath; | |
string dbPath; | |
eth::uint mining = ~(eth::uint)0; | |
NodeMode mode = NodeMode::Full; | |
@@ -323,6 +329,16 @@ int main(int argc, char** argv) | |
interactive = true; | |
else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) | |
dbPath = argv[++i]; | |
+ else if ((arg == "-e" || arg == "--export") && i + 1 < argc) | |
+ { | |
+ exportBlockChain = true; | |
+ exportPath = argv[++i]; | |
+ if (!boost::filesystem::exists(dbPath + "/" + exportPath)) | |
+ { | |
+ cerr << "Export directory '" << dbPath + "/" + exportPath << "' does not exist" << endl; | |
+ return -1; | |
+ } | |
+ } | |
else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) | |
{ | |
string m = argv[++i]; | |
@@ -655,6 +671,10 @@ int main(int argc, char** argv) | |
} | |
} | |
+ // Mode flags | |
+ if (exportBlockChain) | |
+ mvwaddstr(consolewin, 0, width / 4 - 14, "Export Mode"); | |
+ | |
// Peers | |
y = 0; | |
string psc; | |
@@ -704,6 +724,157 @@ int main(int argc, char** argv) | |
wrefresh(peerswin); | |
wrefresh(contractswin); | |
wrefresh(mainwin); | |
+ | |
+ | |
+ if (exportBlockChain) | |
+ { | |
+ c.lock(); | |
+ | |
+ unsigned int currentRunMax = 0; | |
+ | |
+ auto const& bc = c.blockChain(); | |
+ auto const& state = c.state(); | |
+ | |
+ stringstream blockStream; | |
+ stringstream txStream; | |
+ | |
+ if (c.changed()) | |
+ { | |
+ cout << "New block detected, exporting..." << endl; | |
+ | |
+ for (auto h = bc.currentHash(); h != bc.genesisHash(); h = bc.details(h).parent) | |
+ { | |
+ auto b = bc.block(h); | |
+ auto bi = BlockInfo(b); | |
+ | |
+ auto d = bc.details(h); | |
+ | |
+ if (d.number > currentRunMax) | |
+ currentRunMax = d.number; | |
+ | |
+ // cout << "Block Number " << d.number << endl; | |
+ | |
+ blockStream << bi.hash << ";" << d.number << ";" << bi.parentHash << ";" << bi.sha3Uncles << ";" << bi.coinbaseAddress << ";" << bi.stateRoot << ";" << bi.sha3Transactions << ";" << bi.difficulty << ";" << bi.timestamp << ";" << bi.nonce << endl; | |
+ | |
+ // Create virtual txs for the mining rewards | |
+ auto _block = bc.block(h); | |
+ Addresses rewarded; | |
+ for (auto const& i : RLP(_block)[2]) | |
+ { | |
+ BlockInfo uncle = BlockInfo::fromHeader(i.data()); | |
+ rewarded.push_back(uncle.coinbaseAddress); | |
+ } | |
+ u256 m_blockReward = 1500 * finney; | |
+ u256 r = m_blockReward; | |
+ | |
+ for (auto const& i : rewarded) | |
+ { | |
+ txStream << bi.hash << ";" << bi.hash << ";" << i << ";" << "Mining reward" << ";" << (m_blockReward * 3 / 4) << ";" << endl; | |
+ r += m_blockReward / 8; | |
+ } | |
+ txStream << bi.hash << ";" << bi.hash << ";" << bi.coinbaseAddress << ";" << "Mining reward" << ";" << r << ";" << endl; | |
+ | |
+ for (auto const& i : RLP(_block)[1]) | |
+ { | |
+ Transaction t(i.data()); | |
+ | |
+ txStream << t.sha3() << ";" << bi.hash << ";" << t.receiveAddress << ";" << t.safeSender() << ";" << t.value; | |
+ | |
+ if (t.receiveAddress) | |
+ { | |
+ txStream << ";" << "0"; | |
+ } | |
+ else | |
+ { | |
+ txStream << ";" << "1"; | |
+ } | |
+ if (t.data.size()) | |
+ { | |
+ txStream << ";" << eth::disassemble(t.data) << endl; | |
+ } | |
+ else | |
+ { | |
+ txStream << ";" << endl; | |
+ } | |
+ } | |
+ } | |
+ | |
+ ofstream blockFile; | |
+ blockFile.open(dbPath + "/" + exportPath + "/blocks.csv"); | |
+ blockFile << blockStream.str(); | |
+ blockFile.close(); | |
+ | |
+ ofstream txFile; | |
+ txFile.open(dbPath + "/" + exportPath + "/tx.csv"); | |
+ txFile << txStream.str(); | |
+ txFile.close(); | |
+ | |
+ ofstream addrFile; | |
+ addrFile.open(dbPath + "/" + exportPath + "/addresses.csv"); | |
+ | |
+ ofstream addrBalanceFile; | |
+ addrBalanceFile.open(dbPath + "/" + exportPath + "/balances.csv"); | |
+ | |
+ // Export contract states | |
+ auto acs = state.addresses(); | |
+ for (auto a : acs) | |
+ { | |
+ if (state.isContractAddress(a.first)) | |
+ { | |
+ auto mem = state.contractMemory(a.first); | |
+ u256 next = 0; | |
+ unsigned numerics = 0; | |
+ bool unexpectedNumeric = false; | |
+ stringstream s; | |
+ for (auto ii : mem) | |
+ { | |
+ if (next < ii.first) | |
+ { | |
+ unsigned j; | |
+ for (j = 0; j <= numerics && next + j < ii.first; ++j) | |
+ s << (j < numerics || unexpectedNumeric ? " 0" : " STOP"); | |
+ unexpectedNumeric = false; | |
+ numerics -= min(numerics, j); | |
+ if (next + j < ii.first) | |
+ s << " @" << showbase << hex << ii.first << " "; | |
+ } | |
+ else if (!next) | |
+ { | |
+ s << "@" << showbase << hex << ii.first << " "; | |
+ } | |
+ auto iit = c_instructionInfo.find((Instruction)(unsigned)ii.second); | |
+ if (numerics || iit == c_instructionInfo.end() || (u256)(unsigned)iit->first != ii.second) // not an instruction or expecting an argument... | |
+ { | |
+ if (numerics) | |
+ numerics--; | |
+ else | |
+ unexpectedNumeric = true; | |
+ s << " " << showbase << hex << ii.second; | |
+ } | |
+ else | |
+ { | |
+ auto const& ii = iit->second; | |
+ s << " " << ii.name; | |
+ numerics = ii.additional; | |
+ } | |
+ next = ii.first + 1; | |
+ } | |
+ addrFile << a.first << ";" << s.str() << endl; | |
+ } | |
+ else { | |
+ addrBalanceFile << a.first << ";" << a.second << endl; | |
+ } | |
+ } | |
+ | |
+ addrFile.close(); | |
+ addrBalanceFile.close(); | |
+ } | |
+ | |
+ if (currentRunMax > maxNumber) | |
+ maxNumber = currentRunMax; | |
+ | |
+ c.unlock(); | |
+ } | |
} | |
delwin(contractswin); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment