Commit ddbe3a60 authored by linj's avatar linj

Merge remote-tracking branch 'upstream/master' into exchange_order_0929

upstream/master : 33cn/plugin:master
parents 139ba285 e869c482
# This is a basic workflow that is manually triggered
name: manually auto publish release
# Controls when the action will run. Workflow runs when manually triggered using the UI
# or API.
on:
workflow_dispatch:
# Inputs the workflow accepts.
inputs:
name:
# Friendly description to be shown in the UI instead of 'name'
description: 'auto make'
# Default value if no value is explicitly provided
default: 'push'
# Input has to be provided for the workflow to run
required: true
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
automake:
name: automake
runs-on: ubuntu-latest
steps:
- name: Set up Golang env
uses: actions/setup-go@v2
with:
go-version: 1.17
id: go
- name: checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: false # <--- this
- name: Semantic Release
uses: cycjimmy/semantic-release-action@v2
id: semantic
with:
branch: master
extra_plugins: |
conventional-changelog/conventional-changelog-jshint
@google/semantic-release-replace-plugin
@semantic-release/exec
@semantic-release/changelog
@semantic-release/git
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Do something when a new release published
if: steps.semantic.outputs.new_release_published == 'true'
run: |
echo ${{ steps.semantic.outputs.new_release_version }}
echo ${{ steps.semantic.outputs.new_release_major_version }}
echo ${{ steps.semantic.outputs.new_release_minor_version }}
echo ${{ steps.semantic.outputs.new_release_patch_version }}
name: build name: ci_base
on: [push,pull_request] on: [push,pull_request]
jobs: jobs:
......
name: build name: ci_cross2eth
on: [push,pull_request] on: [push,pull_request]
jobs: jobs:
......
name: build name: ci_mix
on: [push,pull_request] on: [push,pull_request]
jobs: jobs:
......
name: build name: ci_paracross
on: [push,pull_request] on: [push,pull_request]
jobs: jobs:
ci_paracross: paracross:
name: ci_paracross name: ci_paracross
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
......
name: build name: ci_relay
on: [push,pull_request] on: [push,pull_request]
jobs: jobs:
......
# This is a basic workflow that is manually triggered
name: manually make bin for all branch
# Controls when the action will run. Workflow runs when manually triggered using the UI
# or API.
on: [push,pull_request]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
automake:
name: automake
runs-on: ubuntu-latest
steps:
- name: Set up Golang env
uses: actions/setup-go@v2
with:
go-version: 1.17
id: go
- name: checkout repo
uses: actions/checkout@v2
- name: compile binary
run: make all-arch
- name : Upload artifact bin
uses: actions/upload-artifact@v2
with:
name: chain33-artifact
path: |
build/*.tar.gz
build/*.zip
name: release
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Golang env
uses: actions/setup-go@v2
with:
go-version: 1.17
id: go
- name: checkout repo
uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: false # <--- this
- name: Semantic Release
uses: cycjimmy/semantic-release-action@v2
id: semantic
with:
branch: master
extra_plugins: |
conventional-changelog/conventional-changelog-jshint
@google/semantic-release-replace-plugin
@semantic-release/exec
@semantic-release/changelog
@semantic-release/git
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
- name: Do something when a new release published
if: steps.semantic.outputs.new_release_published == 'true'
run: |
echo ${{ steps.semantic.outputs.new_release_version }}
echo ${{ steps.semantic.outputs.new_release_major_version }}
echo ${{ steps.semantic.outputs.new_release_minor_version }}
echo ${{ steps.semantic.outputs.new_release_patch_version }}
...@@ -47,4 +47,5 @@ build/parawallet/ ...@@ -47,4 +47,5 @@ build/parawallet/
build/sendstock build/sendstock
build/sendstock.toml build/sendstock.toml
build/*.csv build/*.csv
build/CHANGELOG.md
plugin/dapp/dex/boss/build/ plugin/dapp/dex/boss/build/
{ "branches": ["master", "next"],
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "jshint"
}
],
[
"@semantic-release/release-notes-generator",
{
"preset": "jshint"
}
],
[
"@google/semantic-release-replace-plugin",
{
"replacements": [
{
"files": ["version/version.go"],
"from": 'Version =.*',
"to": 'Version = "${nextRelease.version}"',
"results": [
{
"file": "version/version.go",
"hasChanged": true,
"numMatches": 1,
"numReplacements": 1
}
],
"countMatches": true
},
{
"files": ["README.md"],
"from": "# chain33 官方插件系统(.*)",
"to": "# chain33 官方插件系统(v${nextRelease.version})",
"results": [
{
"file": "README.md",
"hasChanged": true,
"numMatches": 1,
"numReplacements": 1
}
],
"countMatches": true
},
]
}
],
[
"@semantic-release/changelog",
{ "changelogFile": "CHANGELOG.md", "changelogTitle": "changelog" },
],
# "@semantic-release/npm", #Default 3
# "@semantic-release/github", #Default 4
[
"@semantic-release/github",
{"assets": ["build/*.tar.gz","build/*.zip"]}
],
[
"@semantic-release/git",
{
"assets": ["version/version.go","CHANGELOG.md","README.md"],
}
],
[
"@semantic-release/exec", {
"prepareCmd": "make all-arch VERSION=${nextRelease.version}"
}
]
]
}
changelog
<a name="1.65.4"></a>
## [1.65.4](https://github.com/33cn/plugin/compare/v1.65.3...v1.65.4) (2021-10-27)
### Bug Fixes
* adjust semantic-release commit message conventions to jshint ([a0eade8](https://github.com/33cn/plugin/commit/a0eade8))
* Fixed semantic-release-replace-plugin config ([6c79cfd](https://github.com/33cn/plugin/commit/6c79cfd))
## [1.65.3](https://github.com/33cn/plugin/compare/v1.65.2...v1.65.3) (2021-10-19)
### Bug Fixes
* 🐛version control: Add github action for auto publish release and tag version ([72ab4fd](https://github.com/33cn/plugin/commit/72ab4fdf9625b348b06ae4b8ae90522a7aa3db6f))
* **doc:** release 1.65.3 ([7484035](https://github.com/33cn/plugin/commit/74840359adb86d9d920fe63b04fd790e8933fe53))
* ebrelayer log ([a8ee06d](https://github.com/33cn/plugin/commit/a8ee06da773bb015b6ec45762a87bbca54ea2268))
* fix ci and add manually auto publish release ([677029b](https://github.com/33cn/plugin/commit/677029bb4c2e6653626b0f0ef4a296f06102c604))
* lottery ci ([8941c81](https://github.com/33cn/plugin/commit/8941c81c70c6ab5a4e07b4d88cdf82b6e5a9f862))
## [6.1.1](https://github.com/33cn/plugin/compare/v6.1.0...v6.1.1) (2021-10-18)
### Bug Fixes
* 🐛version control: Add github action for auto publish release and tag version ([72ab4fd](https://github.com/33cn/plugin/commit/72ab4fdf9625b348b06ae4b8ae90522a7aa3db6f))
* **doc:** release 1.65.3 ([7484035](https://github.com/33cn/plugin/commit/74840359adb86d9d920fe63b04fd790e8933fe53))
* ebrelayer log ([a8ee06d](https://github.com/33cn/plugin/commit/a8ee06da773bb015b6ec45762a87bbca54ea2268))
* fix ci and add manually auto publish release ([677029b](https://github.com/33cn/plugin/commit/677029bb4c2e6653626b0f0ef4a296f06102c604))
* lottery ci ([8941c81](https://github.com/33cn/plugin/commit/8941c81c70c6ab5a4e07b4d88cdf82b6e5a9f862))
...@@ -8,8 +8,14 @@ export GO111MODULE=on ...@@ -8,8 +8,14 @@ export GO111MODULE=on
CLI := build/chain33-cli CLI := build/chain33-cli
SRC_CLI := github.com/33cn/plugin/cli SRC_CLI := github.com/33cn/plugin/cli
APP := build/chain33 APP := build/chain33
BUILD_FLAGS = -ldflags "-X github.com/33cn/chain33/common/version.GitCommit=`git rev-parse --short=8 HEAD`" LDFLAGS := ' -w -s'
LDFLAGS := -ldflags "-w -s" BUILDTIME:=$(shell date +"%Y-%m-%d %H:%M:%S %A")
VERSION=$(shell git describe --tags || git rev-parse --short=8 HEAD)
GitCommit=$(shell git rev-parse --short=8 HEAD)
BUILD_FLAGS := -ldflags '-X "github.com/33cn/plugin/version.GitCommit=$(GitCommit)" \
-X "github.com/33cn/plugin/version.Version=$(VERSION)" \
-X "github.com/33cn/plugin/version.BuildTime=$(BUILDTIME)"'
MKPATH=$(abspath $(lastword $(MAKEFILE_LIST))) MKPATH=$(abspath $(lastword $(MAKEFILE_LIST)))
MKDIR=$(dir $(MKPATH)) MKDIR=$(dir $(MKPATH))
proj := "build" proj := "build"
...@@ -32,6 +38,48 @@ build_ci: depends ## Build the binary file for CI ...@@ -32,6 +38,48 @@ build_ci: depends ## Build the binary file for CI
@cp chain33.para.toml build/ci/paracross/ @cp chain33.para.toml build/ci/paracross/
PLATFORM_LIST = \
darwin-amd64 \
darwin-arm64 \
linux-amd64 \
WINDOWS_ARCH_LIST = \
windows-amd64
GOBUILD=go build $(BUILD_FLAGS)" -w -s"
darwin-amd64:
GOARCH=amd64 GOOS=darwin $(GOBUILD) -o $(APP)-$@ $(SRC)
GOARCH=amd64 GOOS=darwin $(GOBUILD) -o $(CLI)-$@ $(SRC_CLI)
cp chain33.para.toml chain33.toml CHANGELOG.md build/ && cd build && \
chmod +x chain33-darwin-amd64 && \
chmod +x chain33-cli-darwin-amd64 && \
tar -zcvf chain33-darwin-amd64.tar.gz chain33-darwin-amd64 chain33-cli-darwin-amd64 chain33.para.toml chain33.toml CHANGELOG.md
darwin-arm64:
GOARCH=arm64 GOOS=darwin $(GOBUILD) -o $(APP)-$@ $(SRC)
GOARCH=arm64 GOOS=darwin $(GOBUILD) -o $(CLI)-$@ $(SRC_CLI)
cp chain33.para.toml chain33.toml CHANGELOG.md build/ && cd build && \
chmod +x chain33-darwin-arm64 && \
chmod +x chain33-cli-darwin-arm64 && \
tar -zcvf chain33-darwin-arm64.tar.gz chain33-darwin-arm64 chain33-cli-darwin-arm64 chain33.toml chain33.para.toml CHANGELOG.md
linux-amd64:
GOARCH=amd64 GOOS=linux $(GOBUILD) -o $(APP)-$@ $(SRC)
GOARCH=amd64 GOOS=linux $(GOBUILD) -o $(CLI)-$@ $(SRC_CLI)
cp chain33.para.toml chain33.toml CHANGELOG.md build/ && cd build && \
chmod +x chain33-linux-amd64 && \
chmod +x chain33-cli-linux-amd64 && \
tar -zcvf chain33-linux-amd64.tar.gz chain33-linux-amd64 chain33-cli-linux-amd64 chain33.para.toml chain33.toml CHANGELOG.md
windows-amd64:
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(APP)-$@.exe $(SRC)
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(CLI)-$@.exe $(SRC_CLI)
cp chain33.para.toml chain33.toml CHANGELOG.md build/ && cd build && \
zip -j chain33-windows-amd64.zip chain33-windows-amd64.exe chain33-cli-windows-amd64.exe chain33.para.toml chain33.toml CHANGELOG.md
all-arch: $(PLATFORM_LIST) $(WINDOWS_ARCH_LIST)
para: para:
@go build -v -o build/$(NAME) -ldflags "-X $(SRC_CLI)/buildflags.ParaName=user.p.$(NAME). -X $(SRC_CLI)/buildflags.RPCAddr=http://localhost:8901" $(SRC_CLI) @go build -v -o build/$(NAME) -ldflags "-X $(SRC_CLI)/buildflags.ParaName=user.p.$(NAME). -X $(SRC_CLI)/buildflags.RPCAddr=http://localhost:8901" $(SRC_CLI)
......
...@@ -6,13 +6,14 @@ https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/6874 ...@@ -6,13 +6,14 @@ https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/6874
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/33cn/plugin?svg=true&branch=master&passingText=Windows%20-%20OK&failingText=Windows%20-%20failed&pendingText=Windows%20-%20pending)](https://ci.appveyor.com/project/33cn/plugin) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/33cn/plugin?svg=true&branch=master&passingText=Windows%20-%20OK&failingText=Windows%20-%20failed&pendingText=Windows%20-%20pending)](https://ci.appveyor.com/project/33cn/plugin)
[![codecov](https://codecov.io/gh/33cn/plugin/branch/master/graph/badge.svg)](https://codecov.io/gh/33cn/plugin) [![codecov](https://codecov.io/gh/33cn/plugin/branch/master/graph/badge.svg)](https://codecov.io/gh/33cn/plugin)
# chain33 官方插件系统(v6.4.0 # chain33 官方插件系统(v1.65.4
* chain33地址: https://github.com/33cn/chain33 * chain33地址: https://github.com/33cn/chain33
* chain33官网: https://chain.33.cn * chain33官网: https://chain.33.cn
### 环境 ### 环境
``` ```
需要安装golang1.13 or latest 需要安装golang1.13 or latest
...@@ -85,4 +86,3 @@ make push b=branch_dev_name m="hello world" ...@@ -85,4 +86,3 @@ make push b=branch_dev_name m="hello world"
testcase的规则参考plugin/dapp/testcase_compose_rule.md testcase的规则参考plugin/dapp/testcase_compose_rule.md
用户可以在travis自己工程里面设置自己plugin的DAPP变量,如DAPP设置为relay,则travis里面run relay的testcase 用户可以在travis自己工程里面设置自己plugin的DAPP变量,如DAPP设置为relay,则travis里面run relay的testcase
...@@ -31,6 +31,9 @@ NODE4="${1}_chain30_1" ...@@ -31,6 +31,9 @@ NODE4="${1}_chain30_1"
NODE5="${1}_chain29_1" NODE5="${1}_chain29_1"
CLI5="docker exec ${NODE5} /root/chain33-cli" CLI5="docker exec ${NODE5} /root/chain33-cli"
# shellcheck disable=SC2034
NODE6="${1}_chain28_1"
containers=("${NODE1}" "${NODE2}" "${NODE3}" "${NODE4}") containers=("${NODE1}" "${NODE2}" "${NODE3}" "${NODE4}")
export COMPOSE_PROJECT_NAME="$1" export COMPOSE_PROJECT_NAME="$1"
## global config ### ## global config ###
...@@ -111,7 +114,6 @@ function base_init() { ...@@ -111,7 +114,6 @@ function base_init() {
# wallet # wallet
sed -i $sedfix 's/^minerdisable=.*/minerdisable=false/g' chain33.toml sed -i $sedfix 's/^minerdisable=.*/minerdisable=false/g' chain33.toml
sed -i $sedfix 's/^nodeGroupFrozenCoins=.*/nodeGroupFrozenCoins=20/g' chain33.toml
sed -i $sedfix 's/^paraConsensusStopBlocks=.*/paraConsensusStopBlocks=100/g' chain33.toml sed -i $sedfix 's/^paraConsensusStopBlocks=.*/paraConsensusStopBlocks=100/g' chain33.toml
# blockchain # blockchain
...@@ -129,6 +131,10 @@ function base_init() { ...@@ -129,6 +131,10 @@ function base_init() {
sed -i $sedfix 's/^enableReduceLocaldb=.*/enableReduceLocaldb=false/g' chain33.toml sed -i $sedfix 's/^enableReduceLocaldb=.*/enableReduceLocaldb=false/g' chain33.toml
sed -i $sedfix 's/^enablePushSubscribe=.*/enablePushSubscribe=true/g' chain33.toml sed -i $sedfix 's/^enablePushSubscribe=.*/enablePushSubscribe=true/g' chain33.toml
fi fi
#autonomy config
sed -i $sedfix 's/^autonomyExec=.*/autonomyExec=""/g' chain33.toml
} }
function start() { function start() {
...@@ -158,10 +164,9 @@ function start() { ...@@ -158,10 +164,9 @@ function start() {
# query node run status # query node run status
check_docker_status check_docker_status
${CLI} block last_header
${CLI} net info ${CLI} net info
${CLI} net peer ${CLI} net peer
${CLI} block last_header
local count=1000 local count=1000
while [ $count -gt 0 ]; do while [ $count -gt 0 ]; do
peersCount=$(${CLI} net peer | jq '.[] | length') peersCount=$(${CLI} net peer | jq '.[] | length')
......
...@@ -97,7 +97,7 @@ coinDevFund=12 ...@@ -97,7 +97,7 @@ coinDevFund=12
coinBaseReward=3 coinBaseReward=3
#委托账户最少解绑定时间(按小时) #委托账户最少解绑定时间(按小时)
unBindTime=24 unBindTime=24
#支持挖矿奖励的1e8小数模式,比如18coin 需要配置成1800000000 以支持小数位后的配置,如果true,意味着已经打开即coinReward=1800000000 #支持挖矿奖励的1e8小数模式,比如18coin 需要配置成1800000000 以支持小数位后的配置,如果true,意味着已经打开即须配置coinReward=1800000000
decimalMode=false decimalMode=false
#挖矿模式, normal:缺省挖矿,其他自定义,注册名字需要和配置名字保持一致 #挖矿模式, normal:缺省挖矿,其他自定义,注册名字需要和配置名字保持一致
minerMode="normal" minerMode="normal"
...@@ -107,20 +107,18 @@ halvePeriod=1000 ...@@ -107,20 +107,18 @@ halvePeriod=1000
[consensus.sub.para] [consensus.sub.para]
#主链节点的grpc服务器ip,当前可以支持多ip负载均衡,如“118.31.177.1:8802,39.97.2.127:8802” #主链节点的grpc服务器ip,当前可以支持多ip负载均衡,如“118.31.177.1:8802,39.97.2.127:8802”
#ParaRemoteGrpcClient="118.31.177.1:8802,39.97.2.127:8802,120.77.111.44:8802,jiedian2.bityuan.com,cloud.bityuan.com" #ParaRemoteGrpcClient="jiedian2.bityuan.com,cloud.bityuan.com"
ParaRemoteGrpcClient="localhost:8802" ParaRemoteGrpcClient="localhost:8802"
#主链指定高度的区块开始同步 #主链指定高度的区块开始同步
startHeight=345850 startHeight=345850
#主链指定高度后等待块数,防止主链回滚,联盟链最小为1,小于1则采用缺省高度100 #主链指定高度后等待块数,防止主链回滚,联盟链最小为1,小于1则采用缺省高度100
#waitMainBlockNum=100 #waitMainBlockNum=100
#打包时间间隔,单位 #等待打包主链区块时间间隔,单位毫
writeBlockSeconds=2 writeBlockMsec=2000
#验证账户,验证节点需要配置自己的账户,并且钱包导入对应种子,非验证节点留空 #共识节点账户,共识节点需要配置自己的账户,并且钱包导入对应种子,非共识节点留空
authAccount="" authAccount=""
#创世地址额度 #创世地址额度
genesisAmount=100000000 genesisAmount=100000000
#主链计算blockhash forkheight,需要和主链保持严格一致,不可修改,1是bityuan主链对应高度, ycc或其他按实际修改
mainBlockHashForkHeight=1
#主链支持平行链共识tx分叉高度,需要和主链保持严格一致,不可修改,2270000是bityuan主链对应高度, ycc或其他按实际修改 #主链支持平行链共识tx分叉高度,需要和主链保持严格一致,不可修改,2270000是bityuan主链对应高度, ycc或其他按实际修改
#不可为0,主链Local时候需特殊配置 #不可为0,主链Local时候需特殊配置
mainForkParacrossCommitTx=2270000 mainForkParacrossCommitTx=2270000
...@@ -130,6 +128,11 @@ mainLoopCheckCommitTxDoneForkHeight=4320000 ...@@ -130,6 +128,11 @@ mainLoopCheckCommitTxDoneForkHeight=4320000
#无平行链交易的主链区块间隔,平行链产生一个空块,从高度0开始,配置[blockHeight:interval],比如["0:50","1000:100"] #无平行链交易的主链区块间隔,平行链产生一个空块,从高度0开始,配置[blockHeight:interval],比如["0:50","1000:100"]
emptyBlockInterval=["0:50"] emptyBlockInterval=["0:50"]
#平行链共识节点聚合签名配置
[consensus.sub.para.bls]
#是否开启聚合签名,缺省不开启
blsSign=false
[store] [store]
name="kvmvccmavl" name="kvmvccmavl"
...@@ -184,6 +187,8 @@ genesis="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv" ...@@ -184,6 +187,8 @@ genesis="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
[exec.sub.manage] [exec.sub.manage]
superManager=["12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"] superManager=["12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"]
#autonomy执行器名字,空则不开启,使用superManager list
autonomyExec=""
[exec.sub.token] [exec.sub.token]
saveTokenTxList=true saveTokenTxList=true
...@@ -212,6 +217,8 @@ pointHX="19172955941344617222923168298456110557655645809646772800021167670156933 ...@@ -212,6 +217,8 @@ pointHX="19172955941344617222923168298456110557655645809646772800021167670156933
pointHY="21116962883761739586121793871108889864627195706475546685847911817475098399811" pointHY="21116962883761739586121793871108889864627195706475546685847911817475098399811"
#电路最大支持1024个叶子hash,10 level, 配置可以小于1024,但不能大于 #电路最大支持1024个叶子hash,10 level, 配置可以小于1024,但不能大于
maxTreeLeaves=1024 maxTreeLeaves=1024
#管理员列表
mixApprs=[]
#系统中所有的fork,默认用chain33的测试网络的 #系统中所有的fork,默认用chain33的测试网络的
#但是我们可以替换 #但是我们可以替换
...@@ -264,6 +271,8 @@ ForkBadRepeatSecret=0 ...@@ -264,6 +271,8 @@ ForkBadRepeatSecret=0
[fork.sub.manage] [fork.sub.manage]
Enable=0 Enable=0
ForkManageExec=0 ForkManageExec=0
#manage增加配置需要经过autonomy board成员审批,平行链不开启
ForkManageAutonomyEnable=-1
[fork.sub.token] [fork.sub.token]
Enable=0 Enable=0
...@@ -289,8 +298,13 @@ ForkLoopCheckCommitTxDone=0 ...@@ -289,8 +298,13 @@ ForkLoopCheckCommitTxDone=0
#仅平行链适用,自共识分阶段开启,缺省是0,若对应主链高度7200000之前开启过自共识,需要重新配置此分叉,并为之前自共识设置selfConsensEnablePreContract配置项 #仅平行链适用,自共识分阶段开启,缺省是0,若对应主链高度7200000之前开启过自共识,需要重新配置此分叉,并为之前自共识设置selfConsensEnablePreContract配置项
ForkParaSelfConsStages=0 ForkParaSelfConsStages=0
ForkParaAssetTransferRbk=0 ForkParaAssetTransferRbk=0
ForkParaSupervision=0
#仅平行链适用,开启挖矿交易的高度,已有代码版本可能未在0高度开启挖矿,需要设置这个高度,新版本默认从0开启挖矿,通过交易配置分阶段奖励 #仅平行链适用,开启挖矿交易的高度,已有代码版本可能未在0高度开启挖矿,需要设置这个高度,新版本默认从0开启挖矿,通过交易配置分阶段奖励
ForkParaFullMinerHeight=0 ForkParaFullMinerHeight=0
#仅平行链适用,在旧的版本中计算blockTxHash输入高度为0,需要在此高度后统一采用新的主链高度值,旧的版本需要设置此分叉高度,新版本缺省为0即可
ForkParaRootHash=0
#nodegroup approve需要经过autonomy board成员审批,平行链不开启
ForkParaAutonomySuperGroup=-1
[fork.sub.evm] [fork.sub.evm]
Enable=0 Enable=0
...@@ -338,9 +352,6 @@ Enable=0 ...@@ -338,9 +352,6 @@ Enable=0
[fork.sub.accountmanager] [fork.sub.accountmanager]
Enable=0 Enable=0
[fork.sub.exchange]
Enable=0
[fork.sub.wasm] [fork.sub.wasm]
Enable=0 Enable=0
...@@ -371,6 +382,7 @@ ForkUnfreezeIDX= 0 ...@@ -371,6 +382,7 @@ ForkUnfreezeIDX= 0
[fork.sub.autonomy] [fork.sub.autonomy]
Enable=0 Enable=0
ForkAutonomyDelRule=0 ForkAutonomyDelRule=0
ForkAutonomyEnableItem=0
[fork.sub.jsvm] [fork.sub.jsvm]
Enable=0 Enable=0
...@@ -407,3 +419,19 @@ database="chain33metrics" ...@@ -407,3 +419,19 @@ database="chain33metrics"
username="" username=""
password="" password=""
namespace="" namespace=""
#exchange合约相关配置
[mver.exec.sub.exchange]
#银行帐户列表(现第一个地址用来收取手续费)
banks = ["1PTGVR7TUm1MJUH7M1UNcKBGMvfJ7nCrnN"]#Fee
#币种配置,
#rate每笔手续费率,配置时需*1e8(如:收取每笔交易千分之一的手续费,rate=100000)
#minFee最小手续费,配置时需*1e8(如:最小手续费收取1个,minFee=100000000)
coins = [
{ name = "bty", rate = 100000, minFee = 0 },
{ name = "ETH", rate = 100000, minFee = 0 },
{ name = "USDT", rate = 100000, minFee = 0 },
]
[fork.sub.exchange]
Enable=0
\ No newline at end of file
This diff is collapsed.
...@@ -78,6 +78,14 @@ serverStart=true ...@@ -78,6 +78,14 @@ serverStart=true
innerSeedEnable=true innerSeedEnable=true
useGithub=true useGithub=true
innerBounds=300 innerBounds=300
#是否启用ssl/tls 通信,默认不开启
enableTLS=false
#如果需要CA配合认证,则需要配置caCert,caServer
caCert=""
certFile=""
keyFile=""
# ca服务端接口http://ip:port
caServer=""
[p2p.sub.dht] [p2p.sub.dht]
seeds=[] seeds=[]
...@@ -269,6 +277,9 @@ superManager=[ ...@@ -269,6 +277,9 @@ superManager=[
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv", "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK" "1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
] ]
#autonomy执行器名字
autonomyExec="autonomy"
[exec.sub.paracross] [exec.sub.paracross]
nodeGroupFrozenCoins=0 nodeGroupFrozenCoins=0
#平行链共识停止后主链等待的高度 #平行链共识停止后主链等待的高度
...@@ -299,7 +310,7 @@ pointHX="19172955941344617222923168298456110557655645809646772800021167670156933 ...@@ -299,7 +310,7 @@ pointHX="19172955941344617222923168298456110557655645809646772800021167670156933
pointHY="21116962883761739586121793871108889864627195706475546685847911817475098399811" pointHY="21116962883761739586121793871108889864627195706475546685847911817475098399811"
#电路最大支持1024个叶子hash,10 level, 配置可以小于1024,但不能大于 #电路最大支持1024个叶子hash,10 level, 配置可以小于1024,但不能大于
maxTreeLeaves=1024 maxTreeLeaves=1024
mixApprs=["12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"]
[metrics] [metrics]
#是否使能发送metrics数据的发送 #是否使能发送metrics数据的发送
...@@ -315,3 +326,16 @@ database="chain33metrics" ...@@ -315,3 +326,16 @@ database="chain33metrics"
username="" username=""
password="" password=""
namespace="" namespace=""
#exchange合约相关配置
[mver.exec.sub.exchange]
#银行帐户列表(现第一个地址用来收取手续费)
banks = ["1PTGVR7TUm1MJUH7M1UNcKBGMvfJ7nCrnN"]#Fee
#币种配置,
#rate每笔手续费率,配置时需*1e8(如:收取每笔交易千分之一的手续费,rate=100000)
#minFee最小手续费,配置时需*1e8(如:最小手续费收取1个,minFee=100000000)
coins = [
{ name = "bty", rate = 100000, minFee = 0 },
{ name = "ETH", rate = 100000, minFee = 0 },
{ name = "USDT", rate = 100000, minFee = 0 },
]
\ No newline at end of file
...@@ -3,7 +3,7 @@ module github.com/33cn/plugin ...@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.15 go 1.15
require ( require (
github.com/33cn/chain33 v1.65.3-0.20210927064949-1a5b5bef855d github.com/33cn/chain33 v1.65.6-0.20211118074307-04e724cee41c
github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7 github.com/NebulousLabs/Sia v1.3.7
github.com/NebulousLabs/errors v0.0.0-20181203160057-9f787ce8f69e // indirect github.com/NebulousLabs/errors v0.0.0-20181203160057-9f787ce8f69e // indirect
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -12,11 +12,29 @@ ...@@ -12,11 +12,29 @@
package main package main
import ( import (
"flag"
"fmt"
frameVersion "github.com/33cn/chain33/common/version"
_ "github.com/33cn/chain33/system" _ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/util/cli" "github.com/33cn/chain33/util/cli"
_ "github.com/33cn/plugin/plugin" _ "github.com/33cn/plugin/plugin"
"github.com/33cn/plugin/version"
)
var (
versionCmd = flag.Bool("version", false, "detail version")
) )
func main() { func main() {
flag.Parse()
if *versionCmd {
fmt.Println(fmt.Sprintf("Build time: %s", version.BuildTime))
fmt.Println(fmt.Sprintf("System version: %s", version.Platform))
fmt.Println(fmt.Sprintf("Golang version: %s", version.GoVersion))
fmt.Println(fmt.Sprintf("plugin version: %s", version.GetVersion()))
fmt.Println(fmt.Sprintf("chain33 frame version: %s", frameVersion.GetVersion()))
return
}
cli.RunChain33("", "") cli.RunChain33("", "")
} }
...@@ -190,7 +190,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -190,7 +190,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
} }
//为了使用VRF,需要使用SECP256K1体系的公私钥 //为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
dposlog.Error("NewDPosClient", "err", err) dposlog.Error("NewDPosClient", "err", err)
return nil return nil
...@@ -199,7 +199,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -199,7 +199,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
ttypes.ConsensusCrypto = cr ttypes.ConsensusCrypto = cr
//安全连接仍然要使用ed25519 //安全连接仍然要使用ed25519
cr2, err := crypto.New(types.GetSignName("", types.ED25519)) cr2, err := crypto.Load(types.GetSignName("", types.ED25519), -1)
if err != nil { if err != nil {
dposlog.Error("NewDPosClient", "err", err) dposlog.Error("NewDPosClient", "err", err)
return nil return nil
......
...@@ -352,9 +352,9 @@ signType="auth_ecdsa" ...@@ -352,9 +352,9 @@ signType="auth_ecdsa"
) )
func init() { func init() {
cr2, err := crypto.New(types.GetSignName("", types.ED25519)) cr2, err := crypto.Load(types.GetSignName("", types.ED25519), -1)
if err != nil { if err != nil {
fmt.Println("crypto.New failed for types.ED25519") fmt.Println("crypto.Load failed for types.ED25519")
return return
} }
secureConnCrypto = cr2 secureConnCrypto = cr2
......
...@@ -19,7 +19,7 @@ const ( ...@@ -19,7 +19,7 @@ const (
func init() { func init() {
//为了使用VRF,需要使用SECP256K1体系的公私钥 //为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic("init ConsensusCrypto failed.") panic("init ConsensusCrypto failed.")
} }
......
...@@ -32,7 +32,7 @@ const ( ...@@ -32,7 +32,7 @@ const (
func init() { func init() {
//为了使用VRF,需要使用SECP256K1体系的公私钥 //为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic("init ConsensusCrypto failed.") panic("init ConsensusCrypto failed.")
} }
......
...@@ -14,7 +14,7 @@ import ( ...@@ -14,7 +14,7 @@ import (
func init() { func init() {
//为了使用VRF,需要使用SECP256K1体系的公私钥 //为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic("init ConsensusCrypto failed.") panic("init ConsensusCrypto failed.")
} }
......
...@@ -33,7 +33,7 @@ var ( ...@@ -33,7 +33,7 @@ var (
func init() { func init() {
//为了使用VRF,需要使用SECP256K1体系的公私钥 //为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic("init ConsensusCrypto failed.") panic("init ConsensusCrypto failed.")
} }
......
...@@ -27,7 +27,7 @@ var ( ...@@ -27,7 +27,7 @@ var (
func init() { func init() {
//为了使用VRF,需要使用SECP256K1体系的公私钥 //为了使用VRF,需要使用SECP256K1体系的公私钥
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic("init ConsensusCrypto failed.") panic("init ConsensusCrypto failed.")
} }
......
...@@ -35,7 +35,7 @@ const ( ...@@ -35,7 +35,7 @@ const (
//current miner tx take any privatekey for unify all nodes sign purpose, and para chain is free //current miner tx take any privatekey for unify all nodes sign purpose, and para chain is free
minerPrivateKey = "6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" minerPrivateKey = "6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
defaultGenesisAmount int64 = 1e8 defaultGenesisAmount int64 = 1e8
poolMainBlockSec int64 = 5 poolMainBlockMsec int64 = 5000
defaultEmptyBlockInterval int64 = 50 //write empty block every interval blocks in mainchain defaultEmptyBlockInterval int64 = 50 //write empty block every interval blocks in mainchain
defaultSearchMatchedBlockDepth int32 = 10000 defaultSearchMatchedBlockDepth int32 = 10000
) )
...@@ -70,29 +70,28 @@ type client struct { ...@@ -70,29 +70,28 @@ type client struct {
} }
type subConfig struct { type subConfig struct {
WriteBlockSeconds int64 `json:"writeBlockSeconds,omitempty"` WriteBlockMsec int64 `json:"writeBlockMsec,omitempty"`
ParaRemoteGrpcClient string `json:"paraRemoteGrpcClient,omitempty"` ParaRemoteGrpcClient string `json:"paraRemoteGrpcClient,omitempty"`
StartHeight int64 `json:"startHeight,omitempty"` StartHeight int64 `json:"startHeight,omitempty"`
WaitMainBlockNum int64 `json:"waitMainBlockNum,omitempty"` WaitMainBlockNum int64 `json:"waitMainBlockNum,omitempty"`
GenesisStartHeightSame bool `json:"genesisStartHeightSame,omitempty"` GenesisStartHeightSame bool `json:"genesisStartHeightSame,omitempty"`
EmptyBlockInterval []string `json:"emptyBlockInterval,omitempty"` EmptyBlockInterval []string `json:"emptyBlockInterval,omitempty"`
AuthAccount string `json:"authAccount,omitempty"` AuthAccount string `json:"authAccount,omitempty"`
WaitBlocks4CommitMsg int32 `json:"waitBlocks4CommitMsg,omitempty"` WaitBlocks4CommitMsg int32 `json:"waitBlocks4CommitMsg,omitempty"`
GenesisAmount int64 `json:"genesisAmount,omitempty"` GenesisAmount int64 `json:"genesisAmount,omitempty"`
MainBlockHashForkHeight int64 `json:"mainBlockHashForkHeight,omitempty"` MainBlockHashForkHeight int64 `json:"mainBlockHashForkHeight,omitempty"`
WaitConsensStopTimes uint32 `json:"waitConsensStopTimes,omitempty"` WaitConsensStopTimes uint32 `json:"waitConsensStopTimes,omitempty"`
MaxCacheCount int64 `json:"maxCacheCount,omitempty"` MaxCacheCount int64 `json:"maxCacheCount,omitempty"`
MaxSyncErrCount int32 `json:"maxSyncErrCount,omitempty"` MaxSyncErrCount int32 `json:"maxSyncErrCount,omitempty"`
BatchFetchBlockCount int64 `json:"batchFetchBlockCount,omitempty"` BatchFetchBlockCount int64 `json:"batchFetchBlockCount,omitempty"`
ParaConsensStartHeight int64 `json:"paraConsensStartHeight,omitempty"` ParaConsensStartHeight int64 `json:"paraConsensStartHeight,omitempty"`
MultiDownloadOpen bool `json:"multiDownloadOpen,omitempty"` MultiDownloadOpen bool `json:"multiDownloadOpen,omitempty"`
MultiDownInvNumPerJob int64 `json:"multiDownInvNumPerJob,omitempty"` MultiDownInvNumPerJob int64 `json:"multiDownInvNumPerJob,omitempty"`
MultiDownJobBuffNum uint32 `json:"multiDownJobBuffNum,omitempty"` MultiDownJobBuffNum uint32 `json:"multiDownJobBuffNum,omitempty"`
MultiDownServerRspTime uint32 `json:"multiDownServerRspTime,omitempty"` MultiDownServerRspTime uint32 `json:"multiDownServerRspTime,omitempty"`
RmCommitParamMainHeight int64 `json:"rmCommitParamMainHeight,omitempty"` RmCommitParamMainHeight int64 `json:"rmCommitParamMainHeight,omitempty"`
JumpDownloadClose bool `json:"jumpDownloadClose,omitempty"` JumpDownloadClose bool `json:"jumpDownloadClose,omitempty"`
BlsSign bool `json:"blsSign,omitempty"` Bls *blsConfig `json:"bls,omitempty"`
BlsLeaderSwitchIntval int32 `json:"blsLeaderSwitchIntval,omitempty"`
} }
// New function to init paracross env // New function to init paracross env
...@@ -106,8 +105,8 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -106,8 +105,8 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
subcfg.GenesisAmount = defaultGenesisAmount subcfg.GenesisAmount = defaultGenesisAmount
} }
if subcfg.WriteBlockSeconds <= 0 { if subcfg.WriteBlockMsec <= 0 {
subcfg.WriteBlockSeconds = poolMainBlockSec subcfg.WriteBlockMsec = poolMainBlockMsec
} }
//WaitMainBlockNum 配置最小为1,因为genesis块是startHeight-1, wait=1和startHeight相等 //WaitMainBlockNum 配置最小为1,因为genesis块是startHeight-1, wait=1和startHeight相等
...@@ -141,7 +140,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -141,7 +140,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
if err != nil { if err != nil {
panic(err) panic(err)
} }
secp, err := crypto.New(types.GetSignName("", types.SECP256K1)) secp, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
...@@ -292,7 +291,7 @@ func (client *client) GetStartMainHash(height int64) []byte { ...@@ -292,7 +291,7 @@ func (client *client) GetStartMainHash(height int64) []byte {
} }
if height > 0 { if height > 0 {
hint := time.NewTicker(time.Second * time.Duration(client.subCfg.WriteBlockSeconds)) hint := time.NewTicker(time.Second)
for lastHeight < height+client.subCfg.WaitMainBlockNum { for lastHeight < height+client.subCfg.WaitMainBlockNum {
select { select {
case <-hint.C: case <-hint.C:
...@@ -341,13 +340,17 @@ func (client *client) ProcEvent(msg *queue.Message) bool { ...@@ -341,13 +340,17 @@ func (client *client) ProcEvent(msg *queue.Message) bool {
return true return true
} }
plog.Info("paracross ProcEvent", "from", req.GetFrom(), "topic:", req.GetTopic(), "ty", sub.GetTy()) plog.Info("paracross ProcEvent", "from", req.GetFrom(), "topic:", req.GetTopic(), "ty", sub.GetTy())
if !client.blsSignCli.blsSignOn {
plog.Error("paracross ProcEvent bls is closed")
return true
}
switch sub.GetTy() { switch sub.GetTy() {
case P2pSubCommitTx: case P2pSubCommitTx:
go client.blsSignCli.rcvCommitTx(sub.GetCommitTx()) go client.blsSignCli.rcvCommitTx(sub.GetCommitTx())
case P2pSubLeaderSyncMsg: case P2pSubLeaderSyncMsg:
err := client.blsSignCli.rcvLeaderSyncTx(sub.GetSyncMsg()) err := client.blsSignCli.rcvLeaderSyncTx(sub.GetSyncMsg())
if err != nil { if err != nil {
plog.Error("paracross ProcEvent leader sync msg", "err", err) plog.Error("bls.event.paracross ProcEvent leader sync msg", "err", err)
} }
default: default:
plog.Error("paracross ProcEvent not support", "ty", sub.GetTy()) plog.Error("paracross ProcEvent not support", "ty", sub.GetTy())
......
...@@ -155,7 +155,7 @@ func TestAddMinerTx(t *testing.T) { ...@@ -155,7 +155,7 @@ func TestAddMinerTx(t *testing.T) {
pk, err := hex.DecodeString(minerPrivateKey) pk, err := hex.DecodeString(minerPrivateKey)
assert.Nil(t, err) assert.Nil(t, err)
secp, err := crypto.New(types.GetSignName("", types.SECP256K1)) secp, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
assert.Nil(t, err) assert.Nil(t, err)
priKey, err := secp.PrivKeyFromBytes(pk) priKey, err := secp.PrivKeyFromBytes(pk)
......
This diff is collapsed.
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
#1. 订阅P2P topic #1. 订阅P2P topic
1. 以PARA-BLS-SIGN-TOPIC为topic在P2P订阅,平行链内部节点间通过p2p广播同步消息,比如这里bls签名交易和leader同步消息 1. 以PARA-BLS-SIGN-TOPIC为topic在P2P订阅,平行链内部节点间通过p2p DHT机制广播同步消息,
1. 消息有两类,一类是leader心跳和监听消息,leader广播心跳消息,候选节点监听心跳,如果超时没收到,则自动选择下一个节点为leader
1. 另一类是bls签名共识交易,广播出来,由leader节点聚合发送
#2. 协商leader #2. 协商leader
1. 考虑到leader轮换发送共识交易,每隔一定共识高度比如100就会轮换下一个节点为leader发送交易,当前共识高度/100后对nodegroup 地址取余base值就是当前leader地址 1. 考虑到leader轮换发送共识交易,每隔一定共识高度比如100就会轮换下一个节点为leader发送交易,当前共识高度/100后对nodegroup 地址取余base值就是当前leader地址
...@@ -15,6 +17,8 @@ ...@@ -15,6 +17,8 @@
#3. 发送聚合共识交易 #3. 发送聚合共识交易
1. 共识交易P2P广播给所有订阅的节点,leader节点负责聚合后上链,如果收集的签名交易不超过2/3节点,则不发送上链交易,聚合交易最终在主链达成共识 1. 共识交易P2P广播给所有订阅的节点,leader节点负责聚合后上链,如果收集的签名交易不超过2/3节点,则不发送上链交易,聚合交易最终在主链达成共识
1. 节点广播共识交易后,超过一定时间共识高度没增长,重新发送共识交易 1. 节点广播共识交易后,超过一定时间共识高度没增长,重新发送共识交易
1. leader节点长时间未发送成功共识交易,共识高度超过和链高度阈值,任一达成共识的节点都可发送
1. 用户可手工设置达成共识的节点数,可以少于2/3个,其他节点可以选择非聚合签名,直接发送
#4. BLS聚合签名算法 #4. BLS聚合签名算法
......
...@@ -34,11 +34,10 @@ func TestIntegrateCommits(t *testing.T) { ...@@ -34,11 +34,10 @@ func TestIntegrateCommits(t *testing.T) {
assert.Equal(t, len(pool[0].Signs), 2) assert.Equal(t, len(pool[0].Signs), 2)
assert.Equal(t, pool[0].Addrs[0], "aa") assert.Equal(t, pool[0].Addrs[0], "aa")
assert.Equal(t, pool[0].Addrs[1], "bb") assert.Equal(t, pool[0].Addrs[1], "bb")
} }
func TestBlsSignMain(t *testing.T) { func TestBlsSignMain(t *testing.T) {
cryptoCli, err := crypto.New("bls") cryptoCli, err := crypto.Load("bls", -1)
assert.NoError(t, err) assert.NoError(t, err)
testSecpPrikey2BlsPub(t, cryptoCli) testSecpPrikey2BlsPub(t, cryptoCli)
...@@ -126,7 +125,7 @@ func testVerifyBlsSign(t *testing.T, cryptCli crypto.Crypto) { ...@@ -126,7 +125,7 @@ func testVerifyBlsSign(t *testing.T, cryptCli crypto.Crypto) {
data := "0x1a0c757365722e702e706172612e" data := "0x1a0c757365722e702e706172612e"
msg, err := common.FromHex(data) msg, err := common.FromHex(data)
assert.NoError(t, err) assert.NoError(t, err)
types.Decode(msg, status) _ = types.Decode(msg, status)
commit.Status = status commit.Status = status
commit.Bls = blsInfo commit.Bls = blsInfo
err = client.verifyBlsSign(KS, commit) err = client.verifyBlsSign(KS, commit)
......
...@@ -6,6 +6,7 @@ package para ...@@ -6,6 +6,7 @@ package para
import ( import (
"context" "context"
"encoding/hex"
"time" "time"
"strings" "strings"
...@@ -191,12 +192,9 @@ func (client *commitMsgClient) createCommitTx() { ...@@ -191,12 +192,9 @@ func (client *commitMsgClient) createCommitTx() {
if tx == nil { if tx == nil {
return return
} }
//bls sign, send to p2p //如果配置了blsSign 则发送到p2p的leader节点来聚合发送,否则发送到主链
if client.paraClient.subCfg.BlsSign { if client.paraClient.blsSignCli.blsSignOn {
//send to p2p pubsub client.pushCommitTx2P2P(tx)
plog.Info("para commitMs send to p2p", "hash", common.ToHex(tx.Hash()))
act := &pt.ParaP2PSubMsg{Ty: P2pSubCommitTx, Value: &pt.ParaP2PSubMsg_CommitTx{CommitTx: tx}}
client.paraClient.SendPubP2PMsg(paraBlsSignTopic, types.Encode(act))
return return
} }
client.pushCommitTx(tx) client.pushCommitTx(tx)
...@@ -255,16 +253,37 @@ func (client *commitMsgClient) pushCommitTx(signTx *types.Transaction) { ...@@ -255,16 +253,37 @@ func (client *commitMsgClient) pushCommitTx(signTx *types.Transaction) {
client.sendMsgCh <- signTx client.sendMsgCh <- signTx
} }
//仍旧setCurrentTx, 这样在几个块之后仍旧会触发重发,重发只是广播,不然发送p2p之后,如果共识没增加,也没有其他触发的条件了
func (client *commitMsgClient) pushCommitTx2P2P(signTx *types.Transaction) {
client.mutex.Lock()
defer client.mutex.Unlock()
client.checkTxCommitTimes = 0
client.setCurrentTx(signTx)
plog.Debug("bls.event.para bls commitMs send to p2p", "hash", common.ToHex(signTx.Hash()))
act := &pt.ParaP2PSubMsg{Ty: P2pSubCommitTx, Value: &pt.ParaP2PSubMsg_CommitTx{CommitTx: signTx}}
client.paraClient.SendPubP2PMsg(paraBlsSignTopic, types.Encode(act))
}
//根据收集的commit action,签名发送, 比如BLS签名后的commit msg
func (client *commitMsgClient) sendCommitActions(acts []*pt.ParacrossCommitAction) { func (client *commitMsgClient) sendCommitActions(acts []*pt.ParacrossCommitAction) {
//如果当前正在发送交易,则取消此次发送,待发送被确认或取消后再触发. 考虑到已经聚合共识成功,又收到某节点消息场景,会多发送交易
curTx := client.getCurrentTx()
if curTx != nil {
plog.Info("bls.event.paracommitmsg isSendingCommitMsg, cancel this operation", "sending.tx", common.ToHex(curTx.Hash()))
return
}
txs, _, err := client.createCommitMsgTxs(acts) txs, _, err := client.createCommitMsgTxs(acts)
if err != nil { if err != nil {
return return
} }
plog.Debug("paracommitmsg sendCommitActions", "txhash", common.ToHex(txs.Hash())) plog.Info("bls.event.paracommitmsg sendCommitActions", "txhash", common.ToHex(txs.Hash()))
for i, msg := range acts { for i, msg := range acts {
plog.Debug("paracommitmsg sendCommitActions", "idx", i, "height", msg.Status.Height, "mainheight", msg.Status.MainBlockHeight, plog.Debug("paracommitmsg sendCommitActions", "idx", i, "height", msg.Status.Height, "mainheight", msg.Status.MainBlockHeight,
"blockhash", common.HashHex(msg.Status.BlockHash), "mainHash", common.HashHex(msg.Status.MainBlockHash), "blockhash", common.HashHex(msg.Status.BlockHash), "mainHash", common.HashHex(msg.Status.MainBlockHash),
"addrsmap", common.ToHex(msg.Bls.AddrsMap), "sign", common.ToHex(msg.Bls.Sign)) "addrsmap", hex.EncodeToString(msg.Bls.AddrsMap), "sign", common.ToHex(msg.Bls.Sign))
} }
client.pushCommitTx(txs) client.pushCommitTx(txs)
} }
...@@ -341,10 +360,14 @@ func (client *commitMsgClient) checkConsensusStop(checks *commitCheckParams) { ...@@ -341,10 +360,14 @@ func (client *commitMsgClient) checkConsensusStop(checks *commitCheckParams) {
func (client *commitMsgClient) checkAuthAccountIn() { func (client *commitMsgClient) checkAuthAccountIn() {
nodeStr, err := client.getNodeGroupAddrs() nodeStr, err := client.getNodeGroupAddrs()
if err != nil { nodeSupervisionStr, errSupervision := client.getSupervisionNodeGroupAddrs() // 判断是否是监督节点
if err != nil && errSupervision != nil {
return return
} }
authExist := strings.Contains(nodeStr, client.authAccount)
authExist1 := strings.Contains(nodeStr, client.authAccount)
authExist2 := strings.Contains(nodeSupervisionStr, client.authAccount)
authExist := authExist1 || authExist2
//如果授权节点重新加入,需要从当前共识高度重新发送 //如果授权节点重新加入,需要从当前共识高度重新发送
if !client.authAccountIn && authExist { if !client.authAccountIn && authExist {
...@@ -403,7 +426,6 @@ func (client *commitMsgClient) isSync() bool { ...@@ -403,7 +426,6 @@ func (client *commitMsgClient) isSync() bool {
} }
return true return true
} }
func (client *commitMsgClient) getSendingTx(startHeight, endHeight int64) (*types.Transaction, int64) { func (client *commitMsgClient) getSendingTx(startHeight, endHeight int64) (*types.Transaction, int64) {
...@@ -425,7 +447,7 @@ func (client *commitMsgClient) getSendingTx(startHeight, endHeight int64) (*type ...@@ -425,7 +447,7 @@ func (client *commitMsgClient) getSendingTx(startHeight, endHeight int64) (*type
commits = append(commits, &pt.ParacrossCommitAction{Status: stat}) commits = append(commits, &pt.ParacrossCommitAction{Status: stat})
} }
if client.paraClient.subCfg.BlsSign { if client.paraClient.blsSignCli.blsSignOn {
err = client.paraClient.blsSignCli.blsSign(commits) err = client.paraClient.blsSignCli.blsSign(commits)
if err != nil { if err != nil {
plog.Error("paracommitmsg bls sign", "err", err) plog.Error("paracommitmsg bls sign", "err", err)
...@@ -933,6 +955,27 @@ func (client *commitMsgClient) getNodeGroupAddrs() (string, error) { ...@@ -933,6 +955,27 @@ func (client *commitMsgClient) getNodeGroupAddrs() (string, error) {
return resp.Value, nil return resp.Value, nil
} }
//Supervision node group会在主链和平行链都同时配置,只本地查询就可以
func (client *commitMsgClient) getSupervisionNodeGroupAddrs() (string, error) {
cfg := client.paraClient.GetAPI().GetConfig()
ret, err := client.paraClient.GetAPI().QueryChain(&types.ChainExecutor{
Driver: "paracross",
FuncName: "GetSupervisionNodeGroupAddrs",
Param: types.Encode(&pt.ReqParacrossNodeInfo{Title: cfg.GetTitle()}),
})
if err != nil {
plog.Error("commitmsg.getSupervisionNodeGroupAddrs ", "err", err.Error())
return "", err
}
resp, ok := ret.(*types.ReplyConfig)
if !ok {
plog.Error("commitmsg.getSupervisionNodeGroupAddrs rsp nok")
return "", err
}
return resp.Value, nil
}
func (client *commitMsgClient) onWalletStatus(status *types.WalletStatus) { func (client *commitMsgClient) onWalletStatus(status *types.WalletStatus) {
if status == nil || client.authAccount == "" { if status == nil || client.authAccount == "" {
plog.Info("para onWalletStatus", "status", status == nil, "auth", client.authAccount == "") plog.Info("para onWalletStatus", "status", status == nil, "auth", client.authAccount == "")
...@@ -978,7 +1021,7 @@ func getSecpPriKey(key string) (crypto.PrivKey, error) { ...@@ -978,7 +1021,7 @@ func getSecpPriKey(key string) (crypto.PrivKey, error) {
return nil, errors.Wrapf(err, "fromhex=%s", key) return nil, errors.Wrapf(err, "fromhex=%s", key)
} }
secp, err := crypto.New(types.GetSignName("", types.SECP256K1)) secp, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "crypto=%s", key) return nil, errors.Wrapf(err, "crypto=%s", key)
} }
......
...@@ -537,7 +537,7 @@ out: ...@@ -537,7 +537,7 @@ out:
if err == nil { if err == nil {
continue continue
} }
time.Sleep(time.Second * time.Duration(client.subCfg.WriteBlockSeconds)) time.Sleep(time.Millisecond * time.Duration(client.subCfg.WriteBlockMsec))
continue continue
} }
......
...@@ -63,6 +63,7 @@ func (j *jumpDldClient) getParaHeightList(startHeight, endHeight int64) ([]*type ...@@ -63,6 +63,7 @@ func (j *jumpDldClient) getParaHeightList(startHeight, endHeight int64) ([]*type
return heightList, nil return heightList, nil
} }
//分页查找,只获取范围内的高度 //分页查找,只获取范围内的高度
plog.Info("jumpDld.getParaTxHeightList", "start", heights.Items[0].GetHeight(), "end", heights.Items[len(heights.Items)-1].GetHeight())
for _, h := range heights.Items { for _, h := range heights.Items {
if h.Height >= startHeight && h.Height <= endHeight { if h.Height >= startHeight && h.Height <= endHeight {
heightList = append(heightList, h) heightList = append(heightList, h)
...@@ -280,17 +281,20 @@ func (j *jumpDldClient) getParaTxs(startHeight, endHeight int64, heights []*type ...@@ -280,17 +281,20 @@ func (j *jumpDldClient) getParaTxs(startHeight, endHeight int64, heights []*type
//获取每一排1000个paraTxBlocks //获取每一排1000个paraTxBlocks
paraBlocks, err := j.getParaTxsBlocks(row, title) paraBlocks, err := j.getParaTxsBlocks(row, title)
if err != nil { if err != nil {
plog.Error("jumpDld.getParaTxsBlocks", "err", err)
return err return err
} }
//根据1000个paraTxBlocks的头尾高度获取header的头尾高度,header的高度要包含paraTxBlocks高度 //根据1000个paraTxBlocks的头尾高度获取header的头尾高度,header的高度要包含paraTxBlocks高度
headerStart, headerEnd := getHeaderStartEndRange(startHeight, endHeight, heightsRows, i) headerStart, headerEnd := getHeaderStartEndRange(startHeight, endHeight, heightsRows, i)
plog.Debug("jumpDld.getParaTxs", "headerStart", headerStart, "headerEnd", headerEnd, "i", i) plog.Info("jumpDld.getParaTxs", "headerStart", headerStart, "headerEnd", headerEnd, "i", i)
err = j.procParaTxHeaders(headerStart, headerEnd, paraBlocks, jobCh) err = j.procParaTxHeaders(headerStart, headerEnd, paraBlocks, jobCh)
if err != nil { if err != nil {
plog.Error("jumpDld.procParaTxHeaders", "err", err)
return err return err
} }
if atomic.LoadInt32(&j.downFail) != 0 || j.paraClient.isCancel() { if atomic.LoadInt32(&j.downFail) != 0 || j.paraClient.isCancel() {
plog.Error("jumpDld.downFail", "downfail", atomic.LoadInt32(&j.downFail))
return errors.New("verify fail or main thread cancel") return errors.New("verify fail or main thread cancel")
} }
} }
......
...@@ -60,8 +60,8 @@ func (client *client) Query_LeaderInfo(req *types.ReqNil) (types.Message, error) ...@@ -60,8 +60,8 @@ func (client *client) Query_LeaderInfo(req *types.ReqNil) (types.Message, error)
if client == nil { if client == nil {
return nil, fmt.Errorf("%s", "client not bind message queue.") return nil, fmt.Errorf("%s", "client not bind message queue.")
} }
nodes, leader, base, off, isLeader := client.blsSignCli.getLeaderInfo() _, leader, base, off, isLeader, _ := client.blsSignCli.getLeaderInfo()
return &pt.ElectionStatus{IsLeader: isLeader, Leader: &pt.LeaderSyncInfo{ID: nodes[leader], BaseIdx: base, Offset: off}}, nil return &pt.ElectionStatus{IsLeader: isLeader, Leader: &pt.LeaderSyncInfo{ID: leader, BaseIdx: base, Offset: off}}, nil
} }
func (client *client) Query_CommitTxInfo(req *types.ReqNil) (types.Message, error) { func (client *client) Query_CommitTxInfo(req *types.ReqNil) (types.Message, error) {
......
...@@ -427,18 +427,23 @@ func (client *blockSyncClient) addBlock(lastBlock *types.Block, localBlock *pt.P ...@@ -427,18 +427,23 @@ func (client *blockSyncClient) addBlock(lastBlock *types.Block, localBlock *pt.P
} }
//挖矿固定难度 //挖矿固定难度
newBlock.Difficulty = cfg.GetP(0).PowLimitBits newBlock.Difficulty = cfg.GetP(0).PowLimitBits
//需要首先对交易进行排序然后再计算TxHash
if cfg.IsFork(newBlock.GetMainHeight(), "ForkRootHash") {
newBlock.Txs = types.TransactionSort(newBlock.Txs)
}
newBlock.TxHash = merkle.CalcMerkleRoot(cfg, newBlock.GetMainHeight(), newBlock.Txs)
newBlock.BlockTime = localBlock.BlockTime newBlock.BlockTime = localBlock.BlockTime
newBlock.MainHash = localBlock.MainHash newBlock.MainHash = localBlock.MainHash
newBlock.MainHeight = localBlock.MainHeight newBlock.MainHeight = localBlock.MainHeight
if newBlock.Height == 1 && newBlock.BlockTime < client.paraClient.cfg.GenesisBlockTime { if newBlock.Height == 1 && newBlock.BlockTime < client.paraClient.cfg.GenesisBlockTime {
panic("genesisBlockTime bigger than the 1st block time, need rmv db and reset genesisBlockTime") panic("genesisBlockTime bigger than the 1st block time, need rmv db and reset genesisBlockTime")
} }
//需要首先对交易进行排序然后再计算TxHash
if cfg.IsFork(newBlock.GetMainHeight(), "ForkRootHash") {
newBlock.Txs = types.TransactionSort(newBlock.Txs)
}
//在之前版本中CalcMerkleRoot的height是未初始化的MainHeight,等于0,在这个平行链的分叉ForkParaRootHash高度后统一采用新高度
if cfg.IsDappFork(newBlock.Height, pt.ParaX, pt.ForkParaRootHash) {
newBlock.TxHash = merkle.CalcMerkleRoot(cfg, newBlock.GetMainHeight(), newBlock.Txs)
} else {
newBlock.TxHash = merkle.CalcMerkleRoot(cfg, 0, newBlock.Txs)
}
err = client.writeBlock(lastBlock.StateHash, &newBlock) err = client.writeBlock(lastBlock.StateHash, &newBlock)
client.printDebugInfo("Para sync - create new Block", client.printDebugInfo("Para sync - create new Block",
......
...@@ -62,7 +62,7 @@ func createParaTestInstance(t *testing.T, q queue.Queue) *client { ...@@ -62,7 +62,7 @@ func createParaTestInstance(t *testing.T, q queue.Queue) *client {
//生成私钥 //生成私钥
pk, err := hex.DecodeString(TestPrivateKey) pk, err := hex.DecodeString(TestPrivateKey)
assert.Nil(t, err) assert.Nil(t, err)
secp, err := crypto.New(types.GetSignName("", types.SECP256K1)) secp, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
assert.Nil(t, err) assert.Nil(t, err)
priKey, err := secp.PrivKeyFromBytes(pk) priKey, err := secp.PrivKeyFromBytes(pk)
assert.Nil(t, err) assert.Nil(t, err)
......
...@@ -33,7 +33,7 @@ func getPrivKey(t *testing.T) crypto.PrivKey { ...@@ -33,7 +33,7 @@ func getPrivKey(t *testing.T) crypto.PrivKey {
pk, err := common.FromHex("6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b") pk, err := common.FromHex("6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b")
assert.Nil(t, err) assert.Nil(t, err)
secp, err := crypto.New(types.GetSignName("", types.SECP256K1)) secp, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
assert.Nil(t, err) assert.Nil(t, err)
priKey, err := secp.PrivKeyFromBytes(pk) priKey, err := secp.PrivKeyFromBytes(pk)
......
...@@ -108,7 +108,7 @@ func sendReplyList(q queue.Queue) { ...@@ -108,7 +108,7 @@ func sendReplyList(q queue.Queue) {
} }
func getprivkey(key string) crypto.PrivKey { func getprivkey(key string) crypto.PrivKey {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
......
...@@ -299,7 +299,15 @@ func (cs *ConsensusState) reconstructLastCommit(state State) { ...@@ -299,7 +299,15 @@ func (cs *ConsensusState) reconstructLastCommit(state State) {
seenCommit := cs.client.csStore.LoadSeenCommit(state.LastBlockHeight) seenCommit := cs.client.csStore.LoadSeenCommit(state.LastBlockHeight)
commit := ttypes.Commit{QbftCommit: seenCommit} commit := ttypes.Commit{QbftCommit: seenCommit}
voteType := byte(commit.VoteType) voteType := byte(commit.VoteType)
lastCommit := ttypes.NewVoteSet(state.ChainID, state.LastBlockHeight, commit.Round(), voteType, state.LastValidators) round := commit.Round()
validators := state.LastValidators
// Increment validators if necessary
if round > 0 {
validators.IncrementAccum(round)
qbftlog.Info("reconstructLastCommit validator change", "round", round,
"proposer", fmt.Sprintf("%X", ttypes.Fingerprint(validators.Proposer.Address)))
}
lastCommit := ttypes.NewVoteSet(state.ChainID, state.LastBlockHeight, round, voteType, validators, state.LastSequence)
if state.LastSequence == 0 { if state.LastSequence == 0 {
if voteType != ttypes.VoteTypePrecommit { if voteType != ttypes.VoteTypePrecommit {
panic("reconstructLastCommit: voteType not Precommit") panic("reconstructLastCommit: voteType not Precommit")
...@@ -391,7 +399,7 @@ func (cs *ConsensusState) updateToState(state State) { ...@@ -391,7 +399,7 @@ func (cs *ConsensusState) updateToState(state State) {
cs.LockedBlock = nil cs.LockedBlock = nil
cs.ValidRound = -1 cs.ValidRound = -1
cs.ValidBlock = nil cs.ValidBlock = nil
cs.Votes = ttypes.NewHeightVoteSet(state.ChainID, height, validators) cs.Votes = ttypes.NewHeightVoteSet(state.ChainID, height, validators, state.Sequence)
cs.CommitRound = -1 cs.CommitRound = -1
cs.LastCommit = lastCommit cs.LastCommit = lastCommit
cs.LastValidators = state.LastValidators cs.LastValidators = state.LastValidators
...@@ -635,6 +643,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) { ...@@ -635,6 +643,7 @@ func (cs *ConsensusState) enterNewRound(height int64, round int) {
cs.ProposalBlock = nil cs.ProposalBlock = nil
cs.ProposalBlockHash = nil cs.ProposalBlockHash = nil
} }
cs.Votes.SetValSet(validators)
cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping cs.Votes.SetRound(round + 1) // also track next round (round+1) to allow round-skipping
//cs.eventBus.PublishEventNewRound(cs.RoundStateEvent()) //cs.eventBus.PublishEventNewRound(cs.RoundStateEvent())
......
...@@ -26,7 +26,7 @@ import ( ...@@ -26,7 +26,7 @@ import (
) )
const ( const (
qbftVersion = "0.2.0" qbftVersion = "0.2.1"
// DefaultQbftPort 默认端口 // DefaultQbftPort 默认端口
DefaultQbftPort = 33001 DefaultQbftPort = 33001
...@@ -114,7 +114,7 @@ type subConfig struct { ...@@ -114,7 +114,7 @@ type subConfig struct {
MessageInterval int32 `json:"messageInterval"` MessageInterval int32 `json:"messageInterval"`
} }
func applyConfig(sub []byte) { func applyConfig(cfg *types.Consensus, sub []byte) {
var subcfg subConfig var subcfg subConfig
if sub != nil { if sub != nil {
types.MustDecode(sub, &subcfg) types.MustDecode(sub, &subcfg)
...@@ -122,6 +122,9 @@ func applyConfig(sub []byte) { ...@@ -122,6 +122,9 @@ func applyConfig(sub []byte) {
genesis = subcfg.Genesis genesis = subcfg.Genesis
genesisAmount = subcfg.GenesisAmount genesisAmount = subcfg.GenesisAmount
genesisBlockTime = subcfg.GenesisBlockTime genesisBlockTime = subcfg.GenesisBlockTime
if !cfg.Minerstart {
return
}
timeoutTxAvail.Store(subcfg.TimeoutTxAvail) timeoutTxAvail.Store(subcfg.TimeoutTxAvail)
timeoutPropose.Store(subcfg.TimeoutPropose) timeoutPropose.Store(subcfg.TimeoutPropose)
...@@ -182,6 +185,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -182,6 +185,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
qbftlog.Info("create qbft client") qbftlog.Info("create qbft client")
genesis = cfg.Genesis genesis = cfg.Genesis
genesisBlockTime = cfg.GenesisBlockTime genesisBlockTime = cfg.GenesisBlockTime
applyConfig(cfg, sub)
if !cfg.Minerstart { if !cfg.Minerstart {
qbftlog.Info("This node only sync block") qbftlog.Info("This node only sync block")
c := drivers.NewBaseClient(cfg) c := drivers.NewBaseClient(cfg)
...@@ -189,7 +193,6 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -189,7 +193,6 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
c.SetChild(client) c.SetChild(client)
return client return client
} }
applyConfig(sub)
//init rand //init rand
ttypes.Init() ttypes.Init()
...@@ -200,7 +203,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -200,7 +203,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
} }
ttypes.CryptoName = types.GetSignName("", signType) ttypes.CryptoName = types.GetSignName("", signType)
cr, err := crypto.New(ttypes.CryptoName) cr, err := crypto.Load(ttypes.CryptoName, -1)
if err != nil { if err != nil {
qbftlog.Error("load qbft crypto fail", "err", err) qbftlog.Error("load qbft crypto fail", "err", err)
return nil return nil
...@@ -226,8 +229,8 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -226,8 +229,8 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
return nil return nil
} }
qbftlog.Info("show qbft info", "sign", ttypes.CryptoName, "useAggSig", UseAggSig(), "genesisFile", genesisFile, qbftlog.Info("show qbft info", "version", qbftVersion, "sign", ttypes.CryptoName, "useAggSig", UseAggSig(),
"privFile", privFile) "genesisFile", genesisFile, "privFile", privFile)
ttypes.InitMessageMap() ttypes.InitMessageMap()
......
...@@ -118,7 +118,7 @@ func configManagerTx() *types.Transaction { ...@@ -118,7 +118,7 @@ func configManagerTx() *types.Transaction {
} }
func getprivkey(key string) crypto.PrivKey { func getprivkey(key string) crypto.PrivKey {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
......
...@@ -129,6 +129,7 @@ func (s State) StringIndented(indent string) string { ...@@ -129,6 +129,7 @@ func (s State) StringIndented(indent string) string {
%s LastBlockTotalTx: %v %s LastBlockTotalTx: %v
%s LastBlockID: %X %s LastBlockID: %X
%s Validators: %v %s Validators: %v
%s LastProposer: %v
%s Sequence: %v %s Sequence: %v
%s LastSequence: %v %s LastSequence: %v
%s LastCommitRound: %v %s LastCommitRound: %v
...@@ -138,6 +139,7 @@ func (s State) StringIndented(indent string) string { ...@@ -138,6 +139,7 @@ func (s State) StringIndented(indent string) string {
indent, s.LastBlockTotalTx, indent, s.LastBlockTotalTx,
indent, s.LastBlockID, indent, s.LastBlockID,
indent, s.Validators.StringIndented(indent), indent, s.Validators.StringIndented(indent),
indent, s.LastValidators.GetProposer().String(),
indent, s.Sequence, indent, s.Sequence,
indent, s.LastSequence, indent, s.LastSequence,
indent, s.LastCommitRound, indent, s.LastCommitRound,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package types package types
import ( import (
"bytes"
"errors" "errors"
"strings" "strings"
"sync" "sync"
...@@ -37,6 +38,7 @@ One for their LastCommit round, and another for the official commit round. ...@@ -37,6 +38,7 @@ One for their LastCommit round, and another for the official commit round.
type HeightVoteSet struct { type HeightVoteSet struct {
chainID string chainID string
height int64 height int64
seq int64
valSet *ValidatorSet valSet *ValidatorSet
mtx sync.Mutex mtx sync.Mutex
...@@ -46,9 +48,10 @@ type HeightVoteSet struct { ...@@ -46,9 +48,10 @@ type HeightVoteSet struct {
} }
// NewHeightVoteSet ... // NewHeightVoteSet ...
func NewHeightVoteSet(chainID string, height int64, valSet *ValidatorSet) *HeightVoteSet { func NewHeightVoteSet(chainID string, height int64, valSet *ValidatorSet, seq int64) *HeightVoteSet {
hvs := &HeightVoteSet{ hvs := &HeightVoteSet{
chainID: chainID, chainID: chainID,
seq: seq,
} }
hvs.Reset(height, valSet) hvs.Reset(height, valSet)
return hvs return hvs
...@@ -82,15 +85,25 @@ func (hvs *HeightVoteSet) Round() int { ...@@ -82,15 +85,25 @@ func (hvs *HeightVoteSet) Round() int {
return hvs.round return hvs.round
} }
// SetValSet update ValidatorSet
func (hvs *HeightVoteSet) SetValSet(valSet *ValidatorSet) {
hvs.mtx.Lock()
defer hvs.mtx.Unlock()
hvs.valSet = valSet
}
// SetRound Create more RoundVoteSets up to round. // SetRound Create more RoundVoteSets up to round.
func (hvs *HeightVoteSet) SetRound(round int) { func (hvs *HeightVoteSet) SetRound(round int) {
hvs.mtx.Lock() hvs.mtx.Lock()
defer hvs.mtx.Unlock() defer hvs.mtx.Unlock()
if hvs.round != 0 && (round < hvs.round+1) { if hvs.round != 0 && (round < hvs.round-1) {
panic(Fmt("Panicked on a Sanity Check: %v", "SetRound() must increment hvs.round")) panic(Fmt("SetRound() must increment hvs.round %v, round %v", hvs.round, round))
} }
for r := hvs.round + 1; r <= round; r++ { for r := hvs.round - 1; r <= round; r++ {
if _, ok := hvs.roundVoteSets[r]; ok { if rvs, ok := hvs.roundVoteSets[r]; ok {
if r == round-1 {
hvs.updateValSet(rvs)
}
continue // Already exists because peerCatchupRounds. continue // Already exists because peerCatchupRounds.
} }
hvs.addRound(r) hvs.addRound(r)
...@@ -102,12 +115,24 @@ func (hvs *HeightVoteSet) addRound(round int) { ...@@ -102,12 +115,24 @@ func (hvs *HeightVoteSet) addRound(round int) {
if _, ok := hvs.roundVoteSets[round]; ok { if _, ok := hvs.roundVoteSets[round]; ok {
panic("addRound() for an existing round") panic("addRound() for an existing round")
} }
prevotes := NewVoteSet(hvs.chainID, hvs.height, round, VoteTypePrevote, hvs.valSet) prevotes := NewVoteSet(hvs.chainID, hvs.height, round, VoteTypePrevote, hvs.valSet, hvs.seq)
precommits := NewVoteSet(hvs.chainID, hvs.height, round, VoteTypePrecommit, hvs.valSet) precommits := NewVoteSet(hvs.chainID, hvs.height, round, VoteTypePrecommit, hvs.valSet, hvs.seq)
hvs.roundVoteSets[round] = RoundVoteSet{ hvs.roundVoteSets[round] = RoundVoteSet{
Prevotes: prevotes, Prevotes: prevotes,
Precommits: precommits, Precommits: precommits,
} }
ttlog.Debug("addRound", "round", round, "proposer", hvs.valSet.Proposer.String())
}
func (hvs *HeightVoteSet) updateValSet(rvs RoundVoteSet) {
hvsAddr := hvs.valSet.GetProposer().Address
rvsAddr := rvs.Prevotes.valSet.GetProposer().Address
if !bytes.Equal(hvsAddr, rvsAddr) {
ttlog.Info("update RoundVoteSet proposer", "round", rvs.Prevotes.Round(),
"old", Fmt("%X", Fingerprint(rvsAddr)), "new", Fmt("%X", Fingerprint(hvsAddr)))
rvs.Prevotes.valSet = hvs.valSet
rvs.Precommits.valSet = hvs.valSet
}
} }
// AddVote Duplicate votes return added=false, err=nil. // AddVote Duplicate votes return added=false, err=nil.
......
...@@ -66,7 +66,7 @@ func (v *Validator) String() string { ...@@ -66,7 +66,7 @@ func (v *Validator) String() string {
if v == nil { if v == nil {
return "nil-Validator" return "nil-Validator"
} }
return Fmt("Validator{ADDR:%X PUB:%X VP:%v A:%v}", return Fmt("{ADDR:%X PUB:%X VP:%v A:%v}",
v.Address, v.Address,
v.PubKey, v.PubKey,
v.VotingPower, v.VotingPower,
......
...@@ -56,6 +56,7 @@ type VoteSet struct { ...@@ -56,6 +56,7 @@ type VoteSet struct {
height int64 height int64
round int round int
voteType byte voteType byte
seq int64
mtx sync.Mutex mtx sync.Mutex
valSet *ValidatorSet valSet *ValidatorSet
...@@ -69,7 +70,7 @@ type VoteSet struct { ...@@ -69,7 +70,7 @@ type VoteSet struct {
} }
// NewVoteSet Constructs a new VoteSet struct used to accumulate votes for given height/round. // NewVoteSet Constructs a new VoteSet struct used to accumulate votes for given height/round.
func NewVoteSet(chainID string, height int64, round int, voteType byte, valSet *ValidatorSet) *VoteSet { func NewVoteSet(chainID string, height int64, round int, voteType byte, valSet *ValidatorSet, seq int64) *VoteSet {
if height == 0 { if height == 0 {
PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.") PanicSanity("Cannot make VoteSet for height == 0, doesn't make sense.")
} }
...@@ -78,6 +79,7 @@ func NewVoteSet(chainID string, height int64, round int, voteType byte, valSet * ...@@ -78,6 +79,7 @@ func NewVoteSet(chainID string, height int64, round int, voteType byte, valSet *
height: height, height: height,
round: round, round: round,
voteType: voteType, voteType: voteType,
seq: seq,
valSet: valSet, valSet: valSet,
votesBitArray: NewBitArray(valSet.Size()), votesBitArray: NewBitArray(valSet.Size()),
votes: make([]*Vote, valSet.Size()), votes: make([]*Vote, valSet.Size()),
...@@ -323,9 +325,8 @@ func (voteSet *VoteSet) AddAggVote(vote *AggVote) (bool, error) { ...@@ -323,9 +325,8 @@ func (voteSet *VoteSet) AddAggVote(vote *AggVote) (bool, error) {
// Ensure that signer is proposer // Ensure that signer is proposer
propAddr := valset.Proposer.Address propAddr := valset.Proposer.Address
if !bytes.Equal(valAddr, propAddr) { if !bytes.Equal(valAddr, propAddr) {
return false, errors.Wrapf(ErrVoteInvalidValidatorAddress, ttlog.Info("odd aggregate vote", "reason",
"aggVote.ValidatorAddress (%X) does not match proposer address (%X)", Fmt("ValidatorAddress: %X; Proposer: %X", Fingerprint(valAddr), Fingerprint(propAddr)))
valAddr, propAddr)
} }
// If we already know of this vote, return false // If we already know of this vote, return false
if voteSet.aggVote != nil { if voteSet.aggVote != nil {
...@@ -536,7 +537,7 @@ func (voteSet *VoteSet) IsCommit() bool { ...@@ -536,7 +537,7 @@ func (voteSet *VoteSet) IsCommit() bool {
if voteSet == nil { if voteSet == nil {
return false return false
} }
if voteSet.voteType != VoteTypePrecommit { if (voteSet.voteType != VoteTypePrevote || voteSet.seq == 0) && voteSet.voteType != VoteTypePrecommit {
return false return false
} }
voteSet.mtx.Lock() voteSet.mtx.Lock()
......
...@@ -378,7 +378,7 @@ func NormGet(key string) { ...@@ -378,7 +378,7 @@ func NormGet(key string) {
} }
func getprivkey(key string) crypto.PrivKey { func getprivkey(key string) crypto.PrivKey {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
...@@ -394,7 +394,7 @@ func getprivkey(key string) crypto.PrivKey { ...@@ -394,7 +394,7 @@ func getprivkey(key string) crypto.PrivKey {
} }
func genaddress() (string, crypto.PrivKey) { func genaddress() (string, crypto.PrivKey) {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
......
...@@ -23,9 +23,9 @@ var ( ...@@ -23,9 +23,9 @@ var (
) )
func init() { func init() {
cr2, err := crypto.New(types.GetSignName("", types.ED25519)) cr2, err := crypto.Load(types.GetSignName("", types.ED25519), -1)
if err != nil { if err != nil {
fmt.Println("crypto.New failed for types.ED25519") fmt.Println("crypto.Load failed for types.ED25519")
return return
} }
secureConnCrypto = cr2 secureConnCrypto = cr2
......
...@@ -377,7 +377,7 @@ func SaveState(state State) *tmtypes.State { ...@@ -377,7 +377,7 @@ func SaveState(state State) *tmtypes.State {
} }
func getprivkey(key string) crypto.PrivKey { func getprivkey(key string) crypto.PrivKey {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
......
...@@ -175,7 +175,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module { ...@@ -175,7 +175,7 @@ func New(cfg *types.Consensus, sub []byte) queue.Module {
} }
ttypes.CryptoName = types.GetSignName("", signType) ttypes.CryptoName = types.GetSignName("", signType)
cr, err := crypto.New(ttypes.CryptoName) cr, err := crypto.Load(ttypes.CryptoName, -1)
if err != nil { if err != nil {
tendermintlog.Error("NewTendermintClient", "err", err) tendermintlog.Error("NewTendermintClient", "err", err)
return nil return nil
......
...@@ -518,7 +518,7 @@ type RespMsg struct { ...@@ -518,7 +518,7 @@ type RespMsg struct {
} }
func getprivkey(key string) crypto.PrivKey { func getprivkey(key string) crypto.PrivKey {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
...@@ -534,7 +534,7 @@ func getprivkey(key string) crypto.PrivKey { ...@@ -534,7 +534,7 @@ func getprivkey(key string) crypto.PrivKey {
} }
func genaddress() (string, crypto.PrivKey) { func genaddress() (string, crypto.PrivKey) {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
panic(err) panic(err)
} }
......
...@@ -173,7 +173,7 @@ func (client *Client) ProcEvent(msg *queue.Message) bool { ...@@ -173,7 +173,7 @@ func (client *Client) ProcEvent(msg *queue.Message) bool {
} }
func (client *Client) privFromBytes(privkey []byte) (crypto.PrivKey, error) { func (client *Client) privFromBytes(privkey []byte) (crypto.PrivKey, error) {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -138,7 +138,7 @@ func TestTicketMap(t *testing.T) { ...@@ -138,7 +138,7 @@ func TestTicketMap(t *testing.T) {
} }
privmap := make(map[string]crypto.PrivKey) privmap := make(map[string]crypto.PrivKey)
//通过privkey生成一个pubkey然后换算成对应的addr //通过privkey生成一个pubkey然后换算成对应的addr
cr, _ := crypto.New("secp256k1") cr, _ := crypto.Load("secp256k1", -1)
priv, _ := cr.PrivKeyFromBytes([]byte("2116459C0EC8ED01AA0EEAE35CAC5C96F94473F7816F114873291217303F6989")) priv, _ := cr.PrivKeyFromBytes([]byte("2116459C0EC8ED01AA0EEAE35CAC5C96F94473F7816F114873291217303F6989"))
privmap["1111"] = priv privmap["1111"] = priv
privmap["2222"] = priv privmap["2222"] = priv
...@@ -170,7 +170,7 @@ func TestProcEvent(t *testing.T) { ...@@ -170,7 +170,7 @@ func TestProcEvent(t *testing.T) {
} }
func Test_genPrivHash(t *testing.T) { func Test_genPrivHash(t *testing.T) {
c, err := crypto.New(types.GetSignName("", types.SECP256K1)) c, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
assert.NoError(t, err) assert.NoError(t, err)
priv, _ := c.GenKey() priv, _ := c.GenKey()
...@@ -198,7 +198,7 @@ func Test_getNextRequiredDifficulty(t *testing.T) { ...@@ -198,7 +198,7 @@ func Test_getNextRequiredDifficulty(t *testing.T) {
} }
func Test_vrfVerify(t *testing.T) { func Test_vrfVerify(t *testing.T) {
c, err := crypto.New(types.GetSignName("", types.SECP256K1)) c, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
assert.NoError(t, err) assert.NoError(t, err)
priv, err := c.GenKey() priv, err := c.GenKey()
assert.NoError(t, err) assert.NoError(t, err)
......
...@@ -439,7 +439,7 @@ func Exec_QueryExpiredAccounts(expiredtime int64, stateDB db.KV, kvdb db.KVDB) ( ...@@ -439,7 +439,7 @@ func Exec_QueryExpiredAccounts(expiredtime int64, stateDB db.KV, kvdb db.KVDB) (
} }
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1 signType := types.SECP256K1
c, err := crypto.New(types.GetSignName("", signType)) c, err := crypto.Load(types.GetSignName("", signType), -1)
if err != nil { if err != nil {
return tx, err return tx, err
} }
......
...@@ -104,6 +104,8 @@ source "./publicTest.sh" ...@@ -104,6 +104,8 @@ source "./publicTest.sh"
publicPeriod=172800 publicPeriod=172800
pubAttendRatio=60 pubAttendRatio=60
pubApproveRatio=65 pubApproveRatio=65
start_block=50
} }
function update_last_header() { function update_last_header() {
...@@ -159,11 +161,11 @@ function check_activeRule() { ...@@ -159,11 +161,11 @@ function check_activeRule() {
function testProposalRule() { function testProposalRule() {
# proposal # proposal
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}" echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
update_last_header 10 update_last_header "${start_block}"
proposalRuleTx proposalRuleTx
#vote #vote
block_wait "${Chain33Cli}" 10 block_wait "${Chain33Cli}" "${start_block}"
raw=$(${Chain33Cli} autonomy voteRule -r 1 -p "${proposalRuleID}") raw=$(${Chain33Cli} autonomy voteRule -r 1 -p "${proposalRuleID}")
sign_and_send "${raw}" "${votePrKey}" sign_and_send "${raw}" "${votePrKey}"
raw=$(${Chain33Cli} autonomy voteRule -r 1 -p "${proposalRuleID}") raw=$(${Chain33Cli} autonomy voteRule -r 1 -p "${proposalRuleID}")
...@@ -213,11 +215,11 @@ function check_activeBoard() { ...@@ -213,11 +215,11 @@ function check_activeBoard() {
function testProposalBoard() { function testProposalBoard() {
#proposal #proposal
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}" echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
update_last_header 10 update_last_header "${start_block}"
proposalBoardTx proposalBoardTx
#vote #vote
block_wait "${Chain33Cli}" 10 block_wait "${Chain33Cli}" "${start_block}"
raw=$(${Chain33Cli} autonomy voteBoard -r 1 -p "${proposalBoardID}") raw=$(${Chain33Cli} autonomy voteBoard -r 1 -p "${proposalBoardID}")
sign_and_send "${raw}" "${votePrKey}" sign_and_send "${raw}" "${votePrKey}"
raw=$(${Chain33Cli} autonomy voteBoard -r 1 -p "${proposalBoardID}") raw=$(${Chain33Cli} autonomy voteBoard -r 1 -p "${proposalBoardID}")
...@@ -253,11 +255,11 @@ function showProject_status() { ...@@ -253,11 +255,11 @@ function showProject_status() {
function testProposalProject() { function testProposalProject() {
# proposal # proposal
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}" echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
update_last_header 10 update_last_header "${start_block}"
proposalProjectTx proposalProjectTx
#vote #vote
block_wait "${Chain33Cli}" 10 block_wait "${Chain33Cli}" "${start_block}"
for ((i = 0; i < 13; i++)); do for ((i = 0; i < 13; i++)); do
raw=$(${Chain33Cli} autonomy voteProject -r 1 -p "${proposalProjectID}") raw=$(${Chain33Cli} autonomy voteProject -r 1 -p "${proposalProjectID}")
sign_and_send "${raw}" "${arrayKey[$i]}" sign_and_send "${raw}" "${arrayKey[$i]}"
...@@ -304,7 +306,7 @@ function testProposalChange() { ...@@ -304,7 +306,7 @@ function testProposalChange() {
hash=$(${Chain33Cli} send coins transfer -a 20 -n test -t "${autonomyAddr}" -k "${arrayKey[21]}") hash=$(${Chain33Cli} send coins transfer -a 20 -n test -t "${autonomyAddr}" -k "${arrayKey[21]}")
check_tx "${Chain33Cli}" "${hash}" check_tx "${Chain33Cli}" "${hash}"
update_last_header 10 update_last_header "${start_block}"
proposalChangeTx "${changeAddr}" "${arrayKey[20]}" proposalChangeTx "${changeAddr}" "${arrayKey[20]}"
ret=$(${Chain33Cli} autonomy showActiveBoard | jq -r ".boards[20]") ret=$(${Chain33Cli} autonomy showActiveBoard | jq -r ".boards[20]")
...@@ -313,7 +315,7 @@ function testProposalChange() { ...@@ -313,7 +315,7 @@ function testProposalChange() {
fi fi
#vote #vote
block_wait "${Chain33Cli}" 10 block_wait "${Chain33Cli}" "${start_block}"
for ((i = 0; i < 13; i++)); do for ((i = 0; i < 13; i++)); do
raw=$(${Chain33Cli} autonomy voteChange -r 1 -p "${proposalChangeID}") raw=$(${Chain33Cli} autonomy voteChange -r 1 -p "${proposalChangeID}")
sign_and_send "${raw}" "${arrayKey[$i]}" sign_and_send "${raw}" "${arrayKey[$i]}"
...@@ -341,19 +343,19 @@ function testProposalChange() { ...@@ -341,19 +343,19 @@ function testProposalChange() {
function testProposalTerminate() { function testProposalTerminate() {
#test terminate #test terminate
echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}" echo -e "${GRE}=========== $FUNCNAME begin ===========${NOC}"
update_last_header 10 update_last_header "${start_block}"
proposalRuleTx proposalRuleTx
update_last_header 10 update_last_header "${start_block}"
proposalBoardTx proposalBoardTx
update_last_header 10 update_last_header "${start_block}"
proposalProjectTx proposalProjectTx
update_last_header 10 update_last_header "${start_block}"
proposalChangeTx "${changeAddr2}" "${arrayKey[21]}" proposalChangeTx "${changeAddr2}" "${arrayKey[21]}"
block_wait "${Chain33Cli}" 850 block_wait "${Chain33Cli}" 900
raw=$(${Chain33Cli} autonomy terminateRule -p "${proposalRuleID}") raw=$(${Chain33Cli} autonomy terminateRule -p "${proposalRuleID}")
sign_and_send "${raw}" "${propKey}" sign_and_send "${raw}" "${propKey}"
......
...@@ -84,6 +84,8 @@ function check_tx() { ...@@ -84,6 +84,8 @@ function check_tx() {
ty=$(${CLI} tx query -s "${2}" | jq .receipt.ty) ty=$(${CLI} tx query -s "${2}" | jq .receipt.ty)
if [[ ${ty} != 2 ]]; then if [[ ${ty} != 2 ]]; then
echo -e "${RED}check tx error, hash is ${2}${NOC}" echo -e "${RED}check tx error, hash is ${2}${NOC}"
hashInfo=$(${CLI} tx query -s "${2}")
echo -e "${RED}query tx: ${hashInfo}${NOC}"
exit_test exit_test
fi fi
} }
......
...@@ -69,6 +69,15 @@ func AutonomyCmd() *cobra.Command { ...@@ -69,6 +69,15 @@ func AutonomyCmd() *cobra.Command {
ShowProposalChangeCmd(), ShowProposalChangeCmd(),
) )
// item
cmd.AddCommand(
ProposalItemCmd(),
RevokeProposalItemCmd(),
VoteProposalItemCmd(),
TerminateProposalItemCmd(),
ShowProposalItemCmd(),
)
return cmd return cmd
} }
......
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package commands
import (
"encoding/json"
jsonrpc "github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/spf13/cobra"
)
// ProposalItemCmd 创建提案命令
func ProposalItemCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "proposalItem",
Short: "create proposal Item",
Run: proposalItem,
}
addProposalItemFlags(cmd)
return cmd
}
func addProposalItemFlags(cmd *cobra.Command) {
cmd.Flags().Int32P("year", "y", 0, "year")
cmd.Flags().Int32P("month", "m", 0, "month")
cmd.Flags().Int32P("day", "d", 0, "day")
cmd.Flags().StringP("itemTxHash", "i", "", "the tx to apply check")
cmd.MarkFlagRequired("itemTxHash")
cmd.Flags().StringP("description", "p", "", "description item")
cmd.Flags().Int64P("startBlock", "s", 0, "start block height")
cmd.MarkFlagRequired("startBlock")
cmd.Flags().Int64P("endBlock", "e", 0, "end block height")
cmd.MarkFlagRequired("endBlock")
}
func proposalItem(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
year, _ := cmd.Flags().GetInt32("year")
month, _ := cmd.Flags().GetInt32("month")
day, _ := cmd.Flags().GetInt32("day")
txHash, _ := cmd.Flags().GetString("itemTxHash")
description, _ := cmd.Flags().GetString("description")
startBlock, _ := cmd.Flags().GetInt64("startBlock")
endBlock, _ := cmd.Flags().GetInt64("endBlock")
params := &auty.ProposalItem{
Year: year,
Month: month,
Day: day,
ItemTxHash: txHash,
Description: description,
StartBlockHeight: startBlock,
EndBlockHeight: endBlock,
}
payLoad, err := json.Marshal(params)
if err != nil {
return
}
pm := &rpctypes.CreateTxIn{
Execer: types.GetExecName(auty.AutonomyX, paraName),
ActionName: "PropItem",
Payload: payLoad,
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", pm, &res)
ctx.RunWithoutMarshal()
}
// RevokeProposalItemCmd 撤销提案
func RevokeProposalItemCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "revokeItem",
Short: "revoke proposal Item",
Run: revokeProposalItem,
}
addRevokeProposalItemFlags(cmd)
return cmd
}
func addRevokeProposalItemFlags(cmd *cobra.Command) {
cmd.Flags().StringP("proposalID", "p", "", "proposal ID")
cmd.MarkFlagRequired("proposalID")
}
func revokeProposalItem(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ID, _ := cmd.Flags().GetString("proposalID")
params := &auty.RevokeProposalItem{
ProposalID: ID,
}
payLoad, err := json.Marshal(params)
if err != nil {
return
}
pm := &rpctypes.CreateTxIn{
Execer: types.GetExecName(auty.AutonomyX, paraName),
ActionName: "RvkPropItem",
Payload: payLoad,
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", pm, &res)
ctx.RunWithoutMarshal()
}
// VoteProposalItemCmd 投票提案
func VoteProposalItemCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "voteItem",
Short: "vote proposal Item",
Run: voteProposalItem,
}
addVoteProposalItemFlags(cmd)
return cmd
}
func addVoteProposalItemFlags(cmd *cobra.Command) {
cmd.Flags().StringP("proposalID", "p", "", "proposal ID")
cmd.MarkFlagRequired("proposalID")
cmd.Flags().Int32P("approve", "r", 1, "1:approve, 2:oppose, 3:quit, default 1")
}
func voteProposalItem(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ID, _ := cmd.Flags().GetString("proposalID")
approve, _ := cmd.Flags().GetInt32("approve")
params := &auty.VoteProposalItem{
ProposalID: ID,
Vote: auty.AutonomyVoteOption(approve),
}
payLoad, err := json.Marshal(params)
if err != nil {
return
}
pm := &rpctypes.CreateTxIn{
Execer: types.GetExecName(auty.AutonomyX, paraName),
ActionName: "VotePropItem",
Payload: payLoad,
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", pm, &res)
ctx.RunWithoutMarshal()
}
// TerminateProposalItemCmd 终止提案
func TerminateProposalItemCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "terminateItem",
Short: "terminate proposal Item",
Run: terminateProposalItem,
}
addTerminateProposalItemFlags(cmd)
return cmd
}
func addTerminateProposalItemFlags(cmd *cobra.Command) {
cmd.Flags().StringP("proposalID", "p", "", "proposal ID")
cmd.MarkFlagRequired("proposalID")
}
func terminateProposalItem(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ID, _ := cmd.Flags().GetString("proposalID")
params := &auty.RevokeProposalItem{
ProposalID: ID,
}
payLoad, err := json.Marshal(params)
if err != nil {
return
}
pm := &rpctypes.CreateTxIn{
Execer: types.GetExecName(auty.AutonomyX, paraName),
ActionName: "TmintPropItem",
Payload: payLoad,
}
var res string
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", pm, &res)
ctx.RunWithoutMarshal()
}
// ShowProposalItemCmd 显示提案查询信息
func ShowProposalItemCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "showItem",
Short: "show proposal Item info",
Run: showProposalItem,
}
addShowProposalItemflags(cmd)
return cmd
}
func addShowProposalItemflags(cmd *cobra.Command) {
cmd.Flags().Uint32P("type", "y", 0, "type(0:query by hash; 1:list)")
cmd.MarkFlagRequired("type")
cmd.Flags().StringP("proposalID", "p", "", "proposal ID")
cmd.Flags().Uint32P("status", "s", 0, "status")
cmd.Flags().StringP("addr", "a", "", "address")
cmd.Flags().Int32P("count", "c", 1, "count, default is 1")
cmd.Flags().Int32P("direction", "d", 0, "direction, default is reserve")
cmd.Flags().Int64P("height", "t", -1, "height, default is -1")
cmd.Flags().Int32P("index", "i", -1, "index, default is -1")
}
func showProposalItem(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
typ, _ := cmd.Flags().GetUint32("type")
propID, _ := cmd.Flags().GetString("proposalID")
status, _ := cmd.Flags().GetUint32("status")
addr, _ := cmd.Flags().GetString("addr")
count, _ := cmd.Flags().GetInt32("count")
direction, _ := cmd.Flags().GetInt32("direction")
height, _ := cmd.Flags().GetInt64("height")
index, _ := cmd.Flags().GetInt32("index")
var params rpctypes.Query4Jrpc
var rep interface{}
params.Execer = auty.AutonomyX
if 0 == typ {
req := types.ReqString{
Data: propID,
}
params.FuncName = auty.GetProposalItem
params.Payload = types.MustPBToJSON(&req)
rep = &auty.ReplyQueryProposalItem{}
} else if 1 == typ {
req := auty.ReqQueryProposalItem{
Status: int32(status),
Addr: addr,
Count: count,
Direction: direction,
Height: height,
Index: index,
}
params.FuncName = auty.ListProposalItem
params.Payload = types.MustPBToJSON(&req)
rep = &auty.ReplyQueryProposalItem{}
}
ctx := jsonrpc.NewRPCCtx(rpcLaddr, "Chain33.Query", params, rep)
ctx.Run()
}
...@@ -31,6 +31,7 @@ const ( ...@@ -31,6 +31,7 @@ const (
pubApproveRatio int32 = 66 // 全体持票人赞成率,以%计 pubApproveRatio int32 = 66 // 全体持票人赞成率,以%计
pubOpposeRatio int32 = 33 // 全体持票人否决率,以%计 pubOpposeRatio int32 = 33 // 全体持票人否决率,以%计
startEndBlockPeriod = 720 // 提案开始结束最小周期 startEndBlockPeriod = 720 // 提案开始结束最小周期
propEndBlockPeriod = 1000000 // 提案高度 结束高度最大周期 100W
) )
type action struct { type action struct {
...@@ -110,6 +111,14 @@ func (a *action) propBoard(prob *auty.ProposalBoard) (*types.Receipt, error) { ...@@ -110,6 +111,14 @@ func (a *action) propBoard(prob *auty.ProposalBoard) (*types.Receipt, error) {
prob.EndBlockHeight, "height", a.height) prob.EndBlockHeight, "height", a.height)
return nil, auty.ErrSetBlockHeight return nil, auty.ErrSetBlockHeight
} }
if a.api.GetConfig().IsDappFork(a.height, auty.AutonomyX, auty.ForkAutonomyDelRule) {
if prob.EndBlockHeight > a.height+propEndBlockPeriod {
alog.Error("propBoard height invaild", "EndBlockHeight", prob.EndBlockHeight, "height", a.height)
return nil, auty.ErrSetBlockHeight
}
}
if len(prob.Boards) == 0 { if len(prob.Boards) == 0 {
alog.Error("propBoard ", "proposal boards number is zero", len(prob.Boards)) alog.Error("propBoard ", "proposal boards number is zero", len(prob.Boards))
return nil, auty.ErrBoardNumber return nil, auty.ErrBoardNumber
...@@ -398,7 +407,7 @@ func isApproved(totalVotes, approveVotes, opposeVotes, quitVotes, attendRation, ...@@ -398,7 +407,7 @@ func isApproved(totalVotes, approveVotes, opposeVotes, quitVotes, attendRation,
//参与率计算弃权票 //参与率计算弃权票
attendVotes := approveVotes + opposeVotes + quitVotes attendVotes := approveVotes + opposeVotes + quitVotes
//赞成率,忽略弃权票 //赞成率,忽略弃权票
validVotes := approveVotes + opposeVotes validVotes := totalVotes - quitVotes
if totalVotes != 0 && attendVotes != 0 && if totalVotes != 0 && attendVotes != 0 &&
attendVotes*100 > attendRation*totalVotes && attendVotes*100 > attendRation*totalVotes &&
approveVotes*100 > approveRatio*validVotes { approveVotes*100 > approveRatio*validVotes {
......
...@@ -268,6 +268,13 @@ func TestPropBoard(t *testing.T) { ...@@ -268,6 +268,13 @@ func TestPropBoard(t *testing.T) {
StartBlockHeight: env.blockHeight + 5, StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10, EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
}, },
{ // ErrSetBlockHeight
BoardUpdate: auty.BoardUpdate_REPLACEALL,
Boards: boards,
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + propEndBlockPeriod + 10,
},
} }
result := []error{ result := []error{
auty.ErrRepeatAddr, auty.ErrRepeatAddr,
...@@ -284,8 +291,9 @@ func TestPropBoard(t *testing.T) { ...@@ -284,8 +291,9 @@ func TestPropBoard(t *testing.T) {
auty.ErrBoardNumber, auty.ErrBoardNumber,
auty.ErrRepeatAddr, auty.ErrRepeatAddr,
nil, nil,
auty.ErrSetBlockHeight,
} }
lenBoards := []int{0, 0, 0, 22, 0, 0, 21, 0, 0, 0, 0, 20} lenBoards := []int{0, 0, 0, 22, 0, 0, 21, 0, 0, 0, 0, 20, 0}
InitBoard(stateDB) InitBoard(stateDB)
exec.SetStateDB(stateDB) exec.SetStateDB(stateDB)
...@@ -763,7 +771,7 @@ func TestVerifyMinerAddr(t *testing.T) { ...@@ -763,7 +771,7 @@ func TestVerifyMinerAddr(t *testing.T) {
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1 signType := types.SECP256K1
c, err := crypto.New(types.GetSignName(auty.AutonomyX, signType)) c, err := crypto.Load(types.GetSignName(auty.AutonomyX, signType), -1)
if err != nil { if err != nil {
return tx, err return tx, err
} }
......
...@@ -27,6 +27,13 @@ func (a *action) propChange(prob *auty.ProposalChange) (*types.Receipt, error) { ...@@ -27,6 +27,13 @@ func (a *action) propChange(prob *auty.ProposalChange) (*types.Receipt, error) {
return nil, auty.ErrSetBlockHeight return nil, auty.ErrSetBlockHeight
} }
if a.api.GetConfig().IsDappFork(a.height, auty.AutonomyX, auty.ForkAutonomyDelRule) {
if prob.EndBlockHeight > a.height+propEndBlockPeriod {
alog.Error("propBoard height invaild", "EndBlockHeight", prob.EndBlockHeight, "height", a.height)
return nil, auty.ErrSetBlockHeight
}
}
act, err := a.getActiveBoard() act, err := a.getActiveBoard()
if err != nil { if err != nil {
alog.Error("propChange ", "addr", a.fromaddr, "execaddr", a.execaddr, "getActiveBoard failed", err) alog.Error("propChange ", "addr", a.fromaddr, "execaddr", a.execaddr, "getActiveBoard failed", err)
...@@ -248,10 +255,18 @@ func (a *action) votePropChange(voteProb *auty.VoteProposalChange) (*types.Recei ...@@ -248,10 +255,18 @@ func (a *action) votePropChange(voteProb *auty.VoteProposalChange) (*types.Recei
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
} }
if cur.VoteResult.TotalVotes != 0 && if cfg.IsDappFork(a.height, auty.AutonomyX, auty.ForkAutonomyDelRule) {
float32(cur.VoteResult.ApproveVotes)/float32(cur.VoteResult.TotalVotes) > float32(cur.CurRule.BoardApproveRatio)/100.0 { if cur.VoteResult.TotalVotes != 0 && cur.VoteResult.TotalVotes > cur.VoteResult.QuitVotes &&
cur.VoteResult.Pass = true cur.VoteResult.ApproveVotes*100 > cur.CurRule.BoardApproveRatio*(cur.VoteResult.TotalVotes-cur.VoteResult.QuitVotes) {
cur.PropChange.RealEndBlockHeight = a.height cur.VoteResult.Pass = true
cur.PropChange.RealEndBlockHeight = a.height
}
} else {
if cur.VoteResult.TotalVotes != 0 &&
float32(cur.VoteResult.ApproveVotes)/float32(cur.VoteResult.TotalVotes) > float32(cur.CurRule.BoardApproveRatio)/100.0 {
cur.VoteResult.Pass = true
cur.PropChange.RealEndBlockHeight = a.height
}
} }
key := propChangeID(voteProb.ProposalID) key := propChangeID(voteProb.ProposalID)
...@@ -306,12 +321,23 @@ func (a *action) tmintPropChange(tmintProb *auty.TerminateProposalChange) (*type ...@@ -306,12 +321,23 @@ func (a *action) tmintPropChange(tmintProb *auty.TerminateProposalChange) (*type
return nil, err return nil, err
} }
if cur.VoteResult.TotalVotes != 0 && cfg := a.api.GetConfig()
float32(cur.VoteResult.ApproveVotes)/float32(cur.VoteResult.TotalVotes) > float32(cur.CurRule.BoardApproveRatio)/100.0 { if cfg.IsDappFork(a.height, auty.AutonomyX, auty.ForkAutonomyDelRule) {
cur.VoteResult.Pass = true if cur.VoteResult.TotalVotes != 0 && cur.VoteResult.TotalVotes > cur.VoteResult.QuitVotes &&
cur.VoteResult.ApproveVotes*100 > cur.CurRule.BoardApproveRatio*(cur.VoteResult.TotalVotes-cur.VoteResult.QuitVotes) {
cur.VoteResult.Pass = true
} else {
cur.VoteResult.Pass = false
}
} else { } else {
cur.VoteResult.Pass = false if cur.VoteResult.TotalVotes != 0 &&
float32(cur.VoteResult.ApproveVotes)/float32(cur.VoteResult.TotalVotes) > float32(cur.CurRule.BoardApproveRatio)/100.0 {
cur.VoteResult.Pass = true
} else {
cur.VoteResult.Pass = false
}
} }
cur.PropChange.RealEndBlockHeight = a.height cur.PropChange.RealEndBlockHeight = a.height
var logs []*types.ReceiptLog var logs []*types.ReceiptLog
......
...@@ -453,6 +453,7 @@ func voteProposalChangeTx(parm *auty.VoteProposalChange) (*types.Transaction, er ...@@ -453,6 +453,7 @@ func voteProposalChangeTx(parm *auty.VoteProposalChange) (*types.Transaction, er
func terminateProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.KV, kvdb dbm.KVDB, save bool) { func terminateProposalChange(t *testing.T, env *ExecEnv, exec drivers.Driver, stateDB dbm.KV, kvdb dbm.KVDB, save bool) {
api := new(apimock.QueueProtocolAPI) api := new(apimock.QueueProtocolAPI)
api.On("GetConfig", mock.Anything).Return(chainTestCfg, nil)
api.On("StoreList", mock.Anything).Return(&types.StoreListReply{}, nil) api.On("StoreList", mock.Anything).Return(&types.StoreListReply{}, nil)
api.On("GetLastHeader", mock.Anything).Return(&types.Header{StateHash: []byte("")}, nil) api.On("GetLastHeader", mock.Anything).Return(&types.Header{StateHash: []byte("")}, nil)
hear := &types.Header{StateHash: []byte("")} hear := &types.Header{StateHash: []byte("")}
......
...@@ -7,6 +7,7 @@ package executor ...@@ -7,6 +7,7 @@ package executor
import ( import (
"github.com/33cn/chain33/types" "github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types" auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/pkg/errors"
) )
// 提案董事会相关 // 提案董事会相关
...@@ -130,3 +131,39 @@ func (a *Autonomy) Exec_TmintPropChange(payload *auty.TerminateProposalChange, t ...@@ -130,3 +131,39 @@ func (a *Autonomy) Exec_TmintPropChange(payload *auty.TerminateProposalChange, t
action := newAction(a, tx, int32(index)) action := newAction(a, tx, int32(index))
return action.tmintPropChange(payload) return action.tmintPropChange(payload)
} }
// Exec_PropChange 创建事项规则
func (a *Autonomy) Exec_PropItem(payload *auty.ProposalItem, tx *types.Transaction, index int) (*types.Receipt, error) {
if !a.GetAPI().GetConfig().IsDappFork(a.GetHeight(), auty.AutonomyX, auty.ForkAutonomyEnableItem) {
return nil, errors.Wrapf(types.ErrActionNotSupport, "not after fork")
}
action := newAction(a, tx, int32(index))
return action.propItem(payload)
}
// Exec_RvkPropItem 撤销事项规则
func (a *Autonomy) Exec_RvkPropItem(payload *auty.RevokeProposalItem, tx *types.Transaction, index int) (*types.Receipt, error) {
if !a.GetAPI().GetConfig().IsDappFork(a.GetHeight(), auty.AutonomyX, auty.ForkAutonomyEnableItem) {
return nil, errors.Wrapf(types.ErrActionNotSupport, "not after fork")
}
action := newAction(a, tx, int32(index))
return action.rvkPropItem(payload)
}
// Exec_VotePropItem 投票事项规则
func (a *Autonomy) Exec_VotePropItem(payload *auty.VoteProposalItem, tx *types.Transaction, index int) (*types.Receipt, error) {
if !a.GetAPI().GetConfig().IsDappFork(a.GetHeight(), auty.AutonomyX, auty.ForkAutonomyEnableItem) {
return nil, errors.Wrapf(types.ErrActionNotSupport, "not after fork")
}
action := newAction(a, tx, int32(index))
return action.votePropItem(payload)
}
// Exec_TmintPropItem 终止事项规则
func (a *Autonomy) Exec_TmintPropItem(payload *auty.TerminateProposalItem, tx *types.Transaction, index int) (*types.Receipt, error) {
if !a.GetAPI().GetConfig().IsDappFork(a.GetHeight(), auty.AutonomyX, auty.ForkAutonomyEnableItem) {
return nil, errors.Wrapf(types.ErrActionNotSupport, "not after fork")
}
action := newAction(a, tx, int32(index))
return action.tmintPropItem(payload)
}
...@@ -106,3 +106,23 @@ func (a *Autonomy) ExecLocal_VotePropChange(payload *auty.VoteProposalChange, tx ...@@ -106,3 +106,23 @@ func (a *Autonomy) ExecLocal_VotePropChange(payload *auty.VoteProposalChange, tx
func (a *Autonomy) ExecLocal_TmintPropChange(payload *auty.TerminateProposalChange, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) { func (a *Autonomy) ExecLocal_TmintPropChange(payload *auty.TerminateProposalChange, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execAutoLocalChange(tx, receiptData) return a.execAutoLocalChange(tx, receiptData)
} }
// ExecLocal_PropItem 创建事项规则
func (a *Autonomy) ExecLocal_PropItem(payload *auty.ProposalItem, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execAutoLocalItem(tx, receiptData)
}
// ExecLocal_RvkPropItem 撤销事项规则
func (a *Autonomy) ExecLocal_RvkPropItem(payload *auty.RevokeProposalItem, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execAutoLocalItem(tx, receiptData)
}
// ExecLocal_VotePropItem 投票事项规则
func (a *Autonomy) ExecLocal_VotePropItem(payload *auty.VoteProposalItem, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execAutoLocalItem(tx, receiptData)
}
// ExecLocal_TmintPropItem 终止事项规则
func (a *Autonomy) ExecLocal_TmintPropItem(payload *auty.TerminateProposalItem, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
return a.execAutoLocalItem(tx, receiptData)
}
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package executor
import (
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
"github.com/pkg/errors"
)
func (a *Autonomy) execAutoLocalItem(tx *types.Transaction, receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
set, err := a.execLocalItem(receiptData)
if err != nil {
return set, err
}
dbSet := &types.LocalDBSet{}
dbSet.KV = a.AddRollbackKV(tx, tx.Execer, set.KV)
return dbSet, nil
}
func (a *Autonomy) execLocalItem(receiptData *types.ReceiptData) (*types.LocalDBSet, error) {
table := NewItemTable(a.GetLocalDB())
for _, log := range receiptData.Logs {
switch log.Ty {
case auty.TyLogPropItem,
auty.TyLogRvkPropItem,
auty.TyLogVotePropItem,
auty.TyLogTmintPropItem:
{
var receipt auty.ReceiptProposalItem
err := types.Decode(log.Log, &receipt)
if err != nil {
return nil, err
}
err = table.Replace(receipt.Current)
if err != nil {
return nil, err
}
}
default:
break
}
}
kvs, err := table.Save()
if err != nil {
return nil, err
}
dbSet := &types.LocalDBSet{}
dbSet.KV = append(dbSet.KV, kvs...)
return dbSet, nil
}
func (a *Autonomy) listProposalItem(req *auty.ReqQueryProposalItem) (types.Message, error) {
if req == nil {
return nil, types.ErrInvalidParam
}
localDb := a.GetLocalDB()
query := NewItemTable(localDb).GetQuery(localDb)
var primary []byte
if req.Height > 0 {
primary = []byte(dapp.HeightIndexStr(req.Height, int64(req.Index)))
}
indexName := ""
if req.Status > 0 && req.Addr != "" {
indexName = "addr_status"
} else if req.Status > 0 {
indexName = "status"
} else if req.Addr != "" {
indexName = "addr"
}
cur := &ItemRow{
AutonomyProposalItem: &auty.AutonomyProposalItem{},
}
cur.Address = req.Addr
cur.Status = req.Status
cur.Height = req.Height
cur.Index = req.Index
prefix, err := cur.Get(indexName)
if err != nil {
alog.Error("Get", "indexName", indexName, "err", err)
return nil, err
}
rows, err := query.ListIndex(indexName, prefix, primary, req.Count, req.Direction)
if err != nil {
alog.Error("query List failed", "indexName", indexName, "prefix", "prefix", "key", string(primary), "err", err)
return nil, err
}
if len(rows) == 0 {
return nil, types.ErrNotFound
}
var rep auty.ReplyQueryProposalItem
for _, row := range rows {
r, ok := row.Data.(*auty.AutonomyProposalItem)
if !ok {
alog.Error("listProposalItem", "err", "bad row type")
return nil, types.ErrDecode
}
rep.PropItems = append(rep.PropItems, r)
}
return &rep, nil
}
func getProposalItem(db dbm.KV, req *types.ReqString) (*auty.ReplyQueryProposalItem, error) {
if req == nil || len(req.Data) <= 0 {
return nil, errors.Wrapf(types.ErrInvalidParam, "invalid parameter")
}
value, err := db.Get(propItemID(req.Data))
if err != nil {
return nil, errors.Wrapf(err, "fail,db.get item id=%s", req.Data)
}
prop := &auty.AutonomyProposalItem{}
err = types.Decode(value, prop)
if err != nil {
return nil, errors.Wrapf(err, "decode item fail")
}
rep := &auty.ReplyQueryProposalItem{}
rep.PropItems = append(rep.PropItems, prop)
return rep, nil
}
// IsAutonomyApprovedItem get 2 parameters: autonomyItemID, applyTxHash
func IsAutonomyApprovedItem(db dbm.KV, req *types.ReqMultiStrings) (types.Message, error) {
if req == nil {
return nil, errors.Wrapf(types.ErrInvalidParam, "req is nil")
}
if len(req.Datas) < 2 {
return nil, errors.Wrapf(types.ErrInvalidParam, "req datas less 2 parameters")
}
autonomyItemID := req.Datas[0]
applyTxHash := req.Datas[1]
res, err := getProposalItem(db, &types.ReqString{Data: autonomyItemID})
if err != nil {
return nil, err
}
if len(res.GetPropItems()) <= 0 {
return nil, errors.Wrapf(types.ErrNotFound, "not get item")
}
if res.PropItems[0].ProposalID != autonomyItemID {
return nil, errors.Wrapf(types.ErrInvalidParam, "get prop id=%s not equal req=%s", res.PropItems[0].ProposalID, autonomyItemID)
}
if res.PropItems[0].PropItem.ItemTxHash != applyTxHash {
return nil, errors.Wrapf(types.ErrInvalidParam, "get item id=%s != req=%s", res.PropItems[0].PropItem.ItemTxHash, applyTxHash)
}
if res.PropItems[0].Status == auty.AutonomyStatusTmintPropItem && res.PropItems[0].BoardVoteRes.Pass {
return &types.Reply{IsOk: true}, nil
}
if res.PropItems[0].Status != auty.AutonomyStatusTmintPropItem {
return nil, errors.Wrapf(types.ErrNotAllow, "item status =%d not terminate", res.PropItems[0].Status)
}
return nil, errors.Wrapf(types.ErrNotAllow, "item vote status not pass = %v", res.PropItems[0].BoardVoteRes.Pass)
}
This diff is collapsed.
package executor
import (
"fmt"
"github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/common/db/table"
"github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
auty "github.com/33cn/plugin/plugin/dapp/autonomy/types"
)
/*
table struct
data: autonomy item
index: status, addr
*/
var itemOpt = &table.Option{
Prefix: "LODB-autonomy",
Name: "item",
Primary: "heightindex",
Index: []string{"addr", "status", "addr_status"},
}
//NewItemTable 新建表
func NewItemTable(kvdb db.KV) *table.Table {
rowmeta := NewItemRow()
newTable, err := table.NewTable(rowmeta, kvdb, itemOpt)
if err != nil {
panic(err)
}
return newTable
}
//ItemRow table meta 结构
type ItemRow struct {
*auty.AutonomyProposalItem
}
//NewItemRow 新建一个meta 结构
func NewItemRow() *ItemRow {
return &ItemRow{AutonomyProposalItem: &auty.AutonomyProposalItem{}}
}
//CreateRow 新建数据行(注意index 数据一定也要保存到数据中,不能就保存heightindex)
func (r *ItemRow) CreateRow() *table.Row {
return &table.Row{Data: &auty.AutonomyProposalItem{}}
}
//SetPayload 设置数据
func (r *ItemRow) SetPayload(data types.Message) error {
if d, ok := data.(*auty.AutonomyProposalItem); ok {
r.AutonomyProposalItem = d
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (r *ItemRow) Get(key string) ([]byte, error) {
if key == "heightindex" {
return []byte(dapp.HeightIndexStr(r.Height, int64(r.Index))), nil
} else if key == "status" {
return []byte(fmt.Sprintf("%2d", r.Status)), nil
} else if key == "addr" {
return []byte(r.Address), nil
} else if key == "addr_status" {
return []byte(fmt.Sprintf("%s:%2d", r.Address, r.Status)), nil
}
return nil, types.ErrNotFound
}
...@@ -79,3 +79,12 @@ var ( ...@@ -79,3 +79,12 @@ var (
func propChangeID(txHash string) []byte { func propChangeID(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", changePrefix, txHash)) return []byte(fmt.Sprintf("%s%s", changePrefix, txHash))
} }
var (
//item
itemPrefix = idPrefix + "item-"
)
func propItemID(txHash string) []byte {
return []byte(fmt.Sprintf("%s%s", itemPrefix, txHash))
}
...@@ -31,6 +31,13 @@ func (a *action) propProject(prob *auty.ProposalProject) (*types.Receipt, error) ...@@ -31,6 +31,13 @@ func (a *action) propProject(prob *auty.ProposalProject) (*types.Receipt, error)
return nil, auty.ErrSetBlockHeight return nil, auty.ErrSetBlockHeight
} }
if a.api.GetConfig().IsDappFork(a.height, auty.AutonomyX, auty.ForkAutonomyDelRule) {
if prob.EndBlockHeight > a.height+propEndBlockPeriod {
alog.Error("propBoard height invaild", "EndBlockHeight", prob.EndBlockHeight, "height", a.height)
return nil, auty.ErrSetBlockHeight
}
}
if prob.Amount <= 0 { if prob.Amount <= 0 {
err := types.ErrInvalidParam err := types.ErrInvalidParam
alog.Error("propProject amount invaild", "amount", prob.Amount, "error", err) alog.Error("propProject amount invaild", "amount", prob.Amount, "error", err)
...@@ -253,10 +260,18 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec ...@@ -253,10 +260,18 @@ func (a *action) votePropProject(voteProb *auty.VoteProposalProject) (*types.Rec
kv = append(kv, receipt.KV...) kv = append(kv, receipt.KV...)
} }
if cur.BoardVoteRes.TotalVotes != 0 && if a.api.GetConfig().IsDappFork(a.height, auty.AutonomyX, auty.ForkAutonomyDelRule) {
float32(cur.BoardVoteRes.ApproveVotes)/float32(cur.BoardVoteRes.TotalVotes) >= float32(cur.CurRule.BoardApproveRatio)/100.0 { if cur.BoardVoteRes.TotalVotes != 0 && cur.BoardVoteRes.TotalVotes > cur.BoardVoteRes.QuitVotes &&
cur.BoardVoteRes.Pass = true cur.BoardVoteRes.ApproveVotes*100 >= (cur.BoardVoteRes.TotalVotes-cur.BoardVoteRes.QuitVotes)*cur.CurRule.BoardApproveRatio {
cur.PropProject.RealEndBlockHeight = a.height cur.BoardVoteRes.Pass = true
cur.PropProject.RealEndBlockHeight = a.height
}
} else {
if cur.BoardVoteRes.TotalVotes != 0 &&
float32(cur.BoardVoteRes.ApproveVotes)/float32(cur.BoardVoteRes.TotalVotes) >= float32(cur.CurRule.BoardApproveRatio)/100.0 {
cur.BoardVoteRes.Pass = true
cur.PropProject.RealEndBlockHeight = a.height
}
} }
key := propProjectID(voteProb.ProposalID) key := propProjectID(voteProb.ProposalID)
...@@ -447,12 +462,20 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty ...@@ -447,12 +462,20 @@ func (a *action) tmintPropProject(tmintProb *auty.TerminateProposalProject) (*ty
"in board vote period can not terminate", tmintProb.ProposalID, "err", err) "in board vote period can not terminate", tmintProb.ProposalID, "err", err)
return nil, err return nil, err
} }
if a.api.GetConfig().IsDappFork(a.height, auty.AutonomyX, auty.ForkAutonomyDelRule) {
if cur.BoardVoteRes.TotalVotes != 0 && if cur.BoardVoteRes.TotalVotes != 0 && cur.BoardVoteRes.TotalVotes > cur.BoardVoteRes.QuitVotes &&
float32(cur.BoardVoteRes.ApproveVotes)/float32(cur.BoardVoteRes.TotalVotes) >= float32(cur.CurRule.BoardApproveRatio)/100.0 { cur.BoardVoteRes.ApproveVotes*100 >= (cur.BoardVoteRes.TotalVotes-cur.BoardVoteRes.QuitVotes)*cur.CurRule.BoardApproveRatio {
cur.BoardVoteRes.Pass = true cur.BoardVoteRes.Pass = true
} else {
cur.BoardVoteRes.Pass = false
}
} else { } else {
cur.BoardVoteRes.Pass = false if cur.BoardVoteRes.TotalVotes != 0 &&
float32(cur.BoardVoteRes.ApproveVotes)/float32(cur.BoardVoteRes.TotalVotes) >= float32(cur.CurRule.BoardApproveRatio)/100.0 {
cur.BoardVoteRes.Pass = true
} else {
cur.BoardVoteRes.Pass = false
}
} }
if cur.PubVote.Publicity { if cur.PubVote.Publicity {
......
...@@ -89,6 +89,12 @@ func TestPropProject(t *testing.T) { ...@@ -89,6 +89,12 @@ func TestPropProject(t *testing.T) {
StartBlockHeight: env.blockHeight + 5, StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10, EndBlockHeight: env.blockHeight + startEndBlockPeriod + 10,
}, },
{ // ErrSetBlockHeight
Amount: 100,
ToAddr: AddrA,
StartBlockHeight: env.blockHeight + 5,
EndBlockHeight: env.blockHeight + propEndBlockPeriod + 10,
},
} }
result := []error{ result := []error{
...@@ -97,6 +103,7 @@ func TestPropProject(t *testing.T) { ...@@ -97,6 +103,7 @@ func TestPropProject(t *testing.T) {
auty.ErrSetBlockHeight, auty.ErrSetBlockHeight,
types.ErrNotFound, types.ErrNotFound,
auty.ErrNoPeriodAmount, auty.ErrNoPeriodAmount,
auty.ErrSetBlockHeight,
} }
exec.SetStateDB(stateDB) exec.SetStateDB(stateDB)
......
...@@ -63,3 +63,18 @@ func (a *Autonomy) Query_GetProposalChange(in *types.ReqString) (types.Message, ...@@ -63,3 +63,18 @@ func (a *Autonomy) Query_GetProposalChange(in *types.ReqString) (types.Message,
func (a *Autonomy) Query_ListProposalChange(in *auty.ReqQueryProposalChange) (types.Message, error) { func (a *Autonomy) Query_ListProposalChange(in *auty.ReqQueryProposalChange) (types.Message, error) {
return a.listProposalChange(in) return a.listProposalChange(in)
} }
// Query_GetProposalItem 查询提案
func (a *Autonomy) Query_GetProposalItem(in *types.ReqString) (types.Message, error) {
return getProposalItem(a.GetStateDB(), in)
}
// Query_ListProposalItem 批量查询
func (a *Autonomy) Query_ListProposalItem(in *auty.ReqQueryProposalItem) (types.Message, error) {
return a.listProposalItem(in)
}
// Query_GetProposalChange 查询提案修改董事会成员
func (a *Autonomy) Query_IsAutonomyApprovedItem(in *types.ReqMultiStrings) (types.Message, error) {
return IsAutonomyApprovedItem(a.GetStateDB(), in)
}
...@@ -139,6 +139,8 @@ func (a *Autonomy) getActiveRule() (types.Message, error) { ...@@ -139,6 +139,8 @@ func (a *Autonomy) getActiveRule() (types.Message, error) {
rule.ProposalAmount = proposalAmount * cfg.GetCoinPrecision() rule.ProposalAmount = proposalAmount * cfg.GetCoinPrecision()
rule.LargeProjectAmount = largeProjectAmount * cfg.GetCoinPrecision() rule.LargeProjectAmount = largeProjectAmount * cfg.GetCoinPrecision()
rule.PublicPeriod = publicPeriod rule.PublicPeriod = publicPeriod
rule.PubAttendRatio = pubAttendRatio
rule.PubApproveRatio = pubApproveRatio
} }
return rule, nil return rule, nil
} }
......
...@@ -25,7 +25,7 @@ const ( ...@@ -25,7 +25,7 @@ const (
// 最大全体持票人否决率 // 最大全体持票人否决率
maxPubOpposeRatio = 50 maxPubOpposeRatio = 50
// 可以调整,但是可能需要进行范围的限制:参与率最低设置为 50%, 最高设置为 80%,赞成率,最低 50.1%,最高80% ??? 最低 50.1% ???? // 可以调整,但是可能需要进行范围的限制:参与率最低设置为 50%, 最高设置为 80%,赞成率,最低 50.1%,最高80%
//不能设置太低和太高,太低就容易作弊,太高则有可能很难达到 //不能设置太低和太高,太低就容易作弊,太高则有可能很难达到
// 最小全体持票人参与率 // 最小全体持票人参与率
minPubAttendRatio = 50 minPubAttendRatio = 50
...@@ -80,6 +80,11 @@ func (a *action) propRule(prob *auty.ProposalRule) (*types.Receipt, error) { ...@@ -80,6 +80,11 @@ func (a *action) propRule(prob *auty.ProposalRule) (*types.Receipt, error) {
alog.Error("propRule RuleCfg invaild", "PubAttendRatio", prob.RuleCfg.PubAttendRatio, "PubApproveRatio", prob.RuleCfg.PubApproveRatio) alog.Error("propRule RuleCfg invaild", "PubAttendRatio", prob.RuleCfg.PubAttendRatio, "PubApproveRatio", prob.RuleCfg.PubApproveRatio)
return nil, types.ErrInvalidParam return nil, types.ErrInvalidParam
} }
if prob.EndBlockHeight > a.height+propEndBlockPeriod {
alog.Error("propBoard height invaild", "EndBlockHeight", prob.EndBlockHeight, "height", a.height)
return nil, auty.ErrSetBlockHeight
}
} }
if prob.StartBlockHeight < a.height || prob.EndBlockHeight < a.height || if prob.StartBlockHeight < a.height || prob.EndBlockHeight < a.height ||
......
...@@ -9,6 +9,7 @@ import "board.proto"; ...@@ -9,6 +9,7 @@ import "board.proto";
import "project.proto"; import "project.proto";
import "rule.proto"; import "rule.proto";
import "change.proto"; import "change.proto";
import "item.proto";
package types; package types;
option go_package = "../types"; option go_package = "../types";
...@@ -40,6 +41,13 @@ message AutonomyAction { ...@@ -40,6 +41,13 @@ message AutonomyAction {
RevokeProposalChange rvkPropChange = 17; RevokeProposalChange rvkPropChange = 17;
VoteProposalChange votePropChange = 18; VoteProposalChange votePropChange = 18;
TerminateProposalChange tmintPropChange = 19; TerminateProposalChange tmintPropChange = 19;
//提案事项审核相关
ProposalItem propItem = 21;
RevokeProposalItem rvkPropItem = 22;
VoteProposalItem votePropItem = 23;
TerminateProposalItem tmintPropItem = 24;
} }
int32 ty = 20; int32 ty = 20;
} }
// Copyright Fuzamei Corp. 2018 All Rights Reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
syntax = "proto3";
import "lcommon.proto";
package types;
option go_package = "../types";
message AutonomyProposalItem {
ProposalItem propItem = 1;
// 投票该提案的规则
RuleConfig curRule = 2;
// 投票该提案的董事会成员
repeated string boards = 3;
// 董事会投票结果
VoteResult boardVoteRes = 4;
// 状态
int32 status = 6;
string address = 7;
int64 height = 8;
int32 index = 9;
string proposalID = 10;
}
message ProposalItem {
// 提案时间
int32 year = 1;
int32 month = 2;
int32 day = 3;
// 项目相关
string itemTxHash = 4; // item tx hash
string description = 5; // 简述
// 投票相关
int64 startBlockHeight = 12; // 提案开始投票高度
int64 endBlockHeight = 13; // 提案结束投票高度
int64 realEndBlockHeight = 14; // 实际提案结束投票高度
int32 projectNeedBlockNum = 15; // 以提案结束投票高度为准,需要项目需要消耗的区块数目所对应的时间
}
message RevokeProposalItem {
string proposalID = 1;
}
message VoteProposalItem {
string proposalID = 1;
bool approve = 2;
AutonomyVoteOption vote = 3;
}
message TerminateProposalItem {
string proposalID = 1;
}
// receipt
message ReceiptProposalItem {
AutonomyProposalItem prev = 1;
AutonomyProposalItem current = 2;
}
message LocalProposalItem {
AutonomyProposalItem propItem = 1;
repeated string comments = 2;
}
// query
message ReqQueryProposalItem {
int32 status = 1;
string addr = 2;
int32 count = 3;
int32 direction = 4;
int64 height = 5;
int32 index = 6;
}
message ReplyQueryProposalItem {
repeated AutonomyProposalItem propItems = 1;
}
This diff is collapsed.
...@@ -30,6 +30,11 @@ const ( ...@@ -30,6 +30,11 @@ const (
AutonomyActionVotePropChange AutonomyActionVotePropChange
AutonomyActionTmintPropChange AutonomyActionTmintPropChange
AutonomyActionPropItem
AutonomyActionRvkPropItem
AutonomyActionVotePropItem
AutonomyActionTmintPropItem
//log for autonomy //log for autonomy
TyLogPropBoard = 2101 TyLogPropBoard = 2101
TyLogRvkPropBoard = 2102 TyLogRvkPropBoard = 2102
...@@ -53,6 +58,11 @@ const ( ...@@ -53,6 +58,11 @@ const (
TyLogRvkPropChange = 2142 TyLogRvkPropChange = 2142
TyLogVotePropChange = 2143 TyLogVotePropChange = 2143
TyLogTmintPropChange = 2144 TyLogTmintPropChange = 2144
TyLogPropItem = 2161
TyLogRvkPropItem = 2162
TyLogVotePropItem = 2163
TyLogTmintPropItem = 2164
) )
// Board status // Board status
...@@ -88,6 +98,14 @@ const ( ...@@ -88,6 +98,14 @@ const (
AutonomyStatusTmintPropChange AutonomyStatusTmintPropChange
) )
// Item status
const (
AutonomyStatusProposalItem = iota + 1
AutonomyStatusRvkPropItem
AutonomyStatusVotePropItem
AutonomyStatusTmintPropItem
)
const ( const (
// GetProposalBoard 用于在cmd里面的区分不同的查询 // GetProposalBoard 用于在cmd里面的区分不同的查询
GetProposalBoard = "GetProposalBoard" GetProposalBoard = "GetProposalBoard"
...@@ -111,6 +129,11 @@ const ( ...@@ -111,6 +129,11 @@ const (
GetProposalChange = "GetProposalChange" GetProposalChange = "GetProposalChange"
// ListProposalChange 查询多个 // ListProposalChange 查询多个
ListProposalChange = "ListProposalChange" ListProposalChange = "ListProposalChange"
// GetProposalItem 用于在cmd里面的区分不同的查询
GetProposalItem = "GetProposalItem"
// ListProposalItem 查询多个
ListProposalItem = "ListProposalItem"
) )
//包的名字可以通过配置文件来配置 //包的名字可以通过配置文件来配置
......
This diff is collapsed.
...@@ -15,6 +15,8 @@ var name string ...@@ -15,6 +15,8 @@ var name string
var ( var (
//ForkAutonomyDelRule fork for delete boards member rules //ForkAutonomyDelRule fork for delete boards member rules
ForkAutonomyDelRule = "ForkAutonomyDelRule" ForkAutonomyDelRule = "ForkAutonomyDelRule"
//ForkAutonomyEnableItem fork for add autonomy item support
ForkAutonomyEnableItem = "ForkAutonomyEnableItem"
) )
func init() { func init() {
...@@ -28,6 +30,7 @@ func init() { ...@@ -28,6 +30,7 @@ func init() {
func InitFork(cfg *types.Chain33Config) { func InitFork(cfg *types.Chain33Config) {
cfg.RegisterDappFork(AutonomyX, "Enable", 0) cfg.RegisterDappFork(AutonomyX, "Enable", 0)
cfg.RegisterDappFork(AutonomyX, ForkAutonomyDelRule, 9500000) cfg.RegisterDappFork(AutonomyX, ForkAutonomyDelRule, 9500000)
cfg.RegisterDappFork(AutonomyX, ForkAutonomyEnableItem, 10000000)
} }
//InitExecutor ... //InitExecutor ...
...@@ -78,6 +81,11 @@ func (a *AutonomyType) GetLogMap() map[int64]*types.LogInfo { ...@@ -78,6 +81,11 @@ func (a *AutonomyType) GetLogMap() map[int64]*types.LogInfo {
TyLogRvkPropChange: {Ty: reflect.TypeOf(ReceiptProposalChange{}), Name: "LogRvkPropChange"}, TyLogRvkPropChange: {Ty: reflect.TypeOf(ReceiptProposalChange{}), Name: "LogRvkPropChange"},
TyLogVotePropChange: {Ty: reflect.TypeOf(ReceiptProposalChange{}), Name: "LogVotePropChange"}, TyLogVotePropChange: {Ty: reflect.TypeOf(ReceiptProposalChange{}), Name: "LogVotePropChange"},
TyLogTmintPropChange: {Ty: reflect.TypeOf(ReceiptProposalChange{}), Name: "LogTmintPropChange"}, TyLogTmintPropChange: {Ty: reflect.TypeOf(ReceiptProposalChange{}), Name: "LogTmintPropChange"},
TyLogPropItem: {Ty: reflect.TypeOf(ReceiptProposalItem{}), Name: "LogPropItem"},
TyLogRvkPropItem: {Ty: reflect.TypeOf(ReceiptProposalItem{}), Name: "LogRvkPropItem"},
TyLogVotePropItem: {Ty: reflect.TypeOf(ReceiptProposalItem{}), Name: "LogVotePropItem"},
TyLogTmintPropItem: {Ty: reflect.TypeOf(ReceiptProposalItem{}), Name: "LogTmintPropItem"},
} }
} }
...@@ -112,5 +120,10 @@ func (a *AutonomyType) GetTypeMap() map[string]int32 { ...@@ -112,5 +120,10 @@ func (a *AutonomyType) GetTypeMap() map[string]int32 {
"RvkPropChange": AutonomyActionRvkPropChange, "RvkPropChange": AutonomyActionRvkPropChange,
"VotePropChange": AutonomyActionVotePropChange, "VotePropChange": AutonomyActionVotePropChange,
"TmintPropChange": AutonomyActionTmintPropChange, "TmintPropChange": AutonomyActionTmintPropChange,
"PropItem": AutonomyActionPropItem,
"RvkPropItem": AutonomyActionRvkPropItem,
"VotePropItem": AutonomyActionVotePropItem,
"TmintPropItem": AutonomyActionTmintPropItem,
} }
} }
...@@ -362,7 +362,7 @@ func (loader *UserLoader) loadUsers() error { ...@@ -362,7 +362,7 @@ func (loader *UserLoader) loadUsers() error {
} }
func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error) { func (loader *UserLoader) genCryptoPriv(keyBytes []byte) (crypto.PrivKey, error) {
cr, err := crypto.New(types.GetSignName("cert", loader.signType)) cr, err := crypto.Load(types.GetSignName("cert", loader.signType), -1)
if err != nil { if err != nil {
return nil, fmt.Errorf("create crypto %s failed, error:%s", types.GetSignName("cert", loader.signType), err) return nil, fmt.Errorf("create crypto %s failed, error:%s", types.GetSignName("cert", loader.signType), err)
} }
......
...@@ -43,7 +43,7 @@ var ( ...@@ -43,7 +43,7 @@ var (
privRaw, _ = common.FromHex("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944") privRaw, _ = common.FromHex("CC38546E9E659D15E6B4893F0AB32A06D103931A8230B0BDE71459D2B27D6944")
tr = &cty.CoinsAction_Transfer{Transfer: &types.AssetsTransfer{Amount: int64(1e8)}} tr = &cty.CoinsAction_Transfer{Transfer: &types.AssetsTransfer{Amount: int64(1e8)}}
secpp256, _ = crypto.New(types.GetSignName("", types.SECP256K1)) secpp256, _ = crypto.Load(types.GetSignName("", types.SECP256K1), -1)
privKey, _ = secpp256.PrivKeyFromBytes(privRaw) privKey, _ = secpp256.PrivKeyFromBytes(privRaw)
tx14 = &types.Transaction{ tx14 = &types.Transaction{
Execer: []byte("coins"), Execer: []byte("coins"),
...@@ -188,7 +188,7 @@ func TestChckSignWithNoneAuth(t *testing.T) { ...@@ -188,7 +188,7 @@ func TestChckSignWithNoneAuth(t *testing.T) {
TestCase04 不带证书,SM2签名验证 TestCase04 不带证书,SM2签名验证
*/ */
func TestChckSignWithSm2(t *testing.T) { func TestChckSignWithSm2(t *testing.T) {
sm2, err := crypto.New(types.GetSignName("cert", ct.AuthSM2)) sm2, err := crypto.Load(types.GetSignName("cert", ct.AuthSM2), -1)
assert.Nil(t, err) assert.Nil(t, err)
privKeysm2, _ := sm2.PrivKeyFromBytes(privRaw) privKeysm2, _ := sm2.PrivKeyFromBytes(privRaw)
tx15 := &types.Transaction{Execer: []byte("coins"), tx15 := &types.Transaction{Execer: []byte("coins"),
...@@ -213,7 +213,7 @@ func TestChckSignWithSm2(t *testing.T) { ...@@ -213,7 +213,7 @@ func TestChckSignWithSm2(t *testing.T) {
TestCase05 不带证书,secp256r1签名验证 TestCase05 不带证书,secp256r1签名验证
*/ */
func TestChckSignWithEcdsa(t *testing.T) { func TestChckSignWithEcdsa(t *testing.T) {
ecdsacrypto, _ := crypto.New(types.GetSignName("cert", ct.AuthECDSA)) ecdsacrypto, _ := crypto.Load(types.GetSignName("cert", ct.AuthECDSA), -1)
privKeyecdsa, _ := ecdsacrypto.PrivKeyFromBytes(privRaw) privKeyecdsa, _ := ecdsacrypto.PrivKeyFromBytes(privRaw)
tx16 := &types.Transaction{Execer: []byte("coins"), tx16 := &types.Transaction{Execer: []byte("coins"),
Payload: types.Encode(&cty.CoinsAction{Value: tr, Ty: cty.CoinsActionTransfer}), Payload: types.Encode(&cty.CoinsAction{Value: tr, Ty: cty.CoinsActionTransfer}),
......
...@@ -138,7 +138,7 @@ func signCertTx(tx *types.Transaction, priv crypto.PrivKey, cert []byte) { ...@@ -138,7 +138,7 @@ func signCertTx(tx *types.Transaction, priv crypto.PrivKey, cert []byte) {
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1 signType := types.SECP256K1
c, err := crypto.New(types.GetSignName(pkt.CollateralizeX, signType)) c, err := crypto.Load(types.GetSignName(pkt.CollateralizeX, signType), -1)
if err != nil { if err != nil {
return tx, err return tx, err
} }
......
...@@ -670,7 +670,7 @@ func TestCollateralize(t *testing.T) { ...@@ -670,7 +670,7 @@ func TestCollateralize(t *testing.T) {
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1 signType := types.SECP256K1
c, err := crypto.New(types.GetSignName(pkt.CollateralizeX, signType)) c, err := crypto.Load(types.GetSignName(pkt.CollateralizeX, signType), -1)
if err != nil { if err != nil {
return tx, err return tx, err
} }
......
...@@ -426,7 +426,7 @@ function para_create_nodegroup() { ...@@ -426,7 +426,7 @@ function para_create_nodegroup() {
echo "=========== # para chain approve node group =============" echo "=========== # para chain approve node group ============="
##approve ##approve
txhash=$(${PARA_CLI} send para nodegroup approve -i "$id" -c 6 -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc) txhash=$(${PARA_CLI} send para nodegroup approve -i "$id" -a "" -c 6 -k 0xc34b5d9d44ac7b754806f761d3d4d2c4fe5214f6b074c19f069c4f5c2a29c8cc)
echo "tx=$txhash" echo "tx=$txhash"
query_tx "${PARA_CLI}" "${txhash}" query_tx "${PARA_CLI}" "${txhash}"
......
...@@ -611,7 +611,7 @@ MAIN_LOOP: ...@@ -611,7 +611,7 @@ MAIN_LOOP:
} }
func initCryptoImpl() error { func initCryptoImpl() error {
cr, err := crypto.New(types.GetSignName("", types.SECP256K1)) cr, err := crypto.Load(types.GetSignName("", types.SECP256K1), -1)
if err != nil { if err != nil {
fmt.Printf("New crypto impl failed err: %v", err) fmt.Printf("New crypto impl failed err: %v", err)
return err return err
......
...@@ -329,7 +329,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by ...@@ -329,7 +329,7 @@ func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []by
contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr.String()), evm.StateDB.GetCode(addr.String())) contract.SetCallCode(&addr, evm.StateDB.GetCodeHash(addr.String()), evm.StateDB.GetCode(addr.String()))
// 其它逻辑同StaticCall // 其它逻辑同StaticCall
ret, err = run(evm, contract, input, true) ret, err = run(evm, contract, input, false)
} }
......
...@@ -277,6 +277,13 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me ...@@ -277,6 +277,13 @@ func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, me
if err != nil { if err != nil {
return 0, err return 0, err
} }
evm.callGasTemp, err = callGas(true, contract.Gas, gas, stack.Back(0))
if err != nil {
return 0, err
}
log15.Info("gasDelegateCall", "gas", gas, "evm.callGasTemp", evm.callGasTemp)
var overflow bool var overflow bool
if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow {
return 0, ErrGasUintOverflow return 0, ErrGasUintOverflow
......
...@@ -22,7 +22,7 @@ QueryOrderList|根据用户地址和订单状态(ordered,completed,revoked), ...@@ -22,7 +22,7 @@ QueryOrderList|根据用户地址和订单状态(ordered,completed,revoked),
序号|规则 序号|规则
---|---- ---|----
1|买家获利得原则 1|以市场价成交
2|买单高于市场价,按价格由低往高撮合 2|买单高于市场价,按价格由低往高撮合
3|卖单低于市场价,按价格由高往低进行撮合 3|卖单低于市场价,按价格由高往低进行撮合
4|价格相同按先进先出的原则进行撮合 4|价格相同按先进先出的原则进行撮合
......
package client
import (
"github.com/33cn/chain33/types"
"github.com/golang/protobuf/proto"
)
type Cli interface {
Query(fn string, msg proto.Message) ([]byte, error)
Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLog, error)
}
package client
import (
"github.com/33cn/chain33/types"
et "github.com/33cn/plugin/plugin/dapp/exchange/types"
"github.com/golang/protobuf/proto"
)
var cfg = types.NewChain33Config(types.GetDefaultCfgstring())
type ExchangeClient struct {
client Cli
txHeight int64
}
func NewExchangCient(cli Cli) *ExchangeClient {
return &ExchangeClient{
client: cli,
txHeight: types.LowAllowPackHeight,
}
}
func (c *ExchangeClient) QueryMarketDepth(msg proto.Message) (types.Message, error) {
data, err := c.client.Query(et.FuncNameQueryMarketDepth, msg)
if err != nil {
return nil, err
}
var resp et.MarketDepthList
err = types.Decode(data, &resp)
if err != nil {
return nil, err
}
return &resp, nil
}
func (c *ExchangeClient) QueryHistoryOrderList(msg proto.Message) (types.Message, error) {
data, err := c.client.Query(et.FuncNameQueryHistoryOrderList, msg)
if err != nil {
return nil, err
}
var resp et.OrderList
err = types.Decode(data, &resp)
if err != nil {
return nil, err
}
return &resp, nil
}
func (c *ExchangeClient) QueryOrder(msg proto.Message) (types.Message, error) {
data, err := c.client.Query(et.FuncNameQueryOrder, msg)
if err != nil {
return nil, err
}
var resp et.Order
err = types.Decode(data, &resp)
if err != nil {
return nil, err
}
return &resp, nil
}
func (c *ExchangeClient) QueryOrderList(msg proto.Message) (types.Message, error) {
data, err := c.client.Query(et.FuncNameQueryOrderList, msg)
if err != nil {
return nil, err
}
var resp et.OrderList
err = types.Decode(data, &resp)
if err != nil {
return nil, err
}
return &resp, nil
}
func (c *ExchangeClient) LimitOrder(msg proto.Message, hexKey string) (*et.ReceiptExchange, error) {
ety := types.LoadExecutorType(et.ExchangeX)
tx, err := ety.Create("LimitOrder", msg)
if err != nil {
return nil, err
}
logs, err := c.client.Send(tx, hexKey)
if err != nil {
return nil, err
}
var resp et.ReceiptExchange
for _, l := range logs {
if l.Ty == et.TyLimitOrderLog {
err = types.Decode(l.Log, &resp)
if err != nil {
return nil, err
}
break
}
}
return &resp, nil
}
//TODO marketOrder
func (c *ExchangeClient) MarketOrder(msg proto.Message, hexKey string) (*et.ReceiptExchange, error) {
ety := types.LoadExecutorType(et.ExchangeX)
tx, err := ety.Create("MarketOrder", msg)
if err != nil {
return nil, err
}
logs, err := c.client.Send(tx, hexKey)
if err != nil {
return nil, err
}
var resp et.ReceiptExchange
for _, l := range logs {
if l.Ty == et.TyMarketOrderLog {
err = types.Decode(l.Log, &resp)
if err != nil {
return nil, err
}
break
}
}
return &resp, nil
}
func (c *ExchangeClient) RevokeOrder(msg proto.Message, hexKey string) (*et.ReceiptExchange, error) {
ety := types.LoadExecutorType(et.ExchangeX)
tx, err := ety.Create("RevokeOrder", msg)
if err != nil {
return nil, err
}
logs, err := c.client.Send(tx, hexKey)
if err != nil {
return nil, err
}
var resp et.ReceiptExchange
for _, l := range logs {
if l.Ty == et.TyRevokeOrderLog {
err = types.Decode(l.Log, &resp)
if err != nil {
return nil, err
}
break
}
}
return &resp, nil
}
package client_test
import (
"testing"
"github.com/33cn/chain33/types"
excli "github.com/33cn/plugin/plugin/dapp/exchange/client"
etypes "github.com/33cn/plugin/plugin/dapp/exchange/types"
)
var (
privKey = "0x13169cd9ecf0d3e4a78d1a97a9abb506cb12b2f45c127a8a33c84f389a38e674" //1BsJugqWiF47x2c915YW2TkBKVLU9GmvEn
grpcAddr = "127.0.0.1:8802"
execer = "token"
)
func TestQueryMarketDepth(t *testing.T) {
cli := excli.NewGRPCCli(grpcAddr)
client := excli.NewExchangCient(cli)
req := &etypes.QueryMarketDepth{
LeftAsset: &etypes.Asset{Symbol: "BTY", Execer: execer},
RightAsset: &etypes.Asset{Symbol: "USDT", Execer: execer},
Op: 2,
PrimaryKey: "",
Count: 10,
}
resp, err := client.QueryMarketDepth(req)
if err != nil {
t.Log(err)
return
}
t.Log("QueryMarketDepth", resp.(*etypes.MarketDepthList).List)
}
func TestQueryHistoryOrderList(t *testing.T) {
cli := excli.NewGRPCCli(grpcAddr)
client := excli.NewExchangCient(cli)
req := &etypes.QueryHistoryOrderList{
LeftAsset: &etypes.Asset{Symbol: "BTY", Execer: execer},
RightAsset: &etypes.Asset{Symbol: "USDT", Execer: execer},
PrimaryKey: "",
Count: 10,
Direction: 0,
}
resp, err := client.QueryHistoryOrderList(req)
if err != nil {
t.Log(err)
return
}
t.Log("QueryHistory", resp.(*etypes.OrderList).List)
}
func TestQueryOrder(t *testing.T) {
cli := excli.NewGRPCCli(grpcAddr)
client := excli.NewExchangCient(cli)
req := &etypes.QueryOrder{
OrderID: 46000000000,
}
resp, err := client.QueryOrder(req)
if err != nil {
t.Log(err)
return
}
t.Log("QueryOrder", resp.(*etypes.Order))
}
func TestQueryOrderList(t *testing.T) {
cli := excli.NewGRPCCli(grpcAddr)
client := excli.NewExchangCient(cli)
req := &etypes.QueryOrderList{
Status: 1,
Address: "1FpPrLgyuR6reqj8LQ3HNVHkjtA7hAcvHo",
PrimaryKey: "",
Count: 10,
Direction: 0,
}
resp, err := client.QueryOrderList(req)
if err != nil {
t.Log(err)
return
}
t.Log("QueryOrderList", resp.(*etypes.OrderList).List)
}
func TestLimitOrder(t *testing.T) {
cli := excli.NewGRPCCli(grpcAddr)
client := excli.NewExchangCient(cli)
req := &etypes.LimitOrder{
LeftAsset: &etypes.Asset{Symbol: "BTY", Execer: execer},
RightAsset: &etypes.Asset{Symbol: "USDT", Execer: execer},
Op: etypes.OpSell,
Price: 4 * types.DefaultCoinPrecision,
Amount: 4 * types.DefaultCoinPrecision,
}
resp, err := client.LimitOrder(req, privKey)
if err != nil {
t.Log(err)
return
}
t.Log("LimitOrder", resp)
}
//TODO marketOrder
//func TestMarketOrder(t *testing.T) {
// cli := excli.NewGRPCCli(grpcAddr)
// client := excli.NewExchangCient(cli)
//
// req := &etypes.MarketOrder{
// LeftAsset: &etypes.Asset{Symbol: "BTY", Execer: execer},
// RightAsset: &etypes.Asset{Symbol: "USDT", Execer: execer},
// Op: etypes.OpSell,
// Amount: 4 * types.DefaultCoinPrecision,
// }
//
// resp, err := client.MarketOrder(req, privKey)
// if err != nil {
// t.Log(err)
// return
// }
// t.Log("MarketOrder", resp)
//}
func TestRevokeOrder(t *testing.T) {
cli := excli.NewGRPCCli(grpcAddr)
client := excli.NewExchangCient(cli)
req := &etypes.RevokeOrder{
OrderID: 88000000000,
}
resp, err := client.RevokeOrder(req, privKey)
if err != nil {
t.Log(err)
return
}
t.Log("RevokeOrder", resp)
}
package client
import (
"context"
"errors"
"strings"
"sync"
"time"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/types"
et "github.com/33cn/plugin/plugin/dapp/exchange/types"
"github.com/golang/protobuf/proto"
"google.golang.org/grpc"
)
var conns sync.Map
type GRPCCli struct {
client types.Chain33Client
}
func NewGRPCCli(grpcAddr string) *GRPCCli {
client, err := getClient(grpcAddr)
if err != nil {
return nil
}
return &GRPCCli{client: client}
}
func getClient(target string) (types.Chain33Client, error) {
val, ok := conns.Load(target)
if !ok {
conn, err := grpc.Dial(target, grpc.WithInsecure())
if err != nil {
return nil, err
}
client := types.NewChain33Client(conn)
conns.Store(target, client)
return client, nil
} else {
return val.(types.Chain33Client), nil
}
}
func (c *GRPCCli) Query(fn string, msg proto.Message) ([]byte, error) {
ss := strings.Split(fn, ".")
var in types.ChainExecutor
if len(ss) == 2 {
in.Driver = ss[0]
in.FuncName = ss[1]
} else {
in.Driver = et.ExchangeX
in.FuncName = fn
}
in.Param = types.Encode(msg)
r, err := c.client.QueryChain(context.Background(), &in)
if err != nil {
return nil, err
}
if !r.IsOk {
return nil, errors.New(string(r.Msg))
}
return r.Msg, nil
}
func (c *GRPCCli) Send(tx *types.Transaction, hexKey string) ([]*types.ReceiptLog, error) {
logs, err := c.sendAndWaitReceipt(tx, hexKey)
if err != nil {
return nil, parseError(err)
}
for _, l := range logs {
if l.Ty == types.TyLogErr {
return nil, errors.New(string(l.Log))
}
}
return logs, nil
}
// 发送交易并等待执行结果
// 如果交易非法,返回错误信息
// 如果交易执行成功,返回 交易哈希、回报
func (c *GRPCCli) sendAndWaitReceipt(tx *types.Transaction, hexKey string) (logs []*types.ReceiptLog, err error) {
r, err := c.sendTx(tx, hexKey)
if err != nil {
// rpc error: code = Unknown desc = ErrNotBank
return nil, err
}
if !r.IsOk {
return nil, errors.New(string(r.Msg))
}
time.Sleep(time.Second)
d, _ := c.client.QueryTransaction(context.Background(), &types.ReqHash{Hash: r.Msg})
return d.Receipt.Logs, nil
}
//SendTx ...s
func (c *GRPCCli) sendTx(tx *types.Transaction, hexKey string) (reply *types.Reply, err error) {
cfg := types.NewChain33Config(types.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33")
tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
if err != nil {
return nil, err
}
tx, err = signTx(tx, hexKey)
if err != nil {
return nil, err
}
return c.client.SendTransaction(context.Background(), tx)
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1
c, err := crypto.Load(types.GetSignName("", signType), -1)
if err != nil {
return tx, err
}
bytes, err := common.FromHex(hexPrivKey[:])
if err != nil {
return tx, err
}
privKey, err := c.PrivKeyFromBytes(bytes)
if err != nil {
return tx, err
}
tx.Sign(int32(signType), privKey)
return tx, nil
}
func parseError(err error) error {
// rpc error: code = Unknown desc = ErrNotBank
str := err.Error()
sep := "desc = "
i := strings.Index(str, sep)
if i != -1 {
return errors.New(str[i+len(sep):])
}
return err
}
...@@ -39,7 +39,7 @@ var ( ...@@ -39,7 +39,7 @@ var (
func TestExchange(t *testing.T) { func TestExchange(t *testing.T) {
//环境准备 //环境准备
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
Init(et.ExchangeX, cfg, nil) Init(et.ExchangeX, cfg, nil)
total := 100 * types.DefaultCoinPrecision total := 100 * types.DefaultCoinPrecision
...@@ -263,9 +263,9 @@ func TestExchange(t *testing.T) { ...@@ -263,9 +263,9 @@ func TestExchange(t *testing.T) {
order, err = Exec_QueryOrder(orderID7, stateDB, kvdb) order, err = Exec_QueryOrder(orderID7, stateDB, kvdb)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
assert.Equal(t, int32(et.Ordered), order.Status) assert.Equal(t, int32(et.Ordered), order.Status)
//查看账户余额,按卖方价格成交 //查看账户余额,按被动方买单的价格成交
acc := accD1.LoadExecAccount(Nodes[3], execAddr) acc := accD1.LoadExecAccount(Nodes[3], execAddr)
assert.Equal(t, 85*types.DefaultCoinPrecision, acc.Balance) assert.Equal(t, 80*types.DefaultCoinPrecision, acc.Balance)
Exec_LimitOrder(t, &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"}, Exec_LimitOrder(t, &et.LimitOrder{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 400000000, Amount: 5 * types.DefaultCoinPrecision, Op: et.OpSell}, PrivKeyC, stateDB, kvdb, env) RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}, Price: 400000000, Amount: 5 * types.DefaultCoinPrecision, Op: et.OpSell}, PrivKeyC, stateDB, kvdb, env)
...@@ -298,8 +298,8 @@ func TestExchange(t *testing.T) { ...@@ -298,8 +298,8 @@ func TestExchange(t *testing.T) {
assert.Equal(t, 5*types.DefaultCoinPrecision, order.Balance) assert.Equal(t, 5*types.DefaultCoinPrecision, order.Balance)
//余额检查 //余额检查
acc = accD1.LoadExecAccount(Nodes[3], execAddr) acc = accD1.LoadExecAccount(Nodes[3], execAddr)
// 100-3*10-5*4-4.5*5 = 27.5 //100-5*4-(10-5)*3-5*4-(15-5-5)*4.5 = 22.5
assert.Equal(t, int64(2750000000), acc.Balance) assert.Equal(t, int64(2250000000), acc.Balance)
acc = accC.LoadExecAccount(Nodes[2], execAddr) acc = accC.LoadExecAccount(Nodes[2], execAddr)
assert.Equal(t, 80*types.DefaultCoinPrecision, acc.Balance) assert.Equal(t, 80*types.DefaultCoinPrecision, acc.Balance)
...@@ -316,8 +316,8 @@ func TestExchange(t *testing.T) { ...@@ -316,8 +316,8 @@ func TestExchange(t *testing.T) {
assert.Equal(t, 5*types.DefaultCoinPrecision, orderList.List[0].Balance) assert.Equal(t, 5*types.DefaultCoinPrecision, orderList.List[0].Balance)
//余额检查 //余额检查
acc = accD1.LoadExecAccount(Nodes[3], execAddr) acc = accD1.LoadExecAccount(Nodes[3], execAddr)
// 100-3*10-5*4-1*5 = 45 // Nodes[3]为成交 Nodes[2]冻结10
assert.Equal(t, 45*types.DefaultCoinPrecision, acc.Balance) assert.Equal(t, int64(2250000000), acc.Balance)
acc = accC.LoadExecAccount(Nodes[2], execAddr) acc = accC.LoadExecAccount(Nodes[2], execAddr)
assert.Equal(t, 70*types.DefaultCoinPrecision, acc.Balance) assert.Equal(t, 70*types.DefaultCoinPrecision, acc.Balance)
//orderID9和order10未成交 //orderID9和order10未成交
...@@ -688,7 +688,7 @@ func CreateLimitOrder(limitOrder *et.LimitOrder, privKey string) (tx *types.Tran ...@@ -688,7 +688,7 @@ func CreateLimitOrder(limitOrder *et.LimitOrder, privKey string) (tx *types.Tran
if err != nil { if err != nil {
return nil, err return nil, err
} }
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
tx, err = types.FormatTx(cfg, et.ExchangeX, tx) tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
if err != nil { if err != nil {
...@@ -706,7 +706,7 @@ func CreateRevokeOrder(orderID int64, privKey string) (tx *types.Transaction, er ...@@ -706,7 +706,7 @@ func CreateRevokeOrder(orderID int64, privKey string) (tx *types.Transaction, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
tx, err = types.FormatTx(cfg, et.ExchangeX, tx) tx, err = types.FormatTx(cfg, et.ExchangeX, tx)
if err != nil { if err != nil {
...@@ -721,7 +721,7 @@ func CreateRevokeOrder(orderID int64, privKey string) (tx *types.Transaction, er ...@@ -721,7 +721,7 @@ func CreateRevokeOrder(orderID int64, privKey string) (tx *types.Transaction, er
//模拟区块中交易得执行过程 //模拟区块中交易得执行过程
func Exec_Block(t *testing.T, stateDB db.DB, kvdb db.KVDB, env *execEnv, txs ...*types.Transaction) error { func Exec_Block(t *testing.T, stateDB db.DB, kvdb db.KVDB, env *execEnv, txs ...*types.Transaction) error {
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
exec := NewExchange() exec := NewExchange()
q := queue.New("channel") q := queue.New("channel")
...@@ -786,7 +786,7 @@ func Exec_RevokeOrder(t *testing.T, orderID int64, privKey string, stateDB db.DB ...@@ -786,7 +786,7 @@ func Exec_RevokeOrder(t *testing.T, orderID int64, privKey string, stateDB db.DB
} }
func Exec_QueryOrderList(status int32, addr string, primaryKey string, stateDB db.KV, kvdb db.KVDB) (*et.OrderList, error) { func Exec_QueryOrderList(status int32, addr string, primaryKey string, stateDB db.KV, kvdb db.KVDB) (*et.OrderList, error) {
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
exec := NewExchange() exec := NewExchange()
q := queue.New("channel") q := queue.New("channel")
...@@ -803,7 +803,7 @@ func Exec_QueryOrderList(status int32, addr string, primaryKey string, stateDB d ...@@ -803,7 +803,7 @@ func Exec_QueryOrderList(status int32, addr string, primaryKey string, stateDB d
return msg.(*et.OrderList), nil return msg.(*et.OrderList), nil
} }
func Exec_QueryOrder(orderID int64, stateDB db.KV, kvdb db.KVDB) (*et.Order, error) { func Exec_QueryOrder(orderID int64, stateDB db.KV, kvdb db.KVDB) (*et.Order, error) {
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
exec := NewExchange() exec := NewExchange()
q := queue.New("channel") q := queue.New("channel")
...@@ -821,7 +821,7 @@ func Exec_QueryOrder(orderID int64, stateDB db.KV, kvdb db.KVDB) (*et.Order, err ...@@ -821,7 +821,7 @@ func Exec_QueryOrder(orderID int64, stateDB db.KV, kvdb db.KVDB) (*et.Order, err
} }
func Exec_QueryMarketDepth(query *et.QueryMarketDepth, stateDB db.KV, kvdb db.KVDB) (*et.MarketDepthList, error) { func Exec_QueryMarketDepth(query *et.QueryMarketDepth, stateDB db.KV, kvdb db.KVDB) (*et.MarketDepthList, error) {
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
exec := NewExchange() exec := NewExchange()
q := queue.New("channel") q := queue.New("channel")
...@@ -839,7 +839,7 @@ func Exec_QueryMarketDepth(query *et.QueryMarketDepth, stateDB db.KV, kvdb db.KV ...@@ -839,7 +839,7 @@ func Exec_QueryMarketDepth(query *et.QueryMarketDepth, stateDB db.KV, kvdb db.KV
} }
func Exec_QueryHistoryOrder(query *et.QueryHistoryOrderList, stateDB db.KV, kvdb db.KVDB) (*et.OrderList, error) { func Exec_QueryHistoryOrder(query *et.QueryHistoryOrderList, stateDB db.KV, kvdb db.KVDB) (*et.OrderList, error) {
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
exec := NewExchange() exec := NewExchange()
q := queue.New("channel") q := queue.New("channel")
...@@ -854,7 +854,7 @@ func Exec_QueryHistoryOrder(query *et.QueryHistoryOrderList, stateDB db.KV, kvdb ...@@ -854,7 +854,7 @@ func Exec_QueryHistoryOrder(query *et.QueryHistoryOrderList, stateDB db.KV, kvdb
} }
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1 signType := types.SECP256K1
c, err := crypto.New(types.GetSignName("", signType)) c, err := crypto.Load(types.GetSignName("", signType), -1)
if err != nil { if err != nil {
return tx, err return tx, err
} }
......
This diff is collapsed.
...@@ -5,148 +5,160 @@ option go_package = "../types"; ...@@ -5,148 +5,160 @@ option go_package = "../types";
message Exchange {} message Exchange {}
message ExchangeAction { message ExchangeAction {
oneof value { oneof value {
LimitOrder limitOrder = 1; LimitOrder limitOrder = 1;
MarketOrder marketOrder = 2; MarketOrder marketOrder = 2;
RevokeOrder revokeOrder = 3; RevokeOrder revokeOrder = 3;
} }
int32 ty = 6; int32 ty = 6;
} }
//限价订单 //限价订单
message LimitOrder { message LimitOrder {
//交易对 //交易对
asset leftAsset = 1; asset leftAsset = 1;
//交易对 //交易对
asset rightAsset = 2; asset rightAsset = 2;
//价格 //价格
int64 price = 3; int64 price = 3;
//总量 //总量
int64 amount = 4; int64 amount = 4;
//操作, 1为买,2为卖 //操作, 1为买,2为卖
int32 op = 5; int32 op = 5;
} }
//市价委托 //市价委托
message MarketOrder { message MarketOrder {
//资产1 //资产1
asset leftAsset = 1; asset leftAsset = 1;
//资产2 //资产2
asset rightAsset = 2; asset rightAsset = 2;
//总量 //总量
int64 amount = 3; int64 amount = 3;
//操作, 1为买,2为卖 //操作, 1为买,2为卖
int32 op = 4; int32 op = 4;
} }
//撤回订单 //撤回订单
message RevokeOrder { message RevokeOrder {
//订单号 //订单号
int64 orderID = 1; int64 orderID = 1;
} }
//资产类型 //资产类型
message asset { message asset {
string execer = 1; string execer = 1;
string symbol = 2; string symbol = 2;
} }
//订单信息 //订单信息
message Order { message Order {
int64 orderID = 1; int64 orderID = 1;
oneof value { oneof value {
LimitOrder limitOrder = 2; LimitOrder limitOrder = 2;
MarketOrder marketOrder = 3; MarketOrder marketOrder = 3;
} }
//挂单类型 //挂单类型
int32 ty = 4; int32 ty = 4;
//已经成交的数量 //已经成交的数量
int64 executed = 5; int64 executed = 5;
//成交均价 //成交均价
int64 AVG_price = 6; int64 AVG_price = 6;
//余额 //余额
int64 balance = 7; int64 balance = 7;
//状态,0 挂单中ordered, 1 完成completed, 2撤回 revoked //状态,0 挂单中ordered, 1 完成completed, 2撤回 revoked
int32 status = 8; int32 status = 8;
//用户地址 //用户地址
string addr = 9; string addr = 9;
//更新时间 //更新时间
int64 updateTime = 10; int64 updateTime = 10;
//索引 //索引
int64 index = 11; int64 index = 11;
//手续费率
int32 rate = 12;
//手续费
int64 digestedFee = 13;
//最小手续费
int64 minFee = 14;
//挂单hash
string hash = 15;
//撤单hash
string revokeHash = 16;
//创建时间
int64 createTime = 17;
} }
//查询接口 //查询接口
message QueryMarketDepth { message QueryMarketDepth {
//资产1 //资产1
asset leftAsset = 1; asset leftAsset = 1;
//资产2 //资产2
asset rightAsset = 2; asset rightAsset = 2;
//操作, 1为买,2为卖 //操作, 1为买,2为卖
int32 op = 3; int32 op = 3;
// 这里用价格作为索引值 // 这里用价格作为索引值
string primaryKey = 4; string primaryKey = 4;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 //单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 5; int32 count = 5;
} }
//市场深度 //市场深度
message MarketDepth { message MarketDepth {
//资产1 //资产1
asset leftAsset = 1; asset leftAsset = 1;
//资产2 //资产2
asset rightAsset = 2; asset rightAsset = 2;
//价格 //价格
int64 price = 3; int64 price = 3;
//总量 //总量
int64 amount = 4; int64 amount = 4;
//操作, 1为买,2为卖 //操作, 1为买,2为卖
int32 op = 5; int32 op = 5;
} }
//查询接口返回的市场深度列表 //查询接口返回的市场深度列表
message MarketDepthList { message MarketDepthList {
repeated MarketDepth list = 1; repeated MarketDepth list = 1;
string primaryKey = 2; string primaryKey = 2;
} }
//查询最新得成交信息,外部接口 //查询最新得成交信息,外部接口
message QueryHistoryOrderList { message QueryHistoryOrderList {
//资产1 //资产1
asset leftAsset = 1; asset leftAsset = 1;
//资产2 //资产2
asset rightAsset = 2; asset rightAsset = 2;
// 索引值 // 索引值
string primaryKey = 3; string primaryKey = 3;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 //单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 4; int32 count = 4;
// 0降序,1升序,默认降序 // 0降序,1升序,默认降序
int32 direction = 5; int32 direction = 5;
} }
//根据orderID去查询订单信息 //根据orderID去查询订单信息
message QueryOrder { message QueryOrder {
int64 orderID = 1; int64 orderID = 1;
} }
//根据地址,状态查询用户自己的挂单信息 //根据地址,状态查询用户自己的挂单信息
message QueryOrderList { message QueryOrderList {
//挂单状态必填(默认是0,只查询ordered挂单中的) //挂单状态必填(默认是0,只查询ordered挂单中的)
int32 status = 1; int32 status = 1;
//用户地址信息,必填 //用户地址信息,必填
string address = 2; string address = 2;
// 主键索引 // 主键索引
string primaryKey = 3; string primaryKey = 3;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 //单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 4; int32 count = 4;
// 0降序,1升序,默认降序 // 0降序,1升序,默认降序
int32 direction = 5; int32 direction = 5;
} }
//订单列表 //订单列表
message OrderList { message OrderList {
repeated Order list = 1; repeated Order list = 1;
string primaryKey = 2; string primaryKey = 2;
} }
// exchange执行票据日志 // exchange执行票据日志
message ReceiptExchange { message ReceiptExchange {
Order order = 1; Order order = 1;
repeated Order matchOrders = 2; repeated Order matchOrders = 2;
int64 index = 3; int64 index = 3;
} }
service exchange {} service exchange {}
...@@ -76,6 +76,7 @@ enableTLS=false ...@@ -76,6 +76,7 @@ enableTLS=false
certFile="cert.pem" certFile="cert.pem"
# 私钥文件 # 私钥文件
keyFile="key.pem" keyFile="key.pem"
[mempool] [mempool]
# mempool队列名称,可配,timeline,score,price # mempool队列名称,可配,timeline,score,price
name="timeline" name="timeline"
...@@ -86,6 +87,7 @@ minTxFee=100000 ...@@ -86,6 +87,7 @@ minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# timeline 是默认的先来先进的按时间排序 # timeline 是默认的先来先进的按时间排序
[mempool.sub.timeline] [mempool.sub.timeline]
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
...@@ -94,6 +96,7 @@ minTxFee=100000 ...@@ -94,6 +96,7 @@ minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
# score是分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置),按分数来排序 # score是分数队列模式(分数=常量a*手续费/交易字节数-常量b*时间*定量c,按分数排队,高的优先,常量a,b和定量c可配置),按分数来排序
[mempool.sub.score] [mempool.sub.score]
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
...@@ -108,6 +111,7 @@ priceConstant=1544 ...@@ -108,6 +111,7 @@ priceConstant=1544
# 常量比例 # 常量比例
pricePower=1 pricePower=1
# price是价格队列模式(价格=手续费/交易字节数,价格高者优先,同价则时间早优先) # price是价格队列模式(价格=手续费/交易字节数,价格高者优先,同价则时间早优先)
[mempool.sub.price] [mempool.sub.price]
# mempool缓存容量大小,默认10240 # mempool缓存容量大小,默认10240
poolCacheSize=10240 poolCacheSize=10240
...@@ -115,6 +119,7 @@ poolCacheSize=10240 ...@@ -115,6 +119,7 @@ poolCacheSize=10240
minTxFee=100000 minTxFee=100000
# 每个账户在mempool中得最大交易数量,默认100 # 每个账户在mempool中得最大交易数量,默认100
maxTxNumPerAccount=10000 maxTxNumPerAccount=10000
[consensus] [consensus]
#共识名,可选项有solo,ticket,raft,tendermint,para #共识名,可选项有solo,ticket,raft,tendermint,para
name="solo" name="solo"
...@@ -124,6 +129,7 @@ minerstart=true ...@@ -124,6 +129,7 @@ minerstart=true
genesisBlockTime=1514533394 genesisBlockTime=1514533394
#创世交易地址 #创世交易地址
genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs" genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs"
[mver.consensus] [mver.consensus]
#基金账户地址 #基金账户地址
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5" fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
...@@ -150,6 +156,7 @@ targetTimespan = 2304 ...@@ -150,6 +156,7 @@ targetTimespan = 2304
#每个区块打包的目标时间 #每个区块打包的目标时间
targetTimePerBlock = 16 targetTimePerBlock = 16
# 仅保留这一项,其他consensus相关的配置全部删除 # 仅保留这一项,其他consensus相关的配置全部删除
[consensus.sub.solo] [consensus.sub.solo]
#创世交易地址 #创世交易地址
genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs" genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs"
...@@ -157,6 +164,7 @@ genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs" ...@@ -157,6 +164,7 @@ genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs"
genesisBlockTime=1514533394 genesisBlockTime=1514533394
#获取交易间隔时长,单位纳秒 #获取交易间隔时长,单位纳秒
waitTxMs=10 waitTxMs=10
[store] [store]
# 数据存储格式名称,目前支持mavl,kvdb,kvmvcc,mpt # 数据存储格式名称,目前支持mavl,kvdb,kvmvcc,mpt
name="mavl" name="mavl"
...@@ -168,6 +176,7 @@ dbPath="datadir/mavltree" ...@@ -168,6 +176,7 @@ dbPath="datadir/mavltree"
dbCache=128 dbCache=128
# 数据库版本 # 数据库版本
localdbVersion="1.0.0" localdbVersion="1.0.0"
[store.sub.mavl] [store.sub.mavl]
# 是否使能mavl加前缀 # 是否使能mavl加前缀
enableMavlPrefix=false enableMavlPrefix=false
...@@ -177,6 +186,7 @@ enableMVCC=false ...@@ -177,6 +186,7 @@ enableMVCC=false
enableMavlPrune=false enableMavlPrune=false
# 裁剪高度间隔 # 裁剪高度间隔
pruneHeight=10000 pruneHeight=10000
[wallet] [wallet]
# 交易发送最低手续费,单位0.00000001BTY(1e-8),默认100000,即0.001BTY # 交易发送最低手续费,单位0.00000001BTY(1e-8),默认100000,即0.001BTY
minFee=100000 minFee=100000
...@@ -187,12 +197,14 @@ dbPath="wallet" ...@@ -187,12 +197,14 @@ dbPath="wallet"
# walletdb缓存大小 # walletdb缓存大小
dbCache=16 dbCache=16
# 钱包发送交易签名方式 # 钱包发送交易签名方式
signType="secp256k1" signType="secp256k1"
[wallet.sub.ticket] [wallet.sub.ticket]
# 是否关闭ticket自动挖矿,默认false # 是否关闭ticket自动挖矿,默认false
minerdisable=false minerdisable=false
# 允许购买ticket挖矿的白名单地址,默认配置“*”,允许所有地址购买 # 允许购买ticket挖矿的白名单地址,默认配置“*”,允许所有地址购买
minerwhitelist=["*"] minerwhitelist=["*"]
[exec] [exec]
#执行器执行是否免费 #执行器执行是否免费
isFree=false isFree=false
...@@ -203,6 +215,7 @@ enableStat=false ...@@ -203,6 +215,7 @@ enableStat=false
#是否开启MVCC插件 #是否开启MVCC插件
enableMVCC=false enableMVCC=false
alias=["token1:token","token2:token","token3:token"] alias=["token1:token","token2:token","token3:token"]
[exec.sub.token] [exec.sub.token]
#是否保存token交易信息 #是否保存token交易信息
saveTokenTxList=true saveTokenTxList=true
...@@ -215,6 +228,7 @@ tokenApprs = [ ...@@ -215,6 +228,7 @@ tokenApprs = [
"1JYB8sxi4He5pZWHCd3Zi2nypQ4JMB6AxN", "1JYB8sxi4He5pZWHCd3Zi2nypQ4JMB6AxN",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv", "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
] ]
[exec.sub.cert] [exec.sub.cert]
# 是否启用证书验证和签名 # 是否启用证书验证和签名
enable=false enable=false
...@@ -222,9 +236,11 @@ enable=false ...@@ -222,9 +236,11 @@ enable=false
cryptoPath="authdir/crypto" cryptoPath="authdir/crypto"
# 带证书签名类型,支持"auth_ecdsa", "auth_sm2" # 带证书签名类型,支持"auth_ecdsa", "auth_sm2"
signType="auth_ecdsa" signType="auth_ecdsa"
[exec.sub.relay] [exec.sub.relay]
#relay执行器保存BTC头执行权限地址 #relay执行器保存BTC头执行权限地址
genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs" genesis="1CbEVT9RnM5oZhWMj4fxUrJX94VtRotzvs"
[exec.sub.manage] [exec.sub.manage]
#manage执行器超级管理员地址 #manage执行器超级管理员地址
superManager=[ superManager=[
...@@ -233,3 +249,40 @@ superManager=[ ...@@ -233,3 +249,40 @@ superManager=[
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK" "1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK"
] ]
[metrics]
#是否使能发送metrics数据的发送
enableMetrics=false
#数据保存模式
dataEmitMode="influxdb"
[metrics.sub.influxdb]
#以纳秒为单位的发送间隔
duration=1000000000
url="http://influxdb:8086"
database="chain33metrics"
username=""
password=""
namespace=""
[mver.exec.sub.exchange]
banks = [
"1PTGVR7TUm1MJUH7M1UNcKBGMvfJ7nCrnN"
]
coins = [
{name = "bty", rate = 100000, minFee = 0},
{name = "CCNY", rate = 100000, minFee = 0},
]
#[mver.exec.sub.exchange.ForkParamV1]
#banks = [
# "1PTGVR7TUm1MJUH7M1UNcKBGMvfJ7nCrnN"
#]
#coins = [
# {name = "bty", rate = 100000, minFee = 1000000},
# {name = "CCNY", rate = 100000, minFee = 1000000},
#]
[fork.sub.exchange]
Enable=0
#ForkParamV1=1
\ No newline at end of file
...@@ -18,10 +18,35 @@ var ( ...@@ -18,10 +18,35 @@ var (
// 批量测试前,先确保测试账户有足够的币和钱 // 批量测试前,先确保测试账户有足够的币和钱
func main() { func main() {
cli = test.NewGRPCCli("localhost:8802") cli = test.NewGRPCCli("localhost:8802")
onesell()
go buy() go buy()
go sell() go sell()
select {} select {}
} }
func onesell() {
req := &et.LimitOrder{
LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"},
Price: 1,
Amount: types.DefaultCoinPrecision,
Op: et.OpSell,
}
ety := types.LoadExecutorType(et.ExchangeX)
// 卖 2000 次,需 2000*1=2000 个 bty
fmt.Println("one sell ")
tx, err := ety.Create("LimitOrder", req)
if err != nil {
panic(err)
}
reply, err := cli.SendTx(tx, PrivKeyA)
if err != nil {
fmt.Println("send err:", err)
return
}
fmt.Println("reply", reply.IsOk)
fmt.Println("reply", string(reply.GetMsg()))
}
func sell() { func sell() {
req := &et.LimitOrder{ req := &et.LimitOrder{
......
...@@ -17,6 +17,7 @@ var ( ...@@ -17,6 +17,7 @@ var (
PrivKeyB = "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" // 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR PrivKeyB = "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4" // 1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR
PrivKeyC = "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" // 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k PrivKeyC = "0x7a80a1f75d7360c6123c32a78ecf978c1ac55636f87892df38d8b85a9aeff115" // 1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k
PrivKeyD = "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" // 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs PrivKeyD = "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71" // 1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs
PrivKeyFee = "0xa691ceceadb1f6878c39702a057b09077971d2995b29f18ccba1e09cd9619b7f" // 1PTGVR7TUm1MJUH7M1UNcKBGMvfJ7nCrnN
coin = "bty" coin = "bty"
token = "CCNY" token = "CCNY"
leftAsset = &et.Asset{Symbol: coin, Execer: "coins"} leftAsset = &et.Asset{Symbol: coin, Execer: "coins"}
......
...@@ -40,6 +40,8 @@ type ExecCli struct { ...@@ -40,6 +40,8 @@ type ExecCli struct {
accC1 *account.DB accC1 *account.DB
accD *account.DB accD *account.DB
accD1 *account.DB accD1 *account.DB
accF *account.DB
accF1 *account.DB
} }
//Nodes ... //Nodes ...
...@@ -49,6 +51,7 @@ var ( ...@@ -49,6 +51,7 @@ var (
"1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR", "1JRNjdEqp4LJ5fqycUBm9ayCKSeeskgMKR",
"1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k", "1NLHPEcbTWWxxU3dGUZBhayjrCHD3psX7k",
"1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs", "1MCftFynyvG2F4ED5mdHYgziDxx6vDrScs",
"1PTGVR7TUm1MJUH7M1UNcKBGMvfJ7nCrnN",
} }
) )
...@@ -57,7 +60,7 @@ func NewExecCli() *ExecCli { ...@@ -57,7 +60,7 @@ func NewExecCli() *ExecCli {
dir, sdb, ldb := util.CreateTestDB() dir, sdb, ldb := util.CreateTestDB()
log.Println(dir) log.Println(dir)
cfg := types.NewChain33Config(types.GetDefaultCfgstring()) cfg := types.NewChain33Config(et.GetDefaultCfgstring())
cfg.SetTitleOnlyForTest("chain33") cfg.SetTitleOnlyForTest("chain33")
executor.Init(et.ExchangeX, cfg, nil) executor.Init(et.ExchangeX, cfg, nil)
...@@ -72,7 +75,6 @@ func NewExecCli() *ExecCli { ...@@ -72,7 +75,6 @@ func NewExecCli() *ExecCli {
Frozen: 0, Frozen: 0,
Addr: Nodes[1], Addr: Nodes[1],
} }
accountC := &types.Account{ accountC := &types.Account{
Balance: total, Balance: total,
Frozen: 0, Frozen: 0,
...@@ -83,6 +85,11 @@ func NewExecCli() *ExecCli { ...@@ -83,6 +85,11 @@ func NewExecCli() *ExecCli {
Frozen: 0, Frozen: 0,
Addr: Nodes[3], Addr: Nodes[3],
} }
accountFee := &types.Account{
Balance: 0,
Frozen: 0,
Addr: Nodes[4],
}
execAddr := address.ExecAddress(et.ExchangeX) execAddr := address.ExecAddress(et.ExchangeX)
...@@ -98,6 +105,9 @@ func NewExecCli() *ExecCli { ...@@ -98,6 +105,9 @@ func NewExecCli() *ExecCli {
accD, _ := account.NewAccountDB(cfg, "coins", "bty", sdb) accD, _ := account.NewAccountDB(cfg, "coins", "bty", sdb)
accD.SaveExecAccount(execAddr, accountD) accD.SaveExecAccount(execAddr, accountD)
accF, _ := account.NewAccountDB(cfg, "coins", "bty", sdb)
accF.SaveExecAccount(execAddr, accountFee)
accA1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb) accA1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb)
accA1.SaveExecAccount(execAddr, accountA) accA1.SaveExecAccount(execAddr, accountA)
...@@ -110,6 +120,9 @@ func NewExecCli() *ExecCli { ...@@ -110,6 +120,9 @@ func NewExecCli() *ExecCli {
accD1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb) accD1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb)
accD1.SaveExecAccount(execAddr, accountD) accD1.SaveExecAccount(execAddr, accountD)
accF1, _ := account.NewAccountDB(cfg, "token", "CCNY", sdb)
accF1.SaveExecAccount(execAddr, accountFee)
q := queue.New("channel") q := queue.New("channel")
q.SetConfig(cfg) q.SetConfig(cfg)
...@@ -131,6 +144,8 @@ func NewExecCli() *ExecCli { ...@@ -131,6 +144,8 @@ func NewExecCli() *ExecCli {
accC1: accC1, accC1: accC1,
accD: accD, accD: accD,
accD1: accD1, accD1: accD1,
accF: accF,
accF1: accF1,
} }
} }
...@@ -202,7 +217,7 @@ func (c *ExecCli) Query(fn string, msg proto.Message) ([]byte, error) { ...@@ -202,7 +217,7 @@ func (c *ExecCli) Query(fn string, msg proto.Message) ([]byte, error) {
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) { func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1 signType := types.SECP256K1
c, err := crypto.New(types.GetSignName("", signType)) c, err := crypto.Load(types.GetSignName("", signType), -1)
if err != nil { if err != nil {
return tx, err return tx, err
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment