From 2763ccc1a95560716c2edaca2aa0333b03d0e7b8 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 2 Apr 2015 00:33:56 +0200 Subject: [PATCH 01/15] fixed no jsonrpc build for cmake 2.8.12 --- libtestutils/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libtestutils/CMakeLists.txt b/libtestutils/CMakeLists.txt index 4ae52e0c9..3ac4f34f8 100644 --- a/libtestutils/CMakeLists.txt +++ b/libtestutils/CMakeLists.txt @@ -32,7 +32,10 @@ endif() target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${JSONCPP_LIBRARIES}) target_link_libraries(${EXECUTABLE} ethereum) -target_link_libraries(${EXECUTABLE} web3jsonrpc) + +if (JSONRPC) + target_link_libraries(${EXECUTABLE} web3jsonrpc) +endif() install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) From 04d0584bc537bf94334c1766d14b93b80141ffaf Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 2 Apr 2015 10:20:33 +0200 Subject: [PATCH 02/15] - add Search icon. - fix animation bad behavior --- mix/qml/LogsPane.qml | 71 +++++++++++++++++++++++-------------- mix/qml/LogsPaneStyle.qml | 4 +-- mix/qml/StatusPane.qml | 4 +-- mix/qml/img/searchicon.png | Bin 0 -> 1439 bytes mix/res.qrc | 1 + 5 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 mix/qml/img/searchicon.png diff --git a/mix/qml/LogsPane.qml b/mix/qml/LogsPane.qml index c619080bf..ca123f6a0 100644 --- a/mix/qml/LogsPane.qml +++ b/mix/qml/LogsPane.qml @@ -37,7 +37,6 @@ Rectangle height: parent.height - rowAction.height width: parent.width spacing: 0 - ListModel { id: logsModel } @@ -100,7 +99,7 @@ Rectangle Rectangle { - width: 750 + width: LogsPaneStyle.generic.layout.dateWidth + LogsPaneStyle.generic.layout.contentWidth + LogsPaneStyle.generic.layout.typeWidth height: 30 color: { @@ -171,7 +170,7 @@ Rectangle anchors.verticalCenter: parent.verticalCenter elide: Text.ElideRight anchors.left: parent.left - anchors.leftMargin: 190 + anchors.leftMargin: 230 color: { parent.getColor(level); } @@ -486,39 +485,59 @@ Rectangle } } - DefaultTextField + Rectangle { - id: searchBox + width: 120 + radius: 10 + height: 25 + color: "white" anchors.verticalCenter: parent.verticalCenter - width: LogsPaneStyle.generic.layout.headerInputWidth - 50 - font.family: LogsPaneStyle.generic.layout.logLabelFont - font.pointSize: Style.absoluteSize(-3) - font.italic: true - text: qsTr(" - Search - ") - onFocusChanged: + + Image { - if (!focus && text === "") - text = qsTr(" - Search - "); - else if (focus && text === qsTr(" - Search - ")) - text = ""; + id: searchImg + source: "qrc:/qml/img/searchicon.png" + fillMode: Image.PreserveAspectFit + width: 20 + height: 25 + z: 3 } - onTextChanged: { - if (text === qsTr(" - Search - ")) - proxyModel.search(""); - else - proxyModel.search(text); - } + DefaultTextField + { + id: searchBox + z: 2 + width: 100 + anchors.left: searchImg.right + anchors.leftMargin: -7 + font.family: LogsPaneStyle.generic.layout.logLabelFont + font.pointSize: Style.absoluteSize(-3) + font.italic: true + text: qsTr(" - Search - ") + onFocusChanged: + { + if (!focus && text === "") + text = qsTr(" - Search - "); + else if (focus && text === qsTr(" - Search - ")) + text = ""; + } - style: - TextFieldStyle { - background: Rectangle { - radius: 10 + onTextChanged: { + if (text === qsTr(" - Search - ")) + proxyModel.search(""); + else + proxyModel.search(text); + } + + style: + TextFieldStyle { + background: Rectangle { + radius: 10 + } } } } - Rectangle { height: LogsPaneStyle.generic.layout.headerButtonHeight diff --git a/mix/qml/LogsPaneStyle.qml b/mix/qml/LogsPaneStyle.qml index 19f6a653e..0bbdfcee4 100644 --- a/mix/qml/LogsPaneStyle.qml +++ b/mix/qml/LogsPaneStyle.qml @@ -18,8 +18,8 @@ QtObject { property string logLabelColor: "#4a4a4a" property string logLabelFont: "sans serif" property int headerInputWidth: 200 - property int dateWidth: 70 - property int typeWidth: 90 + property int dateWidth: 150 + property int typeWidth: 150 property int contentWidth: 560 property string logAlternateColor: "#f6f5f6" property string errorColor: "#fffcd5" diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index 4a9287bec..6d8042add 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -227,7 +227,7 @@ Rectangle { top = top.parent var coordinates = logsContainer.mapToItem(top, 0, 0); logsContainer.parent = top; - logsContainer.x = status.x + statusContainer.x - LogsPaneStyle.generic.layout.dateWidth - LogsPaneStyle.generic.layout.typeWidth - 30 + logsContainer.x = status.x + statusContainer.x - LogsPaneStyle.generic.layout.dateWidth - LogsPaneStyle.generic.layout.typeWidth + 70 } LogsPane @@ -239,7 +239,6 @@ Rectangle { State { name: "opened"; PropertyChanges { target: logsContainer; height: 500; visible: true } - PropertyChanges { target: statusContainer; width: 100; height: 25 } }, State { name: "closed"; @@ -250,7 +249,6 @@ Rectangle { transitions: Transition { NumberAnimation { properties: "height"; easing.type: Easing.InOutQuad; duration: 200 } NumberAnimation { target: logsContainer; properties: "visible"; easing.type: Easing.InOutQuad; duration: 200 } - NumberAnimation { target: statusContainer; properties: "width"; easing.type: Easing.InOutQuad; duration: 500 } } } } diff --git a/mix/qml/img/searchicon.png b/mix/qml/img/searchicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c10dc9228e7f7ccf39670ea9c7f6c4acbd19caa4 GIT binary patch literal 1439 zcmV;Q1z`G#P)Px)SxH1eRA>e5nq6pIMHI)oNwd4H4@#r9jbBJg5%M7RK}scr65pFdi@-Fdi@-Fdi@-Fdit62V&)bO{dez zcs#x*7K`lye=Fr?OV4bvSe#v6UY=ZBTs+CRTsidnVMa>0udi==MMcG1ka`Z18~qeB zW`QxI5Knh^cVF}y8)aW4gqf+0$z(DEiNlasZy8viJWJb;l$U6yTHH+eAmvVb9Q7sg zdvkMhuMZ9m{u3oRFRajnA$xBkkvI;4M=S+D6SBS3M>{$?e)m#}%pHXMK4iMc+hq)- z&lL)V=exSPe)W=xsx1`Z{{H@L82lB+Y#|pgx-*~84?^f#5Ca*vp2&C=xePdQWU|!j zQ>oN+5P6+3+JpxN25!f=Z!q*B%0E$l07J)gjNsjWjCcQIWbYA)@m{p zs|{GGACkv}Ed6=v&*+jBd_sSc;tBHK#c6NU22d>k{CgcKgXDnG;mkyMt zj51+XQ(0UjefD2bmcJ!zBFWYjnG$8fXue;x6V9^8lqC_;Hg-u@luDEc^KF#zcUcBp ziqa4#7Bg#O+lLNkcc{7&;raRb4QQ(rjm*N;P?~*&9oSVZEiDP3p~_uKgfp3pYz#^p zd}hI(X=SAW1WMQtUlJv=tFn9AmgL->Ti;QgoMv~we5=oUFRm%hK0C!C}Aqrpy45JTAHV_?I_c)#B$O$`)h!N_wklRX|{Nf-xsLO^ugA`Yd_iMc%}W zjx)3S0G4xj9oyM)-sd}Y6|MOhwuw1snzi6OxsjRn{ISlK@hWc`!eYFO^mjBh@;Q^= zwF0L#AJR@H&hTc@m!D_ld#yBSHx*$aZ<8jZz`vN;5AGfAv@!qy002ovPDHLkV1lXRpyU7m literal 0 HcmV?d00001 diff --git a/mix/res.qrc b/mix/res.qrc index 3a4254791..e981f22ae 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -56,5 +56,6 @@ qml/img/cleariconactive.png qml/img/copyicon.png qml/img/copyiconactive.png + qml/img/searchicon.png From 877380bf586ae755487ede47dc507c4478613005 Mon Sep 17 00:00:00 2001 From: yann300 Date: Thu, 2 Apr 2015 12:30:03 +0200 Subject: [PATCH 03/15] - Add actions for play and stop debugging. - Small change in layout of statecombobox. --- mix/qml/Debugger.qml | 12 +++++------ mix/qml/StatesComboBox.qml | 39 +++++++++++++++++++++++----------- mix/qml/TransactionLog.qml | 6 ++++-- mix/qml/img/stop_button2x.png | Bin 0 -> 235 bytes mix/res.qrc | 1 + 5 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 mix/qml/img/stop_button2x.png diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 9ab2f03a4..836bbaf94 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -225,24 +225,24 @@ Rectangle { id: playAction enabledStateImg: "qrc:/qml/img/play_button.png" disableStateImg: "qrc:/qml/img/play_button.png" - onClicked: console.log("play"); + onClicked: projectModel.stateListModel.runState(transactionLog.selectedStateIndex) width: 30 height: 30 buttonShortcut: "Ctrl+Shift+F8" - buttonTooltip: qsTr("Play") + buttonTooltip: qsTr("Start Debugging") visible: true } StepActionImage { id: pauseAction - enabledStateImg: "qrc:/qml/img/pause_button.png" - disableStateImg: "qrc:/qml/img/pause_button.png" - onClicked: console.log("pause"); + enabledStateImg: "qrc:/qml/img/stop_button2x.png" + disableStateImg: "qrc:/qml/img/stop_button2x.png" + onClicked: Debugger.init(null); width: 30 height: 30 buttonShortcut: "Ctrl+Shift+F9" - buttonTooltip: qsTr("Pause") + buttonTooltip: qsTr("Stop Debugging") visible: true } diff --git a/mix/qml/StatesComboBox.qml b/mix/qml/StatesComboBox.qml index 34567d083..bc7a4853d 100644 --- a/mix/qml/StatesComboBox.qml +++ b/mix/qml/StatesComboBox.qml @@ -29,7 +29,7 @@ Rectangle { id: statesComboBox width: 200 - height: 20 + height: 23 Component.onCompleted: { var top = dropDownList @@ -53,7 +53,7 @@ Rectangle { signal selectItem(real item) signal editItem(real item) signal selectCreate - property variant rowHeight: 25 + property int rowHeight: 25 property variant items property alias selectedItem: chosenItemText.text property alias selectedIndex: listView.currentRow @@ -67,21 +67,31 @@ Rectangle { property variant colorItem property variant colorSelect + SourceSansProRegular + { + id: regularFont + } + + SourceSansProBold + { + id: boldFont + } + smooth: true Rectangle { id: chosenItem width: parent.width height: statesComboBox.height color: statesComboBox.color - smooth: true + Text { id: chosenItemText - anchors.top: parent.top anchors.left: parent.left - anchors.margins: 2 + anchors.leftMargin: 10 + anchors.verticalCenter: parent.verticalCenter color: statesComboBox.colorItem text: "" - smooth: true + font.family: regularFont.name } MouseArea { @@ -111,7 +121,7 @@ Rectangle { clip: true radius: 4 anchors.top: chosenItem.top - anchors.margins: 2 + anchors.topMargin: 23 color: statesComboBox.color ColumnLayout { @@ -151,7 +161,9 @@ Rectangle { color: statesComboBox.colorItem anchors.top: parent.top anchors.left: parent.left - anchors.margins: 5 + anchors.leftMargin: 10 + anchors.topMargin: 5 + font.family: regularFont.name } Image { id: imageItemid @@ -197,15 +209,18 @@ Rectangle { } //Table View RowLayout { - Rectangle { - width: 1 - } + anchors.top: listView.bottom + anchors.topMargin: 4 + anchors.left: parent.left + anchors.leftMargin: 10 Text { id: createStateText width: statesComboBox.width height: statesComboBox.height - font.bold: true + font.family: boldFont.name + color: "#808080" text: qsTr("Create State ...") + font.weight: Font.DemiBold MouseArea { anchors.fill: parent hoverEnabled: true diff --git a/mix/qml/TransactionLog.qml b/mix/qml/TransactionLog.qml index 3bcc6c270..5668c6e05 100644 --- a/mix/qml/TransactionLog.qml +++ b/mix/qml/TransactionLog.qml @@ -9,6 +9,7 @@ Item { property ListModel fullModel: ListModel{} property ListModel transactionModel: ListModel{} property ListModel callModel: ListModel{} + property int selectedStateIndex: statesCombo.selectedIndex ColumnLayout { anchors.fill: parent @@ -45,14 +46,15 @@ Item { projectModel.stateListModel.debugDefaultState(); } } + StatesComboBox { id: statesCombo items: projectModel.stateListModel onSelectCreate: projectModel.stateListModel.addState(); onEditItem: projectModel.stateListModel.editState(item) - colorItem: "black" - colorSelect: "blue" + colorItem: "#808080" + colorSelect: "#4a90e2" color: "white" Connections { target: projectModel.stateListModel diff --git a/mix/qml/img/stop_button2x.png b/mix/qml/img/stop_button2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1727b729a391be03065cecb0146a086d9c34ceb4 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^c|aV)!3HGzUpB-7DYhhUcNd2LAh=-f^2tCE&H|6f zVg?3oVGw3ym^DWND9B#o>FdgVpM{CTifz*yho?ZH3QrfukcwMxFER2mC~z=1ny3n9 zuGAISzMIKl9tTh!3L5gVe>Kglj61h})kO1Kb>ICDakdw5sLLEuoKwI-h;>L2tPW-t ai2kzU%1ag>C*>4l5YN-q&t;ucLK6TB13`2E literal 0 HcmV?d00001 diff --git a/mix/res.qrc b/mix/res.qrc index 24bbc3830..0149b96e4 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -62,5 +62,6 @@ qml/img/copyicon.png qml/img/copyiconactive.png qml/img/searchicon.png + qml/img/stop_button2x.png From 8781061b1fd7a16254d2e7e3d65d8f83fd38e3de Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 2 Apr 2015 14:20:33 +0200 Subject: [PATCH 04/15] fix max stack size 1024 --- libevm/VM.h | 2 +- test/stMemoryTestFiller.json | 114 +++++++++++++++++++++++++++++++++-- 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index b14a117df..1cf06b78b 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -56,7 +56,7 @@ public: virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final; - void require(u256 _n, u256 _d) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_n, (bigint)m_stack.size())); } if (m_stack.size() - _n + _d >= c_stackLimit) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)(_d - _n), (bigint)m_stack.size())); } } + void require(u256 _n, u256 _d) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_n, (bigint)m_stack.size())); } if (m_stack.size() - _n + _d > c_stackLimit) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)(_d - _n), (bigint)m_stack.size())); } } void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } } u256 curPC() const { return m_curPC; } diff --git a/test/stMemoryTestFiller.json b/test/stMemoryTestFiller.json index c1754d52f..23f52b657 100644 --- a/test/stMemoryTestFiller.json +++ b/test/stMemoryTestFiller.json @@ -1461,7 +1461,7 @@ } }, - "stackLimitPush32_1024": { + "stackLimitPush32_1023": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1495,7 +1495,7 @@ } }, - "stackLimitPush32_1025": { + "stackLimitPush32_1024": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1529,7 +1529,41 @@ } }, - "stackLimitPush31_1024": { + "stackLimitPush32_1025": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1023 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a0102 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "stackLimitPush31_1023": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1563,7 +1597,7 @@ } }, - "stackLimitPush31_1025": { + "stackLimitPush31_1024": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1597,7 +1631,41 @@ } }, - "stackLimitGas_1024": { + "stackLimitPush31_1025": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1023 0x00 MSTORE JUMPDEST 0x0102030405060708090a0102030405060708090a0102030405060708090a01 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "stackLimitGas_1023": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1631,7 +1699,7 @@ } }, - "stackLimitGas_1025": { + "stackLimitGas_1024": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1665,6 +1733,40 @@ } }, + "stackLimitGas_1025": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "42949672960", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "(asm 1023 0x00 MSTORE JUMPDEST GAS 0x01 0x00 MLOAD SUB 0x00 MSTORE 0x00 MLOAD 0x06 JUMPI STOP )", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "429496729600", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000", + "to" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "value" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "mstroe8_dejavu": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 6485fa07590c2a4bb70ec4d2ad03566ef9540a7e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Apr 2015 16:03:05 +0200 Subject: [PATCH 05/15] PV bump to 60. --- libethcore/Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index d3ecbcc5f..ef4da1dd7 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -34,7 +34,7 @@ namespace eth { const unsigned c_ethashVersion = c_ethashRevision; -const unsigned c_protocolVersion = 59; +const unsigned c_protocolVersion = 60; const unsigned c_databaseBaseVersion = 8; #if ETH_FATDB const unsigned c_databaseVersionModifier = 1; From d4ee45acfdac61f83e54aaef46ff8a0237243bae Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Apr 2015 17:39:48 +0200 Subject: [PATCH 06/15] null return for invalid values. --- libethcore/BlockInfo.h | 2 +- libweb3jsonrpc/WebThreeStubServerBase.cpp | 80 +++++++++++++---------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h index 8f42dc038..91dcecc6b 100644 --- a/libethcore/BlockInfo.h +++ b/libethcore/BlockInfo.h @@ -80,7 +80,7 @@ public: u256 number; u256 gasLimit; u256 gasUsed; - u256 timestamp; + u256 timestamp = Invalid256; bytes extraData; h256 mixHash; Nonce nonce; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 7524e7519..457676fba 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -57,58 +57,70 @@ const unsigned dev::SensibleHttpPort = 8080; static Json::Value toJson(dev::eth::BlockInfo const& _bi) { Json::Value res; - res["hash"] = toJS(_bi.hash); - res["parentHash"] = toJS(_bi.parentHash); - res["sha3Uncles"] = toJS(_bi.sha3Uncles); - res["miner"] = toJS(_bi.coinbaseAddress); - res["stateRoot"] = toJS(_bi.stateRoot); - res["transactionsRoot"] = toJS(_bi.transactionsRoot); - res["difficulty"] = toJS(_bi.difficulty); - res["number"] = toJS(_bi.number); - res["gasUsed"] = toJS(_bi.gasUsed); - res["gasLimit"] = toJS(_bi.gasLimit); - res["timestamp"] = toJS(_bi.timestamp); - res["extraData"] = toJS(_bi.extraData); - res["nonce"] = toJS(_bi.nonce); - res["logsBloom"] = toJS(_bi.logBloom); + if (_bi) + { + res["hash"] = toJS(_bi.hash); + res["parentHash"] = toJS(_bi.parentHash); + res["sha3Uncles"] = toJS(_bi.sha3Uncles); + res["miner"] = toJS(_bi.coinbaseAddress); + res["stateRoot"] = toJS(_bi.stateRoot); + res["transactionsRoot"] = toJS(_bi.transactionsRoot); + res["difficulty"] = toJS(_bi.difficulty); + res["number"] = toJS(_bi.number); + res["gasUsed"] = toJS(_bi.gasUsed); + res["gasLimit"] = toJS(_bi.gasLimit); + res["timestamp"] = toJS(_bi.timestamp); + res["extraData"] = toJS(_bi.extraData); + res["nonce"] = toJS(_bi.nonce); + res["logsBloom"] = toJS(_bi.logBloom); + } return res; } static Json::Value toJson(dev::eth::Transaction const& _t) { Json::Value res; - res["hash"] = toJS(_t.sha3()); - res["input"] = toJS(_t.data()); - res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress()); - res["from"] = toJS(_t.safeSender()); - res["gas"] = toJS(_t.gas()); - res["gasPrice"] = toJS(_t.gasPrice()); - res["nonce"] = toJS(_t.nonce()); - res["value"] = toJS(_t.value()); + if (_t) + { + res["hash"] = toJS(_t.sha3()); + res["input"] = toJS(_t.data()); + res["to"] = _t.isCreation() ? Json::Value() : toJS(_t.receiveAddress()); + res["from"] = toJS(_t.safeSender()); + res["gas"] = toJS(_t.gas()); + res["gasPrice"] = toJS(_t.gasPrice()); + res["nonce"] = toJS(_t.nonce()); + res["value"] = toJS(_t.value()); + } return res; } static Json::Value toJson(dev::eth::BlockInfo const& _bi, UncleHashes const& _us, Transactions const& _ts) { Json::Value res = toJson(_bi); - res["uncles"] = Json::Value(Json::arrayValue); - for (h256 h: _us) - res["uncles"].append(toJS(h)); - res["transactions"] = Json::Value(Json::arrayValue); - for (Transaction const& t: _ts) - res["transactions"].append(toJson(t)); + if (_bi) + { + res["uncles"] = Json::Value(Json::arrayValue); + for (h256 h: _us) + res["uncles"].append(toJS(h)); + res["transactions"] = Json::Value(Json::arrayValue); + for (Transaction const& t: _ts) + res["transactions"].append(toJson(t)); + } return res; } static Json::Value toJson(dev::eth::BlockInfo const& _bi, UncleHashes const& _us, TransactionHashes const& _ts) { Json::Value res = toJson(_bi); - res["uncles"] = Json::Value(Json::arrayValue); - for (h256 h: _us) - res["uncles"].append(toJS(h)); - res["transactions"] = Json::Value(Json::arrayValue); - for (h256 const& t: _ts) - res["transactions"].append(toJS(t)); + if (_bi) + { + res["uncles"] = Json::Value(Json::arrayValue); + for (h256 h: _us) + res["uncles"].append(toJS(h)); + res["transactions"] = Json::Value(Json::arrayValue); + for (h256 const& t: _ts) + res["transactions"].append(toJS(t)); + } return res; } From d6694b609d19fe33339c0a7ef2fd5c6176ecb3d9 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 2 Apr 2015 18:37:14 +0200 Subject: [PATCH 07/15] Typo. --- eth/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 2a065cc8c..ea536f790 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -117,8 +117,8 @@ void help() << " -h,--help Show this help message and exit." << endl << " -i,--interactive Enter interactive mode (default: non-interactive)." << endl #if ETH_JSONRPC - << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl - << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl + << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl + << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl #endif << " -K,--kill-blockchain First kill the blockchain." << endl << " --listen-ip Listen on the given port for incoming connections (default: 30303)." << endl From bb4a79ee96ec4e59c5680e3ee3ae265f256a4f71 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 18:52:41 +0200 Subject: [PATCH 08/15] Dims was backwards. Fixed. --- abi/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/abi/main.cpp b/abi/main.cpp index 80742fcd2..e7382c761 100644 --- a/abi/main.cpp +++ b/abi/main.cpp @@ -436,7 +436,7 @@ struct ABIMethod if (_params[pi].second != Format::Open) throw ExpectedOpen(); ++pi; - int l = a.dims[addr.size()]; + int l = a.dims[a.dims.size() - 1 - addr.size()]; if (l == -1) { // read ahead in params and discover the arity. @@ -486,7 +486,7 @@ struct ABIMethod put(); else { - int l = a.dims[addr.size()]; + int l = a.dims[a.dims.size() - 1 - addr.size()]; if (l == -1) { l = fromBigEndian(bytesConstRef(&_data).cropped(di, 32)); @@ -525,7 +525,7 @@ struct ABIMethod { out << "["; addr.push_back(0); - int l = a.dims[addr.size() - 1]; + int l = a.dims[a.dims.size() - 1 - (addr.size() - 1)]; if (l == -1) l = catDims[d++]; for (addr.back() = 0; addr.back() < l; ++addr.back()) From e0b1e40556ccf04fe84a67777d77873df7fa92f8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 19:04:23 +0200 Subject: [PATCH 09/15] Fixes #1505 --- alethzero/MainWin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 610fd032d..e848b4017 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1582,7 +1582,7 @@ void Main::on_debugCurrent_triggered() unsigned txi = item->data(Qt::UserRole + 1).toInt(); bytes t = ethereum()->blockChain().transaction(h, txi); State s(ethereum()->state(txi, h)); - Executive e(s, ethereum()->blockChain(), PendingBlock); + Executive e(s, ethereum()->blockChain()); Debugger dw(this, this); dw.populate(e, Transaction(t, CheckSignature::Sender)); dw.exec(); From 8667b623d3e067e26a0516675df9fbb66e5cb5a9 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 19:18:18 +0200 Subject: [PATCH 10/15] Fix invalid combinations of options rather than bomb out. Fixes #1493 --- CMakeLists.txt | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae0274f6a..80bad7929 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,19 +30,11 @@ endfunction() # propagates CMake configuration options to the compiler function(configureProject) if (PARANOIA) - if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - add_definitions(-DETH_PARANOIA) - else () - message(FATAL_ERROR "Paranoia requires debug.") - endif () + add_definitions(-DETH_PARANOIA) endif () if (VMTRACE) - if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - add_definitions(-DETH_VMTRACE) - else () - message(FATAL_ERROR "VM tracing requires debug.") - endif () + add_definitions(-DETH_VMTRACE) endif () if (ETHASHCL) @@ -123,6 +115,17 @@ endfunction() set(CMAKE_AUTOMOC ON) cmake_policy(SET CMP0015 NEW) +# Clear invalid option +if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + if (PARANOIA) + message("Paranoia requires debug - disabling for release build.") + set(PARANOIA OFF) + endif () + if (VMTRACE) + message("VM Tracing requires debug - disabling for release build.") + set (VMTRACE OFF) + endif () +endif () createDefaultCacheConfig() configureProject() From b9074ff8c68a40b425ec3d66205b6a66c7ba6c06 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 21:09:47 +0200 Subject: [PATCH 11/15] Minor build fix. --- libethereum/Executive.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libethereum/Executive.h b/libethereum/Executive.h index 158e86330..3efdf6f0f 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -61,9 +61,9 @@ class Executive { public: /// Basic constructor. - Executive(State& _s, LastHashes const& _lh, unsigned _level): m_s(_s), m_lastHashes(_lh), m_depth(_level) {} + Executive(State& _s, LastHashes const& _lh, unsigned _level = 0): m_s(_s), m_lastHashes(_lh), m_depth(_level) {} /// Basic constructor. - Executive(State& _s, BlockChain const& _bc, unsigned _level); + Executive(State& _s, BlockChain const& _bc, unsigned _level = 0); /// Basic destructor. ~Executive() = default; From 13232d6e048e27aaa25410fdd4dc9969d67111d0 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 21:10:15 +0200 Subject: [PATCH 12/15] Fixes #1509 --- alethzero/MainWin.cpp | 2 +- eth/main.cpp | 9 ++-- libdevcore/Common.h | 16 ++++++ libethcore/BlockInfo.h | 28 +++++----- libethcore/Common.cpp | 1 + libethcore/Common.h | 3 ++ libethereum/BlockChain.cpp | 85 ++++++++++++++++++++++++++----- libethereum/BlockChain.h | 18 +++++-- libethereum/CanonBlockChain.cpp | 2 +- libethereum/CanonBlockChain.h | 4 +- libethereum/Client.cpp | 36 ++++++++----- libethereum/Client.h | 8 +-- libethereum/State.cpp | 4 +- libethereum/State.h | 4 +- libtestutils/BlockChainLoader.cpp | 2 +- libwebthree/WebThree.cpp | 4 +- libwebthree/WebThree.h | 8 +-- mix/MixClient.h | 2 +- neth/main.cpp | 2 +- test/blockchain.cpp | 2 +- 20 files changed, 166 insertions(+), 74 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index e848b4017..b17d47cdf 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -168,7 +168,7 @@ Main::Main(QWidget *parent) : QSettings s("ethereum", "alethzero"); m_networkConfig = s.value("peers").toByteArray(); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); - m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); + m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth", "shh"}, p2p::NetworkPreferences(), network)); m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads)); m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this)); diff --git a/eth/main.cpp b/eth/main.cpp index ea536f790..3cdcba472 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -129,6 +129,7 @@ void help() << " -o,--mode Start a full node or a peer node (Default: full)." << endl << " -p,--port Connect to remote port (default: 30303)." << endl << " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl + << " -R,--rebuild-blockchain First rebuild the blockchain from the existing database." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl @@ -168,7 +169,7 @@ void version() } Address c_config = Address("ccdeac59d35627b7de09332e819d5159e7bb7250"); -string pretty(h160 _a, dev::eth::State _st) +string pretty(h160 _a, dev::eth::State const& _st) { string ns; h256 n; @@ -216,7 +217,7 @@ int main(int argc, char** argv) bool bootstrap = false; bool upnp = true; bool forceMining = false; - bool killChain = false; + WithExisting killChain = WithExisting::Trust; bool jit = false; bool structuredLogging = false; string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S"; @@ -274,7 +275,9 @@ int main(int argc, char** argv) } } else if (arg == "-K" || arg == "--kill-blockchain") - killChain = true; + killChain = WithExisting::Kill; + else if (arg == "-B" || arg == "--rebuild-blockchain") + killChain = WithExisting::Verify; else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) clientName = argv[++i]; else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) diff --git a/libdevcore/Common.h b/libdevcore/Common.h index 5e778644d..49491d4cc 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -134,4 +134,20 @@ private: std::function m_f; }; +enum class WithExisting: int +{ + Trust = 0, + Verify, + Kill +}; + +} + +namespace std { + +inline dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b) +{ + return static_cast(max(static_cast(_a), static_cast(_b))); +} + } diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h index 91dcecc6b..d262afca7 100644 --- a/libethcore/BlockInfo.h +++ b/libethcore/BlockInfo.h @@ -100,20 +100,20 @@ public: bool operator==(BlockInfo const& _cmp) const { return parentHash == _cmp.parentHash && - sha3Uncles == _cmp.sha3Uncles && - coinbaseAddress == _cmp.coinbaseAddress && - stateRoot == _cmp.stateRoot && - transactionsRoot == _cmp.transactionsRoot && - receiptsRoot == _cmp.receiptsRoot && - logBloom == _cmp.logBloom && - difficulty == _cmp.difficulty && - number == _cmp.number && - gasLimit == _cmp.gasLimit && - gasUsed == _cmp.gasUsed && - timestamp == _cmp.timestamp && - extraData == _cmp.extraData && - mixHash == _cmp.mixHash && - nonce == _cmp.nonce; + sha3Uncles == _cmp.sha3Uncles && + coinbaseAddress == _cmp.coinbaseAddress && + stateRoot == _cmp.stateRoot && + transactionsRoot == _cmp.transactionsRoot && + receiptsRoot == _cmp.receiptsRoot && + logBloom == _cmp.logBloom && + difficulty == _cmp.difficulty && + number == _cmp.number && + gasLimit == _cmp.gasLimit && + gasUsed == _cmp.gasUsed && + timestamp == _cmp.timestamp && + extraData == _cmp.extraData && + mixHash == _cmp.mixHash && + nonce == _cmp.nonce; } bool operator!=(BlockInfo const& _cmp) const { return !operator==(_cmp); } diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index ef4da1dd7..02e806905 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -35,6 +35,7 @@ namespace eth const unsigned c_ethashVersion = c_ethashRevision; const unsigned c_protocolVersion = 60; +const unsigned c_minorProtocolVersion = 0; const unsigned c_databaseBaseVersion = 8; #if ETH_FATDB const unsigned c_databaseVersionModifier = 1; diff --git a/libethcore/Common.h b/libethcore/Common.h index 51322dcb2..aabe663cd 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -35,6 +35,9 @@ namespace eth /// Current protocol version. extern const unsigned c_protocolVersion; +/// Current minor protocol version. +extern const unsigned c_minorProtocolVersion; + /// Current database version. extern const unsigned c_databaseVersion; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 8c0bd2b8b..59f9c4a2d 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -98,7 +98,7 @@ static const unsigned c_minCacheSize = 1024 * 1024 * 32; #endif -BlockChain::BlockChain(bytes const& _genesisBlock, std::string _path, bool _killExisting) +BlockChain::BlockChain(bytes const& _genesisBlock, std::string _path, WithExisting _we, ProgressCallback const& _p) { // initialise deathrow. m_cacheUsage.resize(c_collectionQueueSize); @@ -108,7 +108,9 @@ BlockChain::BlockChain(bytes const& _genesisBlock, std::string _path, bool _kill m_genesisBlock = _genesisBlock; m_genesisHash = sha3(RLP(m_genesisBlock)[0].data()); - open(_path, _killExisting); + open(_path, _we); + if (_we == WithExisting::Verify) + rebuild(_path, _p); } BlockChain::~BlockChain() @@ -116,24 +118,23 @@ BlockChain::~BlockChain() close(); } -void BlockChain::open(std::string _path, bool _killExisting) +void BlockChain::open(std::string const& _path, WithExisting _we) { - if (_path.empty()) - _path = Defaults::get()->m_dbPath; - boost::filesystem::create_directories(_path); - if (_killExisting) + std::string path = _path.empty() ? Defaults::get()->m_dbPath : _path; + boost::filesystem::create_directories(path); + if (_we == WithExisting::Kill) { - boost::filesystem::remove_all(_path + "/blocks"); - boost::filesystem::remove_all(_path + "/details"); + boost::filesystem::remove_all(path + "/blocks"); + boost::filesystem::remove_all(path + "/details"); } ldb::Options o; o.create_if_missing = true; - ldb::DB::Open(o, _path + "/blocks", &m_blocksDB); - ldb::DB::Open(o, _path + "/details", &m_extrasDB); + ldb::DB::Open(o, path + "/blocks", &m_blocksDB); + ldb::DB::Open(o, path + "/details", &m_extrasDB); if (!m_blocksDB || !m_extrasDB) { - if (boost::filesystem::space(_path + "/blocks").available < 1024) + if (boost::filesystem::space(path + "/blocks").available < 1024) { cwarn << "Not enough available space found on hard drive. Please free some up and then re-run. Bailing."; BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace()); @@ -158,7 +159,6 @@ void BlockChain::open(std::string _path, bool _killExisting) // TODO: Implement ability to rebuild details map from DB. std::string l; m_extrasDB->Get(m_readOptions, ldb::Slice("best"), &l); - m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data(); cnote << "Opened blockchain DB. Latest: " << currentHash(); @@ -174,6 +174,53 @@ void BlockChain::close() m_blocks.clear(); } +void BlockChain::rebuild(std::string const& _path, std::function const& _progress) +{ + unsigned originalNumber = number(); + + // Keep extras DB around, but under a temp name + delete m_extrasDB; + m_extrasDB = nullptr; + boost::filesystem::rename(_path + "/details", _path + "/details.old"); + ldb::DB* oldExtrasDB; + ldb::Options o; + o.create_if_missing = true; + ldb::DB::Open(o, _path + "/details.old", &oldExtrasDB); + ldb::DB::Open(o, _path + "/details", &m_extrasDB); + + // Open a fresh state DB + OverlayDB db = State::openDB(_path, WithExisting::Kill); + + // Clear all memos ready for replay. + m_details.clear(); + m_logBlooms.clear(); + m_receipts.clear(); + m_transactionAddresses.clear(); + m_blockHashes.clear(); + m_blocksBlooms.clear(); + m_lastLastHashes.clear(); + m_lastBlockHash = genesisHash(); + + for (unsigned d = 0; d < originalNumber; ++d) + { + try + { + import(block(queryExtras(h256(u256(d)), m_blockHashes, x_blockHashes, NullBlockHash, oldExtrasDB).value), db); + } + catch (...) + { + // Failed to import - stop here. + break; + } + + if (_progress) + _progress(d, originalNumber); + } + + delete oldExtrasDB; + boost::filesystem::remove_all(_path + "/details.old"); +} + template bool contains(T const& _t, V const& _v) { @@ -414,12 +461,22 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db) #endif } #if ETH_CATCH - catch (Exception const& _e) + catch (InvalidNonce const& _e) { clog(BlockChainNote) << " Malformed block: " << diagnostic_information(_e); _e << errinfo_comment("Malformed block "); throw; } + catch (Exception const& _e) + { + clog(BlockChainWarn) << " Malformed block: " << diagnostic_information(_e); + _e << errinfo_comment("Malformed block "); + clog(BlockChainWarn) << "Block: " << bi.hash; + clog(BlockChainWarn) << bi; + clog(BlockChainWarn) << "Block parent: " << bi.parentHash; + clog(BlockChainWarn) << BlockInfo(block(bi.parentHash)); + throw; + } #endif StructuredLogger::chainReceivedNewBlock( diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 03c0fdcfd..7705e0f12 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -58,6 +58,7 @@ struct FutureTime: virtual Exception {}; struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 7; }; struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 4; }; +struct BlockChainWarn: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 1; }; // TODO: Move all this Genesis stuff into Genesis.h/.cpp std::map const& genesisState(); @@ -77,6 +78,8 @@ enum { ExtraBlocksBlooms }; +using ProgressCallback = std::function; + /** * @brief Implements the blockchain database. All data this gives is disk-backed. * @threadsafe @@ -85,10 +88,11 @@ enum { class BlockChain { public: - BlockChain(bytes const& _genesisBlock, std::string _path, bool _killExisting); + BlockChain(bytes const& _genesisBlock, std::string _path, WithExisting _we, ProgressCallback const& _p = ProgressCallback()); ~BlockChain(); - void reopen(std::string _path, bool _killExisting = false) { close(); open(_path, _killExisting); } + /// Attempt a database re-open. + void reopen(std::string const& _path, WithExisting _we = WithExisting::Trust) { close(); open(_path, _we); } /// (Potentially) renders invalid existing bytesConstRef returned by lastBlock. /// To be called from main loop every 100ms or so. @@ -186,6 +190,10 @@ public: /// togther with all their quoted uncles. h256Set allUnclesFrom(h256 const& _parent) const; + /// Run through database and verify all blocks by reevaluating. + /// Will call _progress with the progress in this operation first param done, second total. + void rebuild(std::string const& _path, ProgressCallback const& _progress = std::function()); + /** @returns the hash of all blocks between @a _from and @a _to, all blocks are ordered first by a number of * blocks that are parent-to-child, then two sibling blocks, then a number of blocks that are child-to-parent. * @@ -222,10 +230,10 @@ public: private: static h256 chunkId(unsigned _level, unsigned _index) { return h256(_index * 0xff + _level); } - void open(std::string _path, bool _killExisting = false); + void open(std::string const& _path, WithExisting _we = WithExisting::Trust); void close(); - template T queryExtras(h256 const& _h, std::map& _m, boost::shared_mutex& _x, T const& _n) const + template T queryExtras(h256 const& _h, std::map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const { { ReadGuard l(_x); @@ -235,7 +243,7 @@ private: } std::string s; - m_extrasDB->Get(m_readOptions, toSlice(_h, N), &s); + (_extrasDB ? _extrasDB : m_extrasDB)->Get(m_readOptions, toSlice(_h, N), &s); if (s.empty()) { // cout << "Not found in DB: " << _h << endl; diff --git a/libethereum/CanonBlockChain.cpp b/libethereum/CanonBlockChain.cpp index 21b30d8ef..2a7b97525 100644 --- a/libethereum/CanonBlockChain.cpp +++ b/libethereum/CanonBlockChain.cpp @@ -92,6 +92,6 @@ bytes CanonBlockChain::createGenesisBlock() return block.out(); } -CanonBlockChain::CanonBlockChain(std::string _path, bool _killExisting): BlockChain(CanonBlockChain::createGenesisBlock(), _path, _killExisting) +CanonBlockChain::CanonBlockChain(std::string const& _path, WithExisting _we): BlockChain(CanonBlockChain::createGenesisBlock(), _path, _we) { } diff --git a/libethereum/CanonBlockChain.h b/libethereum/CanonBlockChain.h index 7110dbc90..be1c03998 100644 --- a/libethereum/CanonBlockChain.h +++ b/libethereum/CanonBlockChain.h @@ -55,8 +55,8 @@ std::map const& genesisState(); class CanonBlockChain: public BlockChain { public: - CanonBlockChain(bool _killExisting = false): CanonBlockChain(std::string(), _killExisting) {} - CanonBlockChain(std::string _path, bool _killExisting = false); + CanonBlockChain(WithExisting _we = WithExisting::Trust): CanonBlockChain(std::string(), _we) {} + CanonBlockChain(std::string const& _path, WithExisting _we = WithExisting::Trust); ~CanonBlockChain() {} /// @returns the genesis block header. diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 54f23dc84..185e1a5ca 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -38,14 +38,23 @@ using namespace p2p; VersionChecker::VersionChecker(string const& _dbPath): m_path(_dbPath.size() ? _dbPath : Defaults::dbPath()) { - auto protocolContents = contents(m_path + "/protocol"); - auto databaseContents = contents(m_path + "/database"); - m_ok = RLP(protocolContents).toInt(RLP::LaisezFaire) == eth::c_protocolVersion && RLP(databaseContents).toInt(RLP::LaisezFaire) == c_databaseVersion; + bytes statusBytes = contents(m_path + "/status"); + RLP status(statusBytes); + auto protocolVersion = (unsigned)status[0]; + auto minorProtocolVersion = (unsigned)status[1]; + auto databaseVersion = (unsigned)status[2]; + m_action = + protocolVersion != eth::c_protocolVersion || databaseVersion != c_databaseVersion ? + WithExisting::Kill + : minorProtocolVersion != eth::c_minorProtocolVersion ? + WithExisting::Verify + : + WithExisting::Trust; } void VersionChecker::setOk() { - if (!m_ok) + if (m_action != WithExisting::Trust) { try { @@ -55,8 +64,7 @@ void VersionChecker::setOk() { cwarn << "Unhandled exception! Failed to create directory: " << m_path << "\n" << boost::current_exception_diagnostic_information(); } - writeFile(m_path + "/protocol", rlp(eth::c_protocolVersion)); - writeFile(m_path + "/database", rlp(c_databaseVersion)); + writeFile(m_path + "/status", rlpList(eth::c_protocolVersion, eth::c_minorProtocolVersion, c_databaseVersion)); } } @@ -102,12 +110,12 @@ void BasicGasPricer::update(BlockChain const& _bc) } } -Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, u256 _networkId, int _miners): +Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId, int _miners): Worker("eth"), m_vc(_dbPath), - m_bc(_dbPath, !m_vc.ok() || _forceClean), + m_bc(_dbPath, max(m_vc.action(), _forceAction)), m_gp(new TrivialGasPricer), - m_stateDB(State::openDB(_dbPath, !m_vc.ok() || _forceClean)), + m_stateDB(State::openDB(_dbPath, max(m_vc.action(), _forceAction))), m_preMine(Address(), m_stateDB), m_postMine(Address(), m_stateDB) { @@ -127,12 +135,12 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, bool _forceClean, startWorking(); } -Client::Client(p2p::Host* _extNet, std::shared_ptr _gp, std::string const& _dbPath, bool _forceClean, u256 _networkId, int _miners): +Client::Client(p2p::Host* _extNet, std::shared_ptr _gp, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId, int _miners): Worker("eth"), m_vc(_dbPath), - m_bc(_dbPath, !m_vc.ok() || _forceClean), + m_bc(_dbPath, max(m_vc.action(), _forceAction)), m_gp(_gp), - m_stateDB(State::openDB(_dbPath, !m_vc.ok() || _forceClean)), + m_stateDB(State::openDB(_dbPath, max(m_vc.action(), _forceAction))), m_preMine(Address(), m_stateDB), m_postMine(Address(), m_stateDB) { @@ -202,9 +210,9 @@ void Client::killChain() { WriteGuard l(x_stateDB); m_stateDB = OverlayDB(); - m_stateDB = State::openDB(Defaults::dbPath(), true); + m_stateDB = State::openDB(Defaults::dbPath(), WithExisting::Kill); } - m_bc.reopen(Defaults::dbPath(), true); + m_bc.reopen(Defaults::dbPath(), WithExisting::Kill); m_preMine = State(Address(), m_stateDB); m_postMine = State(Address(), m_stateDB); diff --git a/libethereum/Client.h b/libethereum/Client.h index 1091bba58..f07e4c590 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -65,10 +65,10 @@ public: VersionChecker(std::string const& _dbPath); void setOk(); - bool ok() const { return m_ok; } + WithExisting action() const { return m_action; } private: - bool m_ok; + WithExisting m_action; std::string m_path; }; @@ -126,7 +126,7 @@ public: explicit Client( p2p::Host* _host, std::string const& _dbPath = std::string(), - bool _forceClean = false, + WithExisting _forceAction = WithExisting::Trust, u256 _networkId = 0, int _miners = -1 ); @@ -135,7 +135,7 @@ public: p2p::Host* _host, std::shared_ptr _gpForAdoption, // pass it in with new. std::string const& _dbPath = std::string(), - bool _forceClean = false, + WithExisting _forceAction = WithExisting::Trust, u256 _networkId = 0, int _miners = -1 ); diff --git a/libethereum/State.cpp b/libethereum/State.cpp index fa457dc41..cd46805d8 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -46,13 +46,13 @@ using namespace dev::eth; static const u256 c_blockReward = 1500 * finney; -OverlayDB State::openDB(std::string _path, bool _killExisting) +OverlayDB State::openDB(std::string _path, WithExisting _we) { if (_path.empty()) _path = Defaults::get()->m_dbPath; boost::filesystem::create_directory(_path); - if (_killExisting) + if (_we == WithExisting::Kill) boost::filesystem::remove_all(_path + "/state"); ldb::Options o; diff --git a/libethereum/State.h b/libethereum/State.h index 5ed76cc27..e64a6f0e3 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -123,8 +123,8 @@ public: Address address() const { return m_ourAddress; } /// Open a DB - useful for passing into the constructor & keeping for other states that are necessary. - static OverlayDB openDB(std::string _path, bool _killExisting = false); - static OverlayDB openDB(bool _killExisting = false) { return openDB(std::string(), _killExisting); } + static OverlayDB openDB(std::string _path, WithExisting _we = WithExisting::Trust); + static OverlayDB openDB(WithExisting _we = WithExisting::Trust) { return openDB(std::string(), _we); } OverlayDB const& db() const { return m_db; } /// @returns the set containing all addresses currently in use in Ethereum. diff --git a/libtestutils/BlockChainLoader.cpp b/libtestutils/BlockChainLoader.cpp index 898812b2a..ba0def59e 100644 --- a/libtestutils/BlockChainLoader.cpp +++ b/libtestutils/BlockChainLoader.cpp @@ -35,7 +35,7 @@ BlockChainLoader::BlockChainLoader(Json::Value const& _json) m_state = sl.state(); // load genesisBlock - m_bc.reset(new BlockChain(fromHex(_json["genesisRLP"].asString()), m_dir.path(), true)); + m_bc.reset(new BlockChain(fromHex(_json["genesisRLP"].asString()), m_dir.path(), WithExisting::Kill)); // load blocks for (auto const& block: _json["blocks"]) diff --git a/libwebthree/WebThree.cpp b/libwebthree/WebThree.cpp index b2c6765b5..a74d7fa55 100644 --- a/libwebthree/WebThree.cpp +++ b/libwebthree/WebThree.cpp @@ -39,7 +39,7 @@ using namespace dev::shh; WebThreeDirect::WebThreeDirect( std::string const& _clientVersion, std::string const& _dbPath, - bool _forceClean, + WithExisting _we, std::set const& _interfaces, NetworkPreferences const& _n, bytesConstRef _network, int _miners @@ -50,7 +50,7 @@ WebThreeDirect::WebThreeDirect( if (_dbPath.size()) Defaults::setDBPath(_dbPath); if (_interfaces.count("eth")) - m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean, 0, _miners)); + m_ethereum.reset(new eth::Client(&m_net, _dbPath, _we, 0, _miners)); if (_interfaces.count("shh")) m_whisper = m_net.registerCapability(new WhisperHost); diff --git a/libwebthree/WebThree.h b/libwebthree/WebThree.h index a0e5cc666..de3cc9dcc 100644 --- a/libwebthree/WebThree.h +++ b/libwebthree/WebThree.h @@ -25,17 +25,13 @@ #include #include #include - -// Make sure boost/asio.hpp is included before windows.h. -#include +#include // Make sure boost/asio.hpp is included before windows.h. #include - #include #include #include #include #include - #include #include @@ -113,7 +109,7 @@ public: WebThreeDirect( std::string const& _clientVersion, std::string const& _dbPath, - bool _forceClean = false, + WithExisting _we = WithExisting::Trust, std::set const& _interfaces = {"eth", "shh"}, p2p::NetworkPreferences const& _n = p2p::NetworkPreferences(), bytesConstRef _network = bytesConstRef(), diff --git a/mix/MixClient.h b/mix/MixClient.h index 179b445ac..abd9445c7 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -37,7 +37,7 @@ namespace mix class MixBlockChain: public dev::eth::BlockChain { public: - MixBlockChain(std::string const& _path, h256 _stateRoot): BlockChain(createGenesisBlock(_stateRoot), _path, true) {} + MixBlockChain(std::string const& _path, h256 _stateRoot): BlockChain(createGenesisBlock(_stateRoot), _path, WithExisting::Kill) {} static bytes createGenesisBlock(h256 _stateRoot); }; diff --git a/neth/main.cpp b/neth/main.cpp index e7dde3cc6..7ee4962e9 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -550,7 +550,7 @@ int main(int argc, char** argv) dev::WebThreeDirect web3( clientImplString, dbPath, - killChain, + killChain ? WithExisting::Kill : WithExisting::Trust, mode == NodeMode::Full ? set{"eth", "shh"} : set(), netPrefs, &nodesState, diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 17e6c3588..ffb55da30 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -78,7 +78,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) // construct blockchain TransientDirectory td; - BlockChain bc(rlpGenesisBlock.out(), td.path(), true); + BlockChain bc(rlpGenesisBlock.out(), td.path(), WithExisting::Kill); if (_fillin) { From 1c1951a39b3b88f020f74a39019062a9701694b4 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 21:14:15 +0200 Subject: [PATCH 13/15] Don't crash when the status is bad. --- libethereum/Client.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 185e1a5ca..01ee9696a 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -40,16 +40,23 @@ VersionChecker::VersionChecker(string const& _dbPath): { bytes statusBytes = contents(m_path + "/status"); RLP status(statusBytes); - auto protocolVersion = (unsigned)status[0]; - auto minorProtocolVersion = (unsigned)status[1]; - auto databaseVersion = (unsigned)status[2]; - m_action = - protocolVersion != eth::c_protocolVersion || databaseVersion != c_databaseVersion ? - WithExisting::Kill - : minorProtocolVersion != eth::c_minorProtocolVersion ? - WithExisting::Verify - : - WithExisting::Trust; + try + { + auto protocolVersion = (unsigned)status[0]; + auto minorProtocolVersion = (unsigned)status[1]; + auto databaseVersion = (unsigned)status[2]; + m_action = + protocolVersion != eth::c_protocolVersion || databaseVersion != c_databaseVersion ? + WithExisting::Kill + : minorProtocolVersion != eth::c_minorProtocolVersion ? + WithExisting::Verify + : + WithExisting::Trust; + } + catch (...) + { + m_action = WithExisting::Kill; + } } void VersionChecker::setOk() From 708a218f3a1b923762b36004d0e5010391d2467a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 21:15:08 +0200 Subject: [PATCH 14/15] Version bump. --- libdevcore/Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index cf6bf44c4..251774b68 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -27,7 +27,7 @@ using namespace dev; namespace dev { -char const* Version = "0.9.1"; +char const* Version = "0.9.2"; } From 94ec0c0714917bf0af62fbf1f6679f747c63ecdf Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 3 Apr 2015 21:15:40 +0200 Subject: [PATCH 15/15] Be less verbose. --- libethereum/BlockChain.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 59f9c4a2d..32f36f99d 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -519,14 +519,14 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db) h256s BlockChain::treeRoute(h256 const& _from, h256 const& _to, h256* o_common, bool _pre, bool _post) const { - cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged(); +// cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged(); if (!_from || !_to) return h256s(); h256s ret; h256s back; unsigned fn = details(_from).number; unsigned tn = details(_to).number; - cdebug << "treeRoute" << fn << "..." << tn; +// cdebug << "treeRoute" << fn << "..." << tn; h256 from = _from; while (fn > tn) { @@ -534,7 +534,7 @@ h256s BlockChain::treeRoute(h256 const& _from, h256 const& _to, h256* o_common, ret.push_back(from); from = details(from).parent; fn--; - cdebug << "from:" << fn << _from.abridged(); +// cdebug << "from:" << fn << _from.abridged(); } h256 to = _to; while (fn < tn) @@ -543,7 +543,7 @@ h256s BlockChain::treeRoute(h256 const& _from, h256 const& _to, h256* o_common, back.push_back(to); to = details(to).parent; tn--; - cdebug << "to:" << tn << _to.abridged(); +// cdebug << "to:" << tn << _to.abridged(); } while (from != to) {