mirror of https://github.com/status-im/op-geth.git
Merge branch 'develop' into miner
This commit is contained in:
commit
b64ad7a2a6
|
@ -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
|
||||||
|
|
|
@ -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/...
|
||||||
|
|
|
@ -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 |
|
@ -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 {
|
||||||
|
|
|
@ -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.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -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 {
|
||||||
anchors {
|
id: appInfoPane
|
||||||
|
height: 28
|
||||||
|
color: "#FFFFFF"
|
||||||
|
radius: 6
|
||||||
|
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
z: 10
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
|
onEntered: {
|
||||||
|
showFullUrlBar(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.horizontalCenter
|
||||||
|
top: parent.top
|
||||||
|
bottom: parent.bottom
|
||||||
|
rightMargin: 10
|
||||||
|
}
|
||||||
|
color: "#928484"
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: appDomain
|
||||||
|
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 {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
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
|
||||||
|
|
||||||
Button {
|
anchors {
|
||||||
id: toggleInspector
|
left: back.right
|
||||||
anchors {
|
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
leftMargin:10
|
||||||
|
rightMargin:10
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 23
|
||||||
}
|
}
|
||||||
iconSource: "../../bug.png"
|
|
||||||
onClicked: {
|
|
||||||
// XXX soon
|
|
||||||
return
|
|
||||||
if(inspector.visible == true){
|
|
||||||
inspector.visible = false
|
|
||||||
}else{
|
|
||||||
inspector.visible = true
|
|
||||||
inspector.url = webview.experimental.remoteInspectorUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Border
|
z:1
|
||||||
Rectangle {
|
|
||||||
id: divider
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
top: navBar.bottom
|
|
||||||
}
|
}
|
||||||
z: -1
|
|
||||||
height: 1
|
Rectangle {
|
||||||
color: "#CCCCCC"
|
id: navBarBackground
|
||||||
|
anchors.fill: parent
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop { position: 0.0; color: "#F6F1F2" }
|
||||||
|
GradientStop { position: 1.0; color: "#DED5D5" }
|
||||||
|
}
|
||||||
|
z:-1
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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)}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"},
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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,25 +211,21 @@ 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 {
|
state.stateObjects[k] = stateObject.Copy()
|
||||||
state.stateObjects[k] = stateObject.Copy()
|
|
||||||
}
|
|
||||||
|
|
||||||
for addr, refund := range self.refund {
|
|
||||||
state.refund[addr] = new(big.Int).Set(refund)
|
|
||||||
}
|
|
||||||
|
|
||||||
logs := make(Logs, len(self.logs))
|
|
||||||
copy(logs, self.logs)
|
|
||||||
state.logs = logs
|
|
||||||
|
|
||||||
return state
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
for addr, refund := range self.refund {
|
||||||
|
state.refund[addr] = new(big.Int).Set(refund)
|
||||||
|
}
|
||||||
|
|
||||||
|
logs := make(Logs, len(self.logs))
|
||||||
|
copy(logs, self.logs)
|
||||||
|
state.logs = logs
|
||||||
|
|
||||||
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateDB) Set(state *StateDB) {
|
func (self *StateDB) Set(state *StateDB) {
|
||||||
|
@ -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 {
|
||||||
|
|
11
vm/vm.go
11
vm/vm.go
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue