Merge branch 'develop' into miner

This commit is contained in:
obscuren 2015-02-11 23:46:54 +01:00
commit b64ad7a2a6
41 changed files with 1652 additions and 1098 deletions

View File

@ -11,8 +11,8 @@ install:
# - go get golang.org/x/tools/cmd/vet # - go get golang.org/x/tools/cmd/vet
- if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
- go get github.com/mattn/goveralls - go get github.com/mattn/goveralls
- go get -d github.com/obscuren/qml && cd $HOME/gopath/src/github.com/obscuren/qml && git checkout v1 && cd $TRAVIS_BUILD_DIR - go get gopkg.in/check.v1
- ETH_DEPS=$(go list -f '{{.Imports}} {{.TestImports}} {{.XTestImports}}' github.com/ethereum/go-ethereum/... | sed -e 's/\[//g' | sed -e 's/\]//g' | sed -e 's/C //g'); if [ "$ETH_DEPS" ]; then go get -d $ETH_DEPS; fi - DEPS=$(go list -f '{{.Imports}}' ./... | sed -e 's/\[//g' | sed -e 's/\]//g' | sed -e 's/C //g'); if [ "$DEPS" ]; then go get -d -v $DEPS; fi
before_script: before_script:
- gofmt -l -w . - gofmt -l -w .
- goimports -l -w . - goimports -l -w .
@ -20,7 +20,9 @@ before_script:
# - go vet ./... # - go vet ./...
# - go test -race ./... # - go test -race ./...
script: script:
- ./gocoverage.sh && if [ "$COVERALLS_TOKEN" ]; then goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN; fi - ./gocoverage.sh
after_success:
- if [ "$COVERALLS_TOKEN" ]; then goveralls -coverprofile=profile.cov -service=travis-ci -repotoken $COVERALLS_TOKEN; fi
env: env:
global: global:
- PKG_CONFIG_PATH=/opt/qt54/lib/pkgconfig - PKG_CONFIG_PATH=/opt/qt54/lib/pkgconfig

View File

@ -21,13 +21,10 @@ RUN apt-get install -y qt54quickcontrols qt54webengine
## Build and install latest Go ## Build and install latest Go
RUN git clone https://go.googlesource.com/go golang RUN git clone https://go.googlesource.com/go golang
RUN cd golang && git checkout go1.4.1 RUN cd golang && git checkout go1.4.1
RUN cd golang/src && ./all.bash && go version RUN cd golang/src && ./make.bash && go version
## Fetch and install QML # this is a workaround, to make sure that docker's cache is invalidated whenever the git repo changes
RUN go get -u -v -d github.com/obscuren/qml ADD https://api.github.com/repos/ethereum/go-ethereum/git/refs/heads/develop file_does_not_exist
WORKDIR $GOPATH/src/github.com/obscuren/qml
RUN git checkout v1
RUN go install -v
## Fetch and install go-ethereum ## Fetch and install go-ethereum
RUN go get -u -v -d github.com/ethereum/go-ethereum/... RUN go get -u -v -d github.com/ethereum/go-ethereum/...

View File

