diff --git a/CMakeLists.txt b/CMakeLists.txt index 36ab9dec8..fcadd4be5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -337,12 +337,15 @@ add_subdirectory(lllc) add_subdirectory(sc) if (NOT LANGUAGES) add_subdirectory(secp256k1) - add_subdirectory(libethnet) + add_subdirectory(libp2p) + add_subdirectory(libwhisper) + add_subdirectory(libethcore) add_subdirectory(libevm) - add_subdirectory(libwhisper) add_subdirectory(libethereum) - add_subdirectory(libethereumx) + add_subdirectory(libethereumx) # TODO remove + + #add_subdirectory(libwebthree) add_subdirectory(test) add_subdirectory(eth) if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 64beb7e83..8a78a2e7f 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -58,7 +58,7 @@ using eth::Instruction; using eth::KeyPair; using eth::NodeMode; using eth::BlockChain; -using eth::PeerInfo; +using p2p::PeerInfo; using eth::RLP; using eth::Secret; using eth::Transaction; diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 036169fee..da6775798 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -9,7 +9,7 @@ set(EXECUTABLE exp) add_executable(${EXECUTABLE} ${SRC_LIST}) target_link_libraries(${EXECUTABLE} ethereum) -target_link_libraries(${EXECUTABLE} ethnet) +target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if(MINIUPNPC_LS) diff --git a/exp/main.cpp b/exp/main.cpp index db41def59..eeff5a55f 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -30,13 +30,14 @@ #include #include #include -#include +#include #include #if 0 #include #include "BuildInfo.h" #endif using namespace std; +using namespace p2p; using namespace eth; using namespace shh; #if 0 diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 337b97d98..43812b7d3 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -20,8 +20,8 @@ include_directories(..) target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} whisper) +target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} ethcore) -target_link_libraries(${EXECUTABLE} ethnet) target_link_libraries(${EXECUTABLE} secp256k1) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 9e51f94b3..e3598ec57 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -25,11 +25,12 @@ #include #include #include -#include +#include #include "Defaults.h" #include "EthereumHost.h" using namespace std; using namespace eth; +using namespace p2p; VersionChecker::VersionChecker(string const& _dbPath): m_path(_dbPath.size() ? _dbPath : Defaults::dbPath()) diff --git a/libethereum/Client.h b/libethereum/Client.h index 1ff553082..64e26ec12 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "BlockChain.h" #include "TransactionQueue.h" #include "State.h" @@ -199,7 +199,7 @@ public: // Network stuff: /// Get information on the current peer set. - std::vector peers(); + std::vector peers(); /// Same as peers().size(), but more efficient. size_t peerCount() const; /// Same as peers().size(), but more efficient. @@ -305,7 +305,7 @@ private: std::unique_ptr m_workNet; ///< The network thread. std::atomic m_workNetState; mutable boost::shared_mutex x_net; ///< Lock for the network existance. - std::unique_ptr m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. + std::unique_ptr m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required. std::unique_ptr m_work; ///< The work thread. std::atomic m_workState; diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index e318bd66d..b35186fff 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -27,8 +27,8 @@ #include #include #include -#include -#include +#include +#include #include #include "BlockChain.h" #include "TransactionQueue.h" diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index e8aa57892..0ee56b9cf 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "CommonNet.h" #include "EthereumPeer.h" diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index 75983a2bf..5c121928d 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "BlockChain.h" #include "EthereumHost.h" using namespace std; diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h index 2aea2bdb3..5f01148af 100644 --- a/libethereum/EthereumPeer.h +++ b/libethereum/EthereumPeer.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "CommonNet.h" namespace eth diff --git a/libethereumx/Ethereum.cpp b/libethereumx/Ethereum.cpp index c4cc29d87..f2793a366 100644 --- a/libethereumx/Ethereum.cpp +++ b/libethereumx/Ethereum.cpp @@ -25,6 +25,7 @@ #include using namespace std; using namespace eth; +using namespace p2p; Ethereum::Ethereum() { diff --git a/libethereumx/Ethereum.h b/libethereumx/Ethereum.h index 6ede791cf..9f08234fe 100644 --- a/libethereumx/Ethereum.h +++ b/libethereumx/Ethereum.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include #include @@ -120,7 +120,7 @@ public: // Network stuff: /// Get information on the current peer set. - std::vector peers(); + std::vector peers(); /// Same as peers().size(), but more efficient. size_t peerCount() const; diff --git a/libethnet/All.h b/libethnet/All.h deleted file mode 100644 index 55a5423b7..000000000 --- a/libethnet/All.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "Common.h" -#include "PeerHost.h" -#include "PeerSession.h" - diff --git a/libethnet/CMakeLists.txt b/libp2p/CMakeLists.txt similarity index 99% rename from libethnet/CMakeLists.txt rename to libp2p/CMakeLists.txt index 79d07d7e4..98d9b06bb 100644 --- a/libethnet/CMakeLists.txt +++ b/libp2p/CMakeLists.txt @@ -4,7 +4,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") aux_source_directory(. SRC_LIST) -set(EXECUTABLE ethnet) +set(EXECUTABLE p2p) # set(CMAKE_INSTALL_PREFIX ../lib) if(ETH_STATIC) diff --git a/libethnet/Common.cpp b/libp2p/Common.cpp similarity index 100% rename from libethnet/Common.cpp rename to libp2p/Common.cpp diff --git a/libethnet/Common.h b/libp2p/Common.h similarity index 100% rename from libethnet/Common.h rename to libp2p/Common.h diff --git a/libethnet/PeerHost.cpp b/libp2p/PeerHost.cpp similarity index 100% rename from libethnet/PeerHost.cpp rename to libp2p/PeerHost.cpp diff --git a/libethnet/PeerHost.h b/libp2p/PeerHost.h similarity index 100% rename from libethnet/PeerHost.h rename to libp2p/PeerHost.h diff --git a/libethnet/PeerSession.cpp b/libp2p/PeerSession.cpp similarity index 100% rename from libethnet/PeerSession.cpp rename to libp2p/PeerSession.cpp diff --git a/libethnet/PeerSession.h b/libp2p/PeerSession.h similarity index 100% rename from libethnet/PeerSession.h rename to libp2p/PeerSession.h diff --git a/libethnet/UPnP.cpp b/libp2p/UPnP.cpp similarity index 100% rename from libethnet/UPnP.cpp rename to libp2p/UPnP.cpp diff --git a/libethnet/UPnP.h b/libp2p/UPnP.h similarity index 100% rename from libethnet/UPnP.h rename to libp2p/UPnP.h diff --git a/libpyserpent/pyserpent.cpp b/libpyserpent/pyserpent.cpp index ba3750b51..d97fd8fed 100644 --- a/libpyserpent/pyserpent.cpp +++ b/libpyserpent/pyserpent.cpp @@ -8,8 +8,14 @@ #define PYMETHOD(name, FROM, method, TO) \ static PyObject * name(PyObject *, PyObject *args) { \ + try { \ FROM(med) \ return TO(method(med)); \ + } \ + catch (std::string e) { \ + PyErr_SetString(PyExc_Exception, e.c_str()); \ + return NULL; \ + } \ } #define FROMSTR(v) \ @@ -149,7 +155,7 @@ static PyMethodDef PyextMethods[] = { {NULL, NULL, 0, NULL} /* Sentinel */ }; -PyMODINIT_FUNC initpyext(void) +PyMODINIT_FUNC initserpent_pyext(void) { - Py_InitModule( "pyext", PyextMethods ); + Py_InitModule( "serpent_pyext", PyextMethods ); } diff --git a/libqethereum/QEthereum.cpp b/libqethereum/QEthereum.cpp index 96b06ec89..96963f6ff 100644 --- a/libqethereum/QEthereum.cpp +++ b/libqethereum/QEthereum.cpp @@ -23,7 +23,7 @@ using eth::Client; using eth::Instruction; using eth::KeyPair; using eth::NodeMode; -using eth::PeerInfo; +using p2p::PeerInfo; using eth::RLP; using eth::Secret; using eth::Transaction; diff --git a/libqethereum/QmlEthereum.cpp b/libqethereum/QmlEthereum.cpp index 80ed891eb..3896382fd 100644 --- a/libqethereum/QmlEthereum.cpp +++ b/libqethereum/QmlEthereum.cpp @@ -26,7 +26,7 @@ using eth::Client; using eth::Instruction; using eth::KeyPair; using eth::NodeMode; -using eth::PeerInfo; +using p2p::PeerInfo; using eth::RLP; using eth::Secret; using eth::Transaction; diff --git a/libserpent/bignum.cpp b/libserpent/bignum.cpp index 29315b871..877808ead 100644 --- a/libserpent/bignum.cpp +++ b/libserpent/bignum.cpp @@ -5,9 +5,9 @@ #include "bignum.h" //Integer to string conversion -std::string intToDecimal(int branch) { +std::string unsignedToDecimal(unsigned branch) { if (branch < 10) return nums.substr(branch, 1); - else return intToDecimal(branch / 10) + nums.substr(branch % 10,1); + else return unsignedToDecimal(branch / 10) + nums.substr(branch % 10,1); } //Add two strings representing decimal values @@ -91,8 +91,8 @@ std::string decimalMod(std::string a, std::string b) { } //String to int conversion -int decimalToInt(std::string a) { +unsigned decimalToUnsigned(std::string a) { if (a.size() == 0) return 0; else return (a[a.size() - 1] - '0') - + decimalToInt(a.substr(0,a.size()-1)) * 10; + + decimalToUnsigned(a.substr(0,a.size()-1)) * 10; } diff --git a/libserpent/bignum.h b/libserpent/bignum.h index a12929752..6656fdaec 100644 --- a/libserpent/bignum.h +++ b/libserpent/bignum.h @@ -11,7 +11,7 @@ const std::string tt255 = "57896044618658097711785492504343953926634992332820282019728792003956564819968" ; -std::string intToDecimal(int branch); +std::string unsignedToDecimal(unsigned branch); std::string decimalAdd(std::string a, std::string b); @@ -25,6 +25,6 @@ std::string decimalMod(std::string a, std::string b); bool decimalGt(std::string a, std::string b, bool eqAllowed=false); -int decimalToInt(std::string a); +unsigned decimalToUnsigned(std::string a); #endif diff --git a/libserpent/compiler.cpp b/libserpent/compiler.cpp index 959d2993b..4360bfba6 100644 --- a/libserpent/compiler.cpp +++ b/libserpent/compiler.cpp @@ -17,6 +17,7 @@ struct programAux { struct programData { programAux aux; Node code; + int outs; }; programAux Aux() { @@ -27,10 +28,11 @@ programAux Aux() { return o; } -programData pd(programAux aux = Aux(), Node code=token("_")) { +programData pd(programAux aux = Aux(), Node code=token("_"), int outs=0) { programData o; o.aux = aux; o.code = code; + o.outs = outs; return o; } @@ -44,151 +46,249 @@ Node multiToken(Node nodes[], int len, Metadata met) { Node finalize(programData c); +Node popwrap(Node node) { + Node nodelist[] = { + node, + token("POP", node.metadata) + }; + return multiToken(nodelist, 2, node.metadata); +} + // Turns LLL tree into tree of code fragments -programData opcodeify(Node node, programAux aux=Aux()) { +programData opcodeify(Node node, + programAux aux=Aux(), + int height=0, + std::map dupvars= + std::map()) { std::string symb = "_"+mkUniqueToken(); Metadata m = node.metadata; // Numbers if (node.type == TOKEN) { - return pd(aux, nodeToNumeric(node)); + return pd(aux, nodeToNumeric(node), 1); } else if (node.val == "ref" || node.val == "get" || node.val == "set") { std::string varname = node.args[0].val; if (!aux.vars.count(varname)) { - aux.vars[varname] = intToDecimal(aux.vars.size() * 32); + aux.vars[varname] = unsignedToDecimal(aux.vars.size() * 32); } - if (varname == "msg.data") aux.calldataUsed = true; + if (varname == "'msg.data") aux.calldataUsed = true; // Set variable if (node.val == "set") { - programData sub = opcodeify(node.args[1], aux); - Node nodelist[] = { - sub.code, - token(aux.vars[varname], m), - token("MSTORE", m), - }; - return pd(sub.aux, multiToken(nodelist, 3, m)); + programData sub = opcodeify(node.args[1], aux, height, dupvars); + if (!sub.outs) + err("Value to set variable must have nonzero arity!", m); + if (dupvars.count(node.args[0].val)) { + int h = height - dupvars[node.args[0].val]; + if (h > 16) err("Too deep for stack variable (max 16)", m); + Node nodelist[] = { + sub.code, + token("SWAP"+unsignedToDecimal(h), m), + token("POP", m) + }; + return pd(sub.aux, multiToken(nodelist, 3, m), 0); + } + Node nodelist[] = { + sub.code, + token(sub.aux.vars[varname], m), + token("MSTORE", m), + }; + return pd(sub.aux, multiToken(nodelist, 3, m), 0); } // Get variable else if (node.val == "get") { - Node nodelist[] = - { token(aux.vars[varname], m), token("MLOAD", m) }; - return pd(aux, multiToken(nodelist, 2, m)); + if (dupvars.count(node.args[0].val)) { + int h = height - dupvars[node.args[0].val]; + if (h > 16) err("Too deep for stack variable (max 16)", m); + return pd(aux, token("DUP"+unsignedToDecimal(h)), 1); + } + Node nodelist[] = + { token(aux.vars[varname], m), token("MLOAD", m) }; + return pd(aux, multiToken(nodelist, 2, m), 1); } // Refer variable - else return pd(aux, token(aux.vars[varname], m)); + else { + if (dupvars.count(node.args[0].val)) + err("Cannot ref stack variable!", m); + return pd(aux, token(aux.vars[varname], m), 1); + } } // Code blocks if (node.val == "lll" && node.args.size() == 2) { if (node.args[1].val != "0") aux.allocUsed = true; std::vector o; o.push_back(finalize(opcodeify(node.args[0]))); - programData sub = opcodeify(node.args[1], aux); + programData sub = opcodeify(node.args[1], aux, height, dupvars); Node code = astnode("____CODE", o, m); Node nodelist[] = { - token("$begincode"+symb+".endcode"+symb, m), token("DUP", m), + token("$begincode"+symb+".endcode"+symb, m), token("DUP1", m), token("$begincode"+symb, m), sub.code, token("CODECOPY", m), token("$endcode"+symb, m), token("JUMP", m), token("~begincode"+symb, m), code, token("~endcode"+symb, m) }; - return pd(sub.aux, multiToken(nodelist, 10, m)); + return pd(sub.aux, multiToken(nodelist, 10, m), 1); } - std::vector subs; - for (unsigned i = 0; i < node.args.size(); i++) { - programData sub = opcodeify(node.args[i], aux); - aux = sub.aux; - subs.push_back(sub.code); - } - // Debug - if (node.val == "debug") { + // Stack variables + if (node.val == "with") { + std::map dupvars2 = dupvars; + dupvars2[node.args[0].val] = height; + programData initial = opcodeify(node.args[1], aux, height, dupvars); + if (!initial.outs) + err("Initial variable value must have nonzero arity!", m); + programData sub = opcodeify(node.args[2], initial.aux, height + 1, dupvars2); Node nodelist[] = { - subs[0], - token("DUP", m), token("POP", m), token("POP", m) + initial.code, + sub.code }; - return pd(aux, multiToken(nodelist, 4, m)); + programData o = pd(sub.aux, multiToken(nodelist, 2, m), sub.outs); + if (sub.outs) + o.code.args.push_back(token("SWAP1", m)); + o.code.args.push_back(token("POP", m)); + return o; } // Seq of multiple statements if (node.val == "seq") { - return pd(aux, astnode("_", subs, m)); + std::vector children; + int lastOut = 0; + for (unsigned i = 0; i < node.args.size(); i++) { + programData sub = opcodeify(node.args[i], aux, height, dupvars); + aux = sub.aux; + if (sub.outs == 1) { + if (i < node.args.size() - 1) sub.code = popwrap(sub.code); + else lastOut = 1; + } + children.push_back(sub.code); + } + return pd(aux, astnode("_", children, m), lastOut); } // 2-part conditional (if gets rewritten to unless in rewrites) else if (node.val == "unless" && node.args.size() == 2) { + programData cond = opcodeify(node.args[0], aux, height, dupvars); + programData action = opcodeify(node.args[1], cond.aux, height, dupvars); + aux = action.aux; + if (!cond.outs) err("Condition of if/unless statement has arity 0", m); + if (action.outs) action.code = popwrap(action.code); Node nodelist[] = { - subs[0], + cond.code, token("$endif"+symb, m), token("JUMPI", m), - subs[1], + action.code, token("~endif"+symb, m) }; - return pd(aux, multiToken(nodelist, 5, m)); + return pd(aux, multiToken(nodelist, 5, m), 0); } // 3-part conditional else if (node.val == "if" && node.args.size() == 3) { + programData ifd = opcodeify(node.args[0], aux, height, dupvars); + programData thend = opcodeify(node.args[1], ifd.aux, height, dupvars); + programData elsed = opcodeify(node.args[2], thend.aux, height, dupvars); + aux = elsed.aux; + if (!ifd.outs) + err("Condition of if/unless statement has arity 0", m); + // Handle cases where one conditional outputs something + // and the other does not + int outs = (thend.outs && elsed.outs) ? 1 : 0; + if (thend.outs > outs) thend.code = popwrap(thend.code); + if (elsed.outs > outs) elsed.code = popwrap(elsed.code); Node nodelist[] = { - subs[0], + ifd.code, token("NOT", m), token("$else"+symb, m), token("JUMPI", m), - subs[1], + thend.code, token("$endif"+symb, m), token("JUMP", m), token("~else"+symb, m), - subs[2], + elsed.code, token("~endif"+symb, m) }; - return pd(aux, multiToken(nodelist, 10, m)); + return pd(aux, multiToken(nodelist, 10, m), outs); } // While (rewritten to this in rewrites) else if (node.val == "until") { + programData cond = opcodeify(node.args[0], aux, height, dupvars); + programData action = opcodeify(node.args[1], cond.aux, height, dupvars); + aux = action.aux; + if (!cond.outs) + err("Condition of while/until loop has arity 0", m); + if (action.outs) action.code = popwrap(action.code); Node nodelist[] = { token("~beg"+symb, m), - subs[0], + cond.code, token("$end"+symb, m), token("JUMPI", m), - subs[1], + action.code, token("$beg"+symb, m), token("JUMP", m), token("~end"+symb, m) }; return pd(aux, multiToken(nodelist, 8, m)); } // Memory allocations else if (node.val == "alloc") { + programData bytez = opcodeify(node.args[0], aux, height, dupvars); + aux = bytez.aux; + if (!bytez.outs) + err("Alloc input has arity 0", m); aux.allocUsed = true; Node nodelist[] = { - subs[0], - token("MSIZE", m), token("SWAP", m), token("MSIZE", m), + bytez.code, + token("MSIZE", m), token("SWAP1", m), token("MSIZE", m), token("ADD", m), - token("0", m), token("SWAP", m), token("MSTORE", m) + token("0", m), token("SWAP1", m), token("MSTORE", m) }; - return pd(aux, multiToken(nodelist, 8, m)); + return pd(aux, multiToken(nodelist, 8, m), 1); } // Array literals else if (node.val == "array_lit") { aux.allocUsed = true; std::vector nodes; - if (!subs.size()) { + if (!node.args.size()) { nodes.push_back(token("MSIZE", m)); return pd(aux, astnode("_", nodes, m)); } nodes.push_back(token("MSIZE", m)); nodes.push_back(token("0", m)); nodes.push_back(token("MSIZE", m)); - nodes.push_back(token(intToDecimal(subs.size() * 32 - 1), m)); + nodes.push_back(token(unsignedToDecimal(node.args.size() * 32 - 1), m)); nodes.push_back(token("ADD", m)); nodes.push_back(token("MSTORE8", m)); - for (unsigned i = 0; i < subs.size(); i++) { - nodes.push_back(token("DUP", m)); - nodes.push_back(subs[i]); - nodes.push_back(token("SWAP", m)); + for (unsigned i = 0; i < node.args.size(); i++) { + Metadata m2 = node.args[i].metadata; + nodes.push_back(token("DUP1", m2)); + programData sub = opcodeify(node.args[i], aux, height + 2, dupvars); + if (!sub.outs) + err("Array_lit item " + unsignedToDecimal(i) + " has zero arity", m2); + aux = sub.aux; + nodes.push_back(sub.code); + nodes.push_back(token("SWAP1", m2)); if (i > 0) { - nodes.push_back(token(intToDecimal(i * 32), m)); - nodes.push_back(token("ADD", m)); + nodes.push_back(token(unsignedToDecimal(i * 32), m2)); + nodes.push_back(token("ADD", m2)); } - nodes.push_back(token("MSTORE", m)); + nodes.push_back(token("MSTORE", m2)); } - return pd(aux, astnode("_", nodes, m)); + return pd(aux, astnode("_", nodes, m), 1); } // All other functions/operators else { - std::vector subs2; - while (subs.size()) { - subs2.push_back(subs.back()); - subs.pop_back(); + std::vector subs2; + int depth = opinputs(upperCase(node.val)); + if (node.val != "debug") { + if (depth == -1) + err("Not a function or opcode: "+node.val, m); + if ((int)node.args.size() != depth) + err("Invalid arity for "+node.val, m); + } + for (int i = node.args.size() - 1; i >= 0; i--) { + programData sub = opcodeify(node.args[i], + aux, + height - i - 1 + node.args.size(), + dupvars); + aux = sub.aux; + if (!sub.outs) + err("Input "+unsignedToDecimal(i)+" has arity 0", sub.code.metadata); + subs2.push_back(sub.code); + } + if (node.val == "debug") { + subs2.push_back(token("DUP"+unsignedToDecimal(node.args.size()), m)); + for (int i = 0; i <= (int)node.args.size(); i++) + subs2.push_back(token("POP", m)); } - subs2.push_back(token(upperCase(node.val), m)); - return pd(aux, astnode("_", subs2, m)); + else subs2.push_back(token(upperCase(node.val), m)); + int outdepth = node.val == "debug" ? 0 : opoutputs(upperCase(node.val)); + return pd(aux, astnode("_", subs2, m), outdepth); } } @@ -201,7 +301,7 @@ Node finalize(programData c) { if (c.aux.allocUsed && c.aux.vars.size() > 0) { Node nodelist[] = { token("0", m), - token(intToDecimal(c.aux.vars.size() * 32 - 1)), + token(unsignedToDecimal(c.aux.vars.size() * 32 - 1)), token("MSTORE8", m) }; bottom.push_back(multiToken(nodelist, 3, m)); @@ -211,7 +311,7 @@ Node finalize(programData c) { Node nodelist[] = { token("MSIZE", m), token("CALLDATASIZE", m), token("MSIZE", m), token("0", m), token("CALLDATACOPY", m), - token(c.aux.vars["msg.data"], m), token("MSTORE", m) + token(c.aux.vars["'msg.data"], m), token("MSTORE", m) }; bottom.push_back(multiToken(nodelist, 7, m)); } @@ -235,7 +335,7 @@ programAux buildDict(Node program, programAux aux, int labelLength) { aux.step += 1 + toByteArr(program.val, m).size(); } else if (program.val[0] == '~') { - aux.vars[program.val.substr(1)] = intToDecimal(aux.step); + aux.vars[program.val.substr(1)] = unsignedToDecimal(aux.step); } else if (program.val[0] == '$') { aux.step += labelLength + 1; @@ -245,7 +345,7 @@ programAux buildDict(Node program, programAux aux, int labelLength) { // A sub-program (ie. LLL) else if (program.val == "____CODE") { programAux auks = Aux(); - for (unsigned i = 0; i < program.args.size(); i++) { + for (unsigned i = 0; i < program.args.size(); i++) { auks = buildDict(program.args[i], auks, labelLength); } for (std::map::iterator it=auks.vars.begin(); @@ -257,7 +357,7 @@ programAux buildDict(Node program, programAux aux, int labelLength) { } // Normal sub-block else { - for (unsigned i = 0; i < program.args.size(); i++) { + for (unsigned i = 0; i < program.args.size(); i++) { aux = buildDict(program.args[i], aux, labelLength); } } @@ -271,7 +371,7 @@ Node substDict(Node program, programAux aux, int labelLength) { std::vector inner; if (program.type == TOKEN) { if (program.val[0] == '$') { - std::string tokStr = "PUSH"+intToDecimal(labelLength); + std::string tokStr = "PUSH"+unsignedToDecimal(labelLength); out.push_back(token(tokStr, m)); int dotLoc = program.val.find('.'); if (dotLoc == -1) { @@ -289,13 +389,13 @@ Node substDict(Node program, programAux aux, int labelLength) { else if (program.val[0] == '~') { } else if (isNumberLike(program)) { inner = toByteArr(program.val, m); - out.push_back(token("PUSH"+intToDecimal(inner.size()))); + out.push_back(token("PUSH"+unsignedToDecimal(inner.size()))); out.push_back(astnode("_", inner, m)); } else return program; } else { - for (unsigned i = 0; i < program.args.size(); i++) { + for (unsigned i = 0; i < program.args.size(); i++) { Node n = substDict(program.args[i], aux, labelLength); if (n.type == TOKEN || n.args.size()) out.push_back(n); } @@ -319,9 +419,9 @@ std::vector flatten(Node derefed) { o.push_back(derefed); } else { - for (unsigned i = 0; i < derefed.args.size(); i++) { + for (unsigned i = 0; i < derefed.args.size(); i++) { std::vector oprime = flatten(derefed.args[i]); - for (unsigned j = 0; j < oprime.size(); j++) o.push_back(oprime[j]); + for (unsigned j = 0; j < oprime.size(); j++) o.push_back(oprime[j]); } } return o; @@ -330,13 +430,13 @@ std::vector flatten(Node derefed) { // Opcodes -> bin std::string serialize(std::vector codons) { std::string o; - for (unsigned i = 0; i < codons.size(); i++) { + for (unsigned i = 0; i < codons.size(); i++) { int v; if (isNumberLike(codons[i])) { - v = decimalToInt(codons[i].val); + v = decimalToUnsigned(codons[i].val); } else if (codons[i].val.substr(0,4) == "PUSH") { - v = 95 + decimalToInt(codons[i].val.substr(4)); + v = 95 + decimalToUnsigned(codons[i].val.substr(4)); } else { v = opcode(codons[i].val); @@ -350,14 +450,14 @@ std::string serialize(std::vector codons) { std::vector deserialize(std::string ser) { std::vector o; int backCount = 0; - for (unsigned i = 0; i < ser.length(); i++) { + for (unsigned i = 0; i < ser.length(); i++) { unsigned char v = (unsigned char)ser[i]; std::string oper = op((int)v); if (oper != "" && backCount <= 0) o.push_back(token(oper)); else if (v >= 96 && v < 128 && backCount <= 0) { - o.push_back(token("PUSH"+intToDecimal(v - 95))); + o.push_back(token("PUSH"+unsignedToDecimal(v - 95))); } - else o.push_back(token(intToDecimal(v))); + else o.push_back(token(unsignedToDecimal(v))); if (v >= 96 && v < 128 && backCount <= 0) { backCount = v - 95; } @@ -389,10 +489,10 @@ std::vector prettyCompileLLL(Node program) { // Converts a list of integer values to binary transaction data std::string encodeDatalist(std::vector vals) { std::string o; - for (unsigned i = 0; i < vals.size(); i++) { + for (unsigned i = 0; i < vals.size(); i++) { std::vector n = toByteArr(strToNumeric(vals[i]), Metadata(), 32); - for (unsigned j = 0; j < n.size(); j++) { - int v = decimalToInt(n[j].val); + for (unsigned j = 0; j < n.size(); j++) { + int v = decimalToUnsigned(n[j].val); o += (char)v; } } @@ -402,11 +502,11 @@ std::string encodeDatalist(std::vector vals) { // Converts binary transaction data into a list of integer values std::vector decodeDatalist(std::string ser) { std::vector out; - for (unsigned i = 0; i < ser.length(); i+= 32) { + for (unsigned i = 0; i < ser.length(); i+= 32) { std::string o = "0"; for (unsigned j = i; j < i + 32; j++) { int vj = (int)(unsigned char)ser[j]; - o = decimalAdd(decimalMul(o, "256"), intToDecimal(vj)); + o = decimalAdd(decimalMul(o, "256"), unsignedToDecimal(vj)); } out.push_back(o); } diff --git a/libserpent/opcodes.h b/libserpent/opcodes.h index 6b42df97a..f55834efa 100644 --- a/libserpent/opcodes.h +++ b/libserpent/opcodes.h @@ -6,86 +6,124 @@ #include #include -std::map opcodes; +class Mapping { + public: + Mapping(std::string Op, int Opcode, int In, int Out) { + op = Op; + opcode = Opcode; + in = In; + out = Out; + } + std::string op; + int opcode; + int in; + int out; +}; + +Mapping mapping[] = { + Mapping("STOP", 0x00, 0, 0), + Mapping("ADD", 0x01, 2, 1), + Mapping("MUL", 0x02, 2, 1), + Mapping("SUB", 0x03, 2, 1), + Mapping("DIV", 0x04, 2, 1), + Mapping("SDIV", 0x05, 2, 1), + Mapping("MOD", 0x06, 2, 1), + Mapping("SMOD", 0x07, 2, 1), + Mapping("EXP", 0x08, 2, 1), + Mapping("NEG", 0x09, 1, 1), + Mapping("LT", 0x0a, 2, 1), + Mapping("GT", 0x0b, 2, 1), + Mapping("SLT", 0x0c, 2, 1), + Mapping("SGT", 0x0d, 2, 1), + Mapping("EQ", 0x0e, 2, 1), + Mapping("NOT", 0x0f, 1, 1), + Mapping("AND", 0x10, 2, 1), + Mapping("OR", 0x11, 2, 1), + Mapping("XOR", 0x12, 2, 1), + Mapping("BYTE", 0x13, 2, 1), + Mapping("ADDMOD", 0x14, 3, 1), + Mapping("MULMOD", 0x15, 3, 1), + Mapping("SHA3", 0x20, 2, 1), + Mapping("ADDRESS", 0x30, 0, 1), + Mapping("BALANCE", 0x31, 1, 1), + Mapping("ORIGIN", 0x32, 0, 1), + Mapping("CALLER", 0x33, 0, 1), + Mapping("CALLVALUE", 0x34, 0, 1), + Mapping("CALLDATALOAD", 0x35, 1, 1), + Mapping("CALLDATASIZE", 0x36, 0, 1), + Mapping("CALLDATACOPY", 0x37, 3, 1), + Mapping("CODESIZE", 0x38, 0, 1), + Mapping("CODECOPY", 0x39, 3, 1), + Mapping("GASPRICE", 0x3a, 0, 1), + Mapping("PREVHASH", 0x40, 0, 1), + Mapping("COINBASE", 0x41, 0, 1), + Mapping("TIMESTAMP", 0x42, 0, 1), + Mapping("NUMBER", 0x43, 0, 1), + Mapping("DIFFICULTY", 0x44, 0, 1), + Mapping("GASLIMIT", 0x45, 0, 1), + Mapping("POP", 0x50, 1, 0), + Mapping("MLOAD", 0x53, 1, 1), + Mapping("MSTORE", 0x54, 2, 0), + Mapping("MSTORE8", 0x55, 2, 0), + Mapping("SLOAD", 0x56, 1, 1), + Mapping("SSTORE", 0x57, 2, 0), + Mapping("JUMP", 0x58, 1, 0), + Mapping("JUMPI", 0x59, 2, 0), + Mapping("PC", 0x5a, 0, 1), + Mapping("MSIZE", 0x5b, 0, 1), + Mapping("GAS", 0x5c, 0, 1), + Mapping("CREATE", 0xf0, 3, 1), + Mapping("CALL", 0xf1, 7, 1), + Mapping("RETURN", 0xf2, 2, 0), + Mapping("POST", 0xf3, 5, 0), + Mapping("CALL_STATELESS", 0xf4, 7, 1), + Mapping("SUICIDE", 0xff, 1, 0), + Mapping("---END---", 0x00, 0, 0), +}; + +std::map > opcodes; std::map reverseOpcodes; // Fetches everything EXCEPT PUSH1..32 -std::pair _opcode(std::string ops, int opi) { +std::pair > _opdata(std::string ops, int opi) { if (!opcodes.size()) { - opcodes["STOP"] = 0x00; - opcodes["ADD"] = 0x01; - opcodes["MUL"] = 0x02; - opcodes["SUB"] = 0x03; - opcodes["DIV"] = 0x04; - opcodes["SDIV"] = 0x05; - opcodes["MOD"] = 0x06; - opcodes["SMOD"] = 0x07; - opcodes["EXP"] = 0x08; - opcodes["NEG"] = 0x09; - opcodes["LT"] = 0x0a; - opcodes["GT"] = 0x0b; - opcodes["SLT"] = 0x0c; - opcodes["SGT"] = 0x0d; - opcodes["EQ"] = 0x0e; - opcodes["NOT"] = 0x0f; - opcodes["AND"] = 0x10; - opcodes["OR"] = 0x11; - opcodes["XOR"] = 0x12; - opcodes["BYTE"] = 0x13; - opcodes["SHA3"] = 0x20; - opcodes["ADDRESS"] = 0x30; - opcodes["BALANCE"] = 0x31; - opcodes["ORIGIN"] = 0x32; - opcodes["CALLER"] = 0x33; - opcodes["CALLVALUE"] = 0x34; - opcodes["CALLDATALOAD"] = 0x35; - opcodes["CALLDATASIZE"] = 0x36; - opcodes["CALLDATACOPY"] = 0x37; - opcodes["CODESIZE"] = 0x38; - opcodes["CODECOPY"] = 0x39; - opcodes["GASPRICE"] = 0x3a; - opcodes["PREVHASH"] = 0x40; - opcodes["COINBASE"] = 0x41; - opcodes["TIMESTAMP"] = 0x42; - opcodes["NUMBER"] = 0x43; - opcodes["DIFFICULTY"] = 0x44; - opcodes["GASLIMIT"] = 0x45; - opcodes["POP"] = 0x50; - opcodes["DUP"] = 0x51; - opcodes["SWAP"] = 0x52; - opcodes["MLOAD"] = 0x53; - opcodes["MSTORE"] = 0x54; - opcodes["MSTORE8"] = 0x55; - opcodes["SLOAD"] = 0x56; - opcodes["SSTORE"] = 0x57; - opcodes["JUMP"] = 0x58; - opcodes["JUMPI"] = 0x59; - opcodes["PC"] = 0x5a; - opcodes["MSIZE"] = 0x5b; - opcodes["GAS"] = 0x5c; - opcodes["CREATE"] = 0xf0; - opcodes["CALL"] = 0xf1; - opcodes["RETURN"] = 0xf2; - opcodes["SUICIDE"] = 0xff; - for (std::map::iterator it=opcodes.begin(); + int i = 0; + while (mapping[i].op != "---END---") { + Mapping mi = mapping[i]; + opcodes[mi.op] = triple(mi.opcode, mi.in, mi.out); + i++; + } + for (i = 1; i <= 16; i++) { + opcodes["DUP"+unsignedToDecimal(i)] = triple(0x7f + i, i, i+1); + opcodes["SWAP"+unsignedToDecimal(i)] = triple(0x8f + i, i+1, i+1); + } + for (std::map >::iterator it=opcodes.begin(); it != opcodes.end(); it++) { - reverseOpcodes[(*it).second] = (*it).first; + reverseOpcodes[(*it).second[0]] = (*it).first; } } std::string op; - int opcode; + std::vector opdata; op = reverseOpcodes.count(opi) ? reverseOpcodes[opi] : ""; - opcode = opcodes.count(ops) ? opcodes[ops] : -1; - return std::pair(op, opcode); + opdata = opcodes.count(ops) ? opcodes[ops] : triple(-1, -1, -1); + return std::pair >(op, opdata); } int opcode(std::string op) { - return _opcode(op, 0).second; + return _opdata(op, -1).second[0]; +} + +int opinputs(std::string op) { + return _opdata(op, -1).second[1]; +} + +int opoutputs(std::string op) { + return _opdata(op, -1).second[2]; } std::string op(int opcode) { - return _opcode("", opcode).first; + return _opdata("", opcode).first; } #endif diff --git a/libserpent/parser.cpp b/libserpent/parser.cpp index 497bdb526..5adf1672d 100644 --- a/libserpent/parser.cpp +++ b/libserpent/parser.cpp @@ -85,8 +85,11 @@ std::vector shuntingYard(std::vector tokens) { } oq.push_back(tok); } + else if (toktyp == UNARY_OP) { + stack.push_back(tok); + } // If binary op, keep popping from stack while higher bedmas precedence - else if (toktyp == UNARY_OP || toktyp == BINARY_OP) { + else if (toktyp == BINARY_OP) { if (tok.val == "-" && prevtyp != ALPHANUM && prevtyp != RPAREN) { oq.push_back(token("0", tok.metadata)); } @@ -239,14 +242,16 @@ int spaceCount(std::string s) { // Is this a command that takes an argument on the same line? bool bodied(std::string tok) { - return tok == "if" || tok == "elif" || tok == "while"; + return tok == "if" || tok == "elif" || tok == "while" + || tok == "with" || tok == "def"; } // Is this a command that takes an argument as a child block? bool childBlocked(std::string tok) { return tok == "if" || tok == "elif" || tok == "else" || tok == "code" || tok == "shared" || tok == "init" - || tok == "while" || tok == "repeat" || tok == "for"; + || tok == "while" || tok == "repeat" || tok == "for" + || tok == "with" || tok == "def"; } // Are the two commands meant to continue each other? diff --git a/libserpent/rewriter.cpp b/libserpent/rewriter.cpp index 8b50c9a28..72feb1277 100644 --- a/libserpent/rewriter.cpp +++ b/libserpent/rewriter.cpp @@ -17,8 +17,12 @@ std::string valid[][3] = { { "alloc", "1", "1" }, { "array", "1", "1" }, { "call", "2", "4" }, + { "call_stateless", "2", "4" }, + { "post", "4", "5" }, + { "postcall", "3", "4" }, { "create", "1", "4" }, { "msg", "4", "6" }, + { "msg_stateless", "4", "6" }, { "getch", "2", "2" }, { "setch", "3", "3" }, { "sha3", "1", "2" }, @@ -78,6 +82,10 @@ std::string macros[][2] = { "(access msg.data $ind)", "(calldataload (mul 32 $ind))" }, + { + "(slice $arr $pos)", + "(add $arr (mul 32 $pos))", + }, { "(array $len)", "(alloc (mul 32 $len))" @@ -126,6 +134,22 @@ std::string macros[][2] = { "(send $to $value)", "(call (sub (gas) 25) $to $value 0 0 0 0)" }, + { + "(post $gas $to $value $datain $datainsz)", + "(~post $gas $to $value $datain (mul $datainsz 32))" + }, + { + "(post $gas $to $value $datain)", + "(seq (set $1 $datain) (~post $gas $to $value (ref $1) 32))" + }, + { + "(postcall $gas $to $datain)", + "(post $gas $to 0 $datain)", + }, + { + "(postcall $gas $to $datain $datainsz)", + "(post $gas $to 0 $datain $datainsz)", + }, { "(send $gas $to $value)", "(call $gas $to $value 0 0 0 0)" @@ -156,7 +180,7 @@ std::string macros[][2] = { }, { "(|| $x $y)", - "(seq (set $1 $x) (if (get $1) (get $1) $y))" + "(with $1 $x (if (get $1) (get $1) $y))" }, { "(>= $x $y)", @@ -180,8 +204,9 @@ std::string macros[][2] = { }, { "(create $endowment $code)", - "(seq (set $1 (msize)) (create $endowment (get $1) (lll (outer $code) (msize))))" + "(with $1 (msize) (create $endowment (get $1) (lll (outer $code) (msize))))" }, + // Call and msg { "(call $f $dataval)", "(msg (sub (gas) 45) $f 0 $dataval)" @@ -192,7 +217,7 @@ std::string macros[][2] = { }, { "(call $f $inp $inpsz $outsz)", - "(seq (set $1 $outsz) (set $2 (alloc (mul 32 (get $1)))) (pop (call (sub (gas) (add 25 (get $1))) $f 0 $inp (mul 32 $inpsz) (get $2) (mul 32 (get $1)))) (get $2))" + "(with $1 $outsz (with $2 (alloc (mul 32 (get $1))) (seq (call (sub (gas) (add 25 (get $1))) $f 0 $inp (mul 32 $inpsz) (get $2) (mul 32 (get $1))) (get $2))))" }, { "(msg $gas $to $val $inp $inpsz)", @@ -204,8 +229,34 @@ std::string macros[][2] = { }, { "(msg $gas $to $val $inp $inpsz $outsz)", - "(seq (set $1 (mul 32 $outsz)) (set $2 (alloc (get $1))) (pop (call $gas $to $val $inp (mul 32 $inpsz) (get $2) (get $1))) (get $2))" + "(with $1 (mul 32 $outsz) (with $2 (alloc (get $1)) (call $gas $to $val $inp (mul 32 $inpsz) (get $2) (get $1)) (get $2)))" }, + // Call stateless and msg stateless + { + "(call_stateless $f $dataval)", + "(msg_stateless (sub (gas) 45) $f 0 $dataval)" + }, + { + "(call_stateless $f $inp $inpsz)", + "(msg_stateless (sub (gas) 25) $f 0 $inp $inpsz)" + }, + { + "(call_stateless $f $inp $inpsz $outsz)", + "(with $1 $outsz (with $2 (alloc (mul 32 (get $1))) (seq (call_stateless (sub (gas) (add 25 (get $1))) $f 0 $inp (mul 32 $inpsz) (get $2) (mul 32 (get $1))) (get $2))))" + }, + { + "(msg_stateless $gas $to $val $inp $inpsz)", + "(seq (call_stateless $gas $to $val $inp (mul 32 $inpsz) (ref $1) 32) (get $1))" + }, + { + "(msg_stateless $gas $to $val $dataval)", + "(seq (set $1 $dataval) (call_stateless $gas $to $val (ref $1) 32 (ref $2) 32) (get $2))" + }, + { + "(msg_stateless $gas $to $val $inp $inpsz $outsz)", + "(with $1 (mul 32 $outsz) (with $2 (alloc (get $1)) (call_stateless $gas $to $val $inp (mul 32 $inpsz) (get $2) (get $1)) (get $2)))" + }, + // Wrappers { "(outer (init $init $code))", "(seq $init (~return 0 (lll $code 0)))" @@ -228,7 +279,11 @@ std::string macros[][2] = { }, { "(create $x)", - "(seq (set $1 (msize)) (create $val (get $1) (lll $code (get $1))))" + "(with $1 (msize) (create $val (get $1) (lll $code (get $1))))" + }, + { + "(with (= $var $val) $cond)", + "(with $var $val $cond)" }, { "msg.datasize", "(div (calldatasize) 32)" }, { "msg.sender", "(caller)" }, @@ -253,6 +308,8 @@ std::vector > nodeMacros; std::string synonyms[][2] = { { "or", "||" }, { "and", "&&" }, + { "|", "~or" }, + { "&", "~and" }, { "elif", "if" }, { "!", "not" }, { "string", "alloc" }, @@ -344,7 +401,7 @@ Node subst(Node pattern, Node array_lit_transform(Node node) { std::vector o1; - o1.push_back(token(intToDecimal(node.args.size() * 32), node.metadata)); + o1.push_back(token(unsignedToDecimal(node.args.size() * 32), node.metadata)); std::vector o2; std::string symb = "_temp"+mkUniqueToken()+"_0"; o2.push_back(token(symb, node.metadata)); @@ -357,7 +414,7 @@ Node array_lit_transform(Node node) { o5.push_back(token(symb, node.metadata)); std::vector o6; o6.push_back(astnode("get", o5, node.metadata)); - o6.push_back(token(intToDecimal(i * 32), node.metadata)); + o6.push_back(token(unsignedToDecimal(i * 32), node.metadata)); std::vector o7; o7.push_back(astnode("add", o6)); o7.push_back(node.args[i]); @@ -407,7 +464,8 @@ Node apply_rules(Node node) { node = array_lit_transform(node); if (node.type == ASTNODE) { unsigned i = 0; - if (node.val == "set" || node.val == "ref" || node.val == "get") { + if (node.val == "set" || node.val == "ref" + || node.val == "get" || node.val == "with") { node.args[0].val = "'" + node.args[0].val; i = 1; } @@ -430,7 +488,12 @@ Node apply_rules(Node node) { } Node optimize(Node inp) { - if (inp.type == TOKEN) return tryNumberize(inp); + if (inp.type == TOKEN) { + Node o = tryNumberize(inp); + if (decimalGt(o.val, tt256, true)) + err("Value too large (exceeds 32 bytes or 2^256)", inp.metadata); + return o; + } for (unsigned i = 0; i < inp.args.size(); i++) { inp.args[i] = optimize(inp.args[i]); } @@ -474,10 +537,10 @@ Node validate(Node inp) { int i = 0; while(valid[i][0] != "---END---") { if (inp.val == valid[i][0]) { - if (decimalGt(valid[i][1], intToDecimal(inp.args.size()))) { + if (decimalGt(valid[i][1], unsignedToDecimal(inp.args.size()))) { err("Too few arguments for "+inp.val, inp.metadata); } - if (decimalGt(intToDecimal(inp.args.size()), valid[i][2])) { + if (decimalGt(unsignedToDecimal(inp.args.size()), valid[i][2])) { err("Too many arguments for "+inp.val, inp.metadata); } } diff --git a/libserpent/tokenize.cpp b/libserpent/tokenize.cpp index fc33d5dad..a5d3f1c5b 100644 --- a/libserpent/tokenize.cpp +++ b/libserpent/tokenize.cpp @@ -85,9 +85,10 @@ std::vector tokenize(std::string inp, Metadata metadata, bool lispMode) { } } // Special case the minus sign - if (cur.length() > 1 && cur[cur.length() - 1] == '-') { + if (cur.length() > 1 && (cur.substr(cur.length() - 1) == "-" + || cur.substr(cur.length() - 1) == "!")) { out.push_back(token(cur.substr(0, cur.length() - 1), metadata)); - out.push_back(token("-", metadata)); + out.push_back(token(cur.substr(cur.length() - 1), metadata)); cur = ""; } // Boundary between different char types diff --git a/libserpent/util.cpp b/libserpent/util.cpp index 6ca39de9d..0f7570a18 100644 --- a/libserpent/util.cpp +++ b/libserpent/util.cpp @@ -60,8 +60,8 @@ std::string printAST(Node ast, bool printMetadata) { std::string o = "("; if (printMetadata) { o += ast.metadata.file + " "; - o += intToDecimal(ast.metadata.ln) + " "; - o += intToDecimal(ast.metadata.ch) + ": "; + o += unsignedToDecimal(ast.metadata.ln) + " "; + o += unsignedToDecimal(ast.metadata.ch) + ": "; } o += ast.val; std::vector subs; @@ -132,14 +132,14 @@ std::string strToNumeric(std::string inp) { else if ((inp[0] == '"' && inp[inp.length()-1] == '"') || (inp[0] == '\'' && inp[inp.length()-1] == '\'')) { for (unsigned i = 1; i < inp.length() - 1; i++) { - o = decimalAdd(decimalMul(o,"256"), intToDecimal(inp[i])); + o = decimalAdd(decimalMul(o,"256"), unsignedToDecimal((unsigned char)inp[i])); } } else if (inp.substr(0,2) == "0x") { for (unsigned i = 2; i < inp.length(); i++) { int dig = std::string("0123456789abcdef").find(inp[i]); if (dig < 0) return ""; - o = decimalAdd(decimalMul(o,"16"), intToDecimal(dig)); + o = decimalAdd(decimalMul(o,"16"), unsignedToDecimal(dig)); } } else { @@ -188,7 +188,7 @@ int counter = 0; //Makes a unique token std::string mkUniqueToken() { counter++; - return intToDecimal(counter); + return unsignedToDecimal(counter); } //Does a file exist? http://stackoverflow.com/questions/12774207 @@ -217,7 +217,7 @@ std::string get_file_contents(std::string filename) //Report error void err(std::string errtext, Metadata met) { std::string err = "Error (file \"" + met.file + "\", line " + - intToDecimal(met.ln) + ", char " + intToDecimal(met.ch) + + unsignedToDecimal(met.ln + 1) + ", char " + unsignedToDecimal(met.ch) + "): " + errtext; std::cerr << err << "\n"; throw(err); @@ -254,3 +254,10 @@ std::string upperCase(std::string inp) { } return o; } + +//Three-int vector +std::vector triple(int a, int b, int c) { + std::vector o; + o.push_back(a); o.push_back(b); o.push_back(c); + return o; +} diff --git a/libserpent/util.h b/libserpent/util.h index a593d7451..4fb19bb98 100644 --- a/libserpent/util.h +++ b/libserpent/util.h @@ -103,4 +103,7 @@ std::string hexToBin(std::string inp); //Lower to upper std::string upperCase(std::string inp); +//Three-int vector +std::vector triple(int a, int b, int c); + #endif diff --git a/libwhisper/CMakeLists.txt b/libwhisper/CMakeLists.txt index 36c773979..c85853162 100644 --- a/libwhisper/CMakeLists.txt +++ b/libwhisper/CMakeLists.txt @@ -17,10 +17,9 @@ file(GLOB HEADERS "*.h") include_directories(..) -target_link_libraries(${EXECUTABLE} evm) -target_link_libraries(${EXECUTABLE} lll) -target_link_libraries(${EXECUTABLE} ethential) target_link_libraries(${EXECUTABLE} ethcore) +target_link_libraries(${EXECUTABLE} ethential) +target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} secp256k1) if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) diff --git a/libwhisper/Common.cpp b/libwhisper/Common.cpp index e3a355a8f..73420e32a 100644 --- a/libwhisper/Common.cpp +++ b/libwhisper/Common.cpp @@ -23,5 +23,6 @@ using namespace std; using namespace eth; +using namespace p2p; using namespace shh; diff --git a/libwhisper/Common.h b/libwhisper/Common.h index f3e2e78cb..c669d6ea9 100644 --- a/libwhisper/Common.h +++ b/libwhisper/Common.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include namespace shh { diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp index b59ae9c4a..f355e5df7 100644 --- a/libwhisper/WhisperPeer.cpp +++ b/libwhisper/WhisperPeer.cpp @@ -22,7 +22,7 @@ #include "WhisperPeer.h" #include -#include +#include using namespace std; using namespace eth; using namespace p2p; diff --git a/neth/main.cpp b/neth/main.cpp index c22c9a22c..dbb4ed4b6 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -49,6 +49,7 @@ using namespace std; using namespace eth; +using namespace p2p; using namespace boost::algorithm; using eth::Instruction; diff --git a/sc/cmdline.cpp b/sc/cmdline.cpp index 232cbfeec..69e96b41e 100644 --- a/sc/cmdline.cpp +++ b/sc/cmdline.cpp @@ -64,7 +64,7 @@ int main(int argv, char** argc) { std::cout << assemble(parseLLL(input, true)) << "\n"; } else if (command == "serialize") { - std::cout << binToHex(serialize(tokenize(input))) << "\n"; + std::cout << binToHex(serialize(tokenize(input, Metadata(), false))) << "\n"; } else if (command == "flatten") { std::cout << printTokens(flatten(parseLLL(input, true))) << "\n"; @@ -96,7 +96,7 @@ int main(int argv, char** argc) { else if (command == "biject") { if (argv == 3) std::cerr << "Not enough arguments for biject\n"; - int pos = decimalToInt(secondInput); + int pos = decimalToUnsigned(secondInput); std::vector n = prettyCompile(input); if (pos >= (int)n.size()) std::cerr << "Code position too high\n"; diff --git a/test/peer.cpp b/test/peer.cpp index 16f8383e8..8db4cc129 100644 --- a/test/peer.cpp +++ b/test/peer.cpp @@ -22,10 +22,10 @@ #include #include -#include +#include using namespace std; using namespace eth; -using boost::asio::ip::tcp; +using namespace p2p; int peerTest(int argc, char** argv) { diff --git a/third/MainWin.cpp b/third/MainWin.cpp index 3bebdb7dc..22ce25b66 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -57,7 +57,7 @@ using eth::Instruction; using eth::KeyPair; using eth::NodeMode; using eth::BlockChain; -using eth::PeerInfo; +using p2p::PeerInfo; using eth::RLP; using eth::Secret; using eth::Transaction; diff --git a/walleth/MainWin.cpp b/walleth/MainWin.cpp index 7b8873d45..8abd9ba60 100644 --- a/walleth/MainWin.cpp +++ b/walleth/MainWin.cpp @@ -31,7 +31,7 @@ using eth::Client; using eth::Instruction; using eth::KeyPair; using eth::NodeMode; -using eth::PeerInfo; +using p2p::PeerInfo; using eth::RLP; using eth::Secret; using eth::Transaction;