From beb58f17f0a984ad2062f2875ae43dc0dda0c92b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 4 Mar 2015 23:24:01 +0100 Subject: [PATCH] RLP tool. --- libdevcore/CommonIO.cpp | 5 -- libdevcore/CommonIO.h | 6 +- libethcore/Params.cpp | 4 +- libethcore/ProofOfWork.cpp | 2 - rlp/base64.cpp | 128 +++++++++++++++++++++++++++++++++++++ rlp/base64.h | 40 ++++++++++++ rlp/main.cpp | 115 +++++++++++++++------------------ 7 files changed, 224 insertions(+), 76 deletions(-) create mode 100644 rlp/base64.cpp create mode 100644 rlp/base64.h diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index d7e74d36e..4fa132073 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -115,8 +115,3 @@ void dev::writeFile(std::string const& _file, bytesConstRef _data) ofstream(_file, ios::trunc).write((char const*)_data.data(), _data.size()); } -void dev::writeFile(std::string const& _file, bytesConstRef _data) -{ - ofstream(_file, ios::trunc).write((char const*)_data.data(), _data.size()); -} - diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h index 1f9e29e54..03fc9cffc 100644 --- a/libdevcore/CommonIO.h +++ b/libdevcore/CommonIO.h @@ -43,13 +43,15 @@ namespace dev /// Retrieve and returns the contents of the given file. If the file doesn't exist or isn't readable, returns an empty bytes. bytes contents(std::string const& _file); +std::string contentsString(std::string const& _file); /// Retrieve and returns the allocated contents of the given file. If the file doesn't exist or isn't readable, returns nullptr. Don't forget to delete [] when finished. bytesRef contentsNew(std::string const& _file); -/// Write the given binary data into the given file, replacing the file if it pre-exists. -void writeFile(std::string const& _file, bytes const& _data); /// Write the given binary data into the given file, replacing the file if it pre-exists. void writeFile(std::string const& _file, bytesConstRef _data); +/// Write the given binary data into the given file, replacing the file if it pre-exists. +inline void writeFile(std::string const& _file, bytes const& _data) { writeFile(_file, bytesConstRef(&_data)); } +inline void writeFile(std::string const& _file, std::string const& _data) { writeFile(_file, bytesConstRef(_data)); } /// Nicely renders the given bytes to a string, optionally as HTML. /// @a _bytes: bytes array to be rendered as string. @a _width of a bytes line. diff --git a/libethcore/Params.cpp b/libethcore/Params.cpp index f36af1375..d1154abcc 100644 --- a/libethcore/Params.cpp +++ b/libethcore/Params.cpp @@ -28,13 +28,13 @@ namespace eth { //--- BEGIN: AUTOGENERATED FROM /feeStructure.json -u256 const c_genesisDifficulty = 2048; +u256 const c_genesisDifficulty = 131072; u256 const c_maximumExtraDataSize = 1024; u256 const c_epochDuration = 3000; u256 const c_genesisGasLimit = 1000000; u256 const c_minGasLimit = 125000; u256 const c_gasLimitBoundDivisor = 1024; -u256 const c_minimumDifficulty = 2048; +u256 const c_minimumDifficulty = 131072; u256 const c_difficultyBoundDivisor = 2048; u256 const c_durationLimit = 8; u256 const c_tierStepGas[] = {0, 2, 3, 5, 8, 10, 20, 0}; diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp index 332d739bb..c879df2ce 100644 --- a/libethcore/ProofOfWork.cpp +++ b/libethcore/ProofOfWork.cpp @@ -66,7 +66,6 @@ public: writeFile(memoFile, m_caches[_header.seedHash]); } } - cdebug << "sha3 of cache: " << sha3(m_caches[_header.seedHash]); return m_caches[_header.seedHash]; } @@ -91,7 +90,6 @@ public: writeFile(memoFile, m_fulls[_header.seedHash]); } } - cdebug << "sha3 of full pad: " << sha3(m_fulls[_header.seedHash]); return m_fulls[_header.seedHash].data(); } diff --git a/rlp/base64.cpp b/rlp/base64.cpp new file mode 100644 index 000000000..5e2b32000 --- /dev/null +++ b/rlp/base64.cpp @@ -0,0 +1,128 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ +/// code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c +/// originally by René Nyffenegger, modified by some other guy and then again by Gav Wood. + +#include "base64.h" + +#include + +using namespace std; +using namespace dev; + +static const std::string base64_chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +static inline bool is_base64(byte c) { + return (isalnum(c) || (c == '+') || (c == '/')); +} + +std::string dev::base64_encode(bytesConstRef _in) { + std::string ret; + int i = 0; + int j = 0; + byte char_array_3[3]; + byte char_array_4[4]; + + auto buf = _in.data(); + auto bufLen = _in.size(); + + while (bufLen--) { + char_array_3[i++] = *(buf++); + if (i == 3) { + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for(i = 0; (i <4) ; i++) + ret += base64_chars[char_array_4[i]]; + i = 0; + } + } + + if (i) + { + for(j = i; j < 3; j++) + char_array_3[j] = '\0'; + + char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; + char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); + char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); + char_array_4[3] = char_array_3[2] & 0x3f; + + for (j = 0; (j < i + 1); j++) + ret += base64_chars[char_array_4[j]]; + + while((i++ < 3)) + ret += '='; + } + + return ret; +} + +bytes dev::base64_decode(std::string const& encoded_string) { + int in_len = encoded_string.size(); + int i = 0; + int j = 0; + int in_ = 0; + byte char_array_4[4], char_array_3[3]; + bytes ret; + + while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + char_array_4[i++] = encoded_string[in_]; in_++; + if (i ==4) { + for (i = 0; i <4; i++) + char_array_4[i] = base64_chars.find(char_array_4[i]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (i = 0; (i < 3); i++) + ret.push_back(char_array_3[i]); + i = 0; + } + } + + if (i) { + for (j = i; j <4; j++) + char_array_4[j] = 0; + + for (j = 0; j <4; j++) + char_array_4[j] = base64_chars.find(char_array_4[j]); + + char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); + char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); + char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; + + for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); + } + + return ret; +} diff --git a/rlp/base64.h b/rlp/base64.h new file mode 100644 index 000000000..53ba282c8 --- /dev/null +++ b/rlp/base64.h @@ -0,0 +1,40 @@ +/* + base64.cpp and base64.h + + Copyright (C) 2004-2008 René Nyffenegger + + This source code is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this source code must not be misrepresented; you must not + claim that you wrote the original source code. If you use this source code + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original source code. + + 3. This notice may not be removed or altered from any source distribution. + + René Nyffenegger rene.nyffenegger@adp-gmbh.ch +*/ +/// code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c +/// originally by René Nyffenegger, modified by some other guy and then again by Gav Wood. +#pragma once + +#include +#include +#include + +namespace dev +{ + +std::string base64_encode(bytesConstRef _in); +bytes base64_decode(std::string const& _in); + +} diff --git a/rlp/main.cpp b/rlp/main.cpp index 663bbf14d..9bd51cdfc 100644 --- a/rlp/main.cpp +++ b/rlp/main.cpp @@ -22,9 +22,11 @@ #include #include #include +#include #include #include #include +#include "base64.h" using namespace std; using namespace dev; @@ -33,21 +35,6 @@ void help() cout << "Usage rlp [OPTIONS] [ | -- ]" << endl << "Options:" << endl - << " -r,--render Render the given RLP. Options:" << endl - << " --indent Use string as the level indentation (default ' ')." << endl - << " --hex-ints Render integers in hex." << endl - << " --ascii-strings Render data as C-style strings or hex depending on content being ASCII." << endl - << " --force-string Force all data to be rendered as C-style strings." << endl - << " --force-escape When rendering as C-style strings, force all characters to be escaped." << endl - << " --force-hex Force all data to be rendered as raw hex." << endl - << " -l,--list-archive List the items in the RLP list by hash and size." << endl - << " -e,--extract-archive Extract all items in the RLP list, named by hash." << endl - << "General options:" << endl - << " -L,--lenience Try not to bomb out early if possible." << endl - << " -x,--hex,--base-16 Treat input RLP as hex encoded data." << endl - << " --64,--base-64 Treat input RLP as base-64 encoded data." << endl - << " -b,--bin,--base-256 Treat input RLP as raw binary data." << endl - << " -h,--help Print this help message and exit." << endl << " -V,--version Show the version and exit." << endl ; exit(0); @@ -87,7 +74,7 @@ public: { string indent = " "; bool hexInts = false; - bool forceString = true; + bool forceString = false; bool escapeAll = false; bool forceHex = false; }; @@ -100,7 +87,7 @@ public: m_out << "null"; else if (_d.isInt()) if (m_prefs.hexInts) - m_out << toHex(toCompactBigEndian(_d.toInt(RLP::LaisezFaire), 1), 1); + m_out << toHex(toCompactBigEndian(_d.toInt(RLP::LaisezFaire))); else m_out << _d.toInt(RLP::LaisezFaire); else if (_d.isData()) @@ -151,8 +138,6 @@ int main(int argc, char** argv) prefs.indent = argv[++i]; else if (arg == "--hex-ints") prefs.hexInts = true; - else if (arg == "--ascii-strings") - prefs.forceString = prefs.forceHex = false; else if (arg == "--force-string") prefs.forceString = true; else if (arg == "--force-hex") @@ -219,7 +204,7 @@ int main(int argc, char** argv) boost::algorithm::replace_all(s, " ", ""); boost::algorithm::replace_all(s, "\n", ""); boost::algorithm::replace_all(s, "\t", ""); - b = fromBase64(s); + b = base64_decode(s); break; } default: @@ -229,60 +214,60 @@ int main(int argc, char** argv) try { - RLP rlp(b); - switch (mode) - { - case Mode::ListArchive: + RLP rlp(b); + switch (mode) + { + case Mode::ListArchive: + { + if (!rlp.isList()) { - if (!rlp.isList()) - { - cout << "Error: Invalid format; RLP data is not a list." << endl; - exit(1); - } - cout << rlp.itemCount() << " items:" << endl; - for (auto i: rlp) - { - if (!i.isData()) - { - cout << "Error: Invalid format; RLP list item is not data." << endl; - if (!lenience) - exit(1); - } - cout << " " << i.size() << " bytes: " << sha3(i.data()) << endl; - } - break; + cout << "Error: Invalid format; RLP data is not a list." << endl; + exit(1); } - case Mode::ExtractArchive: + cout << rlp.itemCount() << " items:" << endl; + for (auto i: rlp) { - if (!rlp.isList()) - { - cout << "Error: Invalid format; RLP data is not a list." << endl; - exit(1); - } - cout << rlp.itemCount() << " items:" << endl; - for (auto i: rlp) + if (!i.isData()) { - if (!i.isData()) - { - cout << "Error: Invalid format; RLP list item is not data." << endl; - if (!lenience) - exit(1); - } - ofstream fout; - fout.open(toString(sha3(i.data()))); - fout.write(reinterpret_cast(i.data().data()), i.data().size()); + cout << "Error: Invalid format; RLP list item is not data." << endl; + if (!lenience) + exit(1); } - break; + cout << " " << i.size() << " bytes: " << sha3(i.data()) << endl; } - case Mode::Render: + break; + } + case Mode::ExtractArchive: + { + if (!rlp.isList()) { - RLPStreamer s(cout, prefs); - s.output(rlp); - cout << endl; - break; + cout << "Error: Invalid format; RLP data is not a list." << endl; + exit(1); } - default:; + cout << rlp.itemCount() << " items:" << endl; + for (auto i: rlp) + { + if (!i.isData()) + { + cout << "Error: Invalid format; RLP list item is not data." << endl; + if (!lenience) + exit(1); + } + ofstream fout; + fout.open(toString(sha3(i.data()))); + fout.write(reinterpret_cast(i.data().data()), i.data().size()); } + break; + } + case Mode::Render: + { + RLPStreamer s(cout, prefs); + s.output(rlp); + cout << endl; + break; + } + default:; + } } catch (...) {