diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml
index 0cda6f3e3..55bbc14f9 100644
--- a/.github/workflows/docker-build.yaml
+++ b/.github/workflows/docker-build.yaml
@@ -5,21 +5,20 @@ on:
tags:
- v*
push:
- branches: [ netmarble_v1.0 ]
+ branches: [ netmarble_v1.0, netmarble_v2.0 ]
pull_request:
- branches: [ netmarble_v1.0 ]
+ branches: [ netmarble_v1.0, netmarble_v2.0 ]
env:
REGION: us-east-1
ECR_REGISTRY_ID: 553885929720
- AWS_ASSUMED_ROLE_ARN: arn:aws:iam::553885929720:role/tf_nodereal_prod_ecr_cicd_deployment_assume_role
# Notice: must modify here to fit your service config path
GIT_SYNC_PATH: qa/gitops/qa-us/demo-app/values.yaml
TAG_FIELD: .image.tag
jobs:
CI:
- runs-on: [self-hosted,qa-infra-k8s]
+ runs-on: [self-hosted,prod-cicd-runners]
steps:
- uses: actions/checkout@v3
# - uses: actions/setup-go@v3
@@ -30,25 +29,14 @@ jobs:
# with:
# # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
# version: v1.45.2
- - name: aws assume role
- id: aws-assume-role
- run: |
- UUID=$(cat /proc/sys/kernel/random/uuid)
- OUT=$(aws sts assume-role --role-arn $AWS_ASSUMED_ROLE_ARN --role-session-name $UUID)
- echo ::set-output name=aws_access_key_id::"$(echo $OUT | jq -r '.Credentials''.AccessKeyId')"
- echo ::set-output name=aws_secret_key::"$(echo $OUT | jq -r '.Credentials''.SecretAccessKey')"
- echo ::set-output name=aws_sessions_token::"$(echo $OUT | jq -r '.Credentials''.SessionToken')"
- name: Build, tag, and push image to Amazon ECR
- env:
- AWS_ACCESS_KEY_ID: ${{ steps.aws-assume-role.outputs.aws_access_key_id }}
- AWS_SECRET_ACCESS_KEY: ${{ steps.aws-assume-role.outputs.aws_secret_key }}
- AWS_SESSION_TOKEN: ${{ steps.aws-assume-role.outputs.aws_sessions_token }}
run: |
aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ECR_REGISTRY_ID}.dkr.ecr.${REGION}.amazonaws.com
- aws ecr --region $REGION describe-repositories --registry-id $ECR_REGISTRY_ID --repository-names ${GITHUB_REPOSITORY#*/} || aws ecr --region $REGION create-repository --registry-id $ECR_REGISTRY_ID --repository-name ${GITHUB_REPOSITORY#*/}
- aws ecr --region $REGION set-repository-policy --registry-id $ECR_REGISTRY_ID --repository-name ${GITHUB_REPOSITORY#*/} --policy-text file:///home/runner/repo-access-permissions.json
docker build -t ${ECR_REGISTRY_ID}.dkr.ecr.${REGION}.amazonaws.com/${GITHUB_REPOSITORY#*/}:${GITHUB_SHA} .
docker push ${ECR_REGISTRY_ID}.dkr.ecr.${REGION}.amazonaws.com/${GITHUB_REPOSITORY#*/}:${GITHUB_SHA}
+
+ docker build -t ${ECR_REGISTRY_ID}.dkr.ecr.${REGION}.amazonaws.com/faucet:${GITHUB_SHA} -f Dockerfile.alltools .
+ docker push ${ECR_REGISTRY_ID}.dkr.ecr.${REGION}.amazonaws.com/faucet:${GITHUB_SHA}
# CD:
# needs: [CI]
# runs-on: [self-hosted,qa-infra-k8s]
diff --git a/cmd/faucet/faucet.html b/cmd/faucet/faucet.html
index 950f811f7..264129a49 100644
--- a/cmd/faucet/faucet.html
+++ b/cmd/faucet/faucet.html
@@ -5,6 +5,7 @@
+
{{.Network}}: Faucet
diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go
index 25e51051e..3bf97349c 100644
--- a/cmd/faucet/website.go
+++ b/cmd/faucet/website.go
@@ -1,13 +1,11 @@
-// Code generated by go-bindata. DO NOT EDIT.
+// Code generated for package main by go-bindata DO NOT EDIT. (@generated)
// sources:
-// faucet.html (9.01kB)
-
+// faucet.html
package main
import (
"bytes"
"compress/gzip"
- "crypto/sha256"
"fmt"
"io"
"io/ioutil"
@@ -20,7 +18,7 @@ import (
func bindataRead(data []byte, name string) ([]byte, error) {
gz, err := gzip.NewReader(bytes.NewBuffer(data))
if err != nil {
- return nil, fmt.Errorf("read %q: %w", name, err)
+ return nil, fmt.Errorf("Read %q: %v", name, err)
}
var buf bytes.Buffer
@@ -28,7 +26,7 @@ func bindataRead(data []byte, name string) ([]byte, error) {
clErr := gz.Close()
if err != nil {
- return nil, fmt.Errorf("read %q: %w", name, err)
+ return nil, fmt.Errorf("Read %q: %v", name, err)
}
if clErr != nil {
return nil, err
@@ -38,9 +36,8 @@ func bindataRead(data []byte, name string) ([]byte, error) {
}
type asset struct {
- bytes []byte
- info os.FileInfo
- digest [sha256.Size]byte
+ bytes []byte
+ info os.FileInfo
}
type bindataFileInfo struct {
@@ -50,26 +47,37 @@ type bindataFileInfo struct {
modTime time.Time
}
+// Name return file name
func (fi bindataFileInfo) Name() string {
return fi.name
}
+
+// Size return file size
func (fi bindataFileInfo) Size() int64 {
return fi.size
}
+
+// Mode return file mode
func (fi bindataFileInfo) Mode() os.FileMode {
return fi.mode
}
+
+// Mode return file modify time
func (fi bindataFileInfo) ModTime() time.Time {
return fi.modTime
}
+
+// IsDir return file whether a directory
func (fi bindataFileInfo) IsDir() bool {
- return false
+ return fi.mode&os.ModeDir != 0
}
+
+// Sys return file is sys mode
func (fi bindataFileInfo) Sys() interface{} {
return nil
}
-var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5a\xeb\x8f\xe3\xb6\x11\xff\xec\xfd\x2b\x26\xea\x25\x96\xbb\x2b\xc9\xbe\xcd\x0b\xb6\xe4\xe2\x72\x49\x83\x2b\xda\x4b\x90\x4b\xd0\x16\x49\x3e\xd0\xe2\xd8\xe2\x2e\x45\x2a\x24\x65\xaf\x63\xf8\x7f\x2f\x48\x51\xb2\xfc\xd8\xed\x3d\x02\x14\xbd\x0f\x5e\x91\x1c\xce\xfc\x38\x33\x9c\x87\x74\xe9\x47\x5f\x7f\xf7\xf2\xc7\x7f\x7f\xff\x0d\x14\xa6\xe4\xf3\xab\xd4\xfe\x01\x4e\xc4\x2a\x0b\x50\x04\x76\x02\x09\x9d\x5f\x0d\xd2\x12\x0d\x81\xbc\x20\x4a\xa3\xc9\x82\xda\x2c\xa3\x2f\x83\x6e\xbe\x30\xa6\x8a\xf0\xb7\x9a\xad\xb3\xe0\x5f\xd1\x4f\x2f\xa2\x97\xb2\xac\x88\x61\x0b\x8e\x01\xe4\x52\x18\x14\x26\x0b\x5e\x7d\x93\x21\x5d\xe1\x61\x9b\x20\x25\x66\xc1\x9a\xe1\xa6\x92\xca\xf4\x28\x37\x8c\x9a\x22\xa3\xb8\x66\x39\x46\x6e\x70\x03\x4c\x30\xc3\x08\x8f\x74\x4e\x38\x66\x93\x60\x7e\x75\x35\x48\x0d\x33\x1c\xe7\xbb\x5d\xfc\x1a\xcd\x46\xaa\xfb\xfd\x7e\x0a\x7f\x25\x75\x8e\x26\x4d\x9a\x35\x4b\xc5\x99\xb8\x87\x42\xe1\x32\x0b\x2c\x52\x3d\x4d\x92\x9c\x8a\x3b\x1d\xe7\x5c\xd6\x74\xc9\x89\xc2\x38\x97\x65\x42\xee\xc8\x43\xc2\xd9\x42\x27\x66\xc3\x8c\x41\x15\x2d\xa4\x34\xda\x28\x52\x25\xb7\xf1\x6d\xfc\x45\x92\x6b\x9d\x74\x73\x71\xc9\x44\x9c\x6b\x1d\x80\x42\x9e\x05\xda\x6c\x39\xea\x02\xd1\x04\x90\xcc\xdf\x4b\xec\x52\x0a\x13\x91\x0d\x6a\x59\x62\xf2\x69\xfc\x45\x3c\x76\x12\xfb\xd3\x4f\x0b\xbd\x1a\xa4\x3a\x57\xac\x32\xa0\x55\xfe\xd6\x62\xef\x7e\xab\x51\x6d\x93\xdb\x78\x12\x4f\xfc\xc0\x89\xb9\xd3\xc1\x3c\x4d\x1a\x86\xf3\x0f\x61\x1d\x09\x69\xb6\xc9\xf3\xf8\xd3\x78\x92\x54\x24\xbf\x27\x2b\xa4\xad\x20\xbb\x14\xb7\x93\x7f\x94\xd8\xc7\xec\x77\x77\x6a\xbe\x3f\x40\x56\x29\x4b\x14\x26\xbe\xd3\xc9\xf3\x78\xf2\x65\x3c\x6e\x27\xce\xd9\x5b\xfe\xd6\x5e\xf3\xab\xc1\x20\x5e\xa3\x32\x2c\x27\x3c\xca\x51\x18\x54\xb0\xbb\x1a\x0c\x06\x25\x13\x51\x81\x6c\x55\x98\x29\x4c\xc6\xe3\x8f\x67\x17\x26\xd7\x85\x9b\xa5\x4c\x57\x9c\x6c\xa7\xb0\xe4\xf8\xe0\x66\x08\x67\x2b\x11\x31\x83\xa5\x9e\x42\xc3\xd5\xce\xef\xad\xb4\x4a\xc9\x95\x42\xad\x1b\x31\x95\xd4\xcc\x30\x29\xa6\xd6\x89\x88\x61\x6b\x3c\x27\xd4\x15\x11\xa7\xd4\x64\xa1\x25\xaf\x0d\x1e\x03\x58\x70\x99\xdf\xbb\x29\x77\x55\x7b\xc8\x73\xc9\xa5\x9a\xc2\xa6\x60\xa6\x93\x50\x29\xf4\x6c\x09\xa5\x4c\xac\xa6\xf0\x79\xd5\xe0\x2f\x89\x5a\x31\x31\x85\xb1\x27\x4d\x13\xaf\xad\x34\x69\xa2\xd0\x55\xba\x90\x74\x3b\xbf\x4a\x29\x5b\x43\xce\x89\xd6\x59\x70\xa2\x46\x17\x5c\x7a\xcb\x36\xa4\x10\x26\x9a\x85\xa3\x15\x25\x37\x01\x38\x01\x59\xd0\x48\x8e\x16\xd2\x18\x59\x4e\x61\x62\x11\xb9\x0d\x27\xbc\x78\xc4\x57\xd1\xe4\x79\xb3\x34\x48\x8b\x49\xcb\xc0\xe0\x83\x89\x9c\xfe\x3b\xcd\x07\xf3\x94\xb5\x3b\x97\x04\x96\x24\x5a\x10\x53\x04\x40\x14\x23\x51\xc1\x28\x45\x91\x05\x46\xd5\x68\x3d\x84\xcd\xa1\x1f\xc4\xba\x18\x56\x4c\x1a\x14\x09\x65\x6b\x77\x80\xee\xe1\xe4\x24\x8f\x81\xfd\x12\xfc\x83\x5c\x2e\x35\x9a\xa8\xc3\xde\x23\x65\xa2\xaa\x4d\xb4\x52\xb2\xae\xfc\xea\x20\x75\x73\xc0\x68\x16\xd4\x8a\x07\x3e\x52\xbb\x47\xb3\xad\xfc\x81\x83\xee\x78\x52\x95\x91\xd5\xb4\x92\x3c\x80\x8a\x93\x1c\x0b\xc9\x29\xaa\x2c\x78\x23\x73\x46\x38\x88\xe6\x64\xf0\xd3\x0f\x7f\x07\x6f\x12\x26\x56\xb0\x95\xb5\x82\xaf\x5e\xbc\x01\x42\xa9\x75\xba\x38\x8e\x3b\x04\xce\xff\xce\x11\x46\x0b\x23\x5a\x1a\x4b\xb6\xa8\x8d\x91\x1d\xe1\xc2\x08\x58\x18\x11\x51\x5c\x92\x9a\x1b\xa0\x4a\x56\x54\x6e\x44\x64\xe4\x6a\x65\x93\x51\x83\xbe\xd9\x14\x00\x25\x86\xf8\xa5\x2c\x68\x69\x5b\x13\x11\x5d\xc9\xaa\xae\xbc\x91\x9a\x49\x7c\xa8\x88\xa0\x48\xad\x49\xb9\xc6\x60\xfe\x2d\x5b\x23\x94\x08\xaf\xdd\x2d\x82\x1f\xe5\x3d\x8a\xc1\xa9\xe1\x73\xa2\xd0\x44\x7d\xde\x67\xe6\x4f\x93\x06\x53\x73\x32\xf0\xff\xd2\x9a\xb7\x9c\xba\x93\x94\x28\x6a\x38\x1a\x45\xca\xc6\x86\x60\xbe\xdb\x29\x22\x56\x08\xcf\x18\x7d\xb8\x81\x67\xa4\x94\xb5\x30\x30\xcd\x20\x7e\xe1\x1e\xf5\x7e\x7f\xc4\x1d\x20\xe5\x6c\x9e\x92\xa7\x9c\x18\xa4\xc8\x39\xcb\xef\xb3\xc0\x30\x54\xd9\x6e\x67\x99\xef\xf7\x33\xbd\x2d\x17\x92\x67\xc3\xe6\xdc\xee\xd8\xc3\x19\xec\x76\x6c\x09\xcf\xe2\x1f\x30\x27\x95\xc9\x0b\xb2\xdf\xaf\x54\xfb\x1c\xe3\x03\xe6\xb5\xc1\x70\xb4\xdb\x21\xd7\xb8\xdf\xeb\x7a\x51\x32\x13\xb6\x3c\xed\xbc\xa0\xfb\xbd\x3d\x88\x07\xbf\xdf\xa7\x09\x99\xa7\x09\x67\x73\xbf\x78\xac\x9e\xa4\xe6\x9d\x2b\xa4\x89\xf5\x18\x3f\xdc\xed\x80\x2d\x21\xfe\x0a\xab\xe7\xf8\x4a\x2c\xa5\x06\xbf\xf5\xff\xc5\xaf\xbe\xc7\xd5\x6a\x0b\xc6\xea\x55\xff\x8f\xdc\x09\x3a\x7f\x6a\x8c\x7d\x03\xcf\x16\xad\x3e\x9d\x57\x1d\xb4\xdb\x2a\xd7\x2a\xee\x1d\x5c\xca\x3b\xd1\x6e\xe7\x25\xec\xf7\xef\xe7\x42\x0e\x48\xd8\x63\x73\xe4\x4a\x1d\x68\x7f\x0d\xde\x18\xb5\xdf\x43\x8f\xfa\xfd\x7d\x0c\x05\x6d\x1d\xab\x89\xcc\x0e\x7d\x1f\xfc\x59\xb0\x5d\x45\xdd\x71\xbc\x9f\x68\x66\xf0\x1e\xb7\x59\xb0\xdb\xf5\x77\xfa\xd5\x9c\x70\xbe\x20\x4e\x5b\xee\xac\xdd\xa6\xdf\xd1\xfa\xef\x9a\x69\x57\x65\xcf\x5b\xf9\xdd\x09\xfe\x7b\xce\x38\xc9\x7e\x46\x56\x53\xb8\x7d\xfe\x54\xea\xfb\xfc\x24\x9b\xdc\x5e\xc8\x26\x15\x11\xc8\xc1\xfd\x46\xba\x24\xbc\x7d\xf6\x57\xa7\x8b\xef\xa7\x5b\x22\x9b\xdb\x3b\x4c\x5d\x71\x30\x9e\x81\x5c\xa3\x5a\x72\xb9\x99\x02\xa9\x8d\x9c\x41\x49\x1e\xba\x7a\xe8\x76\x3c\xee\x00\x5b\xae\x86\x2c\x38\xba\xbc\xa5\xf0\xb7\x1a\xb5\xd1\x5d\x96\x6a\x96\xdc\xaf\x4d\x56\x14\x85\x46\x7a\xa2\x04\x2b\xcf\xea\xd2\x51\xb5\x48\x5b\xfd\x5d\x44\xbd\x94\xd2\x97\x1d\x7d\x00\x9e\x69\xaf\x1e\x0a\xe6\xa9\x51\x07\x47\x32\xf4\x9d\x4a\x07\x65\x0b\xfe\xc7\x2a\x87\x26\xa4\xd9\x33\x57\x88\xaa\xa9\x38\xad\x9b\x82\x1b\xa6\x89\xa1\xef\x2d\xd7\xfa\xda\x82\x68\x7c\x1b\xe1\xae\x0c\x3c\x08\x77\xc3\x0f\x93\x5e\x20\x51\x66\x81\xc4\xbc\x8d\xf8\x65\x2d\x68\xef\xec\xfd\x84\xfc\x61\x28\x6a\xc1\xd6\xa8\x34\x33\xdb\xb7\x85\x81\xf4\x80\xa3\x19\xf7\x01\xa4\x89\x51\x8f\xbb\xd8\xe1\xf1\xec\x02\xfb\xbf\xfe\xcf\x55\xda\x75\x2d\x49\x02\xdf\x72\xb9\x20\x1c\xd6\x16\xe0\x82\xa3\x06\x23\xc1\xd6\x60\x60\x0a\x84\xbc\x56\x0a\x85\x01\x6d\x88\xa9\x35\xc8\xa5\x9b\x5d\xba\x1a\xf3\x6a\xb0\x26\x0a\x88\x31\x58\x56\x06\x32\x57\x7c\xdb\x19\x8d\x6a\xed\xfa\x07\x3b\xb0\xb9\xbf\xbf\xd6\xc4\xed\x20\xf0\xe3\xf6\xaa\x41\x06\x3f\xff\x3a\xbb\x72\x80\xbe\xc6\x25\x13\x08\xc4\x2a\x20\xb7\xdd\x03\x98\x82\x18\xc8\x15\x12\x83\x1a\x72\x2e\x75\xad\x1a\x9c\x36\xfb\x80\xc5\xda\xf2\x69\xb8\xda\xe9\xca\xc9\x6d\x59\x84\x05\xd1\xc5\xc8\x75\x0f\x0a\x4d\xad\xc4\x61\xa5\x99\x1d\x2c\xa5\x82\xd0\x6e\x66\xd9\x78\x06\x2c\x6d\x39\xc6\x1c\xc5\xca\x14\x33\x60\xd7\xd7\x9e\x74\xc0\x96\x10\xb6\xeb\x3f\xb3\x5f\x63\xf3\x10\x5b\xfe\x90\x65\x70\x90\x33\xb0\xa2\x3c\x0f\x5d\x71\x96\x63\xc8\x6e\x60\x32\x9a\x35\x6b\x0b\x85\xa4\x69\x7d\x5c\x6f\xe3\x7e\xf6\x57\x83\xfd\xac\xaf\x03\xa7\xec\x23\x2d\x34\xa1\x5c\x03\x81\x15\xd3\x06\x6a\xc5\xad\x1e\x2c\x5d\xa3\x76\xaf\x66\x47\xd5\x3f\xff\x59\x7a\xf1\x0f\x3e\xec\x37\x90\x1b\x16\xb1\x46\x41\xc3\xbf\xbd\xf9\xee\x75\xac\x8d\x62\x62\xc5\x96\xdb\x70\x57\x2b\x3e\x85\x67\x61\xf0\x27\x5b\xca\x8f\x7e\x1e\xff\x1a\xaf\x09\xaf\xf1\xc6\x9b\x74\x0a\x6d\xaa\xb7\x16\x9f\xba\xdf\x33\x99\x37\xe0\x1f\xa7\x70\x2c\x7e\x3f\x1a\xcd\x2e\x25\xc0\x5e\x02\x57\xa8\xd1\x84\x96\xcc\xe7\xa9\x63\x4d\x11\x28\xd1\x14\x92\x5a\x6d\x28\xcc\xa5\x10\x98\x1b\xa8\x2b\x29\xbc\x62\x80\x4b\xad\x5b\xa7\x6b\xd7\xb3\x53\x37\xf0\xb4\x19\x08\xdc\xc0\x3f\x71\xf1\x46\xe6\xf7\x68\xc2\x30\xdc\x30\x41\xe5\x26\xe6\x32\x27\x96\xdc\x36\xbb\x46\xe6\x92\x43\x96\x65\xe0\xfb\xfd\x60\x04\x7f\x81\x60\xa3\x6d\xe7\x1f\xc0\xd4\x3e\xda\xa7\x11\x5c\xc3\xe9\xf6\x42\x6a\x03\xd7\x10\x24\xcd\x55\xb2\xe9\x4e\x99\x84\x54\x2c\x18\xd9\x5b\xd0\x5a\x42\x8a\x12\xb5\x26\x2b\xec\x23\xc5\x35\x0a\xe3\x7d\xcc\x1e\xa7\xd4\x2b\xc8\xc0\xd9\xab\x22\x4a\x63\x43\x10\xdb\x00\xdc\x38\x9b\x75\x57\x47\x94\x65\x20\x6a\xce\x5b\xff\x6c\x6e\xc2\xac\xf1\xbe\x1e\x61\xec\x02\x22\x7c\x94\x65\x60\x43\x90\xd5\x2f\x6d\xf7\x58\x0f\x68\xe2\xe5\x28\xb6\x31\xf0\x40\x3f\x9a\xb5\x6e\x7c\xc4\x07\xe9\xd3\x8c\x90\x9e\x72\x42\x7a\x81\x95\x4b\x48\x8f\x73\x6a\xd2\x57\x8f\x91\x9b\xb8\xc0\x47\xd4\xe5\x02\xd5\xe3\x8c\x9a\x54\xe4\x19\x39\x75\xbe\x12\xa6\xb7\xf3\x06\x26\x9f\x8f\x2e\xf0\x45\xa5\xe4\x23\x6c\x85\x34\xdb\x70\xc7\xc9\x56\xd6\x66\x0a\x43\x23\xab\x97\x2e\x61\x0c\x6f\xc0\x4a\x99\x42\xb7\xff\xc6\x35\x03\x53\x18\xba\x91\x5d\x67\x25\xba\x5d\x9f\x8d\xc7\xe3\x1b\x68\xdf\xb0\x7c\x45\xec\x0d\x53\x35\xee\x2f\x20\xd1\x75\x9e\xa3\x7e\x44\x57\x6f\x85\xc5\x73\xe8\xd0\xf8\xf1\x7b\xe2\xe9\x42\xfc\x11\x20\xf8\xe4\x13\x38\x5b\xed\x3b\x67\x92\xc0\x3f\x88\xba\x07\x57\x06\x2a\x5c\x33\x59\xeb\x43\xba\x28\x99\xd6\x4c\xac\x80\x68\xa0\x52\xa0\xdb\xf1\x2e\x11\xfc\x0c\x9d\x27\x82\x39\x8c\x4f\xa1\xd9\x58\xd7\x8b\xf0\x17\x02\x7f\xc7\xb5\x1f\xd5\x07\xfb\x83\xa4\xa3\x3d\xac\x44\xf8\x28\x83\x20\x38\x6c\x3b\x5b\xb7\xcb\x9e\xcd\x40\xa3\xf9\xb1\xd1\x7b\xe8\x13\xdb\xa5\xe4\x33\xba\xb1\x15\xed\x78\x74\x24\x7c\xdf\xaa\xf2\x45\x55\xd9\x8e\x83\x88\xad\x8b\x6c\x9d\x1e\x99\x30\x12\x64\x6d\xa3\x63\x4e\xb8\xad\xd1\x39\xba\x28\xe3\x36\x5a\x65\xe6\xb2\x2c\xa5\x80\x0c\xa2\xc9\xec\x2c\xf9\xf5\xb4\xd6\x1d\xe6\xd4\x0c\x17\xb4\x7c\x6c\x8a\x63\x0d\x9d\x90\x46\x93\x23\xe5\x1f\xd9\xe5\x92\x01\x06\x1d\x5e\xd6\xea\xef\xc8\x28\xad\x55\xfa\xfa\xe9\x21\x6e\x76\x5f\x4f\xde\x0a\x78\xb7\x58\xd5\xba\x08\x4f\xa0\x8d\x66\xc7\x16\x78\x65\x50\x11\x83\xae\x25\x71\x1a\x47\x61\x98\xc2\x33\xc5\x03\x11\xb6\x9c\x89\x14\x0a\x8a\xaa\xad\x00\x6c\x47\xd3\x34\x20\x3d\xc3\xb8\x4f\x1e\x3d\x57\xe9\x9d\xe3\x4c\x8b\x33\x60\x30\xb7\x75\x18\xb0\x28\xea\x4e\xe0\x8a\x25\x29\xd0\xb6\xab\x27\x9e\xed\xbc\xb0\xe7\x86\x96\x14\x39\xa9\x34\x52\xc8\xa0\x79\x51\x1d\x8e\xe2\x5a\xb0\x87\x70\x14\xf9\xf1\x29\x87\x76\xdd\xe5\x34\x67\x9c\x06\xf3\x75\x06\x41\x6a\x94\x2d\x7b\x87\x01\x5c\x5f\xba\x53\x36\x3b\x0e\xe7\xad\xf4\xfe\x46\x80\xd4\xd0\xb9\xeb\xa7\x9a\x62\xfc\x97\xc0\xb6\xb9\x2b\x25\x6b\x41\xa7\xb6\x24\x0a\xcf\x98\x92\x35\x31\x44\x39\x9e\xa3\x19\x1c\xc8\x5d\x37\x3c\x85\xdc\x5a\x65\x06\x4d\xd3\xe5\x1a\x59\xe8\xda\x44\x37\x5a\x48\x45\x51\x45\x8a\x50\x56\xeb\x29\x7c\x5a\x3d\xcc\x7e\x69\x3b\x67\x57\xa1\x3f\x01\xb4\x52\x38\x3f\xc3\x93\xe7\xee\x15\xdb\x35\x04\x69\x62\x09\x9e\x66\xd2\x1d\xb4\xff\x9a\x1c\x2e\xf4\x20\xd0\xbd\xd4\xf6\xf3\x25\xa3\x94\xa3\x05\xdb\x32\xb7\xb7\xcd\xda\xfc\x70\x67\x8e\xc5\x81\x6f\x3c\x5a\xfa\x3d\x20\xd7\xf8\x28\x71\xd7\xbf\x0c\xad\xc1\x23\x7b\x50\xe6\xf4\xec\x5b\x21\x37\xad\x86\x4e\x03\xfe\xf3\x06\xad\x95\xab\x82\xc2\xc8\x3b\xd4\x0d\x0c\xb5\xad\xc9\xa8\x1e\x8e\xe2\xa2\x2e\x89\x60\xbf\x63\x68\x13\xca\xa8\xd1\x90\x6b\x88\x82\xe3\xb8\x7a\x06\xe4\xd0\x60\x0f\xdb\xc4\x34\xf4\x8a\x1b\xb6\xd6\xb4\x86\x83\x43\xc3\x3e\x7c\x07\xad\x5c\x96\x10\x2d\x88\x82\xfe\x20\x6a\xb3\x25\x28\x69\x25\xb7\x6b\x0b\xa2\x86\x4d\x13\xe8\xea\x66\x21\x37\xd9\xf0\x76\xdc\x01\x6c\x0c\xeb\xec\x3a\xf4\x7e\x75\x62\x00\x8b\xb0\xbd\x80\x73\xb8\x1d\x7f\x38\x52\x4a\xc4\x0a\x4f\xd1\x1b\xc5\x2a\xa4\x40\x72\xdb\x04\xff\xe1\x87\xf8\x60\xe5\xbe\x33\x3c\xeb\x77\xad\xda\x9c\x5b\x1e\x61\xb5\xab\x9d\x56\xff\x6c\xef\x15\x24\x4e\xb7\xd7\x10\x5c\x38\xc4\x23\x9e\x77\x44\x74\x72\x79\x1f\xbb\xd7\xae\x97\x0f\xfa\x49\xc2\x96\x9f\xdd\xab\xa7\x51\x5c\x98\x92\x87\x41\x6a\xdc\x87\x2b\x8b\xb3\xdb\xed\x36\x37\xd3\x87\x7a\x6b\xdf\xef\x1a\x6c\x8f\x8c\x27\xdd\x0d\xf4\xea\x88\xae\x03\x6a\x8b\x06\xb0\xdd\xd4\xde\x35\x54\x6f\x0c\x51\x06\x08\xfc\xf4\x0a\xea\x8a\x12\x63\x93\x90\x04\x9b\xe2\x5c\x32\xea\xbe\xf2\x2d\x88\xd2\xb0\x94\x6a\x43\x14\x85\x5a\x18\xc6\xed\xfa\x16\x88\x42\x5f\x93\x69\x34\xaf\x6c\x54\x5a\x13\x1e\x9e\xf4\x59\xcf\xc2\x61\xdc\x37\xec\x70\x14\x23\xc9\x8b\x53\x32\x97\x75\x3a\x89\x19\xbc\x76\x35\x78\xf8\x2c\x34\x05\xd3\xa3\x98\x18\xa3\xc2\xe1\x91\xc1\x87\x23\x6b\xbb\x49\xd7\xf7\x74\x9b\xd3\xde\x95\x79\x6a\xff\xa1\xaa\xf5\x19\xbc\x25\xce\xb5\x0e\x1b\xaf\x19\xde\xf4\xf8\x1e\x3b\xcd\xf0\xe3\xa1\x37\xc9\xe1\xd2\x1e\xf0\x67\x17\x30\x1c\xb1\x1d\xda\xbb\x33\x3c\x11\x4c\x28\x7d\x69\xef\x45\x18\x5c\xb8\xbd\x7d\x0f\x18\x79\xc5\x36\x11\xf7\x09\x8d\x32\x41\xf1\xe1\x31\x75\x32\x3a\x1c\xc5\xba\x5e\x34\xbd\x7f\xf8\x99\xef\x76\x5a\x22\xe7\x96\xa7\x81\xfc\x2c\xfd\x5b\x01\xc7\x25\x40\x74\x52\x32\x3c\x11\xf3\x9d\x40\x7b\x9a\xfd\x8d\x55\xee\x78\xe4\x5f\x0c\x7d\xa3\x6d\x05\xc4\x74\x01\x04\x36\xb8\xd0\xae\x37\x07\xef\xc9\xee\x0d\x49\xf3\x26\xe4\xc5\xf7\xaf\xba\xb7\x21\x9d\xa7\xdb\x22\xa4\xfb\x9e\x7e\xfe\xae\xe1\xe2\xe7\xfb\xcd\x66\x13\xaf\xa4\x5c\xf1\xe6\xc3\x7d\xf7\x32\xc2\x36\xea\xf1\x9d\x0e\x80\xe8\xad\xc8\x81\xe2\x12\xd5\xbc\xc7\xbc\x79\x43\x91\x26\xfe\x9b\x73\xd2\xfc\x0f\x99\xff\x04\x00\x00\xff\xff\x13\xef\x26\xa6\x32\x23\x00\x00")
+var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xd4\x5a\xeb\x8f\xe3\xb6\x11\xff\xec\xfd\x2b\x26\xea\x25\x96\xbb\x2b\xc9\xbe\xcd\x0b\xb6\xe4\xe2\x72\x49\x83\x2b\xda\x4b\x90\x4b\xd0\x16\x49\x3e\xd0\xe2\xd8\xe2\x2e\x45\x2a\x24\x65\xaf\x63\xf8\x7f\x2f\x48\x51\xb2\xfc\xd8\xed\x3d\x02\x14\xbd\x0f\x5e\x91\x1c\xce\xfc\x38\x33\x9c\x87\x74\xe9\x47\x5f\x7f\xf7\xf2\xc7\x7f\x7f\xff\x0d\x14\xa6\xe4\xf3\xab\xd4\xfe\x01\x4e\xc4\x2a\x0b\x50\x04\x76\x02\x09\x9d\x5f\x0d\xd2\x12\x0d\x81\xbc\x20\x4a\xa3\xc9\x82\xda\x2c\xa3\x2f\x83\x6e\xbe\x30\xa6\x8a\xf0\xb7\x9a\xad\xb3\xe0\x5f\xd1\x4f\x2f\xa2\x97\xb2\xac\x88\x61\x0b\x8e\x01\xe4\x52\x18\x14\x26\x0b\x5e\x7d\x93\x21\x5d\xe1\x61\x9b\x20\x25\x66\xc1\x9a\xe1\xa6\x92\xca\xf4\x28\x37\x8c\x9a\x22\xa3\xb8\x66\x39\x46\x6e\x70\x03\x4c\x30\xc3\x08\x8f\x74\x4e\x38\x66\x93\x60\x7e\x75\x35\x48\x39\x13\xf7\xa0\x90\x67\x01\xcb\xa5\x08\xa0\x50\xb8\xcc\x02\x0b\x47\x4f\x93\x64\x29\xf2\xad\xce\x89\x88\xed\x43\xbc\x91\x8a\xd3\x64\x49\xd6\x96\x34\x66\xb9\x74\x40\x0c\x33\x1c\xe7\xbb\x5d\xfc\x1a\xcd\x46\xaa\xfb\xfd\x7e\x0a\x7f\x25\x75\x8e\x26\x4d\x9a\xb5\x4e\xce\x31\xf3\x9c\x8a\x3b\x1d\xe7\x5c\xd6\x74\xc9\x89\xc2\x38\x97\x65\x42\xee\xc8\x43\xc2\xd9\x42\x27\x66\xc3\x8c\x41\x15\x2d\xa4\x34\xda\x28\x52\x25\xb7\xf1\x6d\xfc\x45\x92\x6b\x9d\x74\x73\x71\xc9\x44\x9c\x6b\x1d\x34\x67\xd0\x66\xcb\x51\x17\x88\x26\x80\x64\xfe\x5e\x62\x97\x52\x98\x88\x6c\x50\xcb\x12\x93\x4f\xe3\x2f\xe2\xb1\x93\xd8\x9f\x7e\x5a\xe8\xd5\x20\xd5\xb9\x62\x95\x01\xad\xf2\xb7\x16\x7b\xf7\x5b\x8d\x6a\x9b\xdc\xc6\x93\x78\xe2\x07\x4e\xcc\x9d\x0e\xe6\x69\xd2\x30\x9c\x7f\x08\xeb\x48\x48\xb3\x4d\x9e\xc7\x9f\xc6\x93\xa4\x22\xf9\x3d\x59\x21\x6d\x05\xd9\xa5\xb8\x9d\xfc\xa3\xc4\x3e\x66\xbf\xbb\x53\xf3\xfd\x01\xb2\x4a\x59\xa2\x30\xf1\x9d\x4e\x9e\xc7\x93\x2f\xe3\x71\x3b\x71\xce\xde\xf2\xb7\xf6\x9a\x5f\x0d\x06\xf1\x1a\x95\x61\x39\xe1\x51\x8e\xc2\xa0\x82\xdd\xd5\x60\x30\x28\x99\x88\x0a\x64\xab\xc2\x4c\x61\x32\x1e\x7f\x3c\xbb\x30\xb9\x2e\xdc\x2c\x65\xba\xe2\x64\x3b\x85\x25\xc7\x07\x37\x43\x38\x5b\x89\x88\x19\x2c\xf5\x14\x1a\xae\x76\x7e\x6f\xa5\x55\x4a\xae\x14\x6a\xdd\x88\xa9\xa4\x66\x86\x49\x31\xb5\x4e\x44\x0c\x5b\xe3\x39\xa1\xae\x88\x38\xa5\x26\x0b\x2d\x79\x6d\xf0\x18\xc0\x82\xcb\xfc\xde\x4d\xb9\xcb\xde\x43\x9e\x4b\x2e\xd5\x14\x36\x05\x33\x9d\x84\x4a\xa1\x67\x4b\x28\x65\x62\x35\x85\xcf\xab\x06\x7f\x49\xd4\x8a\x89\x29\x8c\x3d\x69\x9a\x78\x6d\xa5\x49\x13\xc7\xae\xd2\x85\xa4\xdb\xf9\x55\x4a\xd9\x1a\x72\x4e\xb4\xce\x82\x13\x35\xba\xa8\xd0\x5b\xb6\x41\x89\x30\xd1\x2c\x1c\xad\x28\xb9\x09\xc0\x09\xc8\x82\x46\x72\xb4\x90\xc6\xc8\x72\x0a\x13\x8b\xc8\x6d\x38\xe1\xc5\x23\xbe\x8a\x26\xcf\x9b\xa5\x41\x5a\x4c\x5a\x06\x06\x1f\x4c\xe4\xf4\xdf\x69\x3e\x98\xa7\xac\xdd\xb9\x24\xb0\x24\xd1\x82\x98\x22\x00\xa2\x18\x89\x0a\x46\x29\x8a\x2c\x30\xaa\x46\xeb\x21\x6c\x0e\xfd\x20\xd6\xc5\xb0\x62\xd2\xa0\x48\x28\x5b\xbb\x03\x74\x0f\x27\x27\x79\x0c\xec\x97\xe0\x1f\xe4\x72\xa9\xd1\x44\x1d\xf6\x1e\x29\x13\x55\x6d\xa2\x95\x92\x75\xe5\x57\x07\xa9\x9b\x03\x46\xb3\xa0\x56\x3c\xf0\xb1\xde\x3d\x9a\x6d\xe5\x0f\x1c\x74\xc7\x93\xaa\x8c\xac\xa6\x95\xe4\x01\x54\x9c\xe4\x58\x48\x4e\x51\x65\xc1\x1b\x99\x33\xc2\x41\x34\x27\x83\x9f\x7e\xf8\x3b\x78\x93\x30\xb1\x82\xad\xac\x15\x7c\xf5\xe2\x0d\x10\x4a\xad\xd3\xc5\x71\xdc\x21\x70\xfe\x77\x8e\x30\x5a\x18\xd1\xd2\x58\xb2\x45\x6d\x8c\xec\x08\x17\x46\xc0\xc2\x88\x88\xe2\x92\xd4\xdc\x00\x55\xb2\xa2\x72\x23\x22\x23\x57\x2b\x9b\xce\x1a\xf4\xcd\xa6\x00\x28\x31\xc4\x2f\x65\x41\x4b\xdb\x9a\x88\xe8\x4a\x56\x75\xe5\x8d\xd4\x4c\xe2\x43\x45\x04\x45\x6a\x4d\xca\x35\x06\xf3\x6f\xd9\x1a\xa1\x44\x78\xed\x6e\x11\xfc\x28\xef\x51\x0c\x4e\x0d\x9f\x13\x85\x26\xea\xf3\x3e\x33\x7f\x9a\x34\x98\x9a\x93\x81\xff\x97\xd6\xbc\xe5\xd4\x9d\xa4\x44\x51\xc3\xd1\x28\x52\x36\x36\x04\xf3\xdd\x4e\x11\xb1\x42\x78\xc6\xe8\xc3\x0d\x3c\x23\xa5\xac\x85\x81\x69\x06\xf1\x0b\xf7\xa8\xf7\xfb\x23\xee\x00\x29\x67\xf3\x94\x3c\xe5\xc4\x20\x45\xce\x59\x7e\x9f\x05\x86\xa1\xca\x76\x3b\xcb\x7c\xbf\x9f\xe9\x6d\xb9\x90\x3c\x1b\x36\xe7\x76\xc7\x1e\xce\x60\xb7\x63\x4b\x78\x16\xff\x80\x39\xa9\x4c\x5e\x90\xfd\x7e\xa5\xda\xe7\x18\x1f\x30\xaf\x0d\x86\xa3\xdd\x0e\xb9\xc6\xfd\x5e\xd7\x8b\x92\x99\xb0\xe5\x69\xe7\x05\xdd\xef\xed\x41\x3c\xf8\xfd\x3e\x4d\xc8\x3c\x4d\x38\x9b\xfb\xc5\x63\xf5\x24\x35\xef\x5c\x21\x4d\xac\xc7\xf8\xe1\x6e\x07\x6c\x09\xf1\x57\x58\x3d\xc7\x57\x62\x29\x35\xf8\xad\xff\x2f\x7e\xf5\x3d\xae\x56\x5b\x30\x56\xaf\xfa\x7f\xe4\x4e\xd0\xf9\x53\x63\xec\x1b\x78\xb6\x68\xf5\xe9\xbc\xea\xa0\xdd\x56\xb9\x56\x71\xef\xe0\x52\xde\x89\x76\x3b\x2f\x61\xbf\x7f\x3f\x17\x72\x40\xc2\x1e\x9b\x23\x57\xea\x40\xfb\x6b\xf0\xc6\xa8\xfd\x1e\x7a\xd4\xef\xef\x63\x28\x68\xeb\x58\x4d\x64\x76\xe8\xfb\xe0\xcf\x82\xed\x2a\xea\x8e\xe3\xfd\x44\x33\x83\xf7\xb8\xcd\x82\xdd\xae\xbf\xd3\xaf\xe6\x84\xf3\x05\x71\xda\x72\x67\xed\x36\xfd\x8e\xd6\x7f\xd7\x4c\xbb\x3a\x7d\xde\xca\xef\x4e\xf0\xdf\x73\xc6\x49\xf6\x33\xb2\x9a\xc2\xed\xf3\xa7\x52\xdf\xe7\x27\xd9\xe4\xf6\x42\x36\xa9\x88\x40\x0e\xee\x37\xd2\x25\xe1\xed\xb3\xbf\x3a\x5d\x7c\x3f\xdd\x12\xd9\xdc\xde\x61\xea\x8a\x83\xf1\x0c\xe4\x1a\xd5\x92\xcb\xcd\x14\x48\x6d\xe4\x0c\x4a\xf2\xd0\xd5\x43\xb7\xe3\x71\x07\xd8\x72\x35\x64\xc1\xd1\xe5\x2d\x85\xbf\xd5\xa8\x8d\xee\xb2\x54\xb3\xe4\x7e\x6d\xb2\xa2\x28\x34\xd2\x13\x25\x58\x79\x56\x97\x8e\xaa\x45\xda\xea\xef\x22\xea\xa5\x94\xbe\xec\xe8\x03\xf0\x4c\x7b\xf5\x50\x30\x4f\x8d\x3a\x38\x92\xa1\xef\x54\x3a\x28\x5b\xf0\x3f\x56\x39\x34\x21\xcd\x9e\xb9\x42\x54\x4d\xc5\x69\xdd\x14\xdc\x30\x4d\x0c\x7d\x6f\xb9\xd6\xd7\x16\x44\xe3\xdb\x08\x77\x65\xe0\x41\xb8\x1b\x7e\x98\xf4\x02\x89\x32\x0b\x24\xe6\x6d\xc4\x2f\x6b\x41\x7b\x67\xef\x27\xe4\x0f\x43\x51\x0b\xb6\x46\xa5\x99\xd9\xbe\x2d\x0c\xa4\x07\x1c\xcd\xb8\x0f\x20\x4d\x8c\x7a\xdc\xc5\x0e\x8f\x67\x17\xd8\xff\xf5\x7f\xae\xd2\xae\x6b\x49\x12\xf8\x96\xcb\x05\xe1\xb0\xb6\x00\x17\x1c\x35\x18\x09\xb6\x06\x03\x53\x20\xe4\xb5\x52\x28\x0c\x68\x43\x4c\xad\x41\x2e\xdd\xec\xd2\xd5\x98\x57\x83\x35\x51\x40\x8c\xc1\xb2\x32\x90\xb9\xe2\xdb\xce\x68\x54\x6b\xd7\x3f\xd8\x81\xcd\xfd\xfd\xb5\x26\x6e\x07\x81\x1f\xb7\x57\x0d\x32\xf8\xf9\xd7\xd9\x95\x03\xf4\x35\x2e\x99\x40\x20\x56\x01\xb9\xed\x1e\xc0\x14\xc4\x40\xae\x90\x18\xd4\x90\x73\xa9\x6b\xd5\xe0\xb4\xd9\x07\x2c\xd6\x96\x4f\xc3\xd5\x4e\x57\x4e\x6e\xcb\x22\x2c\x88\x2e\x46\xae\x7b\x50\x68\x6a\x25\x0e\x2b\xcd\xec\x60\x29\x15\x84\x76\x33\xcb\xc6\x33\x60\x69\xcb\x31\xe6\x28\x56\xa6\x98\x01\xbb\xbe\xf6\xa4\x03\xb6\x84\xb0\x5d\xff\x99\xfd\x1a\x9b\x87\xd8\xf2\x87\x2c\x83\x83\x9c\x81\x15\xe5\x79\xe8\x8a\xb3\x1c\x43\x76\x03\x93\xd1\xac\x59\x5b\x28\x24\x4d\xeb\xe3\x7a\x1b\xf7\xb3\xbf\x1a\xec\x67\x7d\x1d\x38\x65\x1f\x69\xa1\x09\xe5\x1a\x08\xac\x98\x36\x50\x2b\x6e\xf5\x60\xe9\x1a\xb5\x7b\x35\x3b\xaa\xfe\xf9\xcf\xd2\x8b\x7f\xf0\x61\xbf\x81\xdc\xb0\x88\x35\x0a\x1a\xfe\xed\xcd\x77\xaf\x63\x6d\x14\x13\x2b\xb6\xdc\x86\xbb\x5a\xf1\x29\x3c\x0b\x83\x3f\xd9\x52\x7e\xf4\xf3\xf8\xd7\x78\x4d\x78\x8d\x37\xde\xa4\x53\x68\x53\xbd\xb5\xf8\xd4\xfd\x9e\xc9\xbc\x01\xff\x38\x85\x63\xf1\xfb\xd1\x68\x76\x29\x01\xf6\x12\xb8\x42\x8d\x26\xb4\x64\x3e\x4f\x1d\x6b\x8a\x40\x89\xa6\x90\xd4\x6a\x43\x61\x2e\x85\xc0\xdc\x40\x5d\x49\xe1\x15\x03\x5c\x6a\xdd\x3a\x5d\xbb\x9e\x9d\xba\x81\xa7\xcd\x40\xe0\x06\xfe\x89\x8b\x37\x32\xbf\x47\x13\x86\xe1\x86\x09\x2a\x37\x31\x97\x39\xb1\xe4\xb6\xd9\x35\x32\x97\x1c\xb2\x2c\x03\xdf\xef\x07\x23\xf8\x0b\x04\x1b\x6d\x3b\xff\x00\xa6\xf6\xd1\x3e\x8d\xe0\x1a\x4e\xb7\x17\x52\x1b\xb8\x86\x20\x69\xae\x92\x4d\x77\xca\x24\xa4\x62\xc1\xc8\xde\x82\xd6\x12\x52\x94\xa8\x35\x59\x61\x1f\x29\xae\x51\x18\xef\x63\xf6\x38\xa5\x5e\x41\x06\xce\x5e\x15\x51\x1a\x1b\x82\xd8\x06\xe0\xc6\xd9\xac\xbb\x3a\xa2\x2c\x03\x51\x73\xde\xfa\x67\x73\x13\x66\x8d\xf7\xf5\x08\x63\x17\x10\xe1\xa3\x2c\x03\x1b\x82\xac\x7e\x69\xbb\xc7\x7a\x40\x13\x2f\x47\xb1\x8d\x81\x07\xfa\xd1\xac\x75\xe3\x23\x3e\x48\x9f\x66\x84\xf4\x94\x13\xd2\x0b\xac\x5c\x42\x7a\x9c\x53\x93\xbe\x7a\x8c\xdc\xc4\x05\x3e\xa2\x2e\x17\xa8\x1e\x67\xd4\xa4\x22\xcf\xc8\xa9\xf3\x95\x30\xbd\x9d\x37\x30\xf9\x7c\x74\x81\x2f\x2a\x25\x1f\x61\x2b\xa4\xd9\x86\x3b\x4e\xb6\xb2\x36\x53\x18\x1a\x59\xbd\x74\x09\x63\x78\x03\x56\xca\x14\xba\xfd\x37\xae\x19\x98\xc2\xd0\x8d\xec\x3a\x2b\xd1\xed\xfa\x6c\x3c\x1e\xdf\x40\xfb\x86\xe5\x2b\x62\x6f\x98\xaa\x71\x7f\x01\x89\xae\xf3\x1c\xf5\x23\xba\x7a\x2b\x2c\x9e\x43\x87\xc6\x8f\xdf\x13\x4f\x17\xe2\x8f\x00\xc1\x27\x9f\xc0\xd9\x6a\xdf\x39\x93\x04\xfe\x41\xd4\x3d\xb8\x32\x50\xe1\x9a\xc9\x5a\x1f\xd2\x45\xc9\xb4\x66\x62\x05\x44\x03\x95\x02\xdd\x8e\x77\x89\xe0\x67\xe8\x3c\x11\xcc\x61\x7c\x0a\xcd\xc6\xba\x5e\x84\xbf\x10\xf8\x3b\xae\xfd\xa8\x3e\xd8\x1f\x24\x1d\xed\x61\x25\xc2\x47\x19\x04\xc1\x61\xdb\xd9\xba\x5d\xf6\x6c\x06\x1a\xcd\x8f\x8d\xde\x43\x9f\xd8\x2e\x25\x9f\xd1\x8d\xad\x68\xc7\xa3\x23\xe1\xfb\x56\x95\x2f\xaa\xca\x76\x1c\x44\x6c\x5d\x64\xeb\xf4\xc8\x84\x91\x20\x6b\x1b\x1d\x73\xc2\x6d\x8d\xce\xd1\x45\x19\xb7\xd1\x2a\x33\x97\x65\x29\x05\x64\x10\x4d\x66\x67\xc9\xaf\xa7\xb5\xee\x30\xa7\x66\xb8\xa0\xe5\x63\x53\x1c\x6b\xe8\x84\x34\x9a\x1c\x29\xff\xc8\x2e\x97\x0c\x30\xe8\xf0\xb2\x56\x7f\x47\x46\x69\xad\xd2\xd7\x4f\x0f\x71\xb3\xfb\x7a\xf2\x56\xc0\xbb\xc5\xaa\xd6\x45\x78\x02\x6d\x34\x3b\xb6\xc0\x2b\x83\x8a\x18\x74\x2d\x89\xd3\x38\x0a\xc3\x14\x9e\x29\x1e\x88\xb0\xe5\x4c\xa4\x50\x50\x54\x6d\x05\x60\x3b\x9a\xa6\x01\xe9\x19\xc6\x7d\x34\xe9\xb9\x4a\xef\x1c\x67\x5a\x9c\x01\x83\xb9\xad\xc3\x80\x45\x51\x77\x02\x57\x2c\x49\x81\xb6\x5d\x3d\xf1\x6c\xe7\x85\x3d\x37\xb4\xa4\xc8\x49\xa5\x91\x42\x06\xcd\x8b\xea\x70\x14\xd7\x82\x3d\x84\xa3\xc8\x8f\x4f\x39\xb4\xeb\x2e\xa7\x39\xe3\x34\x98\xaf\x33\x08\x52\xa3\x6c\xd9\x3b\x0c\xe0\xfa\xd2\x9d\xb2\xd9\x71\x38\x6f\xa5\xf7\x37\x02\xa4\x86\xce\x5d\x3f\xd5\x14\xe3\xbf\x04\xb6\xcd\x5d\x29\x59\x0b\x3a\xb5\x25\x51\x78\xc6\x94\xac\x89\x21\xca\xf1\x1c\xcd\xe0\x40\xee\xba\xe1\x29\xe4\xd6\x2a\x33\x68\x9a\x2e\xd7\xc8\x42\xd7\x26\xba\xd1\x42\x2a\x8a\x2a\x52\x84\xb2\x5a\x4f\xe1\xd3\xea\x61\xf6\x4b\xdb\x39\xbb\x0a\xfd\x09\xa0\x95\xc2\xf9\x19\x9e\x3c\x77\xaf\xd8\xae\x21\x48\x13\x4b\xf0\x34\x93\xee\xa0\xfd\xd7\xe4\x70\xa1\x07\x81\xee\xa5\xb6\x9f\x2f\x19\xa5\x1c\x2d\xd8\x96\xb9\xbd\x6d\xd6\xe6\x87\x3b\x73\x2c\x0e\x7c\xe3\xd1\xd2\xef\x01\xb9\xc6\x47\x89\xbb\xfe\x65\x68\x0d\x1e\xd9\x83\x32\xa7\x67\xdf\x0a\xb9\x69\x35\x74\x1a\xf0\x9f\x37\x68\xad\x5c\x15\x14\x46\xde\xa1\x6e\x60\xa8\x6d\x4d\x46\xf5\x70\x14\x17\x75\x49\x04\xfb\x1d\x43\x9b\x50\x46\x8d\x86\x5c\x43\x14\x1c\xc7\xd5\x33\x20\x87\x06\x7b\xd8\x26\xa6\xa1\x57\xdc\xb0\xb5\xa6\x35\x1c\x1c\x1a\xf6\xe1\x3b\x68\xe5\xb2\x84\x68\x41\x14\xf4\x07\x51\x9b\x2d\x41\x49\x2b\xb9\x5d\x5b\x10\x35\x6c\x9a\x40\x57\x37\x0b\xb9\xc9\x86\xb7\xe3\x0e\x60\x63\x58\x67\xd7\xa1\xf7\xab\x13\x03\x58\x84\xed\x05\x9c\xc3\xed\xf8\xc3\x91\x52\x22\x56\x78\x8a\xde\x28\x56\x21\x05\x92\xdb\x26\xf8\x0f\x3f\xc4\x07\x2b\xf7\x9d\xe1\x59\xbf\x6b\xd5\xe6\xdc\xf2\x08\xab\x5d\xed\xb4\xfa\x67\x7b\xaf\x20\x71\xba\xbd\x86\xe0\xc2\x21\x1e\xf1\xbc\x23\xa2\x93\xcb\xfb\xd8\xbd\x76\xbd\x7c\xd0\x4f\x12\xb6\xfc\xec\x5e\x3d\x8d\xe2\xc2\x94\x3c\x0c\x52\xe3\x3e\x5c\x59\x9c\xdd\x6e\xb7\xb9\x99\x3e\xd4\x5b\xfb\x7e\xd7\x60\x7b\x64\x3c\xe9\x6e\xa0\x57\x47\x74\x1d\x50\x5b\x34\x80\xed\xa6\xf6\xae\xa1\x7a\x63\x88\x32\x40\xe0\xa7\x57\x50\x57\x94\x18\x9b\x84\x24\xd8\x14\xe7\x92\x51\xf7\x95\x6f\x41\x94\x86\xa5\x54\x1b\xa2\x28\xd4\xc2\x30\x6e\xd7\xb7\x40\x14\xfa\x9a\x4c\xa3\x79\x65\xa3\xd2\x9a\xf0\xf0\xa4\xcf\x7a\x16\x0e\xe3\xbe\x61\x87\xa3\x18\x49\x5e\x9c\x92\xb9\xac\xd3\x49\xcc\xe0\xb5\xab\xc1\xc3\x67\xa1\x29\x98\x1e\xc5\xc4\x18\x15\x0e\x8f\x0c\x3e\x1c\x59\xdb\x4d\xba\xbe\xa7\xdb\x9c\xf6\xae\xcc\x53\xfb\x0f\x55\xad\xcf\xe0\x2d\x71\xae\x75\xd8\x78\xcd\xf0\xa6\xc7\xf7\xd8\x69\x86\x1f\x0f\xbd\x49\x0e\x97\xf6\x80\x3f\xbb\x80\xe1\x88\xed\xd0\xde\x9d\xe1\x89\x60\x42\xe9\x4b\x7b\x2f\xc2\xe0\xc2\xed\xed\x7b\xc0\xc8\x2b\xb6\x89\xb8\x4f\x68\x94\x09\x8a\x0f\x8f\xa9\x93\xd1\xe1\x28\xd6\xf5\xa2\xe9\xfd\xc3\xcf\x7c\xb7\xd3\x12\x39\xb7\x3c\x0d\xe4\x67\xe9\xdf\x0a\x38\x2e\x01\xa2\x93\x92\xe1\x89\x98\xef\x04\xda\xd3\xec\x6f\xac\x72\xc7\x23\xff\x62\xe8\x1b\x6d\x2b\x20\xa6\x0b\x20\xb0\xc1\x85\x76\xbd\x39\x78\x4f\x76\x6f\x48\x9a\x37\x21\x2f\xbe\x7f\xd5\xbd\x0d\xe9\x3c\xdd\x16\x21\xdd\xf7\xf4\xf3\x77\x0d\x17\x3f\xdf\x6f\x36\x9b\x78\x25\xe5\x8a\x37\x1f\xee\xbb\x97\x11\xb6\x51\x8f\xef\x74\x00\x44\x6f\x45\x0e\x14\x97\xa8\xe6\x3d\xe6\xcd\x1b\x8a\x34\xf1\xdf\x9c\x93\xe6\xff\xd8\xfc\x27\x00\x00\xff\xff\xe5\xd8\xf8\x8e\x74\x23\x00\x00")
func faucetHtmlBytes() ([]byte, error) {
return bindataRead(
@@ -84,8 +92,8 @@ func faucetHtml() (*asset, error) {
return nil, err
}
- info := bindataFileInfo{name: "faucet.html", size: 9010, mode: os.FileMode(0644), modTime: time.Unix(1653732396, 0)}
- a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb, 0xb7, 0xec, 0xe1, 0xa2, 0x8e, 0x94, 0xb, 0x2a, 0xc4, 0x21, 0x38, 0xa9, 0x6d, 0xdd, 0x31, 0x4, 0x3f, 0xa6, 0x26, 0xbe, 0x79, 0x11, 0xfc, 0xc0, 0x81, 0xe7, 0x85, 0x56, 0xec, 0x3, 0x77}}
+ info := bindataFileInfo{name: "faucet.html", size: 0, mode: os.FileMode(0), modTime: time.Unix(0, 0)}
+ a := &asset{bytes: bytes, info: info}
return a, nil
}
@@ -93,8 +101,8 @@ func faucetHtml() (*asset, error) {
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
- canonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[canonicalName]; ok {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
@@ -104,12 +112,6 @@ func Asset(name string) ([]byte, error) {
return nil, fmt.Errorf("Asset %s not found", name)
}
-// AssetString returns the asset contents as a string (instead of a []byte).
-func AssetString(name string) (string, error) {
- data, err := Asset(name)
- return string(data), err
-}
-
// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
@@ -121,18 +123,12 @@ func MustAsset(name string) []byte {
return a
}
-// MustAssetString is like AssetString but panics when Asset would return an
-// error. It simplifies safe initialization of global variables.
-func MustAssetString(name string) string {
- return string(MustAsset(name))
-}
-
// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
- canonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[canonicalName]; ok {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
@@ -142,33 +138,6 @@ func AssetInfo(name string) (os.FileInfo, error) {
return nil, fmt.Errorf("AssetInfo %s not found", name)
}
-// AssetDigest returns the digest of the file with the given name. It returns an
-// error if the asset could not be found or the digest could not be loaded.
-func AssetDigest(name string) ([sha256.Size]byte, error) {
- canonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[canonicalName]; ok {
- a, err := f()
- if err != nil {
- return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err)
- }
- return a.digest, nil
- }
- return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name)
-}
-
-// Digests returns a map of all known files and their checksums.
-func Digests() (map[string][sha256.Size]byte, error) {
- mp := make(map[string][sha256.Size]byte, len(_bindata))
- for name := range _bindata {
- a, err := _bindata[name]()
- if err != nil {
- return nil, err
- }
- mp[name] = a.digest
- }
- return mp, nil
-}
-
// AssetNames returns the names of the assets.
func AssetNames() []string {
names := make([]string, 0, len(_bindata))
@@ -183,27 +152,26 @@ var _bindata = map[string]func() (*asset, error){
"faucet.html": faucetHtml,
}
-// AssetDebug is true if the assets were built with the debug flag enabled.
-const AssetDebug = false
-
// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
-// data/
-// foo.txt
-// img/
-// a.png
-// b.png
-// then AssetDir("data") would return []string{"foo.txt", "img"},
-// AssetDir("data/img") would return []string{"a.png", "b.png"},
-// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and
+//
+// data/
+// foo.txt
+// img/
+// a.png
+// b.png
+//
+// then AssetDir("data") would return []string{"foo.txt", "img"}
+// AssetDir("data/img") would return []string{"a.png", "b.png"}
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
- canonicalName := strings.Replace(name, "\\", "/", -1)
- pathList := strings.Split(canonicalName, "/")
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ pathList := strings.Split(cannonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
@@ -230,7 +198,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"faucet.html": {faucetHtml, map[string]*bintree{}},
}}
-// RestoreAsset restores an asset under the given directory.
+// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
data, err := Asset(name)
if err != nil {
@@ -248,10 +216,14 @@ func RestoreAsset(dir, name string) error {
if err != nil {
return err
}
- return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+ err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+ if err != nil {
+ return err
+ }
+ return nil
}
-// RestoreAssets restores an asset under the given directory recursively.
+// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
children, err := AssetDir(name)
// File
@@ -269,6 +241,6 @@ func RestoreAssets(dir, name string) error {
}
func _filePath(dir, name string) string {
- canonicalName := strings.Replace(name, "\\", "/", -1)
- return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...)
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index 47d333fed..1c37e00c4 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -311,6 +311,14 @@ func geth(ctx *cli.Context) error {
defer stack.Close()
startNode(ctx, stack, backend)
+
+ log.Info("***************************** CONFIG INFO ****************************")
+ log.Info("******* FNCY_2.0", "chainId", backend.ChainConfig().ChainID)
+ log.Info("******* FNCY_2.0", "contract48kBlock", backend.ChainConfig().Contract48kBlock.Int64())
+ log.Info("******* FNCY_2.0", "fncy2Block", backend.ChainConfig().Fncy2Block.Int64())
+ log.Info("******* FNCY_2.0", "stopMintBlock", backend.ChainConfig().Parlia.StopMintBlock.Int64())
+ log.Info("***************************** CONFIG INFO *****************************")
+ log.Info("Start FNCY_2.0 success")
stack.Wait()
return nil
}
diff --git a/consensus/parlia/abi.go b/consensus/parlia/abi.go
index a0b49800c..7c0817b8b 100644
--- a/consensus/parlia/abi.go
+++ b/consensus/parlia/abi.go
@@ -2,544 +2,1051 @@ package parlia
const validatorSetABI = `
[
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "batchTransfer",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "deprecatedDeposit",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address payable",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "directTransfer",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "systemTransfer",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "validatorDeposit",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "validatorFelony",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "validatorJailed",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "validator",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
- ],
- "name": "validatorMisdemeanor",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [],
- "name": "validatorSetUpdated",
- "type": "event"
- },
- {
- "inputs": [],
- "name": "CHANNEL_ID",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "DUSTY_INCOMING",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "EXTRA_FEE",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "JAIL_MESSAGE_TYPE",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "RELAYER_REWARD",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "SYSTEM_ADDRESS",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "VALIDATORS_UPDATE_MESSAGE_TYPE",
- "outputs": [
- {
- "internalType": "uint8",
- "name": "",
- "type": "uint8"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "alreadyInit",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "name": "currentValidatorSet",
- "outputs": [
- {
- "internalType": "address",
- "name": "consensusAddress",
- "type": "address"
- },
- {
- "internalType": "address payable",
- "name": "feeAddress",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "BBCFeeAddress",
- "type": "address"
- },
- {
- "internalType": "uint64",
- "name": "votingPower",
- "type": "uint64"
- },
- {
- "internalType": "bool",
- "name": "jailed",
- "type": "bool"
- },
- {
- "internalType": "uint256",
- "name": "incoming",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "fromChainId",
- "outputs": [
- {
- "internalType": "uint16",
- "name": "",
- "type": "uint16"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "initLightClientAddr",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "initSlashContract",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "initSystemRewardAddr",
- "outputs": [
- {
- "internalType": "address payable",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "initTokenHubAddr",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "initValidatorSetBytes",
- "outputs": [
- {
- "internalType": "bytes",
- "name": "",
- "type": "bytes"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "keyPrefix",
- "outputs": [
- {
- "internalType": "bytes",
- "name": "",
- "type": "bytes"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "previousDepositHeight",
- "outputs": [
- {
- "internalType": "uint64",
- "name": "",
- "type": "uint64"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "sequence",
- "outputs": [
- {
- "internalType": "uint64",
- "name": "",
- "type": "uint64"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "toChainId",
- "outputs": [
- {
- "internalType": "uint16",
- "name": "",
- "type": "uint16"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "totalInComing",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "init",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "valAddr",
- "type": "address"
- }
- ],
- "name": "deposit",
- "outputs": [],
- "stateMutability": "payable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "bytes",
- "name": "msgBytes",
- "type": "bytes"
- },
- {
- "internalType": "bytes",
- "name": "proof",
- "type": "bytes"
- },
- {
- "internalType": "uint64",
- "name": "height",
- "type": "uint64"
- },
- {
- "internalType": "uint64",
- "name": "packageSequence",
- "type": "uint64"
- }
- ],
- "name": "update",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "getValidators",
- "outputs": [
- {
- "internalType": "address[]",
- "name": "",
- "type": "address[]"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "getIncoming",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "misdemeanor",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "validator",
- "type": "address"
- }
- ],
- "name": "felony",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- }
- ]
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "staker",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "Claimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "staker",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "Delegated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint8",
+ "name": "version",
+ "type": "uint8"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "staker",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "dust",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "Redelegated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "ShareRewards",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "staker",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "Undelegated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint8",
+ "name": "status",
+ "type": "uint8"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint16",
+ "name": "commissionRate",
+ "type": "uint16"
+ }
+ ],
+ "name": "ValidatorAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "ValidatorDeposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "ValidatorJailed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint8",
+ "name": "status",
+ "type": "uint8"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint16",
+ "name": "commissionRate",
+ "type": "uint16"
+ }
+ ],
+ "name": "ValidatorModified",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "ValidatorOwnerClaimed",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "ValidatorReleased",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ }
+ ],
+ "name": "ValidatorRemoved",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint32",
+ "name": "slashes",
+ "type": "uint32"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "ValidatorSlashed",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "init",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isInitialized",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes[]",
+ "name": "data",
+ "type": "bytes[]"
+ }
+ ],
+ "name": "multicall",
+ "outputs": [
+ {
+ "internalType": "bytes[]",
+ "name": "results",
+ "type": "bytes[]"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes",
+ "name": "delayedInitializer",
+ "type": "bytes"
+ }
+ ],
+ "name": "useDelayedInitializer",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "validators",
+ "type": "address[]"
+ },
+ {
+ "internalType": "address[]",
+ "name": "owners",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "initialStakes",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint16",
+ "name": "commissionRate",
+ "type": "uint16"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "delegator",
+ "type": "address"
+ }
+ ],
+ "name": "getValidatorDelegation",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "delegatedAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint64",
+ "name": "atEpoch",
+ "type": "uint64"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getValidatorStatus",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "ownerAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "status",
+ "type": "uint8"
+ },
+ {
+ "internalType": "uint256",
+ "name": "totalDelegated",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint32",
+ "name": "slashesCount",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint64",
+ "name": "changedAt",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "jailedBefore",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "claimedAt",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint16",
+ "name": "commissionRate",
+ "type": "uint16"
+ },
+ {
+ "internalType": "uint96",
+ "name": "totalRewards",
+ "type": "uint96"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint64",
+ "name": "epoch",
+ "type": "uint64"
+ }
+ ],
+ "name": "getValidatorStatusAtEpoch",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "ownerAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint8",
+ "name": "status",
+ "type": "uint8"
+ },
+ {
+ "internalType": "uint256",
+ "name": "totalDelegated",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint32",
+ "name": "slashesCount",
+ "type": "uint32"
+ },
+ {
+ "internalType": "uint64",
+ "name": "changedAt",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "jailedBefore",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint64",
+ "name": "claimedAt",
+ "type": "uint64"
+ },
+ {
+ "internalType": "uint16",
+ "name": "commissionRate",
+ "type": "uint16"
+ },
+ {
+ "internalType": "uint96",
+ "name": "totalRewards",
+ "type": "uint96"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "getValidatorByOwner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "releaseValidatorFromJail",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "forceUnJailValidator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "delegate",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "undelegate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "currentEpoch",
+ "outputs": [
+ {
+ "internalType": "uint64",
+ "name": "",
+ "type": "uint64"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "nextEpoch",
+ "outputs": [
+ {
+ "internalType": "uint64",
+ "name": "",
+ "type": "uint64"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint16",
+ "name": "commissionRate",
+ "type": "uint16"
+ }
+ ],
+ "name": "registerValidator",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "removeValidator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "activateValidator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "disableValidator",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint16",
+ "name": "commissionRate",
+ "type": "uint16"
+ }
+ ],
+ "name": "changeValidatorCommissionRate",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "changeValidatorOwner",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isValidatorActive",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "isValidator",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getValidators",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "deposit",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "blockRewards",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "gasFee",
+ "type": "uint256"
+ }
+ ],
+ "name": "distributeRewards",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getValidatorFee",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getPendingValidatorFee",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "claimValidatorFee",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "delegatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getDelegatorFee",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "delegatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "getPendingDelegatorFee",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "claimDelegatorFee",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ }
+ ],
+ "name": "claimPendingUndelegates",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "delegator",
+ "type": "address"
+ }
+ ],
+ "name": "calcAvailableForRedelegateAmount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "amountToStake",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "rewardsDust",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validator",
+ "type": "address"
+ }
+ ],
+ "name": "redelegateDelegatorFee",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "validatorAddress",
+ "type": "address"
+ }
+ ],
+ "name": "slash",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ }
+]
`
const slashABI = `
diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go
index 9cb505e2e..9db67a943 100644
--- a/consensus/parlia/parlia.go
+++ b/consensus/parlia/parlia.go
@@ -1054,6 +1054,9 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash) ([]common.Address,
}
func (p *Parlia) BlockRewards(blockNumber *big.Int) *big.Int {
if rules := p.chainConfig.Rules(blockNumber); rules.HasBlockRewards {
+ if p.chainConfig.Parlia.StopMintBlock != nil && p.chainConfig.Parlia.StopMintBlock.Cmp(blockNumber) <= 0 {
+ return nil
+ }
blockRewards := p.chainConfig.Parlia.BlockRewards
if blockRewards != nil && blockRewards.Cmp(common.Big0) > 0 {
return blockRewards
@@ -1070,17 +1073,21 @@ func (p *Parlia) distributeIncoming(val common.Address, state *state.StateDB, he
state.SetBalance(consensus.SystemAddress, big.NewInt(0))
state.AddBalance(coinbase, balance)
rewards := big.NewInt(0).Abs(balance)
- if rules := p.chainConfig.Rules(header.Number); rules.HasBlockRewards {
- blockRewards := p.chainConfig.Parlia.BlockRewards
- // if we have enabled block rewards and rewards are greater than 0 then
- if blockRewards != nil && blockRewards.Cmp(common.Big0) > 0 {
- state.AddBalance(coinbase, blockRewards)
- rewards = rewards.Add(rewards, blockRewards)
- }
+ blockRewards := p.BlockRewards(header.Number)
+ if blockRewards != nil {
+ rewards = rewards.Add(rewards, blockRewards)
+ state.AddBalance(coinbase, blockRewards)
}
if rewards.Cmp(common.Big0) <= 0 {
return nil
}
+ if p.chainConfig.IsFncy2(header.Number) {
+ if blockRewards == nil {
+ blockRewards = big.NewInt(0)
+ }
+ log.Trace("fncy2 distribute to validator contract", "block hash", header.Hash(), "amount", rewards)
+ return p.distributeRewards(rewards, blockRewards, balance, val, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
+ }
// remove 1/16 reward according to netmarble
//doDistributeSysReward := state.GetBalance(common.HexToAddress(systemcontract.SystemRewardContract)).Cmp(maxSystemBalance) < 0
//if doDistributeSysReward {
@@ -1160,6 +1167,27 @@ func (p *Parlia) distributeToSystem(amount *big.Int, state *state.StateDB, heade
return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
}
+// slash spoiled validators
+func (p *Parlia) distributeRewards(amount *big.Int, blockRewards *big.Int, gasFee *big.Int, validator common.Address,
+ state *state.StateDB, header *types.Header, chain core.ChainContext,
+ txs *[]*types.Transaction, receipts *[]*types.Receipt, receivedTxs *[]*types.Transaction, usedGas *uint64, mining bool) error {
+ // method
+ method := "distributeRewards"
+
+ // get packed data
+ data, err := p.validatorSetABI.Pack(method,
+ validator, blockRewards, gasFee,
+ )
+ if err != nil {
+ log.Error("Unable to pack tx for distributeRewards", "error", err)
+ return err
+ }
+ // get system message
+ msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontract.ValidatorContract), data, amount)
+ // apply message
+ return p.applyTransaction(msg, state, header, chain, txs, receipts, receivedTxs, usedGas, mining)
+}
+
// slash spoiled validators
func (p *Parlia) distributeToValidator(amount *big.Int, validator common.Address,
state *state.StateDB, header *types.Header, chain core.ChainContext,
diff --git a/core/state_transition.go b/core/state_transition.go
index e71b98075..636c90636 100644
--- a/core/state_transition.go
+++ b/core/state_transition.go
@@ -39,8 +39,10 @@ The state transitioning model does all the necessary work to work out a valid ne
3) Create a new state object if the recipient is \0*32
4) Value transfer
== If contract creation ==
- 4a) Attempt to run transaction data
- 4b) If valid, use result as code for the new state object
+
+ 4a) Attempt to run transaction data
+ 4b) If valid, use result as code for the new state object
+
== end ==
5) Run Script section
6) Derive new state root
@@ -213,13 +215,13 @@ func (st *StateTransition) preCheck() error {
// TransitionDb will transition the state by applying the current message and
// returning the evm execution result with following fields.
//
-// - used gas:
-// total gas used (including gas being refunded)
-// - returndata:
-// the returned data from evm
-// - concrete execution error:
-// various **EVM** error which aborts the execution,
-// e.g. ErrOutOfGas, ErrExecutionReverted
+// - used gas:
+// total gas used (including gas being refunded)
+// - returndata:
+// the returned data from evm
+// - concrete execution error:
+// various **EVM** error which aborts the execution,
+// e.g. ErrOutOfGas, ErrExecutionReverted
//
// However if any consensus issue encountered, return the error directly with
// nil evm execution result.
@@ -238,6 +240,14 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
if err := st.preCheck(); err != nil {
return nil, err
}
+
+ if st.evm.VmConfig.Debug {
+ st.evm.VmConfig.Tracer.CaptureTxStart(st.initialGas)
+ defer func() {
+ st.evm.VmConfig.Tracer.CaptureTxEnd(st.gas)
+ }()
+ }
+
msg := st.msg
sender := vm.AccountRef(msg.From())
homestead := st.evm.ChainConfig().IsHomestead(st.evm.Context.BlockNumber)
diff --git a/core/tx_pool.go b/core/tx_pool.go
index ba073a29a..954c75cb1 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -253,6 +253,7 @@ type TxPool struct {
gasFreeAddressMap map[common.Address]uint // from address that can join tx_pool for free
gasFreeAddressMapFunc func(common.Hash) (map[common.Address]uint, error) // add func to get gasFreeAddressMap
+ gasPriceFunc func(common.Hash) (*big.Int, error) // add func to get gas price, do nothing when return 0
pending map[common.Address]*txList // All currently processable transactions
queue map[common.Address]*txList // Queued but non-processable transactions
@@ -283,11 +284,17 @@ func getNoGasFreeAddressMapFunc() func(common.Hash) (map[common.Address]uint, er
return gasFreeToAddressMap, nil
}
}
+func getGasPriceFunc() func(common.Hash) (*big.Int, error) {
+ return func(blockHash common.Hash) (*big.Int, error) {
+ return big.NewInt(0), nil
+ }
+}
+
func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool {
- return NewEnhanceTxPool(config, chainconfig, chain, getNoGasFreeAddressMapFunc())
+ return NewEnhanceTxPool(config, chainconfig, chain, getNoGasFreeAddressMapFunc(), getGasPriceFunc())
}
-func NewEnhanceTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain, gasFreeAddressMapFunc func(common.Hash) (map[common.Address]uint, error)) *TxPool {
+func NewEnhanceTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain, gasFreeAddressMapFunc func(common.Hash) (map[common.Address]uint, error), gasPriceFunc func(common.Hash) (*big.Int, error)) *TxPool {
// Sanitize the input to ensure no vulnerable gas prices are set
config = (&config).sanitize()
// Create the transaction pool with its initial settings
@@ -309,6 +316,7 @@ func NewEnhanceTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chai
gasPrice: new(big.Int).SetUint64(config.PriceLimit),
gasFreeAddressMap: make(map[common.Address]uint),
gasFreeAddressMapFunc: gasFreeAddressMapFunc,
+ gasPriceFunc: gasPriceFunc,
}
pool.locals = newAccountSet(pool.signer)
for _, addr := range config.Locals {
@@ -479,10 +487,19 @@ func (pool *TxPool) SubscribeReannoTxsEvent(ch chan<- ReannoTxsEvent) event.Subs
func (pool *TxPool) GasPrice() *big.Int {
pool.mu.RLock()
defer pool.mu.RUnlock()
+ return new(big.Int).Set(pool.gasPrice)
+}
+//Fncy2 Update
+func (pool *TxPool) GasPriceWithoutLock() *big.Int {
return new(big.Int).Set(pool.gasPrice)
}
+func (pool *TxPool) SetGasPriceWithoutLock(price *big.Int) {
+ pool.gasPrice = price
+ log.Info("Transaction pool price threshold updated", "price", price)
+}
+
// SetGasPrice updates the minimum price required by the transaction pool for a
// new transaction, and drops all transactions below this threshold.
func (pool *TxPool) SetGasPrice(price *big.Int) {
@@ -551,7 +568,6 @@ func (pool *TxPool) Content() (map[common.Address]types.Transactions, map[common
func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
pool.mu.Lock()
defer pool.mu.Unlock()
-
pending := make(map[common.Address]types.Transactions)
for addr, list := range pool.pending {
pending[addr] = list.Flatten()
@@ -1293,6 +1309,21 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
next := new(big.Int).Add(newHead.Number, big.NewInt(1))
pool.istanbul = pool.chainconfig.IsIstanbul(next)
pool.eip2718 = pool.chainconfig.IsBerlin(next)
+ //fncy2 update
+ if pool.chainconfig.IsFncy2(next) {
+ gasPrice, err := pool.gasPriceFunc(pool.chain.CurrentBlock().Hash())
+ if err != nil {
+ log.Warn("Failed to get gasPrice", "err", err)
+ } else {
+ if gasPrice != nil && gasPrice.Cmp(common.Big0) > 0 {
+ if pool.gasPrice == nil || pool.gasPrice.Cmp(gasPrice) != 0 {
+ log.Debug("Set gasPrice ", " old gasPrice", pool.gasPrice, " new gasPrice", gasPrice)
+ pool.SetGasPriceWithoutLock(gasPrice)
+ }
+ }
+ }
+ }
+
}
// promoteExecutables moves transactions that have become processable from the
diff --git a/core/vm/access_list_tracer.go b/core/vm/access_list_tracer.go
index d7993b4f7..3f79d6d5a 100644
--- a/core/vm/access_list_tracer.go
+++ b/core/vm/access_list_tracer.go
@@ -180,3 +180,12 @@ func (a *AccessListTracer) AccessList() types.AccessList {
func (a *AccessListTracer) Equal(other *AccessListTracer) bool {
return a.list.equal(other.list)
}
+
+// CaptureTxStart implements the Tracer interface and is invoked at the beginning of
+// transaction processing.
+func (t *AccessListTracer) CaptureTxStart(gasLimit uint64) {
+}
+
+// CaptureTxStart implements the Tracer interface and is invoked at the end of
+// transaction processing.
+func (t *AccessListTracer) CaptureTxEnd(restGas uint64) {}
diff --git a/core/vm/evm.go b/core/vm/evm.go
index e24212105..06cf98e08 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -134,7 +134,7 @@ type EVM struct {
chainRules params.Rules
// virtual machine configuration options used to initialise the
// evm.
- vmConfig Config
+ VmConfig Config
// global (to this context) ethereum virtual machine
// used throughout the execution of the tx.
interpreters []Interpreter
@@ -155,7 +155,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
evm.Context = blockCtx
evm.TxContext = txCtx
evm.StateDB = statedb
- evm.vmConfig = vmConfig
+ evm.VmConfig = vmConfig
evm.chainConfig = chainConfig
evm.chainRules = chainConfig.Rules(blockCtx.BlockNumber)
evm.interpreters = make([]Interpreter, 0, 1)
@@ -215,7 +215,7 @@ func (evm *EVM) Interpreter() Interpreter {
// the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer.
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+ if evm.VmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
@@ -232,13 +232,13 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
if !evm.StateDB.Exist(addr) {
if !isPrecompile && evm.chainRules.IsEIP158 && value.Sign() == 0 {
// Calling a non existing account, don't do anything, but ping the tracer
- if evm.vmConfig.Debug {
+ if evm.VmConfig.Debug {
if evm.depth == 0 {
- evm.vmConfig.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
- evm.vmConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
+ evm.VmConfig.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
+ evm.VmConfig.Tracer.CaptureEnd(ret, 0, 0, nil)
} else {
- evm.vmConfig.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
- evm.vmConfig.Tracer.CaptureExit(ret, 0, nil)
+ evm.VmConfig.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
+ evm.VmConfig.Tracer.CaptureExit(ret, 0, nil)
}
}
return nil, gas, nil
@@ -248,17 +248,17 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value)
// Capture the tracer start/end events in debug mode
- if evm.vmConfig.Debug {
+ if evm.VmConfig.Debug {
if evm.depth == 0 {
- evm.vmConfig.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
+ evm.VmConfig.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value)
defer func(startGas uint64, startTime time.Time) { // Lazy evaluation of the parameters
- evm.vmConfig.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err)
+ evm.VmConfig.Tracer.CaptureEnd(ret, startGas-gas, time.Since(startTime), err)
}(gas, time.Now())
} else {
// Handle tracer events for entering and exiting a call frame
- evm.vmConfig.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
+ evm.VmConfig.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value)
defer func(startGas uint64) {
- evm.vmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
+ evm.VmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
}
@@ -304,7 +304,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas
// CallCode differs from Call in the sense that it executes the given address'
// code with the caller as context.
func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+ if evm.VmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
@@ -321,10 +321,10 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
var snapshot = evm.StateDB.Snapshot()
// Invoke tracer hooks that signal entering/exiting a call frame
- if evm.vmConfig.Debug {
- evm.vmConfig.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
+ if evm.VmConfig.Debug {
+ evm.VmConfig.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value)
defer func(startGas uint64) {
- evm.vmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
+ evm.VmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
@@ -355,7 +355,7 @@ func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte,
// DelegateCall differs from CallCode in the sense that it executes the given address'
// code with the caller as context and the caller is set to the caller of the caller.
func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+ if evm.VmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
@@ -365,10 +365,10 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
var snapshot = evm.StateDB.Snapshot()
// Invoke tracer hooks that signal entering/exiting a call frame
- if evm.vmConfig.Debug {
- evm.vmConfig.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, nil)
+ if evm.VmConfig.Debug {
+ evm.VmConfig.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, nil)
defer func(startGas uint64) {
- evm.vmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
+ evm.VmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
@@ -397,7 +397,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
// Opcodes that attempt to perform such modifications will result in exceptions
// instead of performing the modifications.
func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) {
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+ if evm.VmConfig.NoRecursion && evm.depth > 0 {
return nil, gas, nil
}
// Fail if we're trying to execute above the call depth limit
@@ -418,10 +418,10 @@ func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte
evm.StateDB.AddBalance(addr, big0)
// Invoke tracer hooks that signal entering/exiting a call frame
- if evm.vmConfig.Debug {
- evm.vmConfig.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
+ if evm.VmConfig.Debug {
+ evm.VmConfig.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil)
defer func(startGas uint64) {
- evm.vmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
+ evm.VmConfig.Tracer.CaptureExit(ret, startGas-gas, err)
}(gas)
}
@@ -498,15 +498,15 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
contract := NewContract(caller, AccountRef(address), value, gas)
contract.SetCodeOptionalHash(&address, codeAndHash)
- if evm.vmConfig.NoRecursion && evm.depth > 0 {
+ if evm.VmConfig.NoRecursion && evm.depth > 0 {
return nil, address, gas, nil
}
- if evm.vmConfig.Debug {
+ if evm.VmConfig.Debug {
if evm.depth == 0 {
- evm.vmConfig.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value)
+ evm.VmConfig.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value)
} else {
- evm.vmConfig.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
+ evm.VmConfig.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value)
}
}
@@ -515,7 +515,11 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
ret, err := run(evm, contract, nil, false)
// Check whether the max code size has been exceeded, assign err if the case.
- if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
+ maxCodeSize := params.MaxCodeSize
+ if evm.chainRules.IsContract48kBlock {
+ maxCodeSize = params.MaxCodeSize * 2
+ }
+ if err == nil && evm.chainRules.IsEIP158 && len(ret) > maxCodeSize {
err = ErrMaxCodeSizeExceeded
}
@@ -542,11 +546,11 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
}
}
- if evm.vmConfig.Debug {
+ if evm.VmConfig.Debug {
if evm.depth == 0 {
- evm.vmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
+ evm.VmConfig.Tracer.CaptureEnd(ret, gas-contract.Gas, time.Since(start), err)
} else {
- evm.vmConfig.Tracer.CaptureExit(ret, gas-contract.Gas, err)
+ evm.VmConfig.Tracer.CaptureExit(ret, gas-contract.Gas, err)
}
}
return ret, address, contract.Gas, err
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 0ecf28d59..68571ebd4 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -244,7 +244,7 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byt
interpreter.hasher.Read(interpreter.hasherBuf[:])
evm := interpreter.evm
- if evm.vmConfig.EnablePreimageRecording {
+ if evm.VmConfig.EnablePreimageRecording {
evm.StateDB.AddPreimage(interpreter.hasherBuf, data)
}
@@ -390,16 +390,21 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
// opExtCodeHash returns the code hash of a specified account.
// There are several cases when the function is called, while we can relay everything
// to `state.GetCodeHash` function to ensure the correctness.
-// (1) Caller tries to get the code hash of a normal contract account, state
+//
+// (1) Caller tries to get the code hash of a normal contract account, state
+//
// should return the relative code hash and set it as the result.
//
-// (2) Caller tries to get the code hash of a non-existent account, state should
+// (2) Caller tries to get the code hash of a non-existent account, state should
+//
// return common.Hash{} and zero will be set as the result.
//
-// (3) Caller tries to get the code hash for an account without contract code,
+// (3) Caller tries to get the code hash for an account without contract code,
+//
// state should return emptyCodeHash(0xc5d246...) as the result.
//
-// (4) Caller tries to get the code hash of a precompiled account, the result
+// (4) Caller tries to get the code hash of a precompiled account, the result
+//
// should be zero or emptyCodeHash.
//
// It is worth noting that in order to avoid unnecessary create and clean,
@@ -408,10 +413,12 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
// If the precompile account is not transferred any amount on a private or
// customized chain, the return value will be zero.
//
-// (5) Caller tries to get the code hash for an account which is marked as suicided
+// (5) Caller tries to get the code hash for an account which is marked as suicided
+//
// in the current transaction, the code hash of this account should be returned.
//
-// (6) Caller tries to get the code hash for an account which is marked as deleted,
+// (6) Caller tries to get the code hash for an account which is marked as deleted,
+//
// this account should be regarded as a non-existent account and zero should be returned.
func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
slot := scope.Stack.peek()
diff --git a/core/vm/logger.go b/core/vm/logger.go
index f8f08e726..131f83213 100644
--- a/core/vm/logger.go
+++ b/core/vm/logger.go
@@ -105,6 +105,10 @@ func (s *StructLog) ErrorString() string {
// Note that reference types are actual VM data structures; make copies
// if you need to retain them beyond the current call.
type EVMLogger interface {
+ // Transaction level
+ CaptureTxStart(gasLimit uint64)
+ CaptureTxEnd(restGas uint64)
+
CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int)
CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error)
CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int)
@@ -147,6 +151,10 @@ func (l *StructLogger) Reset() {
l.err = nil
}
+func (*StructLogger) CaptureTxStart(gasLimit uint64) {}
+
+func (*StructLogger) CaptureTxEnd(restGas uint64) {}
+
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
func (l *StructLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
l.env = env
@@ -307,6 +315,15 @@ func NewMarkdownLogger(cfg *LogConfig, writer io.Writer) *mdLogger {
return l
}
+// CaptureTxStart implements the Tracer interface and is invoked at the beginning of
+// transaction processing.
+func (t *mdLogger) CaptureTxStart(gasLimit uint64) {
+}
+
+// CaptureTxStart implements the Tracer interface and is invoked at the end of
+// transaction processing.
+func (t *mdLogger) CaptureTxEnd(restGas uint64) {}
+
func (t *mdLogger) CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
t.env = env
if !create {
diff --git a/core/vm/logger_json.go b/core/vm/logger_json.go
index c249dba7e..8c4fbf3dc 100644
--- a/core/vm/logger_json.go
+++ b/core/vm/logger_json.go
@@ -42,6 +42,15 @@ func NewJSONLogger(cfg *LogConfig, writer io.Writer) *JSONLogger {
return l
}
+// CaptureTxStart implements the Tracer interface and is invoked at the beginning of
+// transaction processing.
+func (t *JSONLogger) CaptureTxStart(gasLimit uint64) {
+}
+
+// CaptureTxStart implements the Tracer interface and is invoked at the end of
+// transaction processing.
+func (t *JSONLogger) CaptureTxEnd(restGas uint64) {}
+
func (l *JSONLogger) CaptureStart(env *EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
l.env = env
}
diff --git a/eth/abi.go b/eth/abi.go
index c76b58bc3..1033c3f66 100644
--- a/eth/abi.go
+++ b/eth/abi.go
@@ -21,6 +21,25 @@ const chainConfigABI = `
"name": "ActiveValidatorsLengthChanged",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint16",
+ "name": "share",
+ "type": "uint16"
+ }
+ ],
+ "name": "DistributeRewardsShareChanged",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -78,6 +97,25 @@ const chainConfigABI = `
"name": "FelonyThresholdChanged",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "preValue",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "newValue",
+ "type": "address"
+ }
+ ],
+ "name": "FoundationAddressChanged",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -142,6 +180,25 @@ const chainConfigABI = `
"name": "FreeGasAddressSizeChanged",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "preValue",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "newValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "GasPriceChanged",
+ "type": "event"
+ },
{
"anonymous": false,
"inputs": [
@@ -250,6 +307,19 @@ const chainConfigABI = `
"name": "ValidatorJailEpochLengthChanged",
"type": "event"
},
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint16",
+ "name": "share",
+ "type": "uint16"
+ }
+ ],
+ "name": "ValidatorRewardsShareChanged",
+ "type": "event"
+ },
{
"inputs": [],
"name": "freeGasAddressAdmin",
@@ -711,6 +781,111 @@ const chainConfigABI = `
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "newValue",
+ "type": "uint256"
+ }
+ ],
+ "name": "setGasPrice",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getGasPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getDistributeRewardsShares",
+ "outputs": [
+ {
+ "internalType": "uint16",
+ "name": "",
+ "type": "uint16"
+ },
+ {
+ "components": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint16",
+ "name": "share",
+ "type": "uint16"
+ }
+ ],
+ "internalType": "struct IChainConfig.DistributeRewardsShare[]",
+ "name": "",
+ "type": "tuple[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint16",
+ "name": "validatorShare",
+ "type": "uint16"
+ },
+ {
+ "internalType": "address[]",
+ "name": "accounts",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint16[]",
+ "name": "shares",
+ "type": "uint16[]"
+ }
+ ],
+ "name": "updateDistributeRewardsShares",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newValue",
+ "type": "address"
+ }
+ ],
+ "name": "setFoundationAddress",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getFoundationAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
}
]
`
diff --git a/eth/api_backend.go b/eth/api_backend.go
index daf6c19ec..2cf670831 100644
--- a/eth/api_backend.go
+++ b/eth/api_backend.go
@@ -19,6 +19,7 @@ package eth
import (
"context"
"errors"
+ "github.com/ethereum/go-ethereum/log"
"math/big"
"github.com/ethereum/go-ethereum/accounts"
@@ -276,6 +277,21 @@ func (b *EthAPIBackend) Downloader() *downloader.Downloader {
}
func (b *EthAPIBackend) SuggestPrice(ctx context.Context) (*big.Int, error) {
+ //Fncy2 Update
+ if b.ChainConfig().IsFncy2(b.Chain().CurrentBlock().Header().Number) {
+ suggestPrice, err := b.gpo.SuggestPrice(ctx)
+ gasPrice := b.eth.TxPool().GasPriceWithoutLock()
+ log.Debug("suggestPrice", "gpo.SuggestPrice", suggestPrice, "gasPrice", gasPrice)
+ if err == nil {
+ if suggestPrice.Cmp(gasPrice) < 0 {
+ return gasPrice, nil
+ }
+ return suggestPrice, nil
+ } else {
+ log.Warn("gpo.SuggestPrice ", "error ", err)
+ return gasPrice, nil
+ }
+ }
return b.gpo.SuggestPrice(ctx)
}
diff --git a/eth/backend.go b/eth/backend.go
index 7aafbe28e..acafba7d9 100644
--- a/eth/backend.go
+++ b/eth/backend.go
@@ -64,6 +64,8 @@ import (
"github.com/ethereum/go-ethereum/rpc"
)
+var maxPrice = big.NewInt(1200000 * params.GWei)
+
// Config contains the configuration options of the ETH protocol.
// Deprecated: use ethconfig.Config instead.
type Config = ethconfig.Config
@@ -225,7 +227,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
if config.TxPool.Journal != "" {
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
}
- eth.txPool = core.NewEnhanceTxPool(config.TxPool, chainConfig, eth.blockchain, getCurrentGasFreeAddressMapFunc(ethAPI))
+ //getCurrentGasPriceFunc
+ eth.txPool = core.NewEnhanceTxPool(config.TxPool, chainConfig, eth.blockchain, getCurrentGasFreeAddressMapFunc(ethAPI), getCurrentGasPriceFunc(eth, ethAPI))
// Permit the downloader to use the trie cache allowance during fast sync
cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit
@@ -599,6 +602,59 @@ func (s *Ethereum) Stop() error {
return nil
}
+func getCurrentGasPriceFunc(eth *Ethereum, ee *ethapi.PublicBlockChainAPI) func(common.Hash) (*big.Int, error) {
+ return func(blockHash common.Hash) (*big.Int, error) {
+ // block
+ blockNr := rpc.BlockNumberOrHashWithHash(blockHash, false)
+ // method
+ method := "getGasPrice"
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel() // cancel when we are finished consuming integers
+ chainConfig, err := abi.JSON(strings.NewReader(chainConfigABI))
+ if err != nil {
+ log.Error("Unable to abi.JSON for getGasPrice", "error", err)
+ return nil, err
+ }
+ data, err := chainConfig.Pack(method)
+ if err != nil {
+ log.Error("Unable to pack tx for getGasPrice", "error", err)
+ return nil, err
+ }
+ // call
+ msgData := (hexutil.Bytes)(data)
+ toAddress := common.HexToAddress(systemcontract.ChainConfigContract)
+ gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2))
+ result, err := ee.Call(ctx, ethapi.CallArgs{
+ Gas: &gas,
+ To: &toAddress,
+ Data: &msgData,
+ }, blockNr, nil)
+ if err != nil {
+ return nil, err
+ }
+ gasPrice := big.NewInt(0)
+ if err := chainConfig.UnpackIntoInterface(&gasPrice, method, result); err != nil {
+ return nil, err
+ }
+ if gasPrice != nil && gasPrice.Cmp(common.Big0) > 0 {
+ if eth.APIBackend.gpo != nil {
+ if eth.APIBackend.gpo.GetDefaultPrice() == nil || eth.APIBackend.gpo.GetDefaultPrice().Cmp(gasPrice) != 0 {
+ eth.APIBackend.gpo.SetDefaultPrice(gasPrice)
+ }
+ if eth.APIBackend.gpo.GetMaxPrice() == nil || eth.APIBackend.gpo.GetMaxPrice().Cmp(maxPrice) != 0 {
+ eth.APIBackend.gpo.SetMaxPrice(maxPrice)
+ }
+ }
+ if eth.gasPrice == nil || eth.gasPrice.Cmp(gasPrice) != 0 {
+ eth.lock.Lock()
+ eth.gasPrice = gasPrice
+ eth.lock.Unlock()
+ }
+ }
+ return gasPrice, nil
+ }
+}
// getCurrentGasFreeAddressMapFunc get current GasFreeAddressMapFunc
func getCurrentGasFreeAddressMapFunc(ee *ethapi.PublicBlockChainAPI) func(common.Hash) (map[common.Address]uint, error) {
diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go
index bc8fa81a4..881ed422f 100644
--- a/eth/gasprice/gasprice.go
+++ b/eth/gasprice/gasprice.go
@@ -98,6 +98,20 @@ func NewOracle(backend OracleBackend, params Config) *Oracle {
}
}
+func (gpo *Oracle) SetDefaultPrice(defaultPrice *big.Int) {
+ gpo.defaultPrice = defaultPrice
+}
+func (gpo *Oracle) GetDefaultPrice() *big.Int {
+ return gpo.defaultPrice
+}
+
+func (gpo *Oracle) SetMaxPrice(maxPrice *big.Int) {
+ gpo.maxPrice = maxPrice
+}
+func (gpo *Oracle) GetMaxPrice() *big.Int {
+ return gpo.maxPrice
+}
+
// SuggestPrice returns a gasprice so that newly created transaction can
// have a very high chance to be included in the following blocks.
func (gpo *Oracle) SuggestPrice(ctx context.Context) (*big.Int, error) {
diff --git a/eth/tracers/api.go b/eth/tracers/api.go
index 8df152fd0..0e1f1b3f2 100644
--- a/eth/tracers/api.go
+++ b/eth/tracers/api.go
@@ -20,6 +20,7 @@ import (
"bufio"
"bytes"
"context"
+ "encoding/json"
"errors"
"fmt"
"io/ioutil"
@@ -172,6 +173,8 @@ type TraceConfig struct {
Tracer *string
Timeout *string
Reexec *uint64
+
+ TracerConfig json.RawMessage
}
// TraceCallConfig is the config for traceCall API. It holds one more
@@ -935,7 +938,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *Contex
return nil, err
}
}
- if t, err := New(*config.Tracer, txctx); err != nil {
+ if t, err := New(*config.Tracer, txctx, config.TracerConfig); err != nil {
return nil, err
} else {
deadlineCtx, cancel := context.WithTimeout(ctx, timeout)
diff --git a/eth/tracers/js/tracer.go b/eth/tracers/js/tracer.go
index b8e035e6f..399aeb8dd 100644
--- a/eth/tracers/js/tracer.go
+++ b/eth/tracers/js/tracer.go
@@ -424,7 +424,7 @@ type jsTracer struct {
// New instantiates a new tracer instance. code specifies a Javascript snippet,
// which must evaluate to an expression returning an object with 'step', 'fault'
// and 'result' functions.
-func newJsTracer(code string, ctx *tracers2.Context) (tracers2.Tracer, error) {
+func newJsTracer(code string, ctx *tracers2.Context, cfg json.RawMessage) (tracers2.Tracer, error) {
if c, ok := assetTracers[code]; ok {
code = c
}
@@ -679,6 +679,15 @@ func wrapError(context string, err error) error {
return fmt.Errorf("%v in server-side tracer function '%v'", err, context)
}
+// CaptureTxStart implements the Tracer interface and is invoked at the beginning of
+// transaction processing.
+func (jst *jsTracer) CaptureTxStart(gasLimit uint64) {
+}
+
+// CaptureTxStart implements the Tracer interface and is invoked at the end of
+// transaction processing.
+func (t *jsTracer) CaptureTxEnd(restGas uint64) {}
+
// CaptureStart implements the Tracer interface to initialize the tracing operation.
func (jst *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
jst.env = env
diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go
index 16ea75aa4..0804db9a0 100644
--- a/eth/tracers/native/call.go
+++ b/eth/tracers/native/call.go
@@ -56,13 +56,22 @@ type callTracer struct {
// newCallTracer returns a native go tracer which tracks
// call frames of a tx, and implements vm.EVMLogger.
-func newCallTracer() tracers.Tracer {
+func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
// First callframe contains tx context info
// and is populated on start and end.
t := &callTracer{callstack: make([]callFrame, 1)}
- return t
+ return t, nil
}
+// CaptureTxStart implements the Tracer interface and is invoked at the beginning of
+// transaction processing.
+func (t *callTracer) CaptureTxStart(gasLimit uint64) {
+}
+
+// CaptureTxStart implements the Tracer interface and is invoked at the end of
+// transaction processing.
+func (t *callTracer) CaptureTxEnd(restGas uint64) {}
+
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
func (t *callTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
t.env = env
diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go
index ee110ef7d..65ccd7017 100644
--- a/eth/tracers/native/noop.go
+++ b/eth/tracers/native/noop.go
@@ -35,8 +35,14 @@ func init() {
type noopTracer struct{}
// newNoopTracer returns a new noop tracer.
-func newNoopTracer() tracers.Tracer {
- return &noopTracer{}
+func newNoopTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
+ return &noopTracer{}, nil
+}
+
+func (l *noopTracer) CaptureTxStart(gasLimit uint64) {
+}
+
+func (l *noopTracer) CaptureTxEnd(restGas uint64) {
}
// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go
new file mode 100644
index 000000000..fe4866e26
--- /dev/null
+++ b/eth/tracers/native/prestate.go
@@ -0,0 +1,276 @@
+// Copyright 2022 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+package native
+
+import (
+ "encoding/json"
+ "github.com/ethereum/go-ethereum/common/hexutil"
+ "math/big"
+ "sync/atomic"
+ "time"
+
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core/vm"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/eth/tracers"
+)
+
+func init() {
+ register("stateDiff", newStateDiffTracer)
+}
+
+type state = map[common.Address]account
+type account struct {
+ Balance string `json:"balance,omitempty"`
+ Nonce uint64 `json:"nonce,omitempty"`
+ storage map[common.Hash]common.Hash
+}
+
+func (a account) exists() bool {
+ bi := new(big.Int)
+ bi.SetString(a.Balance[2:], 16)
+ return a.Nonce > 0 || (bi.Sign() != 0)
+}
+
+type stateDiffTracer struct {
+ env *vm.EVM
+ pre state
+ post state
+ create bool
+ to common.Address
+ gasLimit uint64 // Amount of gas bought for the whole tx
+ interrupt uint32 // Atomic flag to signal execution interruption
+ reason error // Textual reason for the interruption
+
+ config stateDiffTracerConfig
+ created map[common.Address]bool
+ deleted map[common.Address]bool
+}
+
+type stateDiffTracerConfig struct {
+ DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications
+}
+
+func newStateDiffTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
+ var config stateDiffTracerConfig
+ if cfg != nil {
+ if err := json.Unmarshal(cfg, &config); err != nil {
+ return nil, err
+ }
+ }
+ // and is populated on start and end.
+ return &stateDiffTracer{
+ pre: state{},
+ post: state{},
+ config: config,
+ created: make(map[common.Address]bool),
+ deleted: make(map[common.Address]bool),
+ }, nil
+}
+
+// CaptureStart implements the EVMLogger interface to initialize the tracing operation.
+func (t *stateDiffTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) {
+ t.env = env
+ t.create = create
+ t.to = to
+
+ t.lookupAccount(from)
+ t.lookupAccount(to)
+ t.lookupAccount(env.Context.Coinbase)
+ //t.lookupAccount(consensus.SystemAddress)
+
+ // The recipient balance includes the value transferred.
+ toAccount := t.pre[to]
+ toBal := hexutil.MustDecodeBig(toAccount.Balance)
+ toBal = new(big.Int).Sub(toBal, value)
+ toAccount.Balance = hexutil.EncodeBig(toBal)
+ t.pre[to] = toAccount
+
+ // The sender balance is after reducing: value and gasLimit.
+ // We need to re-add them to get the pre-tx balance.
+ fromAccount := t.pre[from]
+ fromBal := hexutil.MustDecodeBig(fromAccount.Balance)
+ gasPrice := env.TxContext.GasPrice
+ consumedGas := new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(t.gasLimit))
+ fromBal.Add(fromBal, new(big.Int).Add(value, consumedGas))
+ fromAccount.Balance = hexutil.EncodeBig(fromBal)
+ fromAccount.Nonce--
+ t.pre[from] = fromAccount
+
+ if create && t.config.DiffMode {
+ t.created[to] = true
+ }
+}
+
+// CaptureEnd is called after the call finishes to finalize the tracing.
+func (t *stateDiffTracer) CaptureEnd(output []byte, gasUsed uint64, _ time.Duration, err error) {
+ if t.config.DiffMode {
+ return
+ }
+
+ if t.create {
+ // Keep existing account prior to contract creation at that address
+ if s := t.pre[t.to]; !s.exists() {
+ // Exclude newly created contract.
+ delete(t.pre, t.to)
+ }
+ }
+}
+
+// CaptureState implements the EVMLogger interface to trace a single step of VM execution.
+func (t *stateDiffTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
+ stack := scope.Stack
+ stackData := stack.Data()
+ stackLen := len(stackData)
+ caller := scope.Contract.Address()
+ switch {
+ case stackLen >= 1 && (op == vm.SLOAD || op == vm.SSTORE):
+ slot := common.Hash(stackData[stackLen-1].Bytes32())
+ t.lookupStorage(caller, slot)
+ case stackLen >= 1 && (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT):
+ addr := common.Address(stackData[stackLen-1].Bytes20())
+ t.lookupAccount(addr)
+ if op == vm.SELFDESTRUCT {
+ t.deleted[caller] = true
+ }
+ case stackLen >= 5 && (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE):
+ addr := common.Address(stackData[stackLen-2].Bytes20())
+ t.lookupAccount(addr)
+ case op == vm.CREATE:
+ nonce := t.env.StateDB.GetNonce(caller)
+ addr := crypto.CreateAddress(caller, nonce)
+ t.lookupAccount(addr)
+ t.created[addr] = true
+ case stackLen >= 4 && op == vm.CREATE2:
+ offset := stackData[stackLen-2]
+ size := stackData[stackLen-3]
+ init := scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
+ inithash := crypto.Keccak256(init)
+ salt := stackData[stackLen-4]
+ addr := crypto.CreateAddress2(caller, salt.Bytes32(), inithash)
+ t.lookupAccount(addr)
+ t.created[addr] = true
+ }
+}
+
+// CaptureFault implements the EVMLogger interface to trace an execution fault.
+func (t *stateDiffTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) {
+}
+
+// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct).
+func (t *stateDiffTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) {
+}
+
+// CaptureExit is called when EVM exits a scope, even if the scope didn't
+// execute any code.
+func (t *stateDiffTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
+}
+
+func (t *stateDiffTracer) CaptureTxStart(gasLimit uint64) {
+ t.gasLimit = gasLimit
+}
+
+func (t *stateDiffTracer) CaptureTxEnd(restGas uint64) {
+ if !t.config.DiffMode {
+ return
+ }
+
+ //for addr, state := range t.pre {
+ for addr, _ := range t.pre {
+ // The deleted account's state is pruned from `post` but kept in `pre`
+ if _, ok := t.deleted[addr]; ok {
+ continue
+ }
+ modified := false
+ postAccount := account{storage: make(map[common.Hash]common.Hash)}
+ newBalance := bigToHex(t.env.StateDB.GetBalance(addr))
+ newNonce := t.env.StateDB.GetNonce(addr)
+ //newCode := t.env.StateDB.GetCode(addr)
+
+ if newBalance != t.pre[addr].Balance {
+ modified = true
+ postAccount.Balance = newBalance
+ }
+ if newNonce != t.pre[addr].Nonce {
+ modified = true
+ postAccount.Nonce = newNonce
+ }
+
+ if modified {
+ t.post[addr] = postAccount
+ } else {
+ // if state is not modified, then no need to include into the pre state
+ delete(t.pre, addr)
+ }
+ }
+ // the new created contracts' prestate were empty, so delete them
+ for a := range t.created {
+ // the created contract maybe exists in statedb before the creating tx
+ if s := t.pre[a]; !s.exists() {
+ delete(t.pre, a)
+ }
+ }
+}
+
+// GetResult returns the json-encoded nested list of call traces, and any
+// error arising from the encoding or forceful termination (via `Stop`).
+func (t *stateDiffTracer) GetResult() (json.RawMessage, error) {
+ var res []byte
+ var err error
+ if t.config.DiffMode {
+ res, err = json.Marshal(struct {
+ Post state `json:"post"`
+ Pre state `json:"pre"`
+ }{t.post, t.pre})
+ } else {
+ res, err = json.Marshal(t.pre)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return json.RawMessage(res), t.reason
+}
+
+// Stop terminates execution of the tracer at the first opportune moment.
+func (t *stateDiffTracer) Stop(err error) {
+ t.reason = err
+ atomic.StoreUint32(&t.interrupt, 1)
+}
+
+// lookupAccount fetches details of an account and adds it to the prestate
+// if it doesn't exist there.
+func (t *stateDiffTracer) lookupAccount(addr common.Address) {
+ if _, ok := t.pre[addr]; ok {
+ return
+ }
+
+ t.pre[addr] = account{
+ Balance: bigToHex(t.env.StateDB.GetBalance(addr)),
+ Nonce: t.env.StateDB.GetNonce(addr),
+ storage: make(map[common.Hash]common.Hash),
+ }
+}
+
+// lookupStorage fetches the requested storage slot and adds
+// it to the prestate of the given contract. It assumes `lookupAccount`
+// has been performed on the contract before.
+func (t *stateDiffTracer) lookupStorage(addr common.Address, key common.Hash) {
+ if _, ok := t.pre[addr].storage[key]; ok {
+ return
+ }
+ t.pre[addr].storage[key] = t.env.StateDB.GetState(addr, key)
+}
diff --git a/eth/tracers/native/tracer.go b/eth/tracers/native/tracer.go
index 3158654f3..187d89fa1 100644
--- a/eth/tracers/native/tracer.go
+++ b/eth/tracers/native/tracer.go
@@ -27,14 +27,17 @@ Aside from implementing the tracer, it also needs to register itself, using the
Example:
```golang
-func init() {
- register("noopTracerNative", newNoopTracer)
-}
+
+ func init() {
+ register("noopTracerNative", newNoopTracer)
+ }
+
```
*/
package native
import (
+ "encoding/json"
"errors"
"github.com/ethereum/go-ethereum/eth/tracers"
@@ -45,6 +48,9 @@ func init() {
tracers.RegisterLookup(false, lookup)
}
+// ctorFn is the constructor signature of a native tracer.
+type ctorFn = func(*tracers.Context, json.RawMessage) (tracers.Tracer, error)
+
/*
ctors is a map of package-local tracer constructors.
@@ -57,23 +63,23 @@ The go spec (https://golang.org/ref/spec#Package_initialization) says
Hence, we cannot make the map in init, but must make it upon first use.
*/
-var ctors map[string]func() tracers.Tracer
+var ctors map[string]ctorFn
// register is used by native tracers to register their presence.
-func register(name string, ctor func() tracers.Tracer) {
+func register(name string, ctor ctorFn) {
if ctors == nil {
- ctors = make(map[string]func() tracers.Tracer)
+ ctors = make(map[string]ctorFn)
}
ctors[name] = ctor
}
// lookup returns a tracer, if one can be matched to the given name.
-func lookup(name string, ctx *tracers.Context) (tracers.Tracer, error) {
+func lookup(name string, ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) {
if ctors == nil {
- ctors = make(map[string]func() tracers.Tracer)
+ ctors = make(map[string]ctorFn)
}
if ctor, ok := ctors[name]; ok {
- return ctor(), nil
+ return ctor(ctx, cfg)
}
return nil, errors.New("no tracer found")
}
diff --git a/eth/tracers/tracers.go b/eth/tracers/tracers.go
index e8fdc08f1..710d3acd9 100644
--- a/eth/tracers/tracers.go
+++ b/eth/tracers/tracers.go
@@ -43,7 +43,7 @@ type Tracer interface {
Stop(err error)
}
-type lookupFunc func(string, *Context) (Tracer, error)
+type lookupFunc func(string, *Context, json.RawMessage) (Tracer, error)
var (
lookups []lookupFunc
@@ -63,9 +63,9 @@ func RegisterLookup(wildcard bool, lookup lookupFunc) {
// New returns a new instance of a tracer, by iterating through the
// registered lookups.
-func New(code string, ctx *Context) (Tracer, error) {
+func New(code string, ctx *Context, cfg json.RawMessage) (Tracer, error) {
for _, lookup := range lookups {
- if tracer, err := lookup(code, ctx); err == nil {
+ if tracer, err := lookup(code, ctx, cfg); err == nil {
return tracer, nil
}
}
diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go
index 578b10f09..421c7dafe 100644
--- a/ethclient/ethclient.go
+++ b/ethclient/ethclient.go
@@ -94,6 +94,16 @@ func (ec *Client) BlockNumber(ctx context.Context) (uint64, error) {
return uint64(result), err
}
+// BlockReceipts returns the receipts of a given block number or hash.
+func (ec *Client) BlockReceipts(ctx context.Context, hash common.Hash) ([]*types.Receipt, error) {
+ var r []*types.Receipt
+ err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", hash.String())
+ if err == nil && r == nil {
+ return nil, ethereum.NotFound
+ }
+ return r, err
+}
+
type rpcBlock struct {
Hash common.Hash `json:"hash"`
Transactions []rpcTransaction `json:"transactions"`
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index 1a02ec5ef..1828aa1f4 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -656,10 +656,10 @@ func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.H
}
// GetBlockByNumber returns the requested canonical block.
-// * When blockNr is -1 the chain head is returned.
-// * When blockNr is -2 the pending chain head is returned.
-// * When fullTx is true all transactions in the block are returned, otherwise
-// only the transaction hash is returned.
+// - When blockNr is -1 the chain head is returned.
+// - When blockNr is -2 the pending chain head is returned.
+// - When fullTx is true all transactions in the block are returned, otherwise
+// only the transaction hash is returned.
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
block, err := s.b.BlockByNumber(ctx, number)
if block != nil && err == nil {
@@ -816,6 +816,68 @@ func (args *CallArgs) ToMessage(globalGasCap uint64) types.Message {
return msg
}
+// GetBlockReceipts returns the block receipts for the given block hash or number or tag.
+func (api *PublicBlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) {
+ block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
+ if block == nil || err != nil {
+ // When the block doesn't exist, the RPC method should return JSON null
+ // as per specification.
+ return nil, nil
+ }
+ receipts, err := api.b.GetReceipts(ctx, block.Hash())
+ if err != nil {
+ return nil, err
+ }
+ txs := block.Transactions()
+ if len(txs) != len(receipts) {
+ return nil, fmt.Errorf("receipts length mismatch: %d vs %d", len(txs), len(receipts))
+ }
+
+ blockHash := block.Hash()
+ blockNumber := block.NumberU64()
+ txReceipts := make([]map[string]interface{}, 0, len(txs))
+ for i, receipt := range receipts {
+ tx := txs[i]
+ var signer types.Signer = types.FrontierSigner{}
+ if tx.Protected() {
+ signer = types.NewEIP155Signer(tx.ChainId())
+ }
+ from, _ := types.Sender(signer, tx)
+
+ fields := map[string]interface{}{
+ "blockHash": blockHash,
+ "blockNumber": hexutil.Uint64(blockNumber),
+ "transactionHash": tx.Hash(),
+ "transactionIndex": hexutil.Uint64(i),
+ "from": from,
+ "to": tx.To(),
+ "gasUsed": hexutil.Uint64(receipt.GasUsed),
+ "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed),
+ "contractAddress": nil,
+ "logs": receipt.Logs,
+ "logsBloom": receipt.Bloom,
+ }
+
+ // Assign receipt status or post state.
+ if len(receipt.PostState) > 0 {
+ fields["root"] = hexutil.Bytes(receipt.PostState)
+ } else {
+ fields["status"] = hexutil.Uint(receipt.Status)
+ }
+ if receipt.Logs == nil {
+ fields["logs"] = [][]*types.Log{}
+ }
+ // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
+ if receipt.ContractAddress != (common.Address{}) {
+ fields["contractAddress"] = receipt.ContractAddress
+ }
+
+ txReceipts = append(txReceipts, fields)
+ }
+
+ return txReceipts, nil
+}
+
// OverrideAccount indicates the overriding fields of account during the execution
// of a message call.
// Note, state and stateDiff can't be specified at the same time. If state is
diff --git a/miner/worker.go b/miner/worker.go
index b9a06208b..e711c8084 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -979,6 +979,7 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st
}
block, receipts, err := w.engine.FinalizeAndAssemble(w.chain, types.CopyHeader(w.current.header), s, w.current.txs, uncles, w.current.receipts)
if err != nil {
+ log.Warn("Miner worker commit failed", "block number", w.current.header.Number, " error", err)
return err
}
if w.isRunning() {
diff --git a/params/config.go b/params/config.go
index fd4a3e499..936eeb02c 100644
--- a/params/config.go
+++ b/params/config.go
@@ -51,6 +51,8 @@ var (
big.NewInt(0),
big.NewInt(0),
big.NewInt(0),
+ big.NewInt(0),
+ big.NewInt(0),
nil,
nil,
nil,
@@ -80,7 +82,9 @@ var (
big.NewInt(0),
big.NewInt(0),
big.NewInt(0),
- nil,
+ big.NewInt(0),
+ big.NewInt(0),
+ big.NewInt(0),
&CliqueConfig{Period: 0, Epoch: 30000},
nil,
}
@@ -104,6 +108,8 @@ var (
big.NewInt(0),
big.NewInt(0),
big.NewInt(0),
+ big.NewInt(0),
+ big.NewInt(0),
nil,
nil, nil,
}
@@ -171,9 +177,8 @@ type ChainConfig struct {
EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed)
- EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
- EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
-
+ EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
+ EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium)
ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople)
@@ -188,13 +193,13 @@ type ChainConfig struct {
EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated) RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated)
CatalystBlock *big.Int `json:"catalystBlock,omitempty"` // Catalyst switch block (nil = no fork, 0 = already on catalyst)
- RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated)
- NielsBlock *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"` // nielsBlock switch block (nil = no fork, 0 = already activated)
- MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated)
- BrunoBlock *big.Int `json:"brunoBlock,omitempty" toml:",omitempty"` // brunoBlock switch block (nil = no fork, 0 = already activated)
-
+ RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated)
+ NielsBlock *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"` // nielsBlock switch block (nil = no fork, 0 = already activated)
+ MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated)
+ BrunoBlock *big.Int `json:"brunoBlock,omitempty" toml:",omitempty"` // brunoBlock switch block (nil = no fork, 0 = already activated)
BlockRewardsBlock *big.Int `json:"blockRewardsBlock,omitempty" toml:",omitempty"`
-
+ Contract48kBlock *big.Int `json:"contract48kBlock,omitempty" toml:",omitempty"` // contract48kBlock switch block (nil = no fork, 0 = already activated)
+ Fncy2Block *big.Int `json:"fncy2Block,omitempty" toml:",omitempty"` // fncy2Block switch block (nil = no fork, 0 = already activated)
// Various consensus engines
Clique *CliqueConfig `json:"clique,omitempty" toml:",omitempty"`
Parlia *ParliaConfig `json:"parlia,omitempty" toml:",omitempty"`
@@ -213,9 +218,10 @@ func (c *CliqueConfig) String() string {
// ParliaConfig is the consensus engine configs for proof-of-staked-authority based sealing.
type ParliaConfig struct {
- Period uint64 `json:"period"` // Number of seconds between blocks to enforce
- Epoch uint64 `json:"epoch"` // Epoch length to update validatorSet
- BlockRewards *big.Int `json:"blockRewards"` // Block rewards to be paid for each produced block
+ Period uint64 `json:"period"` // Number of seconds between blocks to enforce
+ Epoch uint64 `json:"epoch"` // Epoch length to update validatorSet
+ BlockRewards *big.Int `json:"blockRewards"` // Block rewards to be paid for each produced block
+ StopMintBlock *big.Int `json:"stopMintBlock"` // Do not continue minting after configuring the block
}
// String implements the stringer interface, returning the consensus engine details.
@@ -275,6 +281,13 @@ func (c *ChainConfig) IsEIP158(num *big.Int) bool {
return isForked(c.EIP158Block, num)
}
+func (c *ChainConfig) IsContract48kBlock(num *big.Int) bool {
+ return isForked(c.Contract48kBlock, num)
+}
+func (c *ChainConfig) IsFncy2(num *big.Int) bool {
+ return isForked(c.Fncy2Block, num)
+}
+
// IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
func (c *ChainConfig) IsByzantium(num *big.Int) bool {
return isForked(c.ByzantiumBlock, num)
@@ -539,12 +552,12 @@ func (err *ConfigCompatError) Error() string {
// Rules is a one time interface meaning that it shouldn't be used in between transition
// phases.
type Rules struct {
- ChainID *big.Int
- IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
- IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
- IsBerlin, IsCatalyst bool
- HasRuntimeUpgrade, HasDeployerProxy bool
- HasBlockRewards bool
+ ChainID *big.Int
+ IsHomestead, IsEIP150, IsEIP155, IsEIP158, IsContract48kBlock bool
+ IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
+ IsBerlin, IsCatalyst bool
+ HasRuntimeUpgrade, HasDeployerProxy bool
+ HasBlockRewards bool
}
// Rules ensures c's ChainID is not nil.
@@ -554,19 +567,20 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
chainID = new(big.Int)
}
return Rules{
- ChainID: new(big.Int).Set(chainID),
- IsHomestead: c.IsHomestead(num),
- IsEIP150: c.IsEIP150(num),
- IsEIP155: c.IsEIP155(num),
- IsEIP158: c.IsEIP158(num),
- IsByzantium: c.IsByzantium(num),
- IsConstantinople: c.IsConstantinople(num),
- IsPetersburg: c.IsPetersburg(num),
- IsIstanbul: c.IsIstanbul(num),
- IsBerlin: c.IsBerlin(num),
- IsCatalyst: c.IsCatalyst(num),
- HasRuntimeUpgrade: c.HasRuntimeUpgrade(num),
- HasDeployerProxy: c.HasDeployerProxy(num),
- HasBlockRewards: c.IsBlockRewardsBlock(num),
+ ChainID: new(big.Int).Set(chainID),
+ IsHomestead: c.IsHomestead(num),
+ IsEIP150: c.IsEIP150(num),
+ IsEIP155: c.IsEIP155(num),
+ IsEIP158: c.IsEIP158(num),
+ IsContract48kBlock: c.IsContract48kBlock(num),
+ IsByzantium: c.IsByzantium(num),
+ IsConstantinople: c.IsConstantinople(num),
+ IsPetersburg: c.IsPetersburg(num),
+ IsIstanbul: c.IsIstanbul(num),
+ IsBerlin: c.IsBerlin(num),
+ IsCatalyst: c.IsCatalyst(num),
+ HasRuntimeUpgrade: c.HasRuntimeUpgrade(num),
+ HasDeployerProxy: c.HasDeployerProxy(num),
+ HasBlockRewards: c.IsBlockRewardsBlock(num),
}
}