Unverified Commit c8145960 authored by pengjun's avatar pengjun Committed by GitHub

Merge pull request #6 from 33cn/master

update
parents 689edd63 e9e43cb7
......@@ -138,6 +138,24 @@ jobs:
make docker-compose dapp=paracross
make docker-compose-down dapp=paracross
ci_paracross_bls:
name: ci_paracross_bls
runs-on: ubuntu-latest
steps:
- name: Set up Golang
uses: actions/setup-go@v2
with:
go-version: 1.13
id: go
- name: set go env
run: export PATH=${PATH}:`go env GOPATH`/bin
- name: checkout
uses: actions/checkout@v2
- name: deploy
run: |
make docker-compose dapp=paracross extra=1
make docker-compose-down dapp=paracross
ci_x2ethereum:
name: ci_x2ethereum
runs-on: ubuntu-latest
......
......@@ -109,11 +109,12 @@ coverhtml: ## Generate global code coverage report in HTML
docker: ## build docker image for chain33 run
@sudo docker build . -f ./build/Dockerfile-run -t chain33:latest
#extra can make more test setting
docker-compose: ## build docker-compose for chain33 run
@cd build && if ! [ -d ci ]; then \
make -C ../ ; \
fi; \
cp chain33* Dockerfile docker-compose.yml *.sh ci/ && cd ci/ && ./docker-compose-pre.sh run $(proj) $(dapp) && cd ../..
cp chain33* Dockerfile docker-compose.yml *.sh ci/ && cd ci/ && ./docker-compose-pre.sh run $(proj) $(dapp) $(extra) && cd ../..
docker-compose-down: ## build docker-compose for chain33 run
@cd build && if [ -d ci ]; then \
......
......@@ -13,10 +13,10 @@ function dapp_test_rpc() {
rm -f "jobs.log"
rm -rf "outdir"
dapps=$(find . -maxdepth 1 -type d ! -name dapptest ! -name . | sed 's/^\.\///' | sort)
dapps=$(find . -maxdepth 1 -type d ! -name dapptest ! -name autonomy ! -name . | sed 's/^\.\///' | sort)
echo "dapps list: $dapps"
set +e
parallel -k --results outdir --joblog ./jobs.log ./{}/"${RPC_TESTFILE}" "$ip" ::: "$dapps"
parallel -k --jobs 40 --results outdir --joblog ./jobs.log ./{}/"${RPC_TESTFILE}" "$ip" ::: "$dapps"
local ret=$?
if [ $ret -ne 0 ]; then
wrongdapps=$(awk '{print $7,$9 }' jobs.log | grep -a 1 | awk -F '/' '{print $2}')
......
......@@ -13,6 +13,7 @@ fi
OP="${1}"
PROJ="${2}"
DAPP="${3}"
EXTRA="${4}"
TESTCASEFILE="testcase.sh"
FORKTESTFILE="fork-test.sh"
......@@ -60,7 +61,7 @@ function run_dapp() {
exit 1
fi
elif [ "$test" == "$TESTCASEFILE" ]; then
if ! ./${DOCKER_COMPOSE_SH} "${PROJ}" "${app}"; then
if ! ./${DOCKER_COMPOSE_SH} "${PROJ}" "${app}" "${EXTRA}"; then
exit 1
fi
fi
......
......@@ -41,6 +41,12 @@ if [ -n "${2}" ]; then
DAPP=$2
fi
#EXTRA can do more test to dapp
EXTRA=""
if [ -n "${3}" ]; then
EXTRA=$3
fi
DAPP_TEST_FILE=""
if [ -n "${DAPP}" ]; then
DAPP_TEST_FILE="testcase.sh"
......@@ -66,6 +72,7 @@ fi
echo "=========== # env setting ============="
echo "DAPP=$DAPP"
echo "EXTRA=$EXTRA"
echo "DAPP_TEST_FILE=$DAPP_TEST_FILE"
echo "COMPOSE_FILE=$COMPOSE_FILE"
echo "COMPOSE_PROJECT_NAME=$COMPOSE_PROJECT_NAME"
......@@ -482,7 +489,7 @@ function main() {
echo "==============================DAPP=$DAPP main begin========================================================"
### init para ####
base_init
dapp_run init
dapp_run init "${EXTRA}"
### start docker ####
start
......
......@@ -47,12 +47,15 @@ enableReduceLocaldb=true
enablePushSubscribe=false
[p2p]
types=["dht"]
enable=false
driver="leveldb"
dbPath="paradatadir/addrbook"
dbCache=4
grpcLogFile="grpc33.log"
[p2p.sub.dht]
DHTDataPath="paradatadir/p2pstore"
[rpc]
# 避免与主链配置冲突
......@@ -71,7 +74,7 @@ maxTxNumPerAccount=10000
[consensus]
name="para"
genesisBlockTime=1514533394
genesisBlockTime=1514533390
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
minerExecs=["paracross"] #配置挖矿合约
......
......@@ -3,9 +3,12 @@ module github.com/33cn/plugin
go 1.12
require (
github.com/33cn/chain33 v0.0.0-20200618095014-8773a3526b6f
github.com/33cn/chain33 v0.0.0-20200703030312-6b32b7a3906e
github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7
github.com/NebulousLabs/errors v0.0.0-20181203160057-9f787ce8f69e // indirect
github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e // indirect
github.com/NebulousLabs/merkletree v0.0.0-20181203152040-08d5d54b07f5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bitly/go-simplejson v0.5.0
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
......@@ -39,7 +42,7 @@ require (
go.uber.org/atomic v1.4.0 // indirect
go.uber.org/multierr v1.2.0 // indirect
go.uber.org/zap v1.10.0 // indirect
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
google.golang.org/grpc v1.28.0
......
This diff is collapsed.
......@@ -46,8 +46,8 @@ grpcLogFile="grpc33.log"
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
jrpcBindAddr="localhost:0"
grpcBindAddr="localhost:0"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
......
......@@ -559,6 +559,8 @@ func initEnvDpos1(configName string) (queue.Queue, *blockchain.BlockChain, queue
q.SetConfig(chain33Cfg)
cfg := chain33Cfg.GetModuleConfig()
sub := chain33Cfg.GetSubConfig()
rpc.InitCfg(cfg.RPC)
chain := blockchain.New(chain33Cfg)
chain.SetQueueClient(q.Client())
......@@ -578,7 +580,6 @@ func initEnvDpos1(configName string) (queue.Queue, *blockchain.BlockChain, queue
network.SetQueueClient(q.Client())
rpc.InitCfg(cfg.RPC)
gapi := rpc.NewGRpcServer(q.Client(), nil)
go gapi.Listen()
......
This diff is collapsed.
// 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 para
import (
"github.com/33cn/chain33/types"
"github.com/pkg/errors"
)
//新增需要保证顺序
const (
P2pSubCommitTx = 1
P2pSubLeaderSyncMsg = 2
)
func (client *client) sendP2PMsg(ty int64, data interface{}) ([]byte, error) {
msg := client.GetQueueClient().NewMessage("p2p", ty, data)
err := client.GetQueueClient().Send(msg, true)
if err != nil {
return nil, errors.Wrapf(err, "ty=%d", ty)
}
resp, err := client.GetQueueClient().Wait(msg)
if err != nil {
return nil, errors.Wrapf(err, "wait ty=%d", ty)
}
if resp.GetData().(*types.Reply).IsOk {
return resp.GetData().(*types.Reply).Msg, nil
}
return nil, errors.Wrapf(types.ErrInvalidParam, "resp msg=%s", string(resp.GetData().(*types.Reply).GetMsg()))
}
// p2p订阅消息
func (client *client) SendPubP2PMsg(topic string, msg []byte) error {
data := &types.PublishTopicMsg{Topic: topic, Msg: msg}
_, err := client.sendP2PMsg(types.EventPubTopicMsg, data)
return err
}
func (client *client) SendSubP2PTopic(topic string) error {
data := &types.SubTopic{Topic: topic, Module: "consensus"}
_, err := client.sendP2PMsg(types.EventSubTopic, data)
return err
}
func (client *client) SendRmvP2PTopic(topic string) error {
data := &types.RemoveTopic{Topic: topic, Module: "consensus"}
_, err := client.sendP2PMsg(types.EventRemoveTopic, data)
return err
}
This diff is collapsed.
# 平行链 bls 聚合签名
>平行链多个共识节点间通过P2P组成内部局域网,把之前每个节点发送到主链的共识交易转而先互相内部广播,leader节点负责把多个共识交易聚合成一个共识交易发送给主链
#1. 订阅P2P topic
1. 以PARA-BLS-SIGN-TOPIC为topic在P2P订阅,平行链内部节点间通过p2p广播同步消息,比如这里bls签名交易和leader同步消息
#2. 协商leader
1. 考虑到leader轮换发送共识交易,每隔一定共识高度比如100就会轮换下一个节点为leader发送交易,当前共识高度/100后对nodegroup 地址取余base值就是当前leader地址
1. 考虑到某些leader节点可能是僵尸节点,每个节点监听leader节点每隔15s的心跳消息,如果超过1min没收到,则认为leader节点不工作,需要跳到下一个,这里维护
一个offset,如果超时没收到,offset++,和之前的base相加取余一起确定下一个leader节点,如果当前节点发现自己是leader节点则开始发送sync消息,offset停止增长
1. 随着共识高度增长,base增长,offset不变,一起确认新的leader
1. 某些特殊场景有多个leader同步时候,收敛到最大索引值的leader
#3. 发送聚合共识交易
1. 共识交易P2P广播给所有订阅的节点,leader节点负责聚合后上链,如果收集的签名交易不超过2/3节点,则不发送上链交易,聚合交易最终在主链达成共识
1. 节点广播共识交易后,超过一定时间共识高度没增长,重新发送共识交易
#4. BLS聚合签名算法
1. BLS签名需要的私钥比SECP256小一倍,采用SECP256私钥不断取hash直到满足BLS范围为止作为BLS私钥,然后确定BLS公钥
1. BLS公钥注册到主链nodegroup里面,和聚合签名一起验证BLS签名,同时防止BLS leader节点作弊
1. 对同一高度,每个节点签名的共识消息是一样的,只需要保留一份,签名聚合成一个,公钥信息压缩到一个bitmap,作为一个交易发送
1. BLS签名有两种paring曲线,G1和G2,G1产生msg较短,G2的较长,一般公钥放G2上,签名消息放G1上,ETH采用公钥放G1,签名放G2,公钥较短,消息较长,
我们由于公钥静态配置在数据库里,主链验证,签名经过消息发送,占用空间,和ETH相反比较好,静态库可以编译支持反转,但目前还是和ETH 2.0一致。
// 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 para
import (
"testing"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/common/crypto"
_ "github.com/33cn/plugin/plugin/crypto/bls"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/stretchr/testify/assert"
)
func TestIntegrateCommits(t *testing.T) {
pool := make(map[int64]*pt.ParaBlsSignSumDetails)
var commits []*pt.ParacrossCommitAction
cmt1 := &pt.ParacrossCommitAction{
Status: &pt.ParacrossNodeStatus{Height: 0},
Bls: &pt.ParacrossCommitBlsInfo{Addrs: []string{"aa"}, Sign: []byte{}},
}
cmt2 := &pt.ParacrossCommitAction{
Status: &pt.ParacrossNodeStatus{Height: 0},
Bls: &pt.ParacrossCommitBlsInfo{Addrs: []string{"bb"}, Sign: []byte{}},
}
commits = []*pt.ParacrossCommitAction{cmt1, cmt1, cmt1, cmt2, cmt1}
integrateCommits(pool, commits)
assert.Equal(t, len(pool[0].Addrs), 2)
assert.Equal(t, len(pool[0].Msgs), 2)
assert.Equal(t, len(pool[0].Signs), 2)
assert.Equal(t, pool[0].Addrs[0], "aa")
assert.Equal(t, pool[0].Addrs[1], "bb")
}
func TestBlsSignMain(t *testing.T) {
cryptoCli, err := crypto.New("bls")
assert.NoError(t, err)
testSecpPrikey2BlsPub(t, cryptoCli)
testBlsSign(t, cryptoCli)
testVerifyBlsSign(t, cryptoCli)
}
func testSecpPrikey2BlsPub(t *testing.T, cryptCli crypto.Crypto) {
cli := blsClient{}
cli.cryptoCli = cryptCli
key := ""
ret, _ := cli.secp256Prikey2BlsPub(key)
assert.Equal(t, "", ret)
//real prikey="1626b254a75e5c44de9500a0c7897643e7736c09a7270b807546acb7cf7c94c9"
key = "0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71"
q := "0x980287e26d4d44f8c57944ffc096f7d98a460c97dadbffaed14ff0de901fa7f8afc59fcb1805a0b031e5eae5601df1c2"
ret, _ = cli.secp256Prikey2BlsPub(key)
assert.Equal(t, q, ret)
}
func testBlsSign(t *testing.T, cryptCli crypto.Crypto) {
status := &pt.ParacrossNodeStatus{}
status.Height = 0
status.Title = "user.p.para."
KS := "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
PubKS := "a3d97d4186c80268fe6d3689dd574599e25df2dffdcff03f7d8ef64a3bd483241b7d0985958990de2d373d5604caf805"
PriKS := "6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
commit := &pt.ParacrossCommitAction{Status: status}
client := &blsClient{cryptoCli: cryptCli}
client.peersBlsPubKey = make(map[string]crypto.PubKey)
p, err := common.FromHex(PriKS)
assert.NoError(t, err)
prikey, err := client.cryptoCli.PrivKeyFromBytes(p)
assert.NoError(t, err)
client.blsPriKey = prikey
err = client.blsSign([]*pt.ParacrossCommitAction{commit})
assert.NoError(t, err)
p, err = common.FromHex(PubKS)
assert.NoError(t, err)
pub, err := cryptCli.PubKeyFromBytes(p)
assert.NoError(t, err)
client.peersBlsPubKey[KS] = pub
sign, err := cryptCli.SignatureFromBytes(commit.Bls.Sign)
assert.NoError(t, err)
msg := types.Encode(status)
ret := pub.VerifyBytes(msg, sign)
assert.Equal(t, ret, true)
err = client.verifyBlsSign(KS, commit)
assert.Equal(t, err, nil)
}
func testVerifyBlsSign(t *testing.T, cryptCli crypto.Crypto) {
client := &blsClient{cryptoCli: cryptCli}
client.peersBlsPubKey = make(map[string]crypto.PubKey)
KS := "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"
PubKS := "a3d97d4186c80268fe6d3689dd574599e25df2dffdcff03f7d8ef64a3bd483241b7d0985958990de2d373d5604caf805"
p, err := common.FromHex(PubKS)
assert.NoError(t, err)
pub, err := cryptCli.PubKeyFromBytes(p)
assert.NoError(t, err)
client.peersBlsPubKey[KS] = pub
commit := &pt.ParacrossCommitAction{}
blsInfo := &pt.ParacrossCommitBlsInfo{}
//bls-cgo sign data
//signData := "0x82753675393576758571cbbaefada498614b4a0a967ca2dd5724eb46ecfd1c89f1e49792ebbe1866c1d6d6ceaf3054c7189751477a5b7312218eb77dcab1bfb6287c6fbf2e1c6cf8fe2ade7c17596b081dc98be785a34db5b45a5cca08e7e744"
//g1pubs' sign data
signData := "0x90b4510399b16e6b3c3129593b29f88bfbc6bb1ab3fe44f682f7ff32a9b8e7086c07d28a25efc29b460fb40ea2674c7910d63293f0d57670276b7baabe4c95c92143063296371b8ba2a0e540f7956d569740bc08553a0dc6bf2fff4f4241c082"
blsInfo.Sign, err = common.FromHex(signData)
assert.NoError(t, err)
status := &pt.ParacrossNodeStatus{}
//data := "0x1a0c757365722e702e706172612e322097162f9d4a888121fdba2fb1ab402596acdbcb602121bd12284adb739d85f225"
data := "0x1a0c757365722e702e706172612e"
msg, err := common.FromHex(data)
assert.NoError(t, err)
types.Decode(msg, status)
commit.Status = status
commit.Bls = blsInfo
err = client.verifyBlsSign(KS, commit)
assert.Equal(t, err, nil)
}
This diff is collapsed.
......@@ -527,7 +527,7 @@ func (client *client) CreateBlock() {
out:
for {
select {
case <-client.quitCreate:
case <-client.quit:
break out
default:
count, err := client.getBatchSeqCount(currSeq)
......@@ -553,6 +553,7 @@ out:
}
//如果当前正在追赶,暂不处理
if client.commitMsgClient.authAccount != "" && client.isCaughtUp() && len(paraTxs.Items) > 0 {
//在追赶上之后,每次seq只请求一个,只检查第一个即可
client.commitMsgClient.commitTxCheckNotify(paraTxs.Items[0])
}
......
......@@ -28,6 +28,10 @@ type jumpDldClient struct {
wg sync.WaitGroup
}
func newJumpDldCli(para *client, cfg *subConfig) *jumpDldClient {
return &jumpDldClient{paraClient: para}
}
//校验按高度获取的block hash和前一步对应高度的blockhash比对
func verifyBlockHash(heights []*types.BlockInfo, blocks []*types.ParaTxDetail) error {
heightMap := make(map[int64][]byte)
......
......@@ -68,6 +68,26 @@ type multiDldClient struct {
mtx sync.Mutex
}
func newMultiDldCli(para *client, cfg *subConfig) *multiDldClient {
multi := &multiDldClient{
paraClient: para,
invNumPerJob: defaultInvNumPerJob,
jobBufferNum: defaultJobBufferNum,
serverTimeout: maxServerRspTimeout,
}
if cfg.MultiDownInvNumPerJob > 0 {
multi.invNumPerJob = cfg.MultiDownInvNumPerJob
}
if cfg.MultiDownJobBuffNum > 0 {
multi.jobBufferNum = cfg.MultiDownJobBuffNum
}
if cfg.MultiDownServerRspTime > 0 {
multi.serverTimeout = cfg.MultiDownServerRspTime
}
return multi
}
func (m *multiDldClient) getInvs(startHeight, endHeight int64) []*inventory {
var invs []*inventory
if endHeight > startHeight && endHeight-startHeight > maxRollbackHeight {
......
// 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 para
import (
"errors"
"fmt"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
)
//IsCaughtUp 是否追上最新高度,
func (client *client) Query_IsCaughtUp(req *types.ReqNil) (types.Message, error) {
if client == nil {
return nil, fmt.Errorf("%s", "client not bind message queue.")
}
return &types.IsCaughtUp{Iscaughtup: client.isCaughtUp()}, nil
}
func (client *client) Query_LocalBlockInfo(req *types.ReqInt) (types.Message, error) {
if client == nil {
return nil, fmt.Errorf("%s", "client not bind message queue.")
}
var block *pt.ParaLocalDbBlock
var err error
if req.Height <= -1 {
block, err = client.getLastLocalBlock()
if err != nil {
return nil, err
}
} else {
block, err = client.getLocalBlockByHeight(req.Height)
if err != nil {
return nil, err
}
}
blockInfo := &pt.ParaLocalDbBlockInfo{
Height: block.Height,
MainHash: common.ToHex(block.MainHash),
MainHeight: block.MainHeight,
ParentMainHash: common.ToHex(block.ParentMainHash),
BlockTime: block.BlockTime,
}
for _, tx := range block.Txs {
blockInfo.Txs = append(blockInfo.Txs, common.ToHex(tx.Hash()))
}
return blockInfo, nil
}
func (client *client) Query_LeaderInfo(req *types.ReqNil) (types.Message, error) {
if client == nil {
return nil, fmt.Errorf("%s", "client not bind message queue.")
}
nodes, leader, base, off, isLeader := client.blsSignCli.getLeaderInfo()
return &pt.ElectionStatus{IsLeader: isLeader, Leader: &pt.LeaderSyncInfo{ID: nodes[leader], BaseIdx: base, Offset: off}}, nil
}
func (client *client) Query_CommitTxInfo(req *types.ReqNil) (types.Message, error) {
if client == nil {
return nil, fmt.Errorf("%s", "client not bind message queue.")
}
rt := client.blsSignCli.showTxBuffInfo()
return rt, nil
}
func (client *client) Query_BlsPubKey(req *types.ReqString) (types.Message, error) {
if client == nil || req == nil {
return nil, fmt.Errorf("%s", "client not bind message queue.")
}
var pub pt.BlsPubKey
if len(req.Data) > 0 {
p, err := client.blsSignCli.secp256Prikey2BlsPub(req.Data)
if err != nil {
return nil, err
}
pub.Key = p
return &pub, nil
}
//缺省获取钱包的
if nil != client.blsSignCli.blsPubKey {
t := client.blsSignCli.blsPubKey.Bytes()
pub.Key = common.ToHex(t[:])
return &pub, nil
}
return nil, errors.New("no bls prikey init")
}
// Query_CreateNewAccount 通知para共识模块钱包创建了一个新的账户
func (client *client) Query_CreateNewAccount(acc *types.Account) (types.Message, error) {
if acc == nil {
return nil, types.ErrInvalidParam
}
plog.Info("Query_CreateNewAccount", "acc", acc.Addr)
// 需要para共识这边处理新创建的账户是否是超级节点发送commit共识交易的账户
client.commitMsgClient.onWalletAccount(acc)
return &types.Reply{IsOk: true, Msg: []byte("OK")}, nil
}
// Query_WalletStatus 通知para共识模块钱包锁状态有变化
func (client *client) Query_WalletStatus(walletStatus *types.WalletStatus) (types.Message, error) {
if walletStatus == nil {
return nil, types.ErrInvalidParam
}
plog.Info("Query_WalletStatus", "walletStatus", walletStatus.IsWalletLock)
// 需要para共识这边根据walletStatus.IsWalletLock锁的状态开启/关闭发送共识交易
client.commitMsgClient.onWalletStatus(walletStatus)
return &types.Reply{IsOk: true, Msg: []byte("OK")}, nil
}
......@@ -67,6 +67,23 @@ const (
blockSyncStateFinished
)
func newBlockSyncCli(para *client, cfg *subConfig) *blockSyncClient {
cli := &blockSyncClient{
paraClient: para,
notifyChan: make(chan bool, 1),
quitChan: make(chan struct{}),
maxCacheCount: defaultMaxCacheCount,
maxSyncErrCount: defaultMaxSyncErrCount,
}
if cfg.MaxCacheCount > 0 {
cli.maxCacheCount = cfg.MaxCacheCount
}
if cfg.MaxSyncErrCount > 0 {
cli.maxSyncErrCount = cfg.MaxSyncErrCount
}
return cli
}
//syncHasCaughtUp 判断同步是否已追赶上,供发送层调用
func (client *blockSyncClient) syncHasCaughtUp() bool {
return atomic.LoadInt32(&client.isSyncCaughtUpAtom) == 1
......@@ -414,7 +431,7 @@ func (client *blockSyncClient) addBlock(lastBlock *types.Block, localBlock *pt.P
newBlock.BlockTime = localBlock.BlockTime
newBlock.MainHash = localBlock.MainHash
newBlock.MainHeight = localBlock.MainHeight
if newBlock.Height == 1 && newBlock.BlockTime < client.paraClient.subCfg.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")
}
err = client.writeBlock(lastBlock.StateHash, &newBlock)
......
......@@ -26,7 +26,7 @@ import (
func init() {
//types.Init("user.p.para.", nil)
log.SetLogLevel("error")
log.SetLogLevel("info")
}
func getPrivKey(t *testing.T) crypto.PrivKey {
......@@ -64,19 +64,21 @@ func TestCalcCommitMsgTxs(t *testing.T) {
Height: 2,
Title: "user.p.para",
}
notify := []*pt.ParacrossNodeStatus{nt1}
tx, count, err := client.calcCommitMsgTxs(notify, 0)
commit1 := &pt.ParacrossCommitAction{Status: nt1}
notify := []*pt.ParacrossCommitAction{commit1}
tx, count, err := client.createCommitMsgTxs(notify)
assert.Nil(t, err)
assert.Equal(t, int64(1), count)
assert.NotNil(t, tx)
notify = append(notify, nt2)
tx, count, err = client.calcCommitMsgTxs(notify, 0)
commit1 = &pt.ParacrossCommitAction{Status: nt2}
notify = append(notify, commit1)
tx, count, err = client.createCommitMsgTxs(notify)
assert.Nil(t, err)
assert.Equal(t, int64(2), count)
assert.NotNil(t, tx)
tx, err = client.singleCalcTx(nt2, 0)
tx, err = client.singleCalcTx(commit1, 0)
assert.Nil(t, err)
assert.NotNil(t, tx)
......
......@@ -54,8 +54,8 @@ poolCacheSize=10240
minTxFeeRate=100000
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
jrpcBindAddr="localhost:0"
grpcBindAddr="localhost:0"
whitelist=["127.0.0.1"]
[consensus]
......
......@@ -44,8 +44,8 @@ dbCache=4
grpcLogFile="grpc33.log"
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
jrpcBindAddr="localhost:0"
grpcBindAddr="localhost:0"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
......
......@@ -47,8 +47,8 @@ grpcLogFile="grpc33.log"
channel=123
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
jrpcBindAddr="localhost:0"
grpcBindAddr="localhost:0"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
......
......@@ -44,7 +44,7 @@ func (d Driver) PrivKeyFromBytes(b []byte) (privKey crypto.PrivKey, err error) {
privKeyBytes := new([BLSPrivateKeyLength]byte)
copy(privKeyBytes[:], b[:BLSPrivateKeyLength])
priv := g1pubs.DeserializeSecretKey(*privKeyBytes)
if priv == nil {
if priv.GetFRElement() == nil {
return nil, errors.New("invalid bls privkey")
}
privBytes := priv.Serialize()
......
......@@ -8,6 +8,8 @@ import (
"fmt"
"testing"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
"github.com/stretchr/testify/assert"
)
......@@ -46,6 +48,19 @@ func TestSignAndVerify(t *testing.T) {
assert.Equal(t, false, ret)
}
func TestPrivKeyFromBytes(t *testing.T) {
keybyte, _ := common.FromHex("0xcacb1f5d51700aea07fca2246ab43b0917d70405c65edea9b5063d72eb5c6b71")
p, err := blsDrv.PrivKeyFromBytes(keybyte)
assert.Nil(t, p)
assert.NotNil(t, err)
keybyte, _ = common.FromHex("0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b")
p, err = blsDrv.PrivKeyFromBytes(keybyte)
assert.NotNil(t, p)
assert.Nil(t, err)
}
func TestAggregate(t *testing.T) {
m := []byte("message to be signed. 将要做签名的消息")
n := 8
......
......@@ -6,6 +6,6 @@ strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
echo "${OUT_DIR}"
# mkdir -p "${OUT_DIR}"
# cp ./build/* "${OUT_DIR}"
......@@ -166,9 +166,6 @@ func TestAccountManager(t *testing.T) {
accounts, err := Exec_QueryAccountsByStatus(et.Frozen, stateDB, kvdb)
assert.Equal(t, err, nil)
assert.Equal(t, accounts.Accounts[0].Status, et.Frozen)
balance, err = Exec_QueryBalanceByID(&et.QueryBalanceByID{Asset: &types.Asset{Exec: "coins", Symbol: "bty"}, AccountID: "harrylee2015"}, stateDB, kvdb)
assert.Equal(t, err, nil)
assert.Equal(t, balance.Frozen, 199*types.Coin)
//解冻账户
tx9, _ := CreateSupervise(&et.Supervise{
......@@ -180,9 +177,6 @@ func TestAccountManager(t *testing.T) {
//根据状态查询
accounts, err = Exec_QueryAccountsByStatus(et.Frozen, stateDB, kvdb)
assert.NotEqual(t, err, nil)
balance, err = Exec_QueryBalanceByID(&et.QueryBalanceByID{Asset: &types.Asset{Exec: "coins", Symbol: "bty"}, AccountID: "harrylee2015"}, stateDB, kvdb)
assert.Equal(t, err, nil)
assert.Equal(t, balance.Balance, 199*types.Coin)
//过期账户查询
time.Sleep(11 * time.Second)
......
......@@ -200,10 +200,6 @@ func (a *Action) Supervise(payload *et.Supervise) (*types.Receipt, error) {
if managerAddr != a.fromaddr {
return nil, et.ErrNotAdmin
}
coinsAssetDB, err := account.NewAccountDB(cfg, "coins", cfg.GetCoinSymbol(), a.statedb)
if err != nil {
return nil, err
}
var logs []*types.ReceiptLog
var kvs []*types.KeyValue
var re et.SuperviseReceipt
......@@ -215,25 +211,12 @@ func (a *Action) Supervise(payload *et.Supervise) (*types.Receipt, error) {
}
switch payload.Op {
case et.Freeze:
//TODO 账户冻结,还需要冻结账户地址相应得资产,这里因为查不到所有token资产,所以只冻结主币
//TODO 冻结操作交给外部其他执行器去控制,处于freeze状态的地址禁止操作
accountM.Status = et.Frozen
coinsAccount := coinsAssetDB.LoadExecAccount(accountM.Addr, a.execaddr)
receipt, err := coinsAssetDB.ExecFrozen(accountM.Addr, a.execaddr, coinsAccount.Balance)
if err != nil {
elog.Error("Supervise ExecFrozen", "AccountID", ID, "err", err)
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
case et.UnFreeze:
accountM.Status = et.Normal
coinsAccount := coinsAssetDB.LoadExecAccount(accountM.Addr, a.execaddr)
receipt, err := coinsAssetDB.ExecActive(accountM.Addr, a.execaddr, coinsAccount.Frozen)
if err != nil {
elog.Error("Supervise ExecActive", "AccountID", ID, "err", err)
}
logs = append(logs, receipt.Logs...)
kvs = append(kvs, receipt.KV...)
case et.AddExpire:
cfg := a.api.GetConfig()
defaultActiveTime := getConfValue(cfg, a.statedb, ConfNameActiveTime, DefaultActiveTime)
......
......@@ -6,6 +6,6 @@ strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
echo "${OUT_DIR}"
# mkdir -p "${OUT_DIR}"
# cp ./build/* "${OUT_DIR}"
......@@ -6,11 +6,12 @@ strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
PARACLI="${OUT_DIR}/chain33-para-cli"
PARANAME=para
SRC_CLI=github.com/33cn/plugin/cli
#PARACLI="${OUT_DIR}/chain33-para-cli"
#PARANAME=para
#SRC_CLI=github.com/33cn/plugin/cli
#go build -v -o "${PARACLI}" -ldflags "-X ${SRC_CLI}/buildflags.ParaName=user.p.${PARANAME}. -X ${SRC_CLI}/buildflags.RPCAddr=http://localhost:8901" "${SRC_CLI}"
go build -v -o "${PARACLI}" -ldflags "-X ${SRC_CLI}/buildflags.ParaName=user.p.${PARANAME}. -X ${SRC_CLI}/buildflags.RPCAddr=http://localhost:8901" "${SRC_CLI}"
mkdir -p "${OUT_DIR}"
# shellcheck disable=SC2086
cp ./build/* "${OUT_DIR}"
......
......@@ -3,7 +3,6 @@ FROM ubuntu:16.04
WORKDIR /root
COPY chain33 chain33
COPY chain33-cli chain33-cli
COPY chain33-para-cli chain33-para-cli
COPY chain33.toml chain33*.toml ./
COPY entrypoint.sh entrypoint.sh
......
This diff is collapsed.
......@@ -44,6 +44,7 @@ func ParcCmd() *cobra.Command {
GetBlockInfoCmd(),
GetLocalBlockInfoCmd(),
GetConsensDoneInfoCmd(),
blsCmd(),
)
return cmd
}
......@@ -313,7 +314,7 @@ func createCrossAssetTransfer(cmd *cobra.Command, args []string) {
func superNodeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "super_node",
Use: "node",
Short: "super node manage cmd",
}
cmd.AddCommand(nodeJoinCmd())
......@@ -324,6 +325,17 @@ func superNodeCmd() *cobra.Command {
cmd.AddCommand(getNodeInfoCmd())
cmd.AddCommand(getNodeIDInfoCmd())
cmd.AddCommand(getNodeListCmd())
cmd.AddCommand(nodeModifyCmd())
return cmd
}
func nodeJoinCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "join",
Short: "super node apply for join nodegroup cmd",
Run: createNodeJoinTx,
}
addNodeJoinFlags(cmd)
return cmd
}
......@@ -356,13 +368,13 @@ func createNodeJoinTx(cmd *cobra.Command, args []string) {
ctx.RunWithoutMarshal()
}
func nodeJoinCmd() *cobra.Command {
func nodeVoteCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "join",
Short: "super node apply for join nodegroup cmd",
Run: createNodeJoinTx,
Use: "vote",
Short: "nodegroup nodes vote for new join node cmd",
Run: createNodeVoteTx,
}
addNodeJoinFlags(cmd)
addNodeVoteFlags(cmd)
return cmd
}
......@@ -395,13 +407,13 @@ func createNodeVoteTx(cmd *cobra.Command, args []string) {
}
func nodeVoteCmd() *cobra.Command {
func nodeQuitCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "vote",
Short: "nodegroup nodes vote for new join node cmd",
Run: createNodeVoteTx,
Use: "quit",
Short: "super node apply for quit nodegroup cmd",
Run: createNodeQuitTx,
}
addNodeVoteFlags(cmd)
addNodeQuitFlags(cmd)
return cmd
}
......@@ -431,13 +443,13 @@ func createNodeQuitTx(cmd *cobra.Command, args []string) {
}
func nodeQuitCmd() *cobra.Command {
func nodeCancelCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "quit",
Short: "super node apply for quit nodegroup cmd",
Run: createNodeQuitTx,
Use: "cancel",
Short: "super node cancel join or quit action by id cmd",
Run: createNodeCancelTx,
}
addNodeQuitFlags(cmd)
addNodeCancelFlags(cmd)
return cmd
}
......@@ -467,16 +479,45 @@ func createNodeCancelTx(cmd *cobra.Command, args []string) {
}
func nodeCancelCmd() *cobra.Command {
func nodeModifyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cancel",
Short: "super node cancel join or quit action by id cmd",
Run: createNodeCancelTx,
Use: "modify",
Short: "super node modify parameters",
Run: createNodeModifyTx,
}
addNodeCancelFlags(cmd)
addNodeModifyFlags(cmd)
return cmd
}
func addNodeModifyFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addr", "a", "", "operating target apply id")
cmd.MarkFlagRequired("addr")
cmd.Flags().StringP("pubkey", "p", "", "operating target apply id")
cmd.MarkFlagRequired("pubkey")
}
func createNodeModifyTx(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
addr, _ := cmd.Flags().GetString("addr")
pubkey, _ := cmd.Flags().GetString("pubkey")
if !strings.HasPrefix(paraName, "user.p") {
fmt.Fprintln(os.Stderr, "paraName is not right, paraName format like `user.p.guodun.`")
return
}
payload := &pt.ParaNodeAddrConfig{Title: paraName, Op: pt.ParaOpModify, Addr: addr, BlsPubKey: pubkey}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "NodeConfig",
Payload: types.MustPBToJSON(payload),
}
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.CreateTransaction", params, nil)
ctx.RunWithoutMarshal()
}
// getNodeInfoCmd get node current status
func getNodeInfoCmd() *cobra.Command {
cmd := &cobra.Command{
......@@ -739,10 +780,22 @@ func nodeGroupCmd() *cobra.Command {
return cmd
}
func nodeGroupApplyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "apply",
Short: "apply for para chain's super node group",
Run: nodeGroupApply,
}
addNodeGroupApplyCmdFlags(cmd)
return cmd
}
func addNodeGroupApplyCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("addrs", "a", "", "addrs apply for super node,split by ',' ")
cmd.MarkFlagRequired("addrs")
cmd.Flags().StringP("blspubs", "p", "", "bls sign pub key for addr's private key,split by ',' (optional)")
cmd.Flags().Float64P("coins", "c", 0, "coins amount to frozen, not less config")
cmd.MarkFlagRequired("coins")
......@@ -751,6 +804,7 @@ func addNodeGroupApplyCmdFlags(cmd *cobra.Command) {
func nodeGroupApply(cmd *cobra.Command, args []string) {
paraName, _ := cmd.Flags().GetString("paraName")
addrs, _ := cmd.Flags().GetString("addrs")
blspubs, _ := cmd.Flags().GetString("blspubs")
coins, _ := cmd.Flags().GetFloat64("coins")
if !strings.HasPrefix(paraName, "user.p") {
......@@ -758,7 +812,7 @@ func nodeGroupApply(cmd *cobra.Command, args []string) {
return
}
payload := &pt.ParaNodeGroupConfig{Title: paraName, Op: 1, Addrs: addrs, CoinsFrozen: int64(math.Trunc((coins+0.0000001)*1e4)) * 1e4}
payload := &pt.ParaNodeGroupConfig{Title: paraName, Op: 1, Addrs: addrs, BlsPubKeys: blspubs, CoinsFrozen: int64(math.Trunc((coins+0.0000001)*1e4)) * 1e4}
params := &rpctypes.CreateTxIn{
Execer: getRealExecName(paraName, pt.ParaX),
ActionName: "NodeGroupConfig",
......@@ -770,16 +824,6 @@ func nodeGroupApply(cmd *cobra.Command, args []string) {
ctx.RunWithoutMarshal()
}
func nodeGroupApplyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "apply",
Short: "apply for para chain's super node group",
Run: nodeGroupApply,
}
addNodeGroupApplyCmdFlags(cmd)
return cmd
}
func addNodeGroupApproveCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("id", "i", "", "apply id for nodegroup ")
cmd.MarkFlagRequired("id")
......@@ -908,6 +952,72 @@ func isSync(cmd *cobra.Command, args []string) {
ctx.Run()
}
func blsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "bls",
Short: "bls sign manager cmd",
}
cmd.AddCommand(leaderCmd())
cmd.AddCommand(cmtTxInfoCmd())
cmd.AddCommand(blsPubKeyCmd())
return cmd
}
// leaderCmd query parachain is sync
func leaderCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "leader",
Short: "current bls sign leader",
Run: leaderInfo,
}
return cmd
}
func leaderInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
var res pt.ElectionStatus
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetParaNodeLeaderInfo", nil, &res)
ctx.Run()
}
// cmtTxInfoCmd query parachain is sync
func cmtTxInfoCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "cmts",
Short: "current bls sign commits info",
Run: cmtTxInfo,
}
return cmd
}
func cmtTxInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
var res pt.ParaBlsSignSumInfo
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetParaCmtTxInfo", nil, &res)
ctx.Run()
}
// cmtTxInfoCmd query parachain is sync
func blsPubKeyCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "pubkey",
Short: "get bls pub key by secp256 prikey or current wallet bls pubkey",
Run: blsPubKey,
}
return cmd
}
func blsPubKey(cmd *cobra.Command, args []string) {
cmd.Flags().StringP("prikey", "p", "", "secp256 private key")
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
prikey, _ := cmd.Flags().GetString("prikey")
req := &types.ReqString{Data: prikey}
var res pt.BlsPubKey
ctx := jsonclient.NewRPCCtx(rpcLaddr, "paracross.GetParaBlsPubKey", req, &res)
ctx.Run()
}
func consusHeight(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
paraName, _ := cmd.Flags().GetString("paraName")
......
This diff is collapsed.
This diff is collapsed.
......@@ -9,7 +9,6 @@ import (
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/pkg/errors"
)
//Exec_Commit consensus commit tx exec process
......@@ -18,7 +17,7 @@ func (e *Paracross) Exec_Commit(payload *pt.ParacrossCommitAction, tx *types.Tra
receipt, err := a.Commit(payload)
if err != nil {
clog.Error("Paracross commit failed", "error", err, "hash", hex.EncodeToString(tx.Hash()))
return nil, errors.Cause(err)
return nil, err
}
return receipt, nil
}
......
......@@ -9,6 +9,7 @@ import (
"encoding/hex"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/crypto"
log "github.com/33cn/chain33/common/log/log15"
drivers "github.com/33cn/chain33/system/dapp"
"github.com/33cn/chain33/types"
......@@ -24,6 +25,7 @@ var (
// Paracross exec
type Paracross struct {
cryptoCli crypto.Crypto
drivers.DriverBase
}
......@@ -48,6 +50,11 @@ func newParacross() drivers.Driver {
c := &Paracross{}
c.SetChild(c)
c.SetExecutorType(types.LoadExecutorType(driverName))
cli, err := crypto.New("bls")
if err != nil {
panic("paracross need bls sign register")
}
c.cryptoCli = cli
return c
}
......
......@@ -6,9 +6,8 @@ package executor
import (
"bytes"
"testing"
"strings"
"testing"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
......@@ -19,6 +18,7 @@ import (
"github.com/33cn/chain33/common/log"
mty "github.com/33cn/chain33/system/dapp/manage/types"
"github.com/33cn/chain33/types"
_ "github.com/33cn/plugin/plugin/crypto/bls"
"github.com/33cn/plugin/plugin/dapp/paracross/testnode"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/stretchr/testify/assert"
......@@ -169,7 +169,7 @@ func (suite *CommitTestSuite) TestSetup() {
}
func fillRawCommitTx(suite suite.Suite) (*types.Transaction, error) {
st1 := pt.ParacrossNodeStatus{
st1 := &pt.ParacrossNodeStatus{
MainBlockHash: MainBlockHash10,
MainBlockHeight: MainBlockHeight,
Title: Title,
......@@ -184,7 +184,8 @@ func fillRawCommitTx(suite suite.Suite) (*types.Transaction, error) {
CrossTxResult: []byte("abc"),
CrossTxHashs: [][]byte{},
}
tx, err := pt.CreateRawCommitTx4MainChain(chain33TestCfg, &st1, pt.GetExecName(chain33TestCfg), 0)
act := &pt.ParacrossCommitAction{Status: st1}
tx, err := pt.CreateRawCommitTx4MainChain(chain33TestCfg, act, pt.GetExecName(chain33TestCfg), 0)
if err != nil {
suite.T().Error("TestExec", "create tx failed", err)
}
......@@ -718,19 +719,12 @@ func createCrossParaTx(s suite.Suite, to []byte) (*types.Transaction, error) {
func createCrossCommitTx(s suite.Suite) (*types.Transaction, error) {
status := &pt.ParacrossNodeStatus{MainBlockHash: []byte("hash"), MainBlockHeight: 0, Title: Title}
tx, err := pt.CreateRawCommitTx4MainChain(chain33TestCfg, status, Title+pt.ParaX, 0)
act := &pt.ParacrossCommitAction{Status: status}
tx, err := pt.CreateRawCommitTx4MainChain(chain33TestCfg, act, Title+pt.ParaX, 0)
assert.Nil(s.T(), err, "create asset transfer failed")
if err != nil {
return nil, err
}
//tx, err = signTx(s, tx, privFrom)
//assert.Nil(s.T(), err, "sign asset transfer failed")
//if err != nil {
// return nil, err
//}
return tx, nil
}
......@@ -832,3 +826,54 @@ func TestValidParaCrossExec(t *testing.T) {
valid = types.IsParaExecName(string(exec))
assert.Equal(t, true, valid)
}
func TestVerifyBlsSign(t *testing.T) {
cryptoCli, err := crypto.New("bls")
assert.NoError(t, err)
status := &pt.ParacrossNodeStatus{}
status.Height = 0
status.Title = "user.p.para."
msg := types.Encode(status)
blsInfo := &pt.ParacrossCommitBlsInfo{}
commit := &pt.ParacrossCommitAction{Status: status, Bls: blsInfo}
priKSStr := "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b"
p, err := common.FromHex(priKSStr)
assert.NoError(t, err)
priKS, err := cryptoCli.PrivKeyFromBytes(p)
assert.NoError(t, err)
priJRStr := "0x19c069234f9d3e61135fefbeb7791b149cdf6af536f26bebb310d4cd22c3fee4"
p, err = common.FromHex(priJRStr)
assert.NoError(t, err)
priJR, err := cryptoCli.PrivKeyFromBytes(p)
assert.NoError(t, err)
signKs := priKS.Sign(msg)
signJr := priJR.Sign(msg)
pubKs := priKS.PubKey()
pubJr := priJR.PubKey()
agg, err := crypto.ToAggregate(cryptoCli)
assert.NoError(t, err)
aggSigns, err := agg.Aggregate([]crypto.Signature{signKs, signJr})
assert.NoError(t, err)
pubs := []crypto.PubKey{pubKs, pubJr}
err = agg.VerifyAggregatedOne(pubs, msg, aggSigns)
assert.NoError(t, err)
blsInfo.Sign = aggSigns.Bytes()
PubKS := "a3d97d4186c80268fe6d3689dd574599e25df2dffdcff03f7d8ef64a3bd483241b7d0985958990de2d373d5604caf805"
PubJR := "81307df1fdde8f0e846ed1542c859c1e9daba2553e62e48db0877329c5c63fb86e70b9e2e83263da0eb7fcad275857f8"
pubKeys := []string{PubJR, PubKS}
err = verifyBlsSign(cryptoCli, pubKeys, commit)
assert.Equal(t, nil, err)
blsInfo.Sign = signKs.Bytes()
pubKeys = []string{PubKS}
err = verifyBlsSign(cryptoCli, pubKeys, commit)
assert.Equal(t, nil, err)
}
......@@ -6,7 +6,6 @@ package executor
import (
"encoding/hex"
"fmt"
"github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db"
......@@ -78,17 +77,21 @@ func (p *Paracross) Query_GetNodeGroupAddrs(in *pt.ReqParacrossNodeInfo) (types.
return nil, errors.Wrap(types.ErrInvalidParam, "title is null")
}
ret, key, err := getConfigNodes(p.GetStateDB(), in.GetTitle())
_, nodesArry, key, err := getConfigNodes(p.GetStateDB(), in.GetTitle())
if err != nil {
return nil, err
}
var nodes []string
for k := range ret {
nodes = append(nodes, k)
var nodes string
for _, k := range nodesArry {
if len(nodes) == 0 {
nodes = k
continue
}
nodes = nodes + "," + k
}
var reply types.ReplyConfig
reply.Key = string(key)
reply.Value = fmt.Sprint(nodes)
reply.Value = nodes
return &reply, nil
}
......
......@@ -274,7 +274,7 @@ func (a *action) stageVote(config *pt.ConfigVoteInfo) (*types.Receipt, error) {
stat.Votes = updateVotes(stat.Votes, nodes)
most, vote := getMostVote(stat.Votes)
if !isCommitDone(nodes, most) {
if !isCommitDone(len(nodes), most) {
return makeStageConfigReceipt(copyStat, stat), nil
}
clog.Info("paracross.stageVote ----pass", "most", most, "pass", vote)
......
......@@ -208,6 +208,15 @@ func makeParaNodeGroupReceipt(title string, prev, current *types.ConfigItem) *ty
}
}
//get secp256 addr's bls pubkey
func getAddrBlsPubKey(db dbm.KV, title, addr string) (string, error) {
addrStat, err := getNodeAddr(db, title, addr)
if err != nil {
return "", errors.Wrapf(err, "nodeAddr:%s-%s get error", title, addr)
}
return addrStat.BlsPubKey, nil
}
func (a *action) checkValidNode(config *pt.ParaNodeAddrConfig) (bool, error) {
nodes, _, err := getParacrossNodes(a.db, config.Title)
if err != nil {
......@@ -262,6 +271,7 @@ func (a *action) nodeJoin(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
Status: pt.ParaApplyJoining,
Title: config.Title,
TargetAddr: config.Addr,
BlsPubKey: config.BlsPubKey,
FromAddr: a.fromaddr,
Votes: &pt.ParaNodeVoteDetail{},
CoinsFrozen: config.CoinsFrozen,
......@@ -350,6 +360,23 @@ func (a *action) nodeCancel(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro
}
func (a *action) nodeModify(config *pt.ParaNodeAddrConfig) (*types.Receipt, error) {
addrStat, err := getNodeAddr(a.db, config.Title, config.Addr)
if err != nil {
return nil, errors.Wrapf(err, "nodeAddr:%s get error", config.Addr)
}
//只能提案发起人撤销
if a.fromaddr != config.Addr {
return nil, errors.Wrapf(types.ErrNotAllow, "addr create by:%s,not by:%s", config.Addr, a.fromaddr)
}
preStat := *addrStat
addrStat.BlsPubKey = config.BlsPubKey
return makeParaNodeStatusReceipt(a.fromaddr, &preStat, addrStat), nil
}
// IsSuperManager is supper manager or not
func isSuperManager(cfg *types.Chain33Config, addr string) bool {
confManager := types.ConfSub(cfg, manager.ManageX)
......@@ -439,6 +466,7 @@ func (a *action) updateNodeAddrStatus(stat *pt.ParaNodeIdStatus) (*types.Receipt
addrStat = &pt.ParaNodeAddrIdStatus{}
addrStat.Title = stat.Title
addrStat.Addr = stat.TargetAddr
addrStat.BlsPubKey = stat.BlsPubKey
addrStat.Status = pt.ParaApplyJoined
addrStat.ProposalId = stat.Id
addrStat.QuitId = ""
......@@ -544,7 +572,7 @@ func (a *action) nodeVote(config *pt.ParaNodeAddrConfig) (*types.Receipt, error)
stat.Votes = updateVotes(stat.Votes, nodes)
most, vote := getMostVote(stat.Votes)
if !isCommitDone(nodes, most) {
if !isCommitDone(len(nodes), most) {
superManagerPass, err := a.checkIsSuperManagerVote(config, nodes)
if err != nil {
return nil, err
......@@ -769,6 +797,15 @@ func (a *action) nodeGroupApply(config *pt.ParaNodeGroupConfig) (*types.Receipt,
return nil, errors.Wrapf(types.ErrInvalidParam, "node group apply addrs null:%s", config.Addrs)
}
var blsPubKeys []string
if len(config.BlsPubKeys) > 0 {
blsPubKeys = getConfigAddrs(config.BlsPubKeys)
if len(blsPubKeys) != len(addrs) {
return nil, errors.Wrapf(types.ErrInvalidParam, "nodegroup apply blsPubkeys length=%d not match addrs=%d",
len(blsPubKeys), len(addrs))
}
}
receipt := &types.Receipt{Ty: types.ExecOk}
//main chain
cfg := a.api.GetConfig()
......@@ -787,9 +824,12 @@ func (a *action) nodeGroupApply(config *pt.ParaNodeGroupConfig) (*types.Receipt,
Status: pt.ParacrossNodeGroupApply,
Title: config.Title,
TargetAddrs: strings.Join(addrs, ","),
BlsPubKeys: strings.Join(blsPubKeys, ","),
CoinsFrozen: config.CoinsFrozen,
FromAddr: a.fromaddr,
Height: a.height}
Height: a.height,
}
r := makeNodeGroupIDReceipt(a.fromaddr, nil, stat)
receipt.KV = append(receipt.KV, r.KV...)
receipt.Logs = append(receipt.Logs, r.Logs...)
......@@ -977,6 +1017,11 @@ func (a *action) nodeGroupCreate(status *pt.ParaNodeGroupStatus) (*types.Receipt
receipt := makeParaNodeGroupReceipt(status.Title, nil, &item)
var blsPubKeys []string
if len(status.BlsPubKeys) > 0 {
blsPubKeys = strings.Split(status.BlsPubKeys, ",")
}
//update addr status
for i, addr := range nodes {
stat := &pt.ParaNodeIdStatus{
......@@ -988,7 +1033,9 @@ func (a *action) nodeGroupCreate(status *pt.ParaNodeGroupStatus) (*types.Receipt
CoinsFrozen: status.CoinsFrozen,
FromAddr: status.FromAddr,
Height: a.height}
if len(blsPubKeys) > 0 {
stat.BlsPubKey = blsPubKeys[i]
}
r := makeNodeConfigReceipt(a.fromaddr, nil, nil, stat)
receipt = mergeReceipt(receipt, r)
......@@ -1052,25 +1099,28 @@ func (a *action) NodeConfig(config *pt.ParaNodeAddrConfig) (*types.Receipt, erro
return nil, errors.Wrapf(types.ErrInvalidParam, "exec=%s,should prefix with user.p.", string(a.tx.Execer))
}
if config.Op == pt.ParaOpNewApply {
switch config.Op {
case pt.ParaOpNewApply:
return a.nodeJoin(config)
} else if config.Op == pt.ParaOpQuit {
case pt.ParaOpQuit:
//退出nodegroup
return a.nodeQuit(config)
} else if config.Op == pt.ParaOpCancel {
case pt.ParaOpCancel:
//撤销未批准的申请
if config.Id == "" {
return nil, types.ErrInvalidParam
}
return a.nodeCancel(config)
} else if config.Op == pt.ParaOpVote {
case pt.ParaOpVote:
if config.Id == "" || config.Value >= pt.ParaVoteEnd {
return nil, types.ErrInvalidParam
}
return a.nodeVote(config)
case pt.ParaOpModify:
//修改addr相关联的参数,只能原创地址修改
return a.nodeModify(config)
default:
return nil, pt.ErrParaUnSupportNodeOper
}
return nil, pt.ErrParaUnSupportNodeOper
}
......@@ -6,6 +6,7 @@ package paracross
import (
"github.com/33cn/chain33/pluginmgr"
_ "github.com/33cn/plugin/plugin/crypto/bls" // register bls package for ut usage
_ "github.com/33cn/plugin/plugin/dapp/paracross/autotest" // register autotest package
"github.com/33cn/plugin/plugin/dapp/paracross/commands"
"github.com/33cn/plugin/plugin/dapp/paracross/executor"
......
......@@ -61,6 +61,7 @@ message ParaNodeAddrConfig {
string addr = 4;
uint32 value = 5;
int64 coinsFrozen = 6;
string blsPubKey = 7; //本地址私钥对应的bls聚合签名的公钥
}
message ParaNodeVoteDetail {
......@@ -74,6 +75,7 @@ message ParaNodeAddrIdStatus {
string quitId = 3;
int32 status = 4;
string title = 5;
string blsPubKey = 6;
}
message ParaNodeIdStatus {
......@@ -85,6 +87,7 @@ message ParaNodeIdStatus {
ParaNodeVoteDetail votes = 6;
string fromAddr = 7;
int64 height = 8;
string blsPubKey = 9;
}
message ReceiptParaNodeConfig {
......@@ -117,6 +120,7 @@ message ParaNodeGroupConfig {
string id = 3;
string addrs = 4;
int64 coinsFrozen = 5;
string blsPubKeys = 6;
}
message ParaNodeGroupStatus {
......@@ -127,6 +131,7 @@ message ParaNodeGroupStatus {
int64 coinsFrozen = 5;
string fromAddr = 6;
int64 height = 7;
string blsPubKeys = 8;
}
message ReceiptParaNodeGroupConfig {
......@@ -142,6 +147,7 @@ message ReqParacrossNodeInfo {
string id = 2;
string addr = 3;
int32 status = 4;
string blsPubKey = 5;
}
message RespParacrossNodeAddrs {
......@@ -259,8 +265,15 @@ message ReplyQuerySelfStages {
repeated SelfConsensStageInfo stageInfo = 1;
}
message ParacrossCommitBlsInfo {
bytes sign = 1;
bytes addrsMap = 2; //addrs' bitmap
repeated string addrs = 3; //addr's array
}
message ParacrossCommitAction {
ParacrossNodeStatus status = 1;
ParacrossCommitBlsInfo bls = 2;
}
message ParacrossMinerAction {
......@@ -402,6 +415,50 @@ message ParaLocalDbBlockInfo {
repeated string txs = 6;
}
message ParaBlsSignSumDetails {
int64 height = 1;
repeated string addrs = 2;
repeated bytes msgs = 3;
repeated bytes signs = 4;
}
message ParaBlsSignSumDetailsShow {
int64 height = 1;
repeated string addrs = 2;
repeated string msgs = 3;
}
message ParaBlsSignSumInfo {
repeated ParaBlsSignSumDetailsShow info = 1;
}
message LeaderSyncInfo {
string ID = 1; //self id
int32 baseIdx = 2; //calculated by corrent consensus height and remainder by len(nodes)
int32 offset = 3;
}
message ParaP2PSubMsg {
int32 ty = 1;
oneof value {
Transaction commitTx = 10;
LeaderSyncInfo syncMsg = 11;
}
}
//bls sign leader info
message ElectionStatus {
bool isLeader = 1;
LeaderSyncInfo leader = 2;
}
message BlsPubKey{
string key = 1;
}
service paracross {
rpc IsSync(ReqNil) returns (IsCaughtUp) {}
}
\ No newline at end of file
......@@ -52,3 +52,61 @@ func (c *Jrpc) GetParaLocalBlockInfo(in *types.ReqInt, result *interface{}) erro
*result = data
return nil
}
// GetParaNodeLeaderInfo query para bls sign leader info
func (c *channelClient) GetParaNodeLeaderInfo(ctx context.Context, in *types.ReqNil) (*pt.ElectionStatus, error) {
data, err := c.QueryConsensusFunc("para", "LeaderInfo", in)
if err != nil {
return nil, err
}
return data.(*pt.ElectionStatus), nil
}
// GetParaNodeLeaderInfo query para bls sign leader info
func (c *Jrpc) GetParaNodeLeaderInfo(in *types.ReqNil, result *interface{}) error {
data, err := c.cli.GetParaNodeLeaderInfo(context.Background(), in)
if err != nil {
return err
}
*result = data
return nil
}
// GetParaCmtTxInfo query para chain commit tx info to bls sign
func (c *channelClient) GetParaCmtTxInfo(ctx context.Context, in *types.ReqNil) (*pt.ParaBlsSignSumInfo, error) {
data, err := c.QueryConsensusFunc("para", "CommitTxInfo", in)
if err != nil {
return nil, err
}
return data.(*pt.ParaBlsSignSumInfo), nil
}
// GetParaCmtTxInfo query para commit tx info
func (c *Jrpc) GetParaCmtTxInfo(in *types.ReqNil, result *interface{}) error {
data, err := c.cli.GetParaCmtTxInfo(context.Background(), in)
if err != nil {
return err
}
*result = data
return nil
}
// GetParaBlsPubKey query para chain bls pubkey
func (c *channelClient) GetParaBlsPubKey(ctx context.Context, in *types.ReqString) (*pt.BlsPubKey, error) {
ins := *in
data, err := c.QueryConsensusFunc("para", "BlsPubKey", &ins)
if err != nil {
return nil, err
}
return data.(*pt.BlsPubKey), nil
}
// GetParaBlsPubKey query para local height
func (c *Jrpc) GetParaBlsPubKey(in *types.ReqString, result *interface{}) error {
data, err := c.cli.GetParaBlsPubKey(context.Background(), in)
if err != nil {
return err
}
*result = data
return nil
}
......@@ -18,9 +18,11 @@ func TestParaNode(t *testing.T) {
defer para.Close()
//通过rpc 发生信息
tx := util.CreateTxWithExecer(paraCfg, para.Para.GetGenesisKey(), "user.p.test.none")
assert.NotNil(t, tx)
para.Para.SendTxRPC(tx)
para.Para.WaitHeight(1)
tx = util.CreateTxWithExecer(paraCfg, para.Para.GetGenesisKey(), "user.p.test.none")
assert.NotNil(t, tx)
para.Para.SendTxRPC(tx)
para.Para.WaitHeight(2)
......
......@@ -57,4 +57,6 @@ var (
ErrKeyNotExist = errors.New("ErrKeyNotExist")
// ErrConsensClosed consensus closed
ErrConsensClosed = errors.New("ErrConsensClosed")
//ErrBlsSignVerify bls12-381 aggregate sign verify
ErrBlsSignVerify = errors.New("ErrBlsSignVerify")
)
......@@ -105,6 +105,7 @@ const (
ParaOpVote
ParaOpQuit
ParaOpCancel
ParaOpModify
)
// node vote op
......@@ -180,17 +181,14 @@ func CalcMinerHeightKey(title string, height int64) []byte {
}
// CreateRawCommitTx4MainChain create commit tx to main chain
func CreateRawCommitTx4MainChain(cfg *types.Chain33Config, status *ParacrossNodeStatus, name string, fee int64) (*types.Transaction, error) {
func CreateRawCommitTx4MainChain(cfg *types.Chain33Config, status *ParacrossCommitAction, name string, fee int64) (*types.Transaction, error) {
return createRawCommitTx(cfg, status, name, fee)
}
func createRawCommitTx(cfg *types.Chain33Config, status *ParacrossNodeStatus, name string, feeRate int64) (*types.Transaction, error) {
v := &ParacrossCommitAction{
Status: status,
}
func createRawCommitTx(cfg *types.Chain33Config, commit *ParacrossCommitAction, name string, feeRate int64) (*types.Transaction, error) {
action := &ParacrossAction{
Ty: ParacrossActionCommit,
Value: &ParacrossAction_Commit{v},
Value: &ParacrossAction_Commit{commit},
}
tx := &types.Transaction{
Execer: []byte(name),
......
This diff is collapsed.
......@@ -6,6 +6,6 @@ strapp=${strcmd%/cmd*}
OUT_DIR="${1}/$strapp"
#FLAG=$2
mkdir -p "${OUT_DIR}"
cp ./build/* "${OUT_DIR}"
echo "${OUT_DIR}"
# mkdir -p "${OUT_DIR}"
# cp ./build/* "${OUT_DIR}"
......@@ -268,7 +268,7 @@ function TestETH2Chain33Assets() {
result=$(${Chain33Cli} x2ethereum balance -s 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -t eth | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2 https://ropsten-rpc.linkpool.io/
eth_block_wait $((maturityDegree + 3)) https://ropsten-rpc.linkpool.io/
result=$(${CLIA} relayer ethereum balance -o "${bridgeBankAddr}")
cli_ret "${result}" "balance" ".balance" "0"
......@@ -326,7 +326,7 @@ function TestETH2Chain33Erc20() {
result=$(${Chain33Cli} x2ethereum balance -s "${chain33Validator1}" -t "${tokenSymbol}" -a "${tokenAddr}" | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2 https://ropsten-rpc.linkpool.io/
eth_block_wait $((maturityDegree + 3)) https://ropsten-rpc.linkpool.io/
result=$(${CLIA} relayer ethereum balance -o "${ethReceiverAddr2}" -t "${tokenAddr}")
cli_ret "${result}" "balance" ".balance" "100"
......@@ -438,7 +438,7 @@ function TestETH2Chain33AssetsKill() {
result=$(${Chain33Cli} x2ethereum balance -s 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -t eth | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2 https://ropsten-rpc.linkpool.io/
eth_block_wait $((maturityDegree + 3)) https://ropsten-rpc.linkpool.io/
result=$(${CLIA} relayer ethereum balance -o "${bridgeBankAddr}")
cli_ret "${result}" "balance" ".balance" "0.133"
......@@ -510,7 +510,7 @@ function TestETH2Chain33Erc20Kill() {
result=$(${Chain33Cli} x2ethereum balance -s "${chain33Validator1}" -t "${tokenSymbol}" -a "${tokenAddr}" | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2 https://ropsten-rpc.linkpool.io/
eth_block_wait $((maturityDegree + 3)) https://ropsten-rpc.linkpool.io/
start_ebrelayerC
......
......@@ -275,7 +275,7 @@ function TestETH2Chain33Assets() {
result=$(${Chain33Cli} x2ethereum balance -s 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -t eth | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2
eth_block_wait $((maturityDegree + 3))
result=$(${CLIA} relayer ethereum balance -o "${bridgeBankAddr}")
cli_ret "${result}" "balance" ".balance" "0"
......@@ -332,7 +332,7 @@ function TestETH2Chain33Erc20() {
result=$(${Chain33Cli} x2ethereum balance -s "${chain33Validator1}" -t "${tokenSymbol}" -a "${tokenAddr}" | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2
eth_block_wait $((maturityDegree + 3))
result=$(${CLIA} relayer ethereum balance -o "${ethReceiverAddr2}" -t "${tokenAddr}")
cli_ret "${result}" "balance" ".balance" "100"
......@@ -441,7 +441,7 @@ function TestETH2Chain33AssetsKill() {
result=$(${Chain33Cli} x2ethereum balance -s 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv -t eth | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2
eth_block_wait $((maturityDegree + 3))
result=$(${CLIA} relayer ethereum balance -o "${bridgeBankAddr}")
cli_ret "${result}" "balance" ".balance" "0.1"
......@@ -513,7 +513,7 @@ function TestETH2Chain33Erc20Kill() {
result=$(${Chain33Cli} x2ethereum balance -s "${chain33Validator1}" -t "${tokenSymbol}" -a "${tokenAddr2}" | jq ".res" | jq ".[]")
balance_ret "${result}" "0"
eth_block_wait 2
eth_block_wait $((maturityDegree + 3))
start_ebrelayerC
start_ebrelayerD
......
......@@ -351,7 +351,7 @@ function TestETH2Chain33Assets() {
req='{"method":"Chain33.Query","params":[{"execer":"x2ethereum","funcName":"GetRelayerBalance","payload":{"tokenSymbol":"eth","address":"'${sendAddress}'","tokenAddr":"0x0000000000000000000000000000000000000000"}}]}'
queryChain33X2ethBalance "${req}" "0"
eth_block_wait 2
eth_block_wait $((maturityDegree + 3))
req='{"method":"Manager.GetBalance","params":[{"owner":"'${bridgeBankAddr}'","tokenAddr":""}]}'
queryRelayerBalance "$req" "0"
......@@ -408,7 +408,7 @@ function TestETH2Chain33Erc20() {
req='{"method":"Chain33.Query","params":[{"execer":"x2ethereum","funcName":"GetRelayerBalance","payload":{"tokenSymbol":"testc","address":"'${chain33Validator1}'","tokenAddr":"'${tokenAddr}'"}}]}'
queryChain33X2ethBalance "${req}" "0"
eth_block_wait 2
eth_block_wait $((maturityDegree + 3))
req='{"method":"Manager.GetBalance","params":[{"owner":"'${ethReceiverAddr2}'","tokenAddr":"'${tokenAddr}'"}]}'
queryRelayerBalance "$req" "100"
......
......@@ -43,8 +43,4 @@ func TestParaNodeMempool(t *testing.T) {
tx := util.CreateTxWithExecer(chainCfg, mockpara.Para.GetGenesisKey(), "user.p.guodun.none")
hash := mockpara.Para.SendTx(tx)
assert.Equal(t, tx.Hash(), hash)
_, err := mockpara.Para.GetAPI().GetMempool(&types.ReqGetMempool{})
assert.Equal(t, err, types.ErrActionNotSupport)
t.Log(err)
}
......@@ -47,8 +47,8 @@ dbCache=4
grpcLogFile="grpc33.log"
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
jrpcBindAddr="localhost:0"
grpcBindAddr="localhost:0"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
......
......@@ -48,8 +48,8 @@ grpcLogFile="grpc33.log"
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
jrpcBindAddr="localhost:0"
grpcBindAddr="localhost:0"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
......
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