From a5269863bb3116b5f62c9becf5cc624c0250b1a6 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 24 Mar 2015 11:27:17 +0100 Subject: [PATCH 01/17] autocompletion redesign --- mix/qml/html/cm/anyword-hint.js | 39 +++++++++++++++++++++----------- mix/qml/html/cm/show-hint.css | 34 ++++++++++++++++++++++------ mix/qml/html/cm/solidityToken.js | 12 ++++++++++ 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/mix/qml/html/cm/anyword-hint.js b/mix/qml/html/cm/anyword-hint.js index c76044212..5da878fd8 100644 --- a/mix/qml/html/cm/anyword-hint.js +++ b/mix/qml/html/cm/anyword-hint.js @@ -13,6 +13,19 @@ var curWord = start != end && curLine.slice(start, end); var list = [], seen = {}; + + if (editor.getMode().name === "solidity") + { + list = addSolToken(curWord, list, seen, solCurrency(), solCurrency); + list = addSolToken(curWord, list, seen, solKeywords(), solKeywords); + list = addSolToken(curWord, list, seen, solStdContract(), solStdContract); + list = addSolToken(curWord, list, seen, solTime(), solTime); + list = addSolToken(curWord, list, seen, solTypes(), solTypes); + list = addSolToken(curWord, list, seen, solMisc(), solMisc); + } + + seen = solKeywords(); + var re = new RegExp(word.source, "g"); for (var dir = -1; dir <= 1; dir += 2) { var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; @@ -28,32 +41,32 @@ } } - if (editor.getMode().name === "solidity") - { - list = addSolToken(curWord, list, solCurrency(), solCurrency); - list = addSolToken(curWord, list, solKeywords(), solKeywords); - list = addSolToken(curWord, list, solStdContract(), solStdContract); - list = addSolToken(curWord, list, solTime(), solTime); - list = addSolToken(curWord, list, solTypes(), solTypes); - list = addSolToken(curWord, list, solMisc(), solMisc); - } - return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; }); })(); -function addSolToken(curWord, list, tokens, type) +function addSolToken(curWord, list, seen, tokens, type) { + var keywordsTypeName = keywordsName(); for (var key in tokens) { + seen[key] = true; if (curWord === false || key.indexOf(curWord, 0) === 0) { var token = { text: key }; token.render = function(elt, data, cur) { - elt.className = elt.className + " " + type.name.toLowerCase(); - elt.appendChild(document.createTextNode(cur.displayText || cur.text)); + var container = document.createElement("div"); + var word = document.createElement("div"); + word.className = type.name.toLowerCase() + " solToken"; + word.appendChild(document.createTextNode(cur.displayText || cur.text)); + var typeDiv = document.createElement("type"); + typeDiv.appendChild(document.createTextNode(keywordsTypeName[type.name.toLowerCase()])); + typeDiv.className = "solTokenType"; + container.appendChild(word); + container.appendChild(typeDiv); + elt.appendChild(container); } list.push(token); } diff --git a/mix/qml/html/cm/show-hint.css b/mix/qml/html/cm/show-hint.css index 663ac1223..82b99d39a 100644 --- a/mix/qml/html/cm/show-hint.css +++ b/mix/qml/html/cm/show-hint.css @@ -31,33 +31,53 @@ white-space: pre; color: black; cursor: pointer; + padding-left: 20px; + padding-top: 3px; + padding-bottom: 3px; } .CodeMirror-hint-active { background: #4a90e2; - color: white; + color: white !important; +} + +.CodeMirror-hint-active .solToken, +.CodeMirror-hint-active .solTokenType +{ + color: white !important; } .solcurrency { - color: red; + color: #b58900; } .solkeywords { - color: brown; + color: #cb4b16; } .solstdcontract { - color: blue; + color: #d33682; } .soltime { - color: green; + color: #268bd2; } .soltypes { - color: orange; + color: #2aa198; } .solMisc { - color: grey; + color: #859900; +} + +.solToken { + float: left; +} + +.solTokenType +{ + font-style: italic; + color: #808080; + float: right; } diff --git a/mix/qml/html/cm/solidityToken.js b/mix/qml/html/cm/solidityToken.js index 68bd203c7..d8e588a10 100644 --- a/mix/qml/html/cm/solidityToken.js +++ b/mix/qml/html/cm/solidityToken.js @@ -27,3 +27,15 @@ function solMisc() { return { "true": true, "false": true, "null": true }; } + +function keywordsName() +{ + var keywords = {}; + keywords[solCurrency.name.toLowerCase()] = "Currency"; + keywords[solKeywords.name.toLowerCase()] = "Keyword"; + keywords[solStdContract.name.toLowerCase()] = "Contract"; + keywords[solTime.name.toLowerCase()] = "Time"; + keywords[solTypes.name.toLowerCase()] = "Type"; + keywords[solMisc.name.toLowerCase()] = "Misc"; + return keywords; +} From 1b18c5b35ae42b13663741568800b2a565c16088 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 24 Mar 2015 14:01:16 +0100 Subject: [PATCH 02/17] Manage functions and contracts declaration in autocompletion. --- mix/qml/html/cm/anyword-hint.js | 46 +++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/mix/qml/html/cm/anyword-hint.js b/mix/qml/html/cm/anyword-hint.js index 5da878fd8..d1034ed8c 100644 --- a/mix/qml/html/cm/anyword-hint.js +++ b/mix/qml/html/cm/anyword-hint.js @@ -24,8 +24,7 @@ list = addSolToken(curWord, list, seen, solMisc(), solMisc); } - seen = solKeywords(); - + var previousWord = ""; var re = new RegExp(word.source, "g"); for (var dir = -1; dir <= 1; dir += 2) { var line = cur.line, endLine = Math.min(Math.max(line + dir * range, editor.firstLine()), editor.lastLine()) + dir; @@ -35,12 +34,15 @@ if (line == cur.line && m[0] === curWord) continue; if ((!curWord || m[0].lastIndexOf(curWord, 0) === 0) && !Object.prototype.hasOwnProperty.call(seen, m[0])) { seen[m[0]] = true; - list.push({ text: m[0] }); + var w = { text: m[0] }; + checkDeclaration(previousWord, "Contract", w); + checkDeclaration(previousWord, "Function", w); + list.push(w); } + previousWord = m[0]; } } } - return {list: list, from: CodeMirror.Pos(cur.line, start), to: CodeMirror.Pos(cur.line, end)}; }); })(); @@ -57,19 +59,35 @@ function addSolToken(curWord, list, seen, tokens, type) var token = { text: key }; token.render = function(elt, data, cur) { - var container = document.createElement("div"); - var word = document.createElement("div"); - word.className = type.name.toLowerCase() + " solToken"; - word.appendChild(document.createTextNode(cur.displayText || cur.text)); - var typeDiv = document.createElement("type"); - typeDiv.appendChild(document.createTextNode(keywordsTypeName[type.name.toLowerCase()])); - typeDiv.className = "solTokenType"; - container.appendChild(word); - container.appendChild(typeDiv); - elt.appendChild(container); + render(elt, data, cur, type.name.toLowerCase(), keywordsTypeName[type.name.toLowerCase()]); } list.push(token); } } return list; } + +function render(elt, data, cur, csstype, type) +{ + var container = document.createElement("div"); + var word = document.createElement("div"); + word.className = csstype + " solToken"; + word.appendChild(document.createTextNode(cur.displayText || cur.text)); + var typeDiv = document.createElement("type"); + typeDiv.appendChild(document.createTextNode(type)); + typeDiv.className = "solTokenType"; + container.appendChild(word); + container.appendChild(typeDiv); + elt.appendChild(container); +} + +function checkDeclaration(previousToken, target, current) +{ + if (previousToken.toLowerCase() === target.toLowerCase()) + { + current.render = function(elt, data, cur) + { + render(elt, data, cur, "sol" + target, target); + } + } +} From 2321f2914ba2b5023332ae80a7346352bcc7220b Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 25 Mar 2015 12:58:06 +0100 Subject: [PATCH 03/17] - bugfix: #1397. - Debugger panel: UI bug fixes. --- mix/ContractCallDataEncoder.cpp | 16 ++++++++++------ mix/qml/QHashTypeView.qml | 1 - mix/qml/QIntTypeView.qml | 1 - mix/qml/QStringTypeView.qml | 1 - mix/qml/StructView.qml | 11 ++++++----- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index fc5dcee03..6553244dc 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -76,18 +76,22 @@ unsigned ContractCallDataEncoder::encodeSingleItem(QVariant const& _data, Solidi unsigned const alignSize = 32; QString src = _data.toString(); bytes result; - if (src.length() >= 2 && ((src.startsWith("\"") && src.endsWith("\"")) || (src.startsWith("\'") && src.endsWith("\'")))) - { + + if ((src.startsWith("\"") && src.endsWith("\"")) || (src.startsWith("\'") && src.endsWith("\'"))) src = src.remove(src.length() - 1, 1).remove(0, 1); - QByteArray bytesAr = src.toLocal8Bit(); - result = bytes(bytesAr.begin(), bytesAr.end()); - } - else if (src.startsWith("0x")) + + QRegExp rx("[a-z]+"); + if (src.startsWith("0x")) { result = fromHex(src.toStdString().substr(2)); if (_type.type != SolidityType::Type::Bytes) result = padded(result, alignSize); } + else if (rx.indexIn(src.toLower(), 0) != -1) + { + QByteArray bytesAr = src.toLocal8Bit(); + result = bytes(bytesAr.begin(), bytesAr.end()); + } else { bigint i(src.toStdString()); diff --git a/mix/qml/QHashTypeView.qml b/mix/qml/QHashTypeView.qml index 77da45365..a097c22dd 100644 --- a/mix/qml/QHashTypeView.qml +++ b/mix/qml/QHashTypeView.qml @@ -15,7 +15,6 @@ Item Rectangle { anchors.fill: parent radius: 4 - color: "#f7f7f7" TextInput { id: textinput text: value diff --git a/mix/qml/QIntTypeView.qml b/mix/qml/QIntTypeView.qml index 206b641f3..8adb46846 100644 --- a/mix/qml/QIntTypeView.qml +++ b/mix/qml/QIntTypeView.qml @@ -16,7 +16,6 @@ Item Rectangle { anchors.fill: parent radius: 4 - color: "#f7f7f7" TextInput { id: textinput text: value diff --git a/mix/qml/QStringTypeView.qml b/mix/qml/QStringTypeView.qml index 0cde9b662..ffbde734c 100644 --- a/mix/qml/QStringTypeView.qml +++ b/mix/qml/QStringTypeView.qml @@ -15,7 +15,6 @@ Item Rectangle { anchors.fill: parent radius: 4 - color: "#f7f7f7" TextInput { id: textinput text: value diff --git a/mix/qml/StructView.qml b/mix/qml/StructView.qml index 312a24804..045b2eabc 100644 --- a/mix/qml/StructView.qml +++ b/mix/qml/StructView.qml @@ -24,24 +24,24 @@ Column height: 20 id: typeLabel text: modelData.type.name - Layout.preferredWidth: 60 + anchors.verticalCenter: parent.verticalCenter } DefaultLabel { id: nameLabel text: modelData.name - Layout.preferredWidth: 100 + anchors.verticalCenter: parent.verticalCenter } DefaultLabel { id: equalLabel text: "=" - Layout.preferredWidth: 15 + anchors.verticalCenter: parent.verticalCenter } Loader { id: typeLoader - Layout.preferredWidth: 150 + anchors.verticalCenter: parent.verticalCenter sourceComponent: { var t = modelData.type.category; @@ -63,7 +63,8 @@ Column var ptype = members[index].type; var pname = members[index].name; var vals = value; - if (ptype.category === QSolidityType.Struct && !item.members) { + if (ptype.category === QSolidityType.Struct && !item.members) + { item.value = getValue(); item.members = ptype.members; } From 5b18f853b7d645734884545ecf849030d1ad12d6 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 25 Mar 2015 15:28:23 +0100 Subject: [PATCH 04/17] - bug fix: #1399 --- mix/MixClient.cpp | 11 ++++++----- mix/MixClient.h | 2 +- mix/qml/html/WebContainer.html | 6 +++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index fd7b2263d..0272cc129 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -89,6 +89,7 @@ void MixClient::resetState(std::map _accounts) SecureTrieDB accountState(&m_stateDB); accountState.init(); + m_userAccounts.clear(); std::map genesisState; for (auto account: _accounts) { @@ -243,15 +244,15 @@ ExecutionResult MixClient::execution(unsigned _index) const return m_executions.at(_index); } -State MixClient::asOf(int _block) const +State MixClient::asOf(BlockNumber _h) const { ReadGuard l(x_state); - if (_block == 0) - return m_state; - else if (_block == -1) + if (_h == PendingBlock) return m_startState; + else if (_h == LatestBlock) + return m_state; else - return State(m_stateDB, bc(), bc().numberHash(_block)); + return State(m_stateDB, bc(), bc().numberHash(_h)); } void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) diff --git a/mix/MixClient.h b/mix/MixClient.h index e1085a20e..4c45e3162 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -100,7 +100,7 @@ public: private: void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call); void noteChanged(h256Set const& _filters); - dev::eth::State asOf(int _block) const; + dev::eth::State asOf(eth::BlockNumber _block) const; MixBlockChain& bc() { return *m_bc; } MixBlockChain const& bc() const { return *m_bc; } diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index fb716507f..dfce64979 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -23,9 +23,9 @@ updateContracts = function(contracts) { var contractProto = window.web3.eth.contract(contracts[c].interface); var contract = new contractProto(contracts[c].address); window.contracts[c] = { - address: c.address, - interface: c.interface, - contract: contract, + address: contracts[c].address, + interface: contracts[c].interface, + contract: contract }; } } From 58cb54bd49b8bb369ba4b0571f32416af0e2730b Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 06:06:34 +0100 Subject: [PATCH 05/17] correct net/test for ping packet --- test/net.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/net.cpp b/test/net.cpp index 7ba2d8a12..a5f973450 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -145,7 +145,7 @@ public: bool success = false; }; -BOOST_AUTO_TEST_CASE(badPingNodePacket) +BOOST_AUTO_TEST_CASE(v2PingNodePacket) { // test old versino of pingNode packet w/new RLPStream s; @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(badPingNodePacket) PingNode p((bi::udp::endpoint())); BOOST_REQUIRE_NO_THROW(p = PingNode::fromBytesConstRef(bi::udp::endpoint(), bytesConstRef(&s.out()))); - BOOST_REQUIRE(p.version == 0); + BOOST_REQUIRE(p.version == 2); } BOOST_AUTO_TEST_CASE(test_neighbours_packet) From 45df4ab10f76d54d8ffde09c9a98eb1ba6b6c94e Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 06:07:59 +0100 Subject: [PATCH 06/17] isIPType helpers --- libp2p/Common.cpp | 20 ++++++++++++++++++++ libp2p/Common.h | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp index 0429c52ab..86e1135c4 100644 --- a/libp2p/Common.cpp +++ b/libp2p/Common.cpp @@ -26,6 +26,16 @@ using namespace dev::p2p; const unsigned dev::p2p::c_protocolVersion = 3; +bool p2p::isPublicAddress(std::string const& _addressToCheck) +{ + return isPublicAddress(bi::address::from_string(_addressToCheck)); +} + +bool p2p::isPublicAddress(bi::address const& _addressToCheck) +{ + return !(isPrivateAddress(_addressToCheck) || isLocalHostAddress(_addressToCheck)); +} + // Helper function to determine if an address falls within one of the reserved ranges // For V4: // Class A "10.*", Class B "172.[16->31].*", Class C "192.168.*" @@ -55,6 +65,11 @@ bool p2p::isPrivateAddress(bi::address const& _addressToCheck) return false; } +bool p2p::isPrivateAddress(std::string const& _addressToCheck) +{ + return isPrivateAddress(bi::address::from_string(_addressToCheck)); +} + // Helper function to determine if an address is localhost bool p2p::isLocalHostAddress(bi::address const& _addressToCheck) { @@ -69,6 +84,11 @@ bool p2p::isLocalHostAddress(bi::address const& _addressToCheck) return find(c_rejectAddresses.begin(), c_rejectAddresses.end(), _addressToCheck) != c_rejectAddresses.end(); } +bool p2p::isLocalHostAddress(std::string const& _addressToCheck) +{ + return isLocalHostAddress(bi::address::from_string(_addressToCheck)); +} + std::string p2p::reasonOf(DisconnectReason _r) { switch (_r) diff --git a/libp2p/Common.h b/libp2p/Common.h index 66b3f08e8..b35cb379c 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -54,7 +54,11 @@ extern const unsigned c_protocolVersion; using NodeId = h512; bool isPrivateAddress(bi::address const& _addressToCheck); +bool isPrivateAddress(std::string const& _addressToCheck); bool isLocalHostAddress(bi::address const& _addressToCheck); +bool isLocalHostAddress(std::string const& _addressToCheck); +bool isPublicAddress(bi::address const& _addressToCheck); +bool isPublicAddress(std::string const& _addressToCheck); class UPnP; class Capability; @@ -62,6 +66,8 @@ class Host; class Session; struct NetworkStartRequired: virtual dev::Exception {}; +struct InvalidPublicIPAddress: virtual dev::Exception {}; +struct InvalidHostIPAddress: virtual dev::Exception {}; struct NetWarn: public LogChannel { static const char* name() { return "!N!"; } static const int verbosity = 0; }; struct NetNote: public LogChannel { static const char* name() { return "*N*"; } static const int verbosity = 1; }; From 584168a8d734862a072cb6800777177028b809f1 Mon Sep 17 00:00:00 2001 From: caktux Date: Thu, 26 Mar 2015 06:10:12 -0400 Subject: [PATCH 07/17] fix #1415 for neth --- neth/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/neth/main.cpp b/neth/main.cpp index aa10c8a6f..a844da92d 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -1152,7 +1152,7 @@ int main(int argc, char** argv) break; } - +#if ETH_FATDB // Contracts and addresses y = 1; auto acs = c->addresses(); @@ -1181,6 +1181,10 @@ int main(int argc, char** argv) if (y > height * 3 / 5 - 4) break; } +#else + mvwaddnstr(contractswin, 1, x, "build with ETH_FATDB to list contracts", qwidth); + mvwaddnstr(addswin, 1, x, "build with ETH_FATDB to list addresses", width / 2 - 4); +#endif // Peers y = 1; From 568146724726cde36f769c7dfefdb36ed835754b Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 26 Mar 2015 14:42:28 +0100 Subject: [PATCH 08/17] - Hide mapping type from debugger. - Better highlighting if debugger in external source. - Always use pendingBlock when making call and transact MixClient. - Compilation errors not kept in logs history. --- mix/ClientModel.cpp | 11 ++++++----- mix/DebuggingStateWrapper.h | 6 ++++-- mix/MixClient.cpp | 16 ++++++---------- mix/MixClient.h | 3 --- mix/qml/CodeEditorView.qml | 21 ++++++++++++++++++++- mix/qml/LogsPane.qml | 25 ------------------------- mix/qml/StatusPane.qml | 1 - 7 files changed, 36 insertions(+), 47 deletions(-) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index b490661ae..082ff59e6 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -350,10 +350,6 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t) CompiledContract const* contract = contracts[s.codeIndex]; AssemblyItem const& instruction = codeItems[s.codeIndex][instructionIndex]; - std::stringstream str; - str << instruction.getLocation().sourceName; - qDebug() << QString::fromStdString(str.str()); - if (instruction.type() == dev::eth::Push && !instruction.data()) { //register new local variable initialization @@ -380,8 +376,11 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t) for(auto l: solLocals) if (l.first < (int)s.stack.size()) { + if (l.second->type()->name().startsWith("mapping")) + break; //mapping type not yet managed localDeclarations.push_back(QVariant::fromValue(l.second)); localValues[l.second->name()] = formatValue(l.second->type()->type(), s.stack[l.first]); + } locals["variables"] = localDeclarations; locals["values"] = localValues; @@ -404,6 +403,8 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t) storageDec = new QVariableDeclaration(debugData, storageIter.value().name.toStdString(), storageIter.value().type); storageDeclarations[storageDec->name()] = storageDec; } + if (storageDec->type()->name().startsWith("mapping")) + break; //mapping type not yet managed storageDeclarationList.push_back(QVariant::fromValue(storageDec)); storageValues[storageDec->name()] = formatValue(storageDec->type()->type(), st.second); } @@ -412,7 +413,7 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t) storage["values"] = storageValues; prevInstructionIndex = instructionIndex; - solState = new QSolState(debugData, std::move(storage), std::move(solCallStack), std::move(locals), instruction.getLocation().start, instruction.getLocation().end); + solState = new QSolState(debugData, std::move(storage), std::move(solCallStack), std::move(locals), instruction.getLocation().start, instruction.getLocation().end, QString::fromUtf8(instruction.getLocation().sourceName->c_str())); } states.append(QVariant::fromValue(new QMachineState(debugData, instructionIndex, s, codes[s.codeIndex], data[s.dataIndex], solState))); diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index b9eea9365..37bc194fb 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -65,10 +65,11 @@ class QSolState: public QObject Q_PROPERTY(QVariantMap locals MEMBER m_locals CONSTANT) Q_PROPERTY(int start MEMBER m_start CONSTANT) Q_PROPERTY(int end MEMBER m_end CONSTANT) + Q_PROPERTY(QString sourceName MEMBER m_sourceName CONSTANT) public: - QSolState(QObject* _parent, QVariantMap&& _storage, QVariantList&& _callStack, QVariantMap&& _locals, int _start, int _end): - QObject(_parent), m_storage(_storage), m_callStack(_callStack), m_locals(_locals), m_start(_start), m_end(_end) + QSolState(QObject* _parent, QVariantMap&& _storage, QVariantList&& _callStack, QVariantMap&& _locals, int _start, int _end, QString _sourceName): + QObject(_parent), m_storage(_storage), m_callStack(_callStack), m_locals(_locals), m_start(_start), m_end(_end), m_sourceName(_sourceName) { } private: @@ -77,6 +78,7 @@ private: QVariantMap m_locals; int m_start; int m_end; + QString m_sourceName; }; /** diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 47983822a..19d946d01 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -235,15 +235,10 @@ ExecutionResult MixClient::execution(unsigned _index) const return m_executions.at(_index); } -State MixClient::asOf(BlockNumber _h) const +State MixClient::asOf(h256 const& _block) const { ReadGuard l(x_state); - if (_h == PendingBlock) - return m_startState; - else if (_h == LatestBlock) - return m_state; - else - return State(m_stateDB, bc(), bc().numberHash(_h)); + return State(m_stateDB, bc(), _block); } void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) @@ -266,8 +261,8 @@ Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes cons dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber) { - - State temp = asOf(_blockNumber); + (void)_blockNumber; + State temp = asOf(eth::PendingBlock); u256 n = temp.transactionsFrom(toAddress(_secret)); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); bytes rlp = t.rlp(); @@ -278,11 +273,12 @@ dev::eth::ExecutionResult MixClient::call(Secret _secret, u256 _value, Address _ dev::eth::ExecutionResult MixClient::create(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber) { + (void)_blockNumber; u256 n; State temp; { ReadGuard lr(x_state); - temp = asOf(_blockNumber); + temp = asOf(eth::PendingBlock); n = temp.transactionsFrom(toAddress(_secret)); } Transaction t(_value, _gasPrice, _gas, _data, n, _secret); diff --git a/mix/MixClient.h b/mix/MixClient.h index a25657905..179b445ac 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -88,9 +88,6 @@ protected: private: void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call); void noteChanged(h256Set const& _filters); - dev::eth::State asOf(eth::BlockNumber _block) const; - MixBlockChain& bc() { return *m_bc; } - MixBlockChain const& bc() const { return *m_bc; } std::vector m_userAccounts; eth::State m_state; diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 4d8559200..01aa0955f 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -68,9 +68,28 @@ Item { } function highlightExecution(documentId, location) { + var editor = getEditor(documentId); if (editor) - editor.highlightExecution(location); + { + if (documentId !== location.sourceName) + findAndHightlight(location.start, location.end, location.sourceName) + else + editor.highlightExecution(location); + } + } + + // Execution is not in the current document. Try: + // Open targeted document and hightlight (TODO) or + // Relevant hightlighting on the current document + function findAndHightlight(start, end, sourceName) + { + var editor = getEditor(currentDocumentId); + if (editor) + { + var sourceIndex = editor.getText().indexOf(sourceName); + highlightExecution(currentDocumentId, { start: sourceIndex, end: sourceIndex + sourceName.length, sourceName: currentDocumentId }); + } } function editingContract() { diff --git a/mix/qml/LogsPane.qml b/mix/qml/LogsPane.qml index b40dfc4c7..3601483a0 100644 --- a/mix/qml/LogsPane.qml +++ b/mix/qml/LogsPane.qml @@ -153,31 +153,6 @@ Rectangle } } - ToolButton { - id: compilationButton - checkable: true - height: LogsPaneStyle.generic.layout.headerButtonHeight - anchors.verticalCenter: parent.verticalCenter - checked: false - onCheckedChanged: { - proxyModel.toogleFilter("compilation") - } - tooltip: qsTr("Compilation") - style: - ButtonStyle { - label: - Item { - DefaultLabel { - font.family: LogsPaneStyle.generic.layout.logLabelFont - font.pointSize: Style.absoluteSize(-3) - color: "#5391d8" - anchors.centerIn: parent - text: qsTr("Compilation") - } - } - } - } - DefaultTextField { id: searchBox diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index 6d4b5e7e1..1e440b3a8 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -24,7 +24,6 @@ Rectangle { var errorInfo = ErrorLocationFormater.extractErrorInfo(message, true); status.text = errorInfo.errorLocation + " " + errorInfo.errorDetail; debugImg.state = ""; - errorMessage(status.text, "Compilation"); } debugRunActionIcon.enabled = codeModel.hasContract; } From 55e34ddadecca5f8d24f6f3b14a080a3f4129d04 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 26 Mar 2015 15:22:16 +0100 Subject: [PATCH 09/17] - warn user if source not available --- mix/qml/CodeEditorView.qml | 11 ++++------- mix/qml/WebCodeEditor.qml | 5 +++++ mix/qml/html/codeeditor.js | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 01aa0955f..f948f882c 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -67,8 +67,8 @@ Item { return null; } - function highlightExecution(documentId, location) { - + function highlightExecution(documentId, location) + { var editor = getEditor(documentId); if (editor) { @@ -81,15 +81,12 @@ Item { // Execution is not in the current document. Try: // Open targeted document and hightlight (TODO) or - // Relevant hightlighting on the current document + // Warn user that file is not available function findAndHightlight(start, end, sourceName) { var editor = getEditor(currentDocumentId); if (editor) - { - var sourceIndex = editor.getText().indexOf(sourceName); - highlightExecution(currentDocumentId, { start: sourceIndex, end: sourceIndex + sourceName.length, sourceName: currentDocumentId }); - } + editor.showWarning(qsTr("Currently debugging in " + sourceName + ". Source not available.")); } function editingContract() { diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index 7e5945fc7..3313cd2dd 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -45,6 +45,11 @@ Item { editorBrowser.runJavaScript("highlightExecution(" + location.start + "," + location.end + ")"); } + function showWarning(content) { + if (initialized) + editorBrowser.runJavaScript("showWarning('" + content + "')"); + } + function getBreakpoints() { return currentBreakpoints; } diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js index daf1286d8..da87e63e0 100644 --- a/mix/qml/html/codeeditor.js +++ b/mix/qml/html/codeeditor.js @@ -134,6 +134,8 @@ highlightExecution = function(start, end) { executionMark.clear(); if (start === 0 && end + 1 === editor.getValue().length) return; // Do not hightlight the whole document. + if (debugWarning) + debugWarning.clear(); executionMark = editor.markText(editor.posFromIndex(start), editor.posFromIndex(end), { className: "CodeMirror-exechighlight" }); } @@ -148,6 +150,20 @@ isClean = function() return editor.isClean(changeId); } +var debugWarning = null; +showWarning = function(content) +{ + if (executionMark) + executionMark.clear(); + if (debugWarning) + debugWarning.clear(); + var node = document.createElement("div"); + node.id = "annotation" + node.innerHTML = content; + node.className = "CodeMirror-errorannotation-context"; + debugWarning = editor.addLineWidget(0, node, { coverGutter: false, above: true }); +} + var annotation = null; var compilationCompleteBool = true; compilationError = function(line, column, content) From 6bdb3ed08008e1457acdab6f929d91c451bbde96 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 26 Mar 2015 15:25:46 +0100 Subject: [PATCH 10/17] small changes --- mix/ClientModel.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 082ff59e6..a49ee3661 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -380,7 +380,6 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t) break; //mapping type not yet managed localDeclarations.push_back(QVariant::fromValue(l.second)); localValues[l.second->name()] = formatValue(l.second->type()->type(), s.stack[l.first]); - } locals["variables"] = localDeclarations; locals["values"] = localValues; From bddc4f35a4c049d0761e3b1149b9aa7ce3958dc4 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 26 Mar 2015 15:46:52 +0100 Subject: [PATCH 11/17] - move autocompletion color to solarized lib --- mix/qml/html/cm/show-hint.css | 24 ------------------------ mix/qml/html/cm/solarized.css | 12 ++++++------ 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/mix/qml/html/cm/show-hint.css b/mix/qml/html/cm/show-hint.css index 82b99d39a..479acf024 100644 --- a/mix/qml/html/cm/show-hint.css +++ b/mix/qml/html/cm/show-hint.css @@ -47,30 +47,6 @@ color: white !important; } -.solcurrency { - color: #b58900; -} - -.solkeywords { - color: #cb4b16; -} - -.solstdcontract { - color: #d33682; -} - -.soltime { - color: #268bd2; -} - -.soltypes { - color: #2aa198; -} - -.solMisc { - color: #859900; -} - .solToken { float: left; } diff --git a/mix/qml/html/cm/solarized.css b/mix/qml/html/cm/solarized.css index f07b8b43b..b44269e69 100644 --- a/mix/qml/html/cm/solarized.css +++ b/mix/qml/html/cm/solarized.css @@ -16,14 +16,14 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png .solarized.base1 { color: #93a1a1; } .solarized.base2 { color: #eee8d5; } .solarized.base3 { color: #fdf6e3; } -.solarized.solar-yellow { color: #b58900; } -.solarized.solar-orange { color: #cb4b16; } +.solarized.solar-yellow, .solcurrency { color: #b58900; } +.solarized.solar-orange, .solkeywords { color: #cb4b16; } .solarized.solar-red { color: #dc322f; } -.solarized.solar-magenta { color: #d33682; } +.solarized.solar-magenta, .solstdcontract { color: #d33682; } .solarized.solar-violet { color: #6c71c4; } -.solarized.solar-blue { color: #268bd2; } -.solarized.solar-cyan { color: #2aa198; } -.solarized.solar-green { color: #859900; } +.solarized.solar-blue, .soltime { color: #268bd2; } +.solarized.solar-cyan, .soltypes { color: #2aa198; } +.solarized.solar-green, .solMisc { color: #859900; } /* Color scheme for code-mirror */ From 015c1681fb91591bf977ae2a0507616018194448 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 16:21:25 +0100 Subject: [PATCH 12/17] adopt node IP address from udp header when ping.ipAddress isn't public --- libp2p/Host.cpp | 8 ++++---- libp2p/NodeTable.cpp | 42 ++++++++++++++++++++++++++++-------------- test/net.cpp | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index b946d9b3e..41c2fbb77 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -592,12 +592,12 @@ void Host::startedWorking() m_run = true; } - // try to open acceptor (todo: ipv6) - m_listenPort = Network::tcp4Listen(m_tcp4Acceptor, m_netPrefs.listenPort); - - // start capability threads + // start capability threads (ready for incoming connections) for (auto const& h: m_capabilities) h.second->onStarting(); + + // try to open acceptor (todo: ipv6) + m_listenPort = Network::tcp4Listen(m_tcp4Acceptor, m_netPrefs.listenPort); // determine public IP, but only if we're able to listen for connections // todo: GUI when listen is unavailable in UI diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 7fe531762..7bdaf3088 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -84,11 +84,14 @@ shared_ptr NodeTable::addNode(Node const& _node) return move(shared_ptr()); } - // ping address if nodeid is empty + // ping address to recover nodeid if nodeid is empty if (!_node.id) { clog(NodeTableConnect) << "Sending public key discovery Ping to" << _node.endpoint.udp << "(Advertising:" << m_node.endpoint.udp << ")"; - m_pubkDiscoverPings[_node.endpoint.udp.address()] = std::chrono::steady_clock::now(); + { + Guard l(x_pubkDiscoverPings); + m_pubkDiscoverPings[_node.endpoint.udp.address()] = std::chrono::steady_clock::now(); + } PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); p.sign(m_secret); m_socketPointer->send(p); @@ -101,7 +104,11 @@ shared_ptr NodeTable::addNode(Node const& _node) return m_nodes[_node.id]; } - shared_ptr ret(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); + // TODO: SECURITY - Temporary until packets are updated. + NodeIPEndpoint ep(_node.endpoint.udp, _node.endpoint.tcp); + if (!isPublicAddress(ep.tcp.address())) + ep.tcp.address(_node.endpoint.udp.address()); + shared_ptr ret(new NodeEntry(m_node, _node.id, ep)); m_nodes[_node.id] = ret; PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); p.sign(m_secret); @@ -315,9 +322,13 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en { clog(NodeTableConnect) << "Noting active node:" << _pubk.abridged() << _endpoint.address().to_string() << ":" << _endpoint.port(); - // update udp endpoint + // TODO: SECURITY - Temporary until packets are updated. + // update udp endpoint and override tcp endpoint if tcp endpoint isn't public + // (for the rare case where NAT port is mapped but node->endpoint.udp.address(_endpoint.address()); node->endpoint.udp.port(_endpoint.port()); + if (!isPublicAddress(node->endpoint.tcp.address())) + node->endpoint.tcp.address(_endpoint.address()); shared_ptr contested; { @@ -399,7 +410,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes bytesConstRef signedBytes(hashedBytes.cropped(Signature::size, hashedBytes.size() - Signature::size)); - // todo: verify sig via known-nodeid and MDC, or, do ping/pong auth if node/endpoint is unknown/untrusted + // todo: verify sig via known-nodeid and MDC bytesConstRef sigBytes(_packet.cropped(h256::size, Signature::size)); Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(signedBytes))); @@ -430,8 +441,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes dropNode(n); if (auto n = nodeEntry(it->first.first)) - if (m_nodeEventHandler && n->pending) - n->pending = false; + n->pending = false; it = m_evictions.erase(it); } @@ -441,14 +451,18 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes { if (auto n = nodeEntry(nodeid)) n->pending = false; + else if (m_pubkDiscoverPings.count(_from.address())) + { + { + Guard l(x_pubkDiscoverPings); + m_pubkDiscoverPings.erase(_from.address()); + } + if (!haveNode(nodeid)) + addNode(nodeid, _from, bi::tcp::endpoint(_from.address(), _from.port())); + } + else + return; // unsolicited pong; don't note node as active } - else if (m_pubkDiscoverPings.count(_from.address())) - { - m_pubkDiscoverPings.erase(_from.address()); - addNode(nodeid, _from, bi::tcp::endpoint(_from.address(), _from.port())); - } - else - return; // unsolicited pong; don't note node as active break; } diff --git a/test/net.cpp b/test/net.cpp index a5f973450..ec1efb360 100644 --- a/test/net.cpp +++ b/test/net.cpp @@ -145,6 +145,40 @@ public: bool success = false; }; +BOOST_AUTO_TEST_CASE(isIPAddressType) +{ + string wildcard = "0.0.0.0"; + BOOST_REQUIRE(bi::address::from_string(wildcard).is_unspecified()); + + string empty = ""; + BOOST_REQUIRE_THROW(bi::address::from_string(empty).is_unspecified(), std::exception); + + string publicAddress192 = "192.169.0.0"; + BOOST_REQUIRE(isPublicAddress(publicAddress192)); + BOOST_REQUIRE(!isPrivateAddress(publicAddress192)); + BOOST_REQUIRE(!isLocalHostAddress(publicAddress192)); + + string publicAddress172 = "172.32.0.0"; + BOOST_REQUIRE(isPublicAddress(publicAddress172)); + BOOST_REQUIRE(!isPrivateAddress(publicAddress172)); + BOOST_REQUIRE(!isLocalHostAddress(publicAddress172)); + + string privateAddress192 = "192.168.1.0"; + BOOST_REQUIRE(isPrivateAddress(privateAddress192)); + BOOST_REQUIRE(!isPublicAddress(privateAddress192)); + BOOST_REQUIRE(!isLocalHostAddress(privateAddress192)); + + string privateAddress172 = "172.16.0.0"; + BOOST_REQUIRE(isPrivateAddress(privateAddress172)); + BOOST_REQUIRE(!isPublicAddress(privateAddress172)); + BOOST_REQUIRE(!isLocalHostAddress(privateAddress172)); + + string privateAddress10 = "10.0.0.0"; + BOOST_REQUIRE(isPrivateAddress(privateAddress10)); + BOOST_REQUIRE(!isPublicAddress(privateAddress10)); + BOOST_REQUIRE(!isLocalHostAddress(privateAddress10)); +} + BOOST_AUTO_TEST_CASE(v2PingNodePacket) { // test old versino of pingNode packet w/new From 89b484e3efb062fbbbdc43cef9e7ece13013d6d3 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 16:25:54 +0100 Subject: [PATCH 13/17] better handshake error logging, esp when remote disconnects --- libp2p/RLPxHandshake.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index 16bfe0fb1..e311c615a 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -131,7 +131,14 @@ void RLPXHandshake::readAck() void RLPXHandshake::error() { - clog(NetConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Failed)"; + m_idleTimer.cancel(); + + auto connected = m_socket->isConnected(); + if (connected && !m_socket->remoteEndpoint().address().is_unspecified()) + clog(NetConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Failed)"; + else + clog(NetConnect) << "Handshake Failed (Connection reset by peer)"; + m_socket->close(); if (m_io != nullptr) delete m_io; @@ -140,7 +147,10 @@ void RLPXHandshake::error() void RLPXHandshake::transition(boost::system::error_code _ech) { if (_ech || m_nextState == Error || m_cancel) + { + clog(NetConnect) << "Handshake Failed (I/O Error:" << _ech.message() << ")"; return error(); + } auto self(shared_from_this()); if (m_nextState == New) @@ -265,7 +275,8 @@ void RLPXHandshake::transition(boost::system::error_code _ech) { if (!_ec) { - clog(NetWarn) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; + if (!m_socket->remoteEndpoint().address().is_unspecified()) + clog(NetWarn) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; cancel(); } }); From c17edbff0a7c5e01b1b4a2a9d51112a9a6127a66 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 26 Mar 2015 16:41:23 +0100 Subject: [PATCH 14/17] - bug fix #1386 --- mix/ClientModel.cpp | 15 ++++++++++++--- mix/qml/StatusPane.qml | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index a49ee3661..6ba7e54f9 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -242,7 +242,12 @@ void ClientModel::executeSequence(std::vector const& _seque break; } if (!f) - BOOST_THROW_EXCEPTION(FunctionNotFoundException() << FunctionName(transaction.functionId.toStdString())); + { + emit runFailed("Function '" + transaction.functionId + tr("' not found. Please check transactions or the contract code.")); + m_running = false; + emit runStateChanged(); + return; + } if (!transaction.functionId.isEmpty()) encoder.encode(f); for (QVariableDeclaration const* p: f->parametersList()) @@ -269,7 +274,12 @@ void ClientModel::executeSequence(std::vector const& _seque { auto contractAddressIter = m_contractAddresses.find(transaction.contractId); if (contractAddressIter == m_contractAddresses.end()) - BOOST_THROW_EXCEPTION(dev::Exception() << dev::errinfo_comment("Contract not deployed: " + transaction.contractId.toStdString())); + { + emit runFailed("Contract '" + transaction.contractId + tr(" not deployed.") + "' " + tr(" Cannot call ") + transaction.functionId); + m_running = false; + emit runStateChanged(); + return; + } callContract(contractAddressIter->second, encoder.encodedData(), transaction); } } @@ -283,7 +293,6 @@ void ClientModel::executeSequence(std::vector const& _seque std::cerr << boost::current_exception_diagnostic_information(); emit runFailed(QString::fromStdString(boost::current_exception_diagnostic_information())); } - catch(std::exception const& e) { std::cerr << boost::current_exception_diagnostic_information(); diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index 1e440b3a8..70a4b1d30 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -76,9 +76,9 @@ Rectangle { function format(_message) { var formatted = _message.match(/(?:)/); - if (formatted === null) + if (formatted) formatted = _message.match(/(?:)/); - if (formatted.length > 1) + if (formatted && formatted.length > 1) formatted = formatted[1]; else return _message; From a5d2567e811231cb583106abdeef5592fe33b9e7 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 16:46:26 +0100 Subject: [PATCH 15/17] only override tcp address if udp address is public. allow remotes which advertise 0.0.0.0. --- libp2p/NodeTable.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 7bdaf3088..3cba9ec0f 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -70,17 +70,11 @@ shared_ptr NodeTable::addNode(Public const& _pubk, bi::udp::endpoint shared_ptr NodeTable::addNode(Node const& _node) { - if (_node.endpoint.udp.address().to_string() == "0.0.0.0" || _node.endpoint.tcp.address().to_string() == "0.0.0.0") + // re-enable tcp checks when NAT hosts are handled by discover + // we handle when tcp endpoint is 0 below + if (_node.endpoint.udp.address().to_string() == "0.0.0.0") { - string ptype; - if (_node.endpoint.udp.address().to_string() != "0.0.0.0") - ptype = "TCP"; - else if (_node.endpoint.tcp.address().to_string() != "0.0.0.0") - ptype = "UDP"; - else - ptype = "TCP,UDP"; - - clog(NodeTableWarn) << "addNode Failed. Invalid" << ptype << "address 0.0.0.0 for" << _node.id.abridged(); + clog(NodeTableWarn) << "addNode Failed. Invalid UDP address 0.0.0.0 for" << _node.id.abridged(); return move(shared_ptr()); } @@ -106,7 +100,7 @@ shared_ptr NodeTable::addNode(Node const& _node) // TODO: SECURITY - Temporary until packets are updated. NodeIPEndpoint ep(_node.endpoint.udp, _node.endpoint.tcp); - if (!isPublicAddress(ep.tcp.address())) + if (!isPublicAddress(ep.tcp.address()) && isPublicAddress(ep.udp.address())) ep.tcp.address(_node.endpoint.udp.address()); shared_ptr ret(new NodeEntry(m_node, _node.id, ep)); m_nodes[_node.id] = ret; @@ -327,7 +321,7 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en // (for the rare case where NAT port is mapped but node->endpoint.udp.address(_endpoint.address()); node->endpoint.udp.port(_endpoint.port()); - if (!isPublicAddress(node->endpoint.tcp.address())) + if (!isPublicAddress(node->endpoint.tcp.address()) && isPublicAddress(node->endpoint.udp.address())) node->endpoint.tcp.address(_endpoint.address()); shared_ptr contested; From 5959a580712a3c28ebf4520cdd99341e92b4a681 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 19:51:45 +0100 Subject: [PATCH 16/17] abstract overriding tcp endpoint --- libp2p/Common.cpp | 6 ++++++ libp2p/Common.h | 3 +++ libp2p/NodeTable.cpp | 14 +++----------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp index 86e1135c4..b995723c3 100644 --- a/libp2p/Common.cpp +++ b/libp2p/Common.cpp @@ -109,3 +109,9 @@ std::string p2p::reasonOf(DisconnectReason _r) default: return "Unknown reason."; } } + +void Node::cullEndpoint() +{ + if (!isPublicAddress(endpoint.tcp.address()) && isPublicAddress(endpoint.udp.address())) + endpoint.tcp.address(endpoint.udp.address()); +} diff --git a/libp2p/Common.h b/libp2p/Common.h index b35cb379c..c3ca325d9 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -175,6 +175,9 @@ struct Node virtual NodeId const& address() const { return id; } virtual Public const& publicKey() const { return id; } + /// Replace TCP address with UDP address if TCP addr is private and UDP is public. Temp. until protocol update. + void cullEndpoint(); + NodeId id; /// Endpoints by which we expect to reach node. diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 3cba9ec0f..c230c5441 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -98,12 +98,9 @@ shared_ptr NodeTable::addNode(Node const& _node) return m_nodes[_node.id]; } - // TODO: SECURITY - Temporary until packets are updated. - NodeIPEndpoint ep(_node.endpoint.udp, _node.endpoint.tcp); - if (!isPublicAddress(ep.tcp.address()) && isPublicAddress(ep.udp.address())) - ep.tcp.address(_node.endpoint.udp.address()); - shared_ptr ret(new NodeEntry(m_node, _node.id, ep)); + shared_ptr ret(new NodeEntry(m_node, _node.id, NodeIPEndpoint(_node.endpoint.udp, _node.endpoint.tcp))); m_nodes[_node.id] = ret; + ret->cullEndpoint(); PingNode p(_node.endpoint.udp, m_node.endpoint.udp.address().to_string(), m_node.endpoint.udp.port()); p.sign(m_secret); m_socketPointer->send(p); @@ -315,14 +312,9 @@ void NodeTable::noteActiveNode(Public const& _pubk, bi::udp::endpoint const& _en if (!!node && !node->pending) { clog(NodeTableConnect) << "Noting active node:" << _pubk.abridged() << _endpoint.address().to_string() << ":" << _endpoint.port(); - - // TODO: SECURITY - Temporary until packets are updated. - // update udp endpoint and override tcp endpoint if tcp endpoint isn't public - // (for the rare case where NAT port is mapped but node->endpoint.udp.address(_endpoint.address()); node->endpoint.udp.port(_endpoint.port()); - if (!isPublicAddress(node->endpoint.tcp.address()) && isPublicAddress(node->endpoint.udp.address())) - node->endpoint.tcp.address(_endpoint.address()); + node->cullEndpoint(); shared_ptr contested; { From 14e83ffb284f28af9f8576bedd87588fe5ba219e Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 26 Mar 2015 19:57:32 +0100 Subject: [PATCH 17/17] clarify method doc --- libp2p/Common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/Common.h b/libp2p/Common.h index c3ca325d9..3303c9c07 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -175,7 +175,7 @@ struct Node virtual NodeId const& address() const { return id; } virtual Public const& publicKey() const { return id; } - /// Replace TCP address with UDP address if TCP addr is private and UDP is public. Temp. until protocol update. + /// Adopt UDP address for TCP if TCP isn't public and UDP is. (to be removed when protocol is updated for nat) void cullEndpoint(); NodeId id;