Skip to content

Instantly share code, notes, and snippets.

@caktux
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caktux/9615529 to your computer and use it in GitHub Desktop.
Save caktux/9615529 to your computer and use it in GitHub Desktop.
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