@ -29,7 +29,7 @@ For further, detailed, build instruction please see the [Wiki](https://github.co
Automated (dev) builds Automated (dev) builds
====================== ======================
* [[OS X](http://build.ethdev.com/builds/OSX%20Go%20develop%20branch/latest/app/)] * [[OS X](http://build.ethdev.com/builds/OSX%20Go%20develop%20branch/Mist-OSX-latest.dmg)]
* [Windows] Coming soon™ * [Windows] Coming soon™
* [Linux] Coming soon™ * [Linux] Coming soon™

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -7,7 +7,7 @@
</head> </head>
<body> <body>
<h1>JevCoin <code id="address"></code></h1> <h1>JevCoin <code id="contract_addr"></code></h1>
<div> <div>
<strong>Balance</strong> <strong>Balance</strong>
<span id="balance"></strong> <span id="balance"></strong>
@ -58,29 +58,25 @@
}], }],
"outputs": [] "outputs": []
}, { }, {
"name":"changed", "name":"received",
"type":"event", "type":"event",
"inputs": [ "inputs": [
{"name":"to","type":"address","indexed":true},
{"name":"from","type":"address","indexed":true}, {"name":"from","type":"address","indexed":true},
{"name":"amount","type":"uint256","indexed":true},
], ],
}]; }];
var address = localStorage.getItem("address"); var address = localStorage.getItem("address");
// deploy if not exist // deploy if not exist
if (address == null) { if (address == null) {
var code = "0x60056013565b610132806100356000396000f35b620f4240600033600160a060020a0316600052602052604060002081905550560060e060020a6000350480637bb98a681461002b578063d0679d3414610039578063e3d670d71461004d57005b61003361012d565b60006000f35b610047600435602435610062565b60006000f35b61005860043561010b565b8060005260206000f35b80600033600160a060020a0316600052602052604060002054106100855761008a565b610107565b80600033600160a060020a0316600052602052604060002090815403908190555080600083600160a060020a0316600052602052604060002090815401908190555081600160a060020a031633600160a060020a03167f1863989b4bb7c5c3941722099764574df7a459f9f9c6b6cdca35ddc9731792b860006000a35b5050565b6000600082600160a060020a03166000526020526040600020549050919050565b5b60008156"; var code = "0x60056013565b61012b806100346000396000f35b6103e8600033600160a060020a0316600052602052604060002081905550560060e060020a6000350480637bb98a681461002b578063d0679d3414610039578063e3d670d71461004d57005b610033610126565b60006000f35b610047600435602435610062565b60006000f35b610058600435610104565b8060005260206000f35b80600033600160a060020a0316600052602052604060002054101561008657610100565b80600033600160a060020a0316600052602052604060002090815403908190555080600083600160a060020a0316600052602052604060002090815401908190555033600160a060020a0316600052806020527ff11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef60406000a15b5050565b6000600082600160a060020a03166000526020526040600020549050919050565b5b60008156";
address = web3.eth.transact({ address = web3.eth.transact({data: code});
data: code,
gasPrice: "1000000000000000",
gas: "10000",
});
localStorage.setItem("address", address); localStorage.setItem("address", address);
} }
document.querySelector("#address").innerHTML = address.toUpperCase(); document.querySelector("#contract_addr").innerHTML = address.toUpperCase();
var contract = web3.eth.contract(address, desc); var contract = web3.eth.contract(address, desc);
contract.changed({from: eth.accounts[0]}).changed(function() { contract.received({from: eth.coinbase}).changed(function() {
refresh(); refresh();
}); });
eth.watch('chain').changed(function() { eth.watch('chain').changed(function() {
@ -102,7 +98,6 @@
function transact() { function transact() {
var to = document.querySelector("#address").value; var to = document.querySelector("#address").value;
if( to.length == 0 ) { if( to.length == 0 ) {
to = "0x4205b06c2cfa0e30359edcab94543266cb6fa1d3"; to = "0x4205b06c2cfa0e30359edcab94543266cb6fa1d3";
} else { } else {

View File

@ -0,0 +1 @@
var contract = web3.eth.contractFromAbi([{"constant":false,"inputs":[{"name":"_h","type":"hash256"}],"name":"confirm","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"execute","outputs":[{"name":"_r","type":"hash256"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"}],"name":"kill","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"}],"name":"changeOwner","outputs":[],"type":"function"},{"inputs":[{"indexed":false,"name":"value","type":"uint256"}],"name":"CashIn","type":"event"},{"inputs":[{"indexed":true,"name":"out","type":"string32"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"}],"name":"SingleTransact","type":"event"},{"inputs":[{"indexed":true,"name":"out","type":"string32"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"operation","type":"hash256"},{"indexed":false,"name":"value","type":"uint256"},{"indexed":false,"name":"to","type":"address"}],"name":"MultiTransact","type":"event"}]);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -9,14 +9,19 @@ import Ethereum 1.0
import "../ext/filter.js" as Eth import "../ext/filter.js" as Eth
import "../ext/http.js" as Http import "../ext/http.js" as Http
ApplicationWindow { ApplicationWindow {
id: root id: root
//flags: Qt.FramelessWindowHint
// Use this to make the window frameless. But then you'll need to do move and resize by hand
property var ethx : Eth.ethx property var ethx : Eth.ethx
width: 1200 width: 1200
height: 820 height: 820
minimumWidth: 300 minimumHeight: 600
minimumWidth: 800
title: "Mist" title: "Mist"
@ -33,18 +38,20 @@ ApplicationWindow {
// Takes care of loading all default plugins // Takes care of loading all default plugins
Component.onCompleted: { Component.onCompleted: {
var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true});
addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true});
var catalog = addPlugin("./views/catalog.qml", {noAdd: true, close: false, section: "begin"});
var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true});
addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true});
addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"});
addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"});
mainSplit.setView(wallet.view, wallet.menuItem); mainSplit.setView(catalog.view, catalog.menuItem);
newBrowserTab(eth.assetPath("html/home.html")); //newBrowserTab("http://ethereum-dapp-catalog.meteor.com");
// Command setup // Command setup
gui.sendCommand(0) gui.sendCommand(0)
@ -107,11 +114,36 @@ ApplicationWindow {
} }
function newBrowserTab(url) { function newBrowserTab(url) {
var urlMatches = url.toString().match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var requestedDomain = urlMatches && urlMatches[1];
var domainAlreadyOpen = false;
console.log("requested: " + requestedDomain )
for(var i = 0; i < mainSplit.views.length; i++) {
if (mainSplit.views[i].view.url) {
var matches = mainSplit.views[i].view.url.toString().match(/^[a-z]*\:\/\/(?:www\.)?([^\/?#]+)(?:[\/?#]|$)/i);
var existingDomain = matches && matches[1];
console.log("exists: " + existingDomain);
if (requestedDomain == existingDomain) {
domainAlreadyOpen = true;
mainSplit.views[i].view.url = url;
activeView(mainSplit.views[i].view, mainSplit.views[i].menuItem);
}
}
}
if (!domainAlreadyOpen) {
var window = addPlugin("./views/browser.qml", {noAdd: true, close: true, section: "apps", active: true}); var window = addPlugin("./views/browser.qml", {noAdd: true, close: true, section: "apps", active: true});
window.view.url = url; window.view.url = url;
window.menuItem.title = "Mist"; window.menuItem.title = "Mist";
activeView(window.view, window.menuItem); activeView(window.view, window.menuItem);
} }
}
menuBar: MenuBar { menuBar: MenuBar {
Menu { Menu {
@ -137,7 +169,7 @@ ApplicationWindow {
text: "New tab" text: "New tab"
shortcut: "Ctrl+t" shortcut: "Ctrl+t"
onTriggered: { onTriggered: {
newBrowserTab("about:blank"); newBrowserTab("http://etherian.io");
} }
} }
@ -245,6 +277,8 @@ ApplicationWindow {
statusBar: StatusBar { statusBar: StatusBar {
//height: 32 //height: 32
visible: false
id: statusBar id: statusBar
Label { Label {
//y: 6 //y: 6
@ -264,11 +298,10 @@ ApplicationWindow {
} }
Label { Label {
//y: 6
id: lastBlockLabel id: lastBlockLabel
objectName: "lastBlockLabel" objectName: "lastBlockLabel"
visible: true visible: true
text: "" text: "---"
font.pixelSize: 10 font.pixelSize: 10
anchors.right: peerGroup.left anchors.right: peerGroup.left
anchors.rightMargin: 5 anchors.rightMargin: 5
@ -322,7 +355,13 @@ ApplicationWindow {
id: mainSplit id: mainSplit
anchors.fill: parent anchors.fill: parent
resizing: false //resizing: false // this is NOT where we remove that damning resizing handle..
handleDelegate: Item {
//This handle is a way to remove the line between the split views
Rectangle {
anchors.fill: parent
}
}
function setView(view, menu) { function setView(view, menu) {
for(var i = 0; i < views.length; i++) { for(var i = 0; i < views.length; i++) {
@ -359,10 +398,71 @@ ApplicationWindow {
********************/ ********************/
Rectangle { Rectangle {
id: menu id: menu
Layout.minimumWidth: 210 Layout.minimumWidth: 192
Layout.maximumWidth: 210 Layout.maximumWidth: 192
FontLoader {
id: sourceSansPro
source: "fonts/SourceSansPro-Regular.ttf"
}
FontLoader {
source: "fonts/SourceSansPro-Semibold.ttf"
}
FontLoader {
source: "fonts/SourceSansPro-Bold.ttf"
}
FontLoader {
source: "fonts/SourceSansPro-Black.ttf"
}
FontLoader {
source: "fonts/SourceSansPro-Light.ttf"
}
FontLoader {
source: "fonts/SourceSansPro-ExtraLight.ttf"
}
FontLoader {
id: simpleLineIcons
source: "fonts/Simple-Line-Icons.ttf"
}
Rectangle {
color: "steelblue"
anchors.fill: parent
MouseArea {
anchors.fill: parent
property real lastMouseX: 0
property real lastMouseY: 0
onPressed: {
lastMouseX = mouseX
lastMouseY = mouseY
}
onPositionChanged: {
root.x += (mouseX - lastMouseX)
root.y += (mouseY - lastMouseY)
}
/*onDoubleClicked: {
//!maximized ? view.set_max() : view.set_normal()}
visibility = "Minimized"
}*/
}
}
anchors.top: parent.top anchors.top: parent.top
color: "#ececec" Rectangle {
width: parent.height
height: parent.width
anchors.centerIn: parent
rotation: 90
gradient: Gradient {
GradientStop { position: 0.0; color: "#E2DEDE" }
GradientStop { position: 0.1; color: "#EBE8E8" }
GradientStop { position: 1.0; color: "#EBE8E8" }
}
}
Component { Component {
id: menuItemTemplate id: menuItemTemplate
@ -377,10 +477,20 @@ ApplicationWindow {
property alias secondaryTitle: secondary.text property alias secondaryTitle: secondary.text
function setSelection(on) { function setSelection(on) {
sel.visible = on sel.visible = on
if (this.closable == true) {
closeIcon.visible = on
}
} }
width: 206 function setAsBigButton(on) {
height: 28 newAppButton.visible = on
label.visible = !on
buttonLabel.visible = on
}
width: 192
height: 55
color: "#00000000" color: "#00000000"
anchors { anchors {
@ -388,6 +498,19 @@ ApplicationWindow {
leftMargin: 4 leftMargin: 4
} }
Rectangle {
// New App Button
id: newAppButton
visible: false
anchors.fill: parent
anchors.rightMargin: 8
border.width: 0
radius: 5
height: 55
width: 180
color: "#F3F1F3"
}
Rectangle { Rectangle {
id: sel id: sel
visible: false visible: false
@ -396,10 +519,9 @@ ApplicationWindow {
Rectangle { Rectangle {
id: r id: r
anchors.fill: parent anchors.fill: parent
border.color: "#CCCCCC" border.width: 0
border.width: 1
radius: 5 radius: 5
color: "#FFFFFFFF" color: "#FAFAFA"
} }
Rectangle { Rectangle {
anchors { anchors {
@ -408,76 +530,130 @@ ApplicationWindow {
right: r.right right: r.right
} }
width: 10 width: 10
color: "#FFFFFFFF" color: "#FAFAFA"
border.width:0
Rectangle { Rectangle {
// Small line on top of selection. What's this for?
anchors { anchors {
left: parent.left left: parent.left
right: parent.right right: parent.right
top: parent.top top: parent.top
} }
height: 1 height: 1
color: "#CCCCCC" color: "#FAFAFA"
} }
Rectangle { Rectangle {
// Small line on bottom of selection. What's this for again?
anchors { anchors {
left: parent.left left: parent.left
right: parent.right right: parent.right
bottom: parent.bottom bottom: parent.bottom
} }
height: 1 height: 1
color: "#CCCCCC" color: "#FAFAFA"
} }
} }
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true
onClicked: { onClicked: {
activeView(view, menuItem); activeView(view, menuItem);
} }
onEntered: {
if (parent.closable == true) {
closeIcon.visible = sel.visible
}
}
onExited: {
closeIcon.visible = false
}
} }
Image { Image {
id: icon id: icon
height: 20 height: 24
width: 20 width: 24
anchors { anchors {
left: parent.left left: parent.left
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
leftMargin: 3 leftMargin: 6
} }
}
Text {
id: buttonLabel
visible: false
text: "GO TO NEW APP"
font.family: sourceSansPro.name
font.weight: Font.DemiBold
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "#AAA0A0"
}
Text {
id: label
font.family: sourceSansPro.name
font.weight: Font.DemiBold
anchors {
left: icon.right
verticalCenter: parent.verticalCenter
leftMargin: 6
// verticalCenterOffset: -10
}
x:250
color: "#665F5F"
font.pixelSize: 14
}
Text {
id: secondary
font.family: sourceSansPro.name
font.weight: Font.Light
anchors {
left: icon.right
leftMargin: 6
top: label.bottom
}
color: "#6691C2"
font.pixelSize: 12
}
Rectangle {
id: closeIcon
visible: false
width: 10
height: 10
color: "#FFFFFF"
anchors {
fill: icon
}
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
menuItem.closeApp() menuItem.closeApp()
} }
} }
}
Text { Text {
id: label
font.family: simpleLineIcons.name
anchors { anchors {
left: icon.right centerIn: parent
verticalCenter: parent.verticalCenter }
leftMargin: 3 color: "#665F5F"
font.pixelSize: 18
text: "\ue082"
}
} }
color: "#0D0A01"
font.pixelSize: 12
}
Text {
id: secondary
anchors {
right: parent.right
rightMargin: 8
verticalCenter: parent.verticalCenter
}
color: "#AEADBE"
font.pixelSize: 12
}
function closeApp() { function closeApp() {
@ -509,6 +685,9 @@ ApplicationWindow {
var section; var section;
switch(options.section) { switch(options.section) {
case "begin":
section = menuBegin
break;
case "ethereum": case "ethereum":
section = menuDefault; section = menuDefault;
break; break;
@ -529,6 +708,10 @@ ApplicationWindow {
} }
comp.closable = options.close; comp.closable = options.close;
if (options.section === "begin") {
comp.setAsBigButton(true)
}
return comp return comp
} }
@ -540,16 +723,34 @@ ApplicationWindow {
anchors.right: parent.right anchors.right: parent.right
spacing: 3 spacing: 3
Text {
text: "ETHEREUM"
font.bold: true ColumnLayout {
id: menuBegin
spacing: 3
anchors { anchors {
left: parent.left left: parent.left
leftMargin: 5 right: parent.right
} }
color: "#888888"
} }
Rectangle {
height: 55
color: "transparent"
Text {
text: "ETHEREUM"
font.family: sourceSansPro.name
font.weight: Font.DemiBold
anchors {
left: parent.left
top: parent.verticalCenter
leftMargin: 16
}
color: "#AAA0A0"
}
}
ColumnLayout { ColumnLayout {
id: menuDefault id: menuDefault
spacing: 3 spacing: 3
@ -559,15 +760,20 @@ ApplicationWindow {
} }
} }
Rectangle {
height: 55
color: "transparent"
Text { Text {
text: "NET" text: "APPS"
font.bold: true font.family: sourceSansPro.name
font.weight: Font.DemiBold
anchors { anchors {
left: parent.left left: parent.left
leftMargin: 5 top: parent.verticalCenter
leftMargin: 16
}
color: "#AAA0A0"
} }
color: "#888888"
} }
ColumnLayout { ColumnLayout {
@ -579,15 +785,22 @@ ApplicationWindow {
} }
} }
Rectangle {
height: 55
color: "transparent"
Text { Text {
text: "DEBUG" text: "DEBUG"
font.bold: true font.family: sourceSansPro.name
font.weight: Font.DemiBold
anchors { anchors {
left: parent.left left: parent.left
leftMargin: 5 top: parent.verticalCenter
leftMargin: 16
} }
color: "#888888" color: "#AAA0A0"
} }
}
ColumnLayout { ColumnLayout {
id: menuLegacy id: menuLegacy
@ -611,7 +824,7 @@ ApplicationWindow {
anchors.top: parent.top anchors.top: parent.top
color: "#00000000" color: "#00000000"
Rectangle { /*Rectangle {
id: urlPane id: urlPane
height: 40 height: 40
color: "#00000000" color: "#00000000"
@ -658,7 +871,7 @@ ApplicationWindow {
z: -1 z: -1
height: 1 height: 1
color: "#CCCCCC" color: "#CCCCCC"
} }*/
Rectangle { Rectangle {
id: mainView id: mainView
@ -666,7 +879,7 @@ ApplicationWindow {
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.top: divider.bottom anchors.top: parent.top
function createView(component) { function createView(component) {
var view = component.createObject(mainView) var view = component.createObject(mainView)

View File

@ -56,12 +56,34 @@ Rectangle {
//uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>"); //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>");
uriNav.text = uri; uriNav.text = uri;
} else { } else {
// Prevent inf loop. // Prevent inf loop.
window.cleanPath = false; window.cleanPath = false;
} }
} }
function showFullUrlBar(on){
if (on) {
//appTitle.visible = false
//appDomain.visible = false
//uriNav.visible = true
clickAnywhereOnApp.visible = true
navBar.state = "fullUrlVisible"
} else {
//appTitle.visible = true
//appDomain.visible = true
//uriNav.visible = false
clickAnywhereOnApp.visible = false
navBar.state = "titleVisible"
}
}
Component.onCompleted: { Component.onCompleted: {
} }
@ -71,75 +93,234 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
state: "inspectorShown" state: "inspectorShown"
MouseArea {
id: clickAnywhereOnApp
z:15
//hoverEnabled: true
anchors.fill: parent
/*hoverEnabled: true*/
onClicked: {
showFullUrlBar(false);
}
/*Rectangle {
anchors.fill: parent
color: "#88888888"
}*/
}
RowLayout { RowLayout {
id: navBar id: navBar
height: 40 height: 74
z: 20
anchors { anchors {
left: parent.left left: parent.left
right: parent.right right: parent.right
leftMargin: 7
} }
Button { Button {
id: back id: back
onClicked: { onClicked: {
webview.goBack() webview.goBack()
} }
anchors{
left: parent.left
leftMargin: 6
}
style: ButtonStyle { style: ButtonStyle {
background: Image { background: Image {
source: "../../back.png" source: "../../backButton.png"
width: 30 width: 20
height: 30 height: 30
} }
} }
} }
TextField { Rectangle {
id: appInfoPane
height: 28
color: "#FFFFFF"
radius: 6
MouseArea {
anchors.fill: parent
z: 10
hoverEnabled: true
onEntered: {
showFullUrlBar(true);
}
}
anchors { anchors {
left: back.right left: back.right
right: toggleInspector.left right: parent.right
leftMargin: 10 leftMargin: 10
rightMargin: 10 rightMargin: 10
} }
text: webview.url;
id: uriNav
y: parent.height / 2 - this.height / 2
Keys.onReturnPressed: { Text {
webview.url = this.text; id: appTitle
} text: "LOADING"
} font.bold: true
font.capitalization: Font.AllUppercase
horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
Button {
id: toggleInspector
anchors { anchors {
right: parent.right left: parent.left
} right: parent.horizontalCenter
iconSource: "../../bug.png" top: parent.top
onClicked: { bottom: parent.bottom
// XXX soon rightMargin: 10
return
if(inspector.visible == true){
inspector.visible = false
}else{
inspector.visible = true
inspector.url = webview.experimental.remoteInspectorUrl
}
}
} }
color: "#928484"
} }
// Border Text {
Rectangle { id: appDomain
id: divider text: "loading domain"
font.bold: false
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
anchors {
left: parent.horizontalCenter
right: parent.right
top: parent.top
bottom: parent.bottom
leftMargin: 10
}
color: "#C0AFAF"
}
TextField {
id: uriNav
opacity: 0.0
anchors { anchors {
left: parent.left left: parent.left
right: parent.right right: parent.right
top: navBar.bottom leftMargin: 16
}
horizontalAlignment: Text.AlignHCenter
style: TextFieldStyle {
textColor: "#928484"
background: Rectangle {
border.width: 0
color: "transparent"
}
}
text: webview.url;
y: parent.height / 2 - this.height / 2
z: 20
activeFocusOnPress: true
Keys.onReturnPressed: {
webview.url = this.text;
}
/* onFocusedChanged: {
if (focused) {
//uriNav.selectAll();
}
}*/
}
z:2
}
Rectangle {
id: appInfoPaneShadow
width: 10
height: 30
color: "#BDB6B6"
radius: 6
anchors {
left: back.right
right: parent.right
leftMargin:10
rightMargin:10
top: parent.top
topMargin: 23
}
z:1
}
Rectangle {
id: navBarBackground
anchors.fill: parent
gradient: Gradient {
GradientStop { position: 0.0; color: "#F6F1F2" }
GradientStop { position: 1.0; color: "#DED5D5" }
} }
z:-1 z:-1
height: 1 }
color: "#CCCCCC"
states: [
State {
name: "fullUrlVisible"
PropertyChanges {
target: appTitle
anchors.rightMargin: -50
opacity: 0.0
}
PropertyChanges {
target: appDomain
anchors.leftMargin: -50
opacity: 0.0
}
PropertyChanges {
target: uriNav
anchors.leftMargin: 0
opacity: 1.0
}
},
State {
name: "titleVisible"
PropertyChanges {
target: appTitle
anchors.rightMargin: 10
opacity: 1.0
}
PropertyChanges {
target: appDomain
anchors.leftMargin: 10
opacity: 1.0
}
PropertyChanges {
target: uriNav
anchors.leftMargin: -50
opacity: 0.0
}
}
]
transitions: [
// This adds a transition that defaults to applying to all state changes
Transition {
// This applies a default NumberAnimation to any changes a state change makes to x or y properties
NumberAnimation {
properties: "anchors.leftMargin, anchors.rightMargin, opacity"
easing.type: Easing.InOutQuad //Easing.InOutBack
duration: 300
}
}
]
} }
WebEngineView { WebEngineView {
@ -149,16 +330,51 @@ Rectangle {
left: parent.left left: parent.left
right: parent.right right: parent.right
bottom: parent.bottom bottom: parent.bottom
top: divider.bottom top: navBar.bottom
} }
z: 10
onLoadingChanged: { onLoadingChanged: {
if (loadRequest.status == WebEngineView.LoadSucceededStatus) { if (loadRequest.status == WebEngineView.LoadSucceededStatus) {
webview.runJavaScript("document.title", function(pageTitle) { webview.runJavaScript("document.title", function(pageTitle) {
menuItem.title = pageTitle; menuItem.title = pageTitle;
}); });
//var topBarStyle
webView.runJavaScript("document.querySelector(\"meta[name='ethereum-dapp-url-bar-style']\").getAttribute(\"content\")", function(topBarStyle){
if (topBarStyle=="transparent") {
// Adjust for a transparent sidebar Dapp
navBarBackground.visible = false;
back.visible = false;
appInfoPane.anchors.leftMargin = -16;
appInfoPaneShadow.anchors.leftMargin = -16;
webview.anchors.topMargin = -74;
webview.runJavaScript("document.querySelector('body').classList.add('ethereum-dapp-url-bar-style-transparent')")
} else {
navBarBackground.visible = true;
back.visible = true;
appInfoPane.anchors.leftMargin = 0;
appInfoPaneShadow.anchors.leftMargin = 0;
webview.anchors.topMargin = 0;
};
});
webview.runJavaScript(eth.readFile("bignumber.min.js")); webview.runJavaScript(eth.readFile("bignumber.min.js"));
webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js")); webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js"));
var cleanTitle = webview.url.toString()
var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];
appDomain.text = domain //webview.url.replace("a", "z")
appTitle.text = webview.title
showFullUrlBar(false);
} }
} }
onJavaScriptConsoleMessage: { onJavaScriptConsoleMessage: {
@ -208,4 +424,3 @@ Rectangle {
] ]
} }
} }

View File

@ -0,0 +1,155 @@
import QtQuick 2.0
import QtQuick.Controls 1.0;
import QtQuick.Controls.Styles 1.0
import QtQuick.Layouts 1.0;
import QtWebEngine 1.0
//import QtWebEngine.experimental 1.0
import QtQuick.Window 2.0;
Rectangle {
id: window
anchors.fill: parent
color: "#00000000"
property var title: "Catalog"
property var iconSource: ""
property var menuItem
property var hideUrl: true
property alias url: webview.url
property alias windowTitle: webview.title
property alias webView: webview
property var cleanPath: false
property var open: function(url) {
if(!window.cleanPath) {
var uri = url;
if(!/.*\:\/\/.*/.test(uri)) {
uri = "http://" + uri;
}
var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/
if(reg.test(uri)) {
uri.replace(reg, function(match, pre, domain, path) {
uri = pre;
var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4));
var ip = [];
for(var i = 0, l = lookup.length; i < l; i++) {
ip.push(lookup.charCodeAt(i))
}
if(ip.length != 0) {
uri += lookup;
} else {
uri += domain;
}
uri += path;
});
}
window.cleanPath = true;
webview.url = uri;
//uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2<span style='color:#CCC'>$3</span>");
uriNav.text = uri;
} else {
// Prevent inf loop.
window.cleanPath = false;
}
}
Component.onCompleted: {
}
Item {
objectName: "root"
id: root
anchors.fill: parent
state: "inspectorShown"
WebEngineView {
objectName: "webView"
id: webview
anchors.fill: parent
property var protocol: "http://"
//property var domain: "localhost:3000"
property var domain: "ethereum-dapp-catalog.meteor.com"
url: protocol + domain
//navigationRequest: WebEngineView.IgnoreRequest
// onLoadingChanged: {
// if (loadRequest.status == WebEngineView.LoadSucceededStatus) {
// webview.runJavaScript(eth.readFile("bignumber.min.js"));
// webview.runJavaScript(eth.readFile("ethereum.js/dist/ethereum.js"));
// }
// }
//onNavigationRequested: {
// detect URL scheme prefix, most likely an external link
//var schemaRE = /^\w+:/;
//if (schemaRE.test(request.url)) {
// request.action = WebView.AcceptRequest;
//} else {
//request.action = WebView.IgnoreRequest;
// delegate request.url here
//}
//}
onJavaScriptConsoleMessage: {
console.log(sourceID + ":" + lineNumber + ":" + JSON.stringify(message));
}
onNavigationRequested: {
var cleanTitle = request.url.toString()
var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var requestedDomain = matches && matches[1];
console.debug ("NavigationRequested: " + request.url + " navigationType=" + request.navigationType)
if(request.navigationType==0){
if (requestedDomain === this.domain){
request.action = WebEngineView.AcceptRequest;
} else {
request.action = WebEngineView.IgnoreRequest;
newBrowserTab(request.url);
}
}
}
}
WebEngineView {
id: inspector
visible: false
z:10
anchors {
left: root.left
right: root.right
top: sizeGrip.bottom
bottom: root.bottom
}
}
states: [
State {
name: "inspectorShown"
PropertyChanges {
target: inspector
}
}
]
}
}

View File

@ -8,11 +8,9 @@ import (
"time" "time"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/pow" "github.com/ethereum/go-ethereum/pow"
"github.com/ethereum/go-ethereum/pow/ezp" "github.com/ethereum/go-ethereum/pow/ezp"
"github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/state"
@ -25,20 +23,6 @@ type PendingBlockEvent struct {
var statelogger = logger.NewLogger("BLOCK") var statelogger = logger.NewLogger("BLOCK")
type EthManager interface {
BlockProcessor() *BlockProcessor
ChainManager() *ChainManager
TxPool() *TxPool
PeerCount() int
IsMining() bool
IsListening() bool
Peers() []*p2p.Peer
KeyManager() *crypto.KeyManager
ClientIdentity() p2p.ClientIdentity
Db() ethutil.Database
EventMux() *event.TypeMux
}
type BlockProcessor struct { type BlockProcessor struct {
db ethutil.Database db ethutil.Database
// Mutex for locking the block processor. Blocks can only be handled one at a time // Mutex for locking the block processor. Blocks can only be handled one at a time
@ -160,6 +144,9 @@ func (self *BlockProcessor) ApplyTransactions(coinbase *state.StateObject, state
return receipts, handled, unhandled, erroneous, err return receipts, handled, unhandled, erroneous, err
} }
// Process block will attempt to process the given block's transactions and applies them
// on top of the block's parent state (given it exists) and will return wether it was
// successful or not.
func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) { func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) {
// Processing a blocks may never happen simultaneously // Processing a blocks may never happen simultaneously
sm.mutex.Lock() sm.mutex.Lock()
@ -175,14 +162,14 @@ func (sm *BlockProcessor) Process(block *types.Block) (td *big.Int, err error) {
} }
parent := sm.bc.GetBlock(header.ParentHash) parent := sm.bc.GetBlock(header.ParentHash)
return sm.ProcessWithParent(block, parent) return sm.processWithParent(block, parent)
} }
func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big.Int, err error) { func (sm *BlockProcessor) processWithParent(block, parent *types.Block) (td *big.Int, err error) {
sm.lastAttemptedBlock = block sm.lastAttemptedBlock = block
// Create a new state based on the parent's root (e.g., create copy)
state := state.New(parent.Root(), sm.db) state := state.New(parent.Root(), sm.db)
//state := state.New(parent.Trie().Copy())
// Block validation // Block validation
if err = sm.ValidateBlock(block, parent); err != nil { if err = sm.ValidateBlock(block, parent); err != nil {
@ -196,18 +183,23 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
header := block.Header() header := block.Header()
// Validate the received block's bloom with the one derived from the generated receipts.
// For valid blocks this should always validate to true.
rbloom := types.CreateBloom(receipts) rbloom := types.CreateBloom(receipts)
if bytes.Compare(rbloom, header.Bloom) != 0 { if bytes.Compare(rbloom, header.Bloom) != 0 {
err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom) err = fmt.Errorf("unable to replicate block's bloom=%x", rbloom)
return return
} }
// The transactions Trie's root (R = (Tr [[H1, T1], [H2, T2], ... [Hn, Tn]]))
// can be used by light clients to make sure they've received the correct Txs
txSha := types.DeriveSha(block.Transactions()) txSha := types.DeriveSha(block.Transactions())
if bytes.Compare(txSha, header.TxHash) != 0 { if bytes.Compare(txSha, header.TxHash) != 0 {
err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha) err = fmt.Errorf("validating transaction root. received=%x got=%x", header.TxHash, txSha)
return return
} }
// Tre receipt Trie's root (R = (Tr [[H1, R1], ... [Hn, R1]]))
receiptSha := types.DeriveSha(receipts) receiptSha := types.DeriveSha(receipts)
if bytes.Compare(receiptSha, header.ReceiptHash) != 0 { if bytes.Compare(receiptSha, header.ReceiptHash) != 0 {
fmt.Println("receipts", receipts) fmt.Println("receipts", receipts)
@ -215,12 +207,14 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
return return
} }
// Accumulate static rewards; block reward, uncle's and uncle inclusion.
if err = sm.AccumulateRewards(state, block, parent); err != nil { if err = sm.AccumulateRewards(state, block, parent); err != nil {
return return
} }
// Commit state objects/accounts to a temporary trie (does not save)
// used to calculate the state root.
state.Update(ethutil.Big0) state.Update(ethutil.Big0)
if !bytes.Equal(header.Root, state.Root()) { if !bytes.Equal(header.Root, state.Root()) {
err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root()) err = fmt.Errorf("invalid merkle root. received=%x got=%x", header.Root, state.Root())
return return
@ -230,10 +224,6 @@ func (sm *BlockProcessor) ProcessWithParent(block, parent *types.Block) (td *big
td = CalculateTD(block, parent) td = CalculateTD(block, parent)
// Sync the current block's state to the database // Sync the current block's state to the database
state.Sync() state.Sync()
// Set the block hashes for the current messages
state.Manifest().SetHash(block.Hash())
// Reset the manifest XXX We need this?
state.Manifest().Reset()
// Remove transactions from the pool // Remove transactions from the pool
sm.txpool.RemoveSet(block.Transactions()) sm.txpool.RemoveSet(block.Transactions())
@ -313,27 +303,6 @@ func (sm *BlockProcessor) AccumulateRewards(statedb *state.StateDB, block, paren
return nil return nil
} }
func (sm *BlockProcessor) GetMessages(block *types.Block) (messages []*state.Message, err error) {
if !sm.bc.HasBlock(block.Header().ParentHash) {
return nil, ParentError(block.Header().ParentHash)
}
sm.lastAttemptedBlock = block
var (
parent = sm.bc.GetBlock(block.Header().ParentHash)
//state = state.New(parent.Trie().Copy())
state = state.New(parent.Root(), sm.db)
)
defer state.Reset()
sm.TransitionState(state, parent, block)
sm.AccumulateRewards(state, block, parent)
return state.Manifest().Messages, nil
}
func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) { func (sm *BlockProcessor) GetLogs(block *types.Block) (logs state.Logs, err error) {
if !sm.bc.HasBlock(block.Header().ParentHash) { if !sm.bc.HasBlock(block.Header().ParentHash) {
return nil, ParentError(block.Header().ParentHash) return nil, ParentError(block.Header().ParentHash)

22
core/manager.go Normal file
View File

@ -0,0 +1,22 @@
package core
import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/p2p"
)
type EthManager interface {
BlockProcessor() *BlockProcessor
ChainManager() *ChainManager
TxPool() *TxPool
PeerCount() int
IsMining() bool
IsListening() bool
Peers() []*p2p.Peer
KeyManager() *crypto.KeyManager
ClientIdentity() p2p.ClientIdentity
Db() ethutil.Database
EventMux() *event.TypeMux
}

View File

@ -613,6 +613,7 @@ func TestInvalidBlock(t *testing.T) {
} }
func TestVerifyPoW(t *testing.T) { func TestVerifyPoW(t *testing.T) {
t.Skip("***FIX*** This test is broken")
logInit() logInit()
_, blockPool, blockPoolTester := newTestBlockPool(t) _, blockPool, blockPoolTester := newTestBlockPool(t)
blockPoolTester.blockChain[0] = nil blockPoolTester.blockChain[0] = nil

View File

@ -32,6 +32,48 @@ type Encoder interface {
EncodeRLP(io.Writer) error EncodeRLP(io.Writer) error
} }
// Flat wraps a value (which must encode as a list) so
// it encodes as the list's elements.
//
// Example: suppose you have defined a type
//
// type foo struct { A, B uint }
//
// Under normal encoding rules,
//
// rlp.Encode(foo{1, 2}) --> 0xC20102
//
// This function can help you achieve the following encoding:
//
// rlp.Encode(rlp.Flat(foo{1, 2})) --> 0x0102
func Flat(val interface{}) Encoder {
return flatenc{val}
}
type flatenc struct{ val interface{} }
func (e flatenc) EncodeRLP(out io.Writer) error {
// record current output position
var (
eb = out.(*encbuf)
prevstrsize = len(eb.str)
prevnheads = len(eb.lheads)
)
if err := eb.encode(e.val); err != nil {
return err
}
// check that a new list header has appeared
if len(eb.lheads) == prevnheads || eb.lheads[prevnheads].offset == prevstrsize-1 {
return fmt.Errorf("rlp.Flat: %T did not encode as list", e.val)
}
// remove the new list header
newhead := eb.lheads[prevnheads]
copy(eb.lheads[prevnheads:], eb.lheads[prevnheads+1:])
eb.lheads = eb.lheads[:len(eb.lheads)-1]
eb.lhsize -= newhead.tagsize()
return nil
}
// Encode writes the RLP encoding of val to w. Note that Encode may // Encode writes the RLP encoding of val to w. Note that Encode may
// perform many small writes in some cases. Consider making w // perform many small writes in some cases. Consider making w
// buffered. // buffered.
@ -123,6 +165,13 @@ func (head *listhead) encode(buf []byte) []byte {
} }
} }
func (head *listhead) tagsize() int {
if head.size < 56 {
return 1
}
return 1 + intsize(uint64(head.size))
}
func newencbuf() *encbuf { func newencbuf() *encbuf {
return &encbuf{sizebuf: make([]byte, 9)} return &encbuf{sizebuf: make([]byte, 9)}
} }

View File

@ -177,6 +177,15 @@ var encTests = []encTest{
{val: &recstruct{5, nil}, output: "C205C0"}, {val: &recstruct{5, nil}, output: "C205C0"},
{val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"}, {val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"},
// flat
{val: Flat(uint(1)), error: "rlp.Flat: uint did not encode as list"},
{val: Flat(simplestruct{A: 3, B: "foo"}), output: "0383666F6F"},
{
// value generates more list headers after the Flat
val: []interface{}{"foo", []uint{1, 2}, Flat([]uint{3, 4}), []uint{5, 6}, "bar"},
output: "D083666F6FC201020304C2050683626172",
},
// nil // nil
{val: (*uint)(nil), output: "80"}, {val: (*uint)(nil), output: "80"},
{val: (*string)(nil), output: "80"}, {val: (*string)(nil), output: "80"},

View File

@ -102,7 +102,7 @@ func (s *RpcHttpServer) apiHandler(api *rpc.EthereumApi) http.Handler {
if reserr != nil { if reserr != nil {
rpchttplogger.Warnln(reserr) rpchttplogger.Warnln(reserr)
jsonerr := &rpc.RpcErrorObject{-32603, reserr.Error()} jsonerr := &rpc.RpcErrorObject{-32603, reserr.Error()}
JSON.Send(w, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: &reqParsed.ID, Error: jsonerr}) JSON.Send(w, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr})
return return
} }

View File

@ -34,20 +34,20 @@ const (
) )
type RpcRequest struct { type RpcRequest struct {
ID interface{} `json:"id"`
JsonRpc string `json:"jsonrpc"` JsonRpc string `json:"jsonrpc"`
ID int `json:"id"`
Method string `json:"method"` Method string `json:"method"`
Params []json.RawMessage `json:"params"` Params []json.RawMessage `json:"params"`
} }
type RpcSuccessResponse struct { type RpcSuccessResponse struct {
ID int `json:"id"` ID interface{} `json:"id"`
JsonRpc string `json:"jsonrpc"` JsonRpc string `json:"jsonrpc"`
Result interface{} `json:"result"` Result interface{} `json:"result"`
} }
type RpcErrorResponse struct { type RpcErrorResponse struct {
ID *int `json:"id"` ID interface{} `json:"id"`
JsonRpc string `json:"jsonrpc"` JsonRpc string `json:"jsonrpc"`
Error *RpcErrorObject `json:"error"` Error *RpcErrorObject `json:"error"`
} }

View File

@ -47,7 +47,6 @@ func (self JsonWrapper) ParseRequestBody(req *http.Request) (RpcRequest, error)
// Convert JSON to native types // Convert JSON to native types
d := json.NewDecoder(req.Body) d := json.NewDecoder(req.Body)
// d.UseNumber()
defer req.Body.Close() defer req.Body.Close()
err := d.Decode(&reqParsed) err := d.Decode(&reqParsed)
@ -55,6 +54,7 @@ func (self JsonWrapper) ParseRequestBody(req *http.Request) (RpcRequest, error)
rpclogger.Errorln("Error decoding JSON: ", err) rpclogger.Errorln("Error decoding JSON: ", err)
return reqParsed, err return reqParsed, err
} }
rpclogger.DebugDetailf("Parsed request: %s", reqParsed) rpclogger.DebugDetailf("Parsed request: %s", reqParsed)
return reqParsed, nil return reqParsed, nil

View File

@ -94,9 +94,10 @@ func sockHandler(api *rpc.EthereumApi) websocket.Handler {
var jsonrpcver string = "2.0" var jsonrpcver string = "2.0"
fn := func(conn *websocket.Conn) { fn := func(conn *websocket.Conn) {
for { for {
wslogger.Debugln("Handling request") wslogger.Debugln("Handling connection")
var reqParsed rpc.RpcRequest var reqParsed rpc.RpcRequest
// reqParsed, reqerr := JSON.ParseRequestBody(conn.Request())
if err := websocket.JSON.Receive(conn, &reqParsed); err != nil { if err := websocket.JSON.Receive(conn, &reqParsed); err != nil {
jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest} jsonerr := &rpc.RpcErrorObject{-32700, rpc.ErrorParseRequest}
JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr}) JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: nil, Error: jsonerr})
@ -108,7 +109,7 @@ func sockHandler(api *rpc.EthereumApi) websocket.Handler {
if reserr != nil { if reserr != nil {
wslogger.Warnln(reserr) wslogger.Warnln(reserr)
jsonerr := &rpc.RpcErrorObject{-32603, reserr.Error()} jsonerr := &rpc.RpcErrorObject{-32603, reserr.Error()}
JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: &reqParsed.ID, Error: jsonerr}) JSON.Send(conn, &rpc.RpcErrorResponse{JsonRpc: jsonrpcver, ID: reqParsed.ID, Error: jsonerr})
continue continue
} }

View File

@ -1,61 +0,0 @@
package state
import (
"fmt"
"math/big"
)
// Object manifest
//
// The object manifest is used to keep changes to the state so we can keep track of the changes
// that occurred during a state transitioning phase.
type Manifest struct {
Messages Messages
}
func NewManifest() *Manifest {
m := &Manifest{}
m.Reset()
return m
}
func (m *Manifest) Reset() {
m.Messages = nil
}
func (self *Manifest) AddMessage(msg *Message) *Message {
self.Messages = append(self.Messages, msg)
return msg
}
func (self *Manifest) SetHash(hash []byte) {
for _, message := range self.Messages {
message.Block = hash
}
}
type Messages []*Message
type Message struct {
To, From []byte
Input []byte
Output []byte
Path int
Origin []byte
Timestamp int64
Coinbase []byte
Block []byte
Number *big.Int
Value *big.Int
ChangedAddresses [][]byte
}
func (self *Message) AddStorageChange(addr []byte) {
self.ChangedAddresses = append(self.ChangedAddresses, addr)
}
func (self *Message) String() string {
return fmt.Sprintf("Message{to: %x from: %x input: %x output: %x origin: %x coinbase: %x block: %x number: %v timestamp: %d path: %d value: %v", self.To, self.From, self.Input, self.Output, self.Origin, self.Coinbase, self.Block, self.Number, self.Timestamp, self.Path, self.Value)
}

View File

@ -22,8 +22,6 @@ type StateDB struct {
stateObjects map[string]*StateObject stateObjects map[string]*StateObject
manifest *Manifest
refund map[string]*big.Int refund map[string]*big.Int
logs Logs logs Logs
@ -32,7 +30,7 @@ type StateDB struct {
// Create a new state from a given trie // Create a new state from a given trie
func New(root []byte, db ethutil.Database) *StateDB { func New(root []byte, db ethutil.Database) *StateDB {
trie := trie.New(ethutil.CopyBytes(root), db) trie := trie.New(ethutil.CopyBytes(root), db)
return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), manifest: NewManifest(), refund: make(map[string]*big.Int)} return &StateDB{db: db, trie: trie, stateObjects: make(map[string]*StateObject), refund: make(map[string]*big.Int)}
} }
func (self *StateDB) EmptyLogs() { func (self *StateDB) EmptyLogs() {
@ -47,6 +45,13 @@ func (self *StateDB) Logs() Logs {
return self.logs return self.logs
} }
func (self *StateDB) Refund(addr []byte, gas *big.Int) {
if self.refund[string(addr)] == nil {
self.refund[string(addr)] = new(big.Int)
}
self.refund[string(addr)].Add(self.refund[string(addr)], gas)
}
// Retrieve the balance from the given address or 0 if object not found // Retrieve the balance from the given address or 0 if object not found
func (self *StateDB) GetBalance(addr []byte) *big.Int { func (self *StateDB) GetBalance(addr []byte) *big.Int {
stateObject := self.GetStateObject(addr) stateObject := self.GetStateObject(addr)
@ -57,13 +62,6 @@ func (self *StateDB) GetBalance(addr []byte) *big.Int {
return ethutil.Big0 return ethutil.Big0
} }
func (self *StateDB) Refund(addr []byte, gas *big.Int) {
if self.refund[string(addr)] == nil {
self.refund[string(addr)] = new(big.Int)
}
self.refund[string(addr)].Add(self.refund[string(addr)], gas)
}
func (self *StateDB) AddBalance(addr []byte, amount *big.Int) { func (self *StateDB) AddBalance(addr []byte, amount *big.Int) {
stateObject := self.GetStateObject(addr) stateObject := self.GetStateObject(addr)
if stateObject != nil { if stateObject != nil {
@ -103,6 +101,7 @@ func (self *StateDB) SetCode(addr, code []byte) {
} }
} }
// TODO vars
func (self *StateDB) GetState(a, b []byte) []byte { func (self *StateDB) GetState(a, b []byte) []byte {
stateObject := self.GetStateObject(a) stateObject := self.GetStateObject(a)
if stateObject != nil { if stateObject != nil {
@ -212,7 +211,6 @@ func (s *StateDB) Cmp(other *StateDB) bool {
} }
func (self *StateDB) Copy() *StateDB { func (self *StateDB) Copy() *StateDB {
if self.trie != nil {
state := New(nil, self.db) state := New(nil, self.db)
state.trie = self.trie.Copy() state.trie = self.trie.Copy()
for k, stateObject := range self.stateObjects { for k, stateObject := range self.stateObjects {
@ -230,9 +228,6 @@ func (self *StateDB) Copy() *StateDB {
return state return state
} }
return nil
}
func (self *StateDB) Set(state *StateDB) { func (self *StateDB) Set(state *StateDB) {
self.trie = state.trie self.trie = state.trie
self.stateObjects = state.stateObjects self.stateObjects = state.stateObjects
@ -301,10 +296,6 @@ func (self *StateDB) Update(gasUsed *big.Int) {
} }
} }
func (self *StateDB) Manifest() *Manifest {
return self.manifest
}
// Debug stuff // Debug stuff
func (self *StateDB) CreateOutputForDiff() { func (self *StateDB) CreateOutputForDiff() {
for _, stateObject := range self.stateObjects { for _, stateObject := range self.stateObjects {

View File

@ -38,13 +38,6 @@ func New(env Environment) *Vm {
func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) { func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) {
self.env.SetDepth(self.env.Depth() + 1) self.env.SetDepth(self.env.Depth() + 1)
msg := self.env.State().Manifest().AddMessage(&state.Message{
To: me.Address(), From: caller.Address(),
Input: callData,
Origin: self.env.Origin(),
Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(),
Value: value,
})
context := NewContext(caller, me, code, gas, price) context := NewContext(caller, me, code, gas, price)
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData) vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData)
@ -618,8 +611,6 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
val, loc := stack.Popn() val, loc := stack.Popn()
statedb.SetState(context.Address(), loc.Bytes(), val) statedb.SetState(context.Address(), loc.Bytes(), val)
msg.AddStorageChange(loc.Bytes())
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
case JUMP: case JUMP:
jump(pc, stack.Pop()) jump(pc, stack.Pop())
@ -670,7 +661,6 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
dataGas.Mul(dataGas, GasCreateByte) dataGas.Mul(dataGas, GasCreateByte)
if context.UseGas(dataGas) { if context.UseGas(dataGas) {
ref.SetCode(ret) ref.SetCode(ret)
msg.Output = ret
} }
addr = ref.Address() addr = ref.Address()
@ -713,7 +703,6 @@ func (self *Vm) Run(me, caller ContextRef, code []byte, value, gas, price *big.I
vmlogger.Debugln(err) vmlogger.Debugln(err)
} else { } else {
stack.Push(ethutil.BigTrue) stack.Push(ethutil.BigTrue)
msg.Output = ret
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret) mem.Set(retOffset.Uint64(), retSize.Uint64(), ret)
} }

View File

@ -12,6 +12,8 @@ type Message struct {
Signature []byte Signature []byte
Payload []byte Payload []byte
Sent int64 Sent int64
To *ecdsa.PublicKey
} }
func NewMessage(payload []byte) *Message { func NewMessage(payload []byte) *Message {

View File

@ -256,6 +256,8 @@ func (self *Whisper) postEvent(envelope *Envelope) {
func (self *Whisper) open(envelope *Envelope) (*Message, *ecdsa.PrivateKey) { func (self *Whisper) open(envelope *Envelope) (*Message, *ecdsa.PrivateKey) {
for _, key := range self.keys { for _, key := range self.keys {
if message, err := envelope.Open(key); err == nil || (err != nil && err == ecies.ErrInvalidPublicKey) { if message, err := envelope.Open(key); err == nil || (err != nil && err == ecies.ErrInvalidPublicKey) {
message.To = &key.PublicKey
return message, key return message, key
} }
} }

View File

@ -99,8 +99,9 @@ type Options struct {
type WhisperMessage struct { type WhisperMessage struct {
ref *whisper.Message ref *whisper.Message
Payload string `json:"payload"` Payload string `json:"payload"`
To string `json:"to"`
From string `json:"from"` From string `json:"from"`
Sent int64 `json:"time"` Sent int64 `json:"sent"`
} }
func NewWhisperMessage(msg *whisper.Message) WhisperMessage { func NewWhisperMessage(msg *whisper.Message) WhisperMessage {
@ -108,6 +109,7 @@ func NewWhisperMessage(msg *whisper.Message) WhisperMessage {
ref: msg, ref: msg,
Payload: toHex(msg.Payload), Payload: toHex(msg.Payload),
From: toHex(crypto.FromECDSAPub(msg.Recover())), From: toHex(crypto.FromECDSAPub(msg.Recover())),
To: toHex(crypto.FromECDSAPub(msg.To)),
Sent: msg.Sent, Sent: msg.Sent,
} }
} }