Commit 7a2a2e85 authored by 袁兴强's avatar 袁兴强

merge master

parents 623207aa e950a553
......@@ -12,6 +12,8 @@ jobs:
id: go
- name: checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Intsall Golangci-lint
run: |
......@@ -28,6 +30,7 @@ jobs:
- name: Lint
run: |
make largefile-check
make checkgofmt && make fmt_go
make linter
......
......@@ -49,9 +49,9 @@ autotest_tick: autotest ## run with ticket mining
update: ## version 可以是git tag打的具体版本号,也可以是commit hash, 什么都不填的情况下默认从master分支拉取最新版本
@if [ -n "$(version)" ]; then \
go get github.com/33cn/chain33@${version} ; \
go get -v github.com/33cn/chain33@${version} ; \
else \
go get github.com/33cn/chain33@master ;fi
go get -v github.com/33cn/chain33@master ;fi
@go mod tidy
dep:
@go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.18.0
......@@ -132,6 +132,9 @@ metrics:## build docker-compose for chain33 metrics
fork-test: ## build fork-test for chain33 run
@cd build && cp chain33* Dockerfile system-fork-test.sh docker-compose* ci/ && cd ci/ && ./docker-compose-pre.sh forktest $(proj) $(dapp) && cd ../..
largefile-check:
git gc
./findlargefile.sh
clean: ## Remove previous build
@rm -rf $(shell find . -name 'datadir' -not -path "./vendor/*")
......
go env -w CGO_ENABLED=0
go build -o chain33.exe
go build -o chain33-cli.exe github.com/33cn/plugin/cli
......@@ -53,6 +53,7 @@ driver="leveldb"
dbPath="paradatadir/addrbook"
dbCache=4
grpcLogFile="grpc33.log"
waitPid=true
[p2p.sub.dht]
DHTDataPath="paradatadir/p2pstore"
......@@ -93,7 +94,8 @@ coinDevFund=12
coinBaseReward=3
#委托账户最少解绑定时间(按小时)
unBindTime=24
#支持挖矿奖励的1e8小数模式,比如18coin 需要配置成1800000000 以支持小数位后的配置
#decimalMode=true
[consensus.sub.para]
#主链节点的grpc服务器ip,当前可以支持多ip负载均衡,如“118.31.177.1:8802,39.97.2.127:8802”
......
#!/bin/bash
#set -x
# Shows you the largest objects in your repo's pack file.
# Written for osx.
#
# @see https://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/
# @author Antony Stubbs
# set the internal field separator to line break, so that we can iterate easily over the verify-pack output
IFS=$'\n'
# list all objects including their size, sort by size, take top 10
objects=$(git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head -n 15)
echo "All sizes are in kB's. The pack column is the size of the object, compressed, inside the pack file."
# 46034 13074 650902c0f310f2f64e9ae5dfda35656ce8dadae3 chain33
# 42998 12325 5e8c0c3e6bc33034fd804d4c68b589c1eb66804b chain33-cli
# 30440 9801 d2d4a3aa838d85738e27ee474c785331bfe8e81c plugin/consensus/raft/tools/scripts/chain33.tgz
# 21292 10288 1e21797c3af8a4385c9169570b9b1c4072d7b3b6 plugin/dapp/exchange/test/cmd/main
# 4834 1113 9ec4f3d49403e8b9dd46885031a92e23af3828b9 vendor/golang.org/x/text/collate/tables.go
# 3468 1767 825659f96c308cd79ed2b32860d45d510dff6cce vendor/github.com/33cn/chain33/doc/golang/Go的50度灰:Golang新开发者要注意的陷阱和常见错误 .pdf
# 2556 863 9df156a7f0c9570431161873e3f605c7e4bb7ba9 vendor/github.com/haltingstate/secp256k1-go/secp256k1-go2/z_consts.go
# 2432 2159 0304d27f62317d2216c3288047a1a2a8bf37d94a vendor/github.com/33cn/chain33/doc/PBFT/pbft.pdf
history="650902c0f310f2f64e9ae5dfda35656ce8dadae3 5e8c0c3e6bc33034fd804d4c68b589c1eb66804b d2d4a3aa838d85738e27ee474c785331bfe8e81c \
1e21797c3af8a4385c9169570b9b1c4072d7b3b6 9ec4f3d49403e8b9dd46885031a92e23af3828b9 825659f96c308cd79ed2b32860d45d510dff6cce \
9df156a7f0c9570431161873e3f605c7e4bb7ba9 0304d27f62317d2216c3288047a1a2a8bf37d94a 0304d27f62317d2216c3288047a1a2a8bf37d94a"
oversize="false"
output="size,pack,SHA,location"
allObjects=$(git rev-list --all --objects)
for y in $objects; do
# extract the size in bytes
size=$(($(echo "$y" | cut -f 5 -d ' ') / 1024))
# extract the compressed size in bytes
compressedSize=$(($(echo "$y" | cut -f 6 -d ' ') / 1024))
# extract the SHA
sha=$(echo "$y" | cut -f 1 -d ' ')
if [[ ! $history =~ $sha ]]; then
if [ $size -ge 2000 ]; then
echo "over size file = $sha"
oversize="true"
fi
fi
# find the objects location in the repository tree
other=$(echo "${allObjects}" | grep "$sha")
#lineBreak=`echo -e "\n"`
output="${output}\n${size},${compressedSize},${other}"
done
echo -e "$output" | column -t -s ', '
if [ "$oversize" == "true" ]; then
echo "there are files over 2M size committed!!!"
exit 1
fi
......@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.12
require (
github.com/33cn/chain33 v0.0.0-20200729032621-0fbd543868cf
github.com/33cn/chain33 v1.65.1-0.20201022110501-fde367b8c955
github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7
github.com/NebulousLabs/errors v0.0.0-20181203160057-9f787ce8f69e // indirect
......@@ -24,26 +24,23 @@ require (
github.com/hashicorp/golang-lru v0.5.4
github.com/holiman/uint256 v1.1.1
github.com/huin/goupnp v1.0.0
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458
github.com/jackpal/go-nat-pmp v1.0.2
github.com/miguelmota/go-solidity-sha3 v0.1.0
github.com/mr-tron/base58 v1.1.3
github.com/mr-tron/base58 v1.2.0
github.com/pborman/uuid v1.2.0
github.com/perlin-network/life v0.0.0-20191203030451-05c0e0f7eaea
github.com/phoreproject/bls v0.0.0-20200525203911-a88a5ae26844
github.com/pkg/errors v0.8.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v0.9.2 // indirect
github.com/prometheus/common v0.4.1
github.com/prometheus/procfs v0.0.3 // indirect
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d
github.com/rs/cors v1.6.0
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.4.0
github.com/tjfoc/gmsm v1.3.1
github.com/stretchr/testify v1.6.1
github.com/tjfoc/gmsm v1.3.2
github.com/valyala/fasthttp v1.5.0
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
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-20200604202706-70a84ac30bf9
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
......
This diff is collapsed.
......@@ -26,7 +26,7 @@ const (
maxRcvTxCount = 100 //channel buffer, max 100 nodes, 1 height tx or 1 txgroup per node
leaderSyncInt = 15 //15s heartbeat sync interval
defLeaderSwitchInt = 100 //每隔100个共识高度切换一次leader,大约6小时(按50个空块间隔计算)
delaySubP2pTopic = 30 //30s to sub p2p topic
delaySubP2pTopic = 10 //30s to sub p2p topic
paraBlsSignTopic = "PARA-BLS-SIGN-TOPIC"
)
......
package paillier
import (
"bytes"
"encoding/binary"
"encoding/hex"
"fmt"
"math/big"
"github.com/33cn/chain33/common"
)
func CiphertextAdd(ciphertext1, ciphertext2 string) (string, error) {
cipherbytes1, err := common.FromHex(ciphertext1)
if err != nil {
return "", fmt.Errorf("CiphertextAdd.FromHex. ciphertext1:%s, error:%v", ciphertext1, err)
}
cipherbytes2, err := common.FromHex(ciphertext2)
if err != nil {
return "", fmt.Errorf("CiphertextAdd.FromHex. ciphertext2:%s, error:%v", ciphertext2, err)
}
res, err := CiphertextAddBytes(cipherbytes1, cipherbytes2)
if err != nil {
return "", fmt.Errorf("CiphertextAdd.CiphertextAddBytes. error:%v", err)
}
return hex.EncodeToString(res), nil
}
func CiphertextAddBytes(cipherbytes1, cipherbytes2 []byte) ([]byte, error) {
nlen1 := bytesToInt(cipherbytes1[0:2])
if nlen1 >= len(cipherbytes1)-2 {
return nil, fmt.Errorf("CiphertextAddBytes. error param length")
}
nBytes1 := make([]byte, nlen1)
copy(nBytes1, cipherbytes1[2:2+nlen1])
nlen2 := bytesToInt(cipherbytes2[0:2])
if nlen2 >= len(cipherbytes2)-2 {
return nil, fmt.Errorf("CiphertextAddBytes. error param length")
}
nBytes2 := make([]byte, nlen2)
copy(nBytes2, cipherbytes2[2:2+nlen2])
if !bytes.Equal(nBytes1, nBytes2) {
return nil, fmt.Errorf("CiphertextAddBytes. error: param error nBytes1!=nBytes2")
}
data1 := make([]byte, len(cipherbytes1)-nlen1-2)
copy(data1, cipherbytes1[2+nlen1:])
data2 := make([]byte, len(cipherbytes2)-nlen2-2)
copy(data2, cipherbytes2[2+nlen2:])
cipher1 := new(big.Int).SetBytes(data1)
cipher2 := new(big.Int).SetBytes(data2)
n1 := new(big.Int).SetBytes(nBytes1)
nsquare := new(big.Int).Mul(n1, n1)
res := big.NewInt(0)
res.Mul(cipher1, cipher2).Mod(res, nsquare)
data := make([]byte, nlen1+2+len(res.Bytes()))
copy(data[:nlen1+2], cipherbytes1[:nlen1+2])
copy(data[nlen1+2:], res.Bytes())
return data, nil
}
func bytesToInt(cipherbytes []byte) int {
bytebuff := bytes.NewBuffer(cipherbytes)
var data int16
binary.Read(bytebuff, binary.BigEndian, &data)
return int(data)
}
package paillier
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCiphertextAdd(t *testing.T) {
c1 := "010070061bde0fc57d38e0ce9c82c088f793a93a20f830ed94a5f7e01f5af0decccf0ee7f70a711dc78b69b40f7e411f7f6ff34a5de4ad32fa5dc9d09b09dbbcf8e49bb1c9be19b215577167458b969bb40634f71dba00bdfdd12f1c878effd9e08475b8301a214bc7dfc95c2f341aa8fbd985a5da05af046336c23cf356570772530017c9a8bb96140977698d50c3258e8d31c040bb887c56d3d6e583db7a4ff2ea28aa93885312dfa50bf86a15618288b2c2701e6d75743fec9f3ca35b7e20ad902ad6985fe0b3c389b9582b3c62d9bea90230d1512a07c66a5404bf804693b6bb677a4ff038ae4a762f89f6a877d7621f7461431a7d4cadaf1687057ca4a9d1570e4ceeab32c86856d89731d50edf6f0886ccf348cc4565227f1df6b813569c49b3170e9efd722e4f4e957add9a115a2122a9f5c00780a1b8020d44b8b865d16113eadcfd15d1b755aed7c983b3d4b9390eda68d22d165a32d4055eee95adee79d7d28d2ee6d593d4eff217cd3e3d70bb9c32a6608af78afb7d5cb7ee0422500273b934209b950cd07842ab7e10c0dfc790d212c9085058d39c667b7dfff0963478118451ec64af30aff518384cc47758b2aa4331c8b5f36d6d1b9c3a6ee7ba77d28ea6ca844960e24ab6384e36127745f1285f3b71cea6c5c6a41c51ca7edbfae07766a3fb7bd9ef6b8f999460741a5b44eeb0b98937b57f4582294e18fd70d402dee2e557fa7df5cfb13240458f77b62a32169940ab5a1fce95b52583ecb13e21c22749f7620caaa6fd998e4f9bd0e617c925b83bed5ed2215ec8a404357a782b70d2c6ece6fa7a4fb30d18a01b81b2f3a8e38cc12f32becfdf195e02879b710f2feda5b0c2e86ba6df2a0fa25c60cef58224ee466787034cc5d0872a28cf8d6bad106125660b0b4bfe86eacb829dbb073420ff3af3ac76e5718c199fcf53258397a9e4fed0d98f360d16248693aced1ecbc5ca5211f48df011d14d372ee07f9b7c24bc219f3cdc403ebeb5b452643ddd1f4276779fab76a19c8b195a1213a235f7facf67a26b8a7804cb326f58200d756d62d40edb650498c198a524c091f0"
c2 := "010070061bde0fc57d38e0ce9c82c088f793a93a20f830ed94a5f7e01f5af0decccf0ee7f70a711dc78b69b40f7e411f7f6ff34a5de4ad32fa5dc9d09b09dbbcf8e49bb1c9be19b215577167458b969bb40634f71dba00bdfdd12f1c878effd9e08475b8301a214bc7dfc95c2f341aa8fbd985a5da05af046336c23cf356570772530017c9a8bb96140977698d50c3258e8d31c040bb887c56d3d6e583db7a4ff2ea28aa93885312dfa50bf86a15618288b2c2701e6d75743fec9f3ca35b7e20ad902ad6985fe0b3c389b9582b3c62d9bea90230d1512a07c66a5404bf804693b6bb677a4ff038ae4a762f89f6a877d7621f7461431a7d4cadaf1687057ca4a9d157195acafe73f5eed77b314dd640999ee20de461600ce3d3620cef84abc256774a514db5b65721cd93d1601e0fa8f53630dbe8567493018588e9619783e1526eb9bc56cc7b37c99025a9bdc10465bfb01605232292e50ac3b56b2ffefe48f0615651649d1db4ebff57d955e434f0c564b2a6842d3af04be1bfc5e968abe390f15bc89b9a4ed7a00b82beea07cf8e03c82bdd6a40b6c6334e51a432024caf9247db25058eb0cbce567ed49c56730058480e5854f3888e988053c403045239098ba6977aa0adb7f6dec785d31bacee8276a87d7a8f2114bb6662a117e3e37846c5b713e599801fbae5185cf21360760721376efe0736b7f4fa049d0c9f3086324be3a0f44d6cae5450d87d79a7bcaa0a2aa259b738ed85a59fead48d985597f6d77022ecdf37685df4182267d4fbdb24747f208a9e1b3126251b320066d8499ab5298395dab0340a78325b39d383d34a31a27f223114a9774498a314e3ba3cf4b87150e1f959f29556e67ae136a6290922e8cd3890c3b93bb68f38990ac3a4700cbe075795f7603755a28f3226e31c29a2eab2bff2423dc6177a6d8eaa950fbe2320b9bee89b8bbc3149b7ee177224e59726f28bcb796ccb09ac6b3feb3256ca033eb177aeea997be798f0e1b63b284dc8361ff870de717263cb86838a0c6cd5a82e12d162bd04f9c85267d4abd3a6828639fd0584a023388cc220d404d4646d0318"
c3 := "010070061bde0fc57d38e0ce9c82c088f793a93a20f830ed94a5f7e01f5af0decccf0ee7f70a711dc78b69b40f7e411f7f6ff34a5de4ad32fa5dc9d09b09dbbcf8e49bb1c9be19b215577167458b969bb40634f71dba00bdfdd12f1c878effd9e08475b8301a214bc7dfc95c2f341aa8fbd985a5da05af046336c23cf356570772530017c9a8bb96140977698d50c3258e8d31c040bb887c56d3d6e583db7a4ff2ea28aa93885312dfa50bf86a15618288b2c2701e6d75743fec9f3ca35b7e20ad902ad6985fe0b3c389b9582b3c62d9bea90230d1512a07c66a5404bf804693b6bb677a4ff038ae4a762f89f6a877d7621f7461431a7d4cadaf1687057ca4a9d1571d74c0a358b73242b65cf84139071503ffa45c824d84cb0336510de9a1ad1a7c56142efa23f8b69b4094c940adb42df385fc11bf2704a2608b1a65c5d17f2a051114832ab141290c16201b59eae28639ece329eb5b8003b4f1025e57066115d7d378581268359e0ca94117451ca3aa6b0d597cf8f621b66bf20fc488b18848aa47e31d5939d59b8058def7df416f6734b3821bacd1fc8f4f1d422fc2c17c9bd903e80fabea7eb0f6237f771d0be65941cfca8ed6ec0e412bc940fc09cb0033abe4e668fee7f07a9cba77da04815747271eb32a5a9278ca0f57d7e05cffa6bdb5902984586259fab80be0460e9af3391f2a3212a1e4f350e060f988781e6ab2254e76c972e5611151fa501607d1d342667253d21e9ca113f2b87d823a55e70d4f5899e0ba8121477dded3d3b858438c4d0486a0c9846eb05b737a734ba37cdfdaaca8a4a38f2bd1c1ed0b4583b96c2fd2d1675991b4a151470811b4f4bfbad46ddbaa0e1fa28a81a3801e8c211137db822fb5a07344dc719b13e50562bd1e3a391a7747709db2445543f7412fd9c3011141d9ad4f05182593e6e75033764395fa8be80039cb47ed5d750f62836312e7b23152f69a65e41a9782d841b3c48719403e98bd8e72c824083275a29a53d681dc25b7df6c60cb0c4c74feab1d7b1edc76c09a1fe4da1acf9979d3c200233b082f66710725867ef6418e866cd93d26c7fd"
data, err := CiphertextAdd(c1, c2)
assert.Nil(t, err)
assert.Equal(t, c3, data)
}
......@@ -2,21 +2,254 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package sm2 带证书交易的签名
package sm2
import (
"bytes"
"crypto/elliptic"
"errors"
"fmt"
"math/big"
"github.com/33cn/chain33/types"
pkt "github.com/33cn/plugin/plugin/dapp/cert/types"
"github.com/33cn/chain33/common/crypto"
"github.com/33cn/chain33/system/crypto/sm2"
"github.com/tjfoc/gmsm/sm2"
)
//const
const (
SM2PrivateKeyLength = 32
SM2PublicKeyLength = 65
SM2PublicKeyCompressed = 33
)
type sm2Driver struct {
sm2.Driver
//Driver 驱动
type Driver struct{}
//GenKey 生成私钥
func (d Driver) GenKey() (crypto.PrivKey, error) {
privKeyBytes := [SM2PrivateKeyLength]byte{}
copy(privKeyBytes[:], crypto.CRandBytes(SM2PrivateKeyLength))
priv, _ := privKeyFromBytes(sm2.P256Sm2(), privKeyBytes[:])
copy(privKeyBytes[:], SerializePrivateKey(priv))
return PrivKeySM2(privKeyBytes), nil
}
//PrivKeyFromBytes 字节转为私钥
func (d Driver) PrivKeyFromBytes(b []byte) (privKey crypto.PrivKey, err error) {
if len(b) != SM2PrivateKeyLength {
return nil, errors.New("invalid priv key byte")
}
privKeyBytes := new([SM2PrivateKeyLength]byte)
copy(privKeyBytes[:], b[:SM2PrivateKeyLength])
priv, _ := privKeyFromBytes(sm2.P256Sm2(), privKeyBytes[:])
copy(privKeyBytes[:], SerializePrivateKey(priv))
return PrivKeySM2(*privKeyBytes), nil
}
//PubKeyFromBytes 字节转为公钥
func (d Driver) PubKeyFromBytes(b []byte) (pubKey crypto.PubKey, err error) {
if len(b) != SM2PublicKeyLength && len(b) != SM2PublicKeyCompressed {
return nil, errors.New("invalid pub key byte")
}
pubKeyBytes := new([SM2PublicKeyLength]byte)
copy(pubKeyBytes[:], b[:])
return PubKeySM2(*pubKeyBytes), nil
}
//SignatureFromBytes 字节转为签名
func (d Driver) SignatureFromBytes(b []byte) (sig crypto.Signature, err error) {
var certSignature pkt.CertSignature
err = types.Decode(b, &certSignature)
if err != nil {
return SignatureSM2(b), nil
}
return &SignatureS{
Signature: SignatureSM2(certSignature.Signature),
uid: certSignature.Uid,
}, nil
}
//PrivKeySM2 私钥
type PrivKeySM2 [SM2PrivateKeyLength]byte
//Bytes 字节格式
func (privKey PrivKeySM2) Bytes() []byte {
s := make([]byte, SM2PrivateKeyLength)
copy(s, privKey[:])
return s
}
//Sign 签名
func (privKey PrivKeySM2) Sign(msg []byte) crypto.Signature {
priv, _ := privKeyFromBytes(sm2.P256Sm2(), privKey[:])
r, s, err := sm2.Sm2Sign(priv, msg, nil)
if err != nil {
return nil
}
//sm2不需要LowS转换
//s = ToLowS(pub, s)
return SignatureSM2(Serialize(r, s))
}
//PubKey 私钥生成公钥
func (privKey PrivKeySM2) PubKey() crypto.PubKey {
_, pub := privKeyFromBytes(sm2.P256Sm2(), privKey[:])
var pubSM2 PubKeySM2
copy(pubSM2[:], sm2.Compress(pub))
return pubSM2
}
//Equals 公钥
func (privKey PrivKeySM2) Equals(other crypto.PrivKey) bool {
if otherSecp, ok := other.(PrivKeySM2); ok {
return bytes.Equal(privKey[:], otherSecp[:])
}
return false
}
func (privKey PrivKeySM2) String() string {
return fmt.Sprintf("PrivKeySM2{*****}")
}
//PubKeySM2 公钥
type PubKeySM2 [SM2PublicKeyLength]byte
//Bytes 字节格式
func (pubKey PubKeySM2) Bytes() []byte {
length := SM2PublicKeyLength
if pubKey.isCompressed() {
length = SM2PublicKeyCompressed
}
s := make([]byte, length)
copy(s, pubKey[0:length])
return s
}
func (pubKey PubKeySM2) isCompressed() bool {
return pubKey[0] != pubkeyUncompressed
}
//VerifyBytes 验证字节
func (pubKey PubKeySM2) VerifyBytes(msg []byte, sig crypto.Signature) bool {
var uid []byte
if wrap, ok := sig.(*SignatureS); ok {
sig = wrap.Signature
uid = wrap.uid
}
sigSM2, ok := sig.(SignatureSM2)
if !ok {
fmt.Printf("convert failed\n")
return false
}
var pub *sm2.PublicKey
if pubKey.isCompressed() {
pub = sm2.Decompress(pubKey[0:SM2PublicKeyCompressed])
} else {
var err error
pub, err = parsePubKey(pubKey[:], sm2.P256Sm2())
if err != nil {
fmt.Printf("parse pubkey failed\n")
return false
}
}
r, s, err := Deserialize(sigSM2)
if err != nil {
fmt.Printf("unmarshal sign failed")
return false
}
//国密签名算法和ecdsa不一样,-s验签不通过,所以不需要LowS检查
//fmt.Printf("verify:%x, r:%d, s:%d\n", crypto.Sm3Hash(msg), r, s)
//lowS := IsLowS(s)
//if !lowS {
// fmt.Printf("lowS check failed")
// return false
//}
return sm2.Sm2Verify(pub, msg, uid, r, s)
}
func (pubKey PubKeySM2) String() string {
return fmt.Sprintf("PubKeySM2{%X}", pubKey[:])
}
//KeyString Must return the full bytes in hex.
// Used for map keying, etc.
func (pubKey PubKeySM2) KeyString() string {
return fmt.Sprintf("%X", pubKey[:])
}
//Equals 相等
func (pubKey PubKeySM2) Equals(other crypto.PubKey) bool {
if otherSecp, ok := other.(PubKeySM2); ok {
return bytes.Equal(pubKey[:], otherSecp[:])
}
return false
}
//SignatureSM2 签名
type SignatureSM2 []byte
//SignatureS 签名
type SignatureS struct {
crypto.Signature
uid []byte
}
//Bytes 字节格式
func (sig SignatureSM2) Bytes() []byte {
s := make([]byte, len(sig))
copy(s, sig[:])
return s
}
//IsZero 是否为0
func (sig SignatureSM2) IsZero() bool { return len(sig) == 0 }
func (sig SignatureSM2) String() string {
fingerprint := make([]byte, len(sig[:]))
copy(fingerprint, sig[:])
return fmt.Sprintf("/%X.../", fingerprint)
}
const name = "auth_sm2"
const id = 258
//Equals 相等
func (sig SignatureSM2) Equals(other crypto.Signature) bool {
if otherEd, ok := other.(SignatureSM2); ok {
return bytes.Equal(sig[:], otherEd[:])
}
return false
}
//const
const (
Name = "auth_sm2"
ID = 258
)
func init() {
crypto.Register(name, &sm2Driver{}, false)
crypto.RegisterType(name, id)
crypto.Register(Name, &Driver{}, false)
crypto.RegisterType(Name, ID)
}
func privKeyFromBytes(curve elliptic.Curve, pk []byte) (*sm2.PrivateKey, *sm2.PublicKey) {
x, y := curve.ScalarBaseMult(pk)
priv := &sm2.PrivateKey{
PublicKey: sm2.PublicKey{
Curve: curve,
X: x,
Y: y,
},
D: new(big.Int).SetBytes(pk),
}
return priv, &priv.PublicKey
}
// 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 sm2
import (
"crypto/elliptic"
"errors"
"fmt"
"math/big"
"github.com/btcsuite/btcd/btcec"
"github.com/tjfoc/gmsm/sm2"
)
const (
pubkeyUncompressed byte = 0x4 // x coord + y coord
)
func canonicalizeInt(val *big.Int) []byte {
b := val.Bytes()
if len(b) == 0 {
b = []byte{0x00}
}
if b[0]&0x80 != 0 {
paddedBytes := make([]byte, len(b)+1)
copy(paddedBytes[1:], b)
b = paddedBytes
}
return b
}
//Serialize 序列化
func Serialize(r, s *big.Int) []byte {
rb := canonicalizeInt(r)
sb := canonicalizeInt(s)
length := 6 + len(rb) + len(sb)
b := make([]byte, length)
b[0] = 0x30
b[1] = byte(length - 2)
b[2] = 0x02
b[3] = byte(len(rb))
offset := copy(b[4:], rb) + 4
b[offset] = 0x02
b[offset+1] = byte(len(sb))
copy(b[offset+2:], sb)
return b
}
//Deserialize 反序列化
func Deserialize(sigStr []byte) (*big.Int, *big.Int, error) {
sig, err := btcec.ParseDERSignature(sigStr, sm2.P256Sm2())
if err != nil {
return nil, nil, err
}
return sig.R, sig.S, nil
}
func parsePubKey(pubKeyStr []byte, curve elliptic.Curve) (key *sm2.PublicKey, err error) {
pubkey := sm2.PublicKey{}
pubkey.Curve = curve
if len(pubKeyStr) == 0 {
return nil, errors.New("pubkey string is empty")
}
pubkey.X = new(big.Int).SetBytes(pubKeyStr[1:33])
pubkey.Y = new(big.Int).SetBytes(pubKeyStr[33:])
if pubkey.X.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey X parameter is >= to P")
}
if pubkey.Y.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey Y parameter is >= to P")
}
if !pubkey.Curve.IsOnCurve(pubkey.X, pubkey.Y) {
return nil, fmt.Errorf("pubkey isn't on secp256k1 curve")
}
return &pubkey, nil
}
//SerializePublicKey 公钥序列化
func SerializePublicKey(p *sm2.PublicKey, isCompress bool) []byte {
if isCompress {
return sm2.Compress(p)
}
b := make([]byte, 0, SM2PublicKeyLength)
b = append(b, pubkeyUncompressed)
b = paddedAppend(32, b, p.X.Bytes())
return paddedAppend(32, b, p.Y.Bytes())
}
//SerializePrivateKey 私钥序列化
func SerializePrivateKey(p *sm2.PrivateKey) []byte {
b := make([]byte, 0, SM2PrivateKeyLength)
return paddedAppend(SM2PrivateKeyLength, b, p.D.Bytes())
}
func paddedAppend(size uint, dst, src []byte) []byte {
for i := 0; i < int(size)-len(src); i++ {
dst = append(dst, 0)
}
return append(dst, src...)
}
......@@ -265,6 +265,12 @@ func (auth *Authority) Validate(signature *types.Signature) error {
return nil
}
// GetSnFromSig 解析证书序列号
func (auth *Authority) GetSnFromByte(signature *types.Signature) ([]byte, error) {
return auth.validator.GetCertSnFromSignature(signature.Signature)
}
// ToHistoryCertStore 历史数据转成store可存储的历史数据
func (certdata *HistoryCertData) ToHistoryCertStore(store *types.HistoryCertStore) {
if store == nil {
......
......@@ -59,7 +59,7 @@ var SIGNTYPE = ct.AuthSM2
func signtx(tx *types.Transaction, priv crypto.PrivKey, cert []byte) {
tx.Sign(int32(SIGNTYPE), priv)
tx.Signature.Signature, _ = utils.EncodeCertToSignature(tx.Signature.Signature, cert)
tx.Signature.Signature = utils.EncodeCertToSignature(tx.Signature.Signature, cert, nil)
}
func signtxs(priv crypto.PrivKey, cert []byte) {
......
......@@ -162,7 +162,7 @@ func (validator *ecdsaValidator) Validate(certByte []byte, pubKey []byte) error
return fmt.Errorf("Could not obtain certification chain, err %s", err)
}
err = validator.validateCertAgainstChain(cert, validationChain)
err = validator.validateCertAgainstChain(cert.SerialNumber, validationChain)
if err != nil {
return fmt.Errorf("Could not validate identity against certification chain, err %s", err)
}
......@@ -360,10 +360,10 @@ func (validator *ecdsaValidator) validateCAIdentity(cert *x509.Certificate) erro
return nil
}
return validator.validateCertAgainstChain(cert, validationChain)
return validator.validateCertAgainstChain(cert.SerialNumber, validationChain)
}
func (validator *ecdsaValidator) validateCertAgainstChain(cert *x509.Certificate, validationChain []*x509.Certificate) error {
func (validator *ecdsaValidator) validateCertAgainstChain(serialNumber *big.Int, validationChain []*x509.Certificate) error {
SKI, err := getSubjectKeyIdentifierFromCert(validationChain[1])
if err != nil {
return fmt.Errorf("Could not obtain Subject Key Identifier for signer cert, err %s", err)
......@@ -377,7 +377,7 @@ func (validator *ecdsaValidator) validateCertAgainstChain(cert *x509.Certificate
if bytes.Equal(aki, SKI) {
for _, rc := range crl.TBSCertList.RevokedCertificates {
if rc.SerialNumber.Cmp(cert.SerialNumber) == 0 {
if rc.SerialNumber.Cmp(serialNumber) == 0 {
err = validationChain[1].CheckCRLSignature(crl)
if err != nil {
authLogger.Warn("Invalid signature over the identified CRL, error %s", err)
......@@ -405,16 +405,31 @@ func (validator *ecdsaValidator) getValidityOptsForCert(cert *x509.Certificate)
}
func (validator *ecdsaValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
cert, _, err := utils.DecodeCertFromSignature(signature)
certSign, err := utils.DecodeCertFromSignature(signature)
if err != nil {
authLogger.Error(fmt.Sprintf("unmashal certificate from signature failed. %s", err.Error()))
return nil, err
}
if len(cert) == 0 {
if len(certSign.Cert) == 0 {
authLogger.Error("cert can not be null")
return nil, types.ErrInvalidParam
}
return cert, nil
return certSign.Cert, nil
}
func (validator *ecdsaValidator) GetCertSnFromSignature(signature []byte) ([]byte, error) {
certByte, err := validator.GetCertFromSignature(signature)
if err != nil {
authLogger.Error(fmt.Sprintf("GetCertSnFromSignature from signature failed. %s", err.Error()))
return nil, err
}
cert, err := validator.getCertFromPem(certByte)
if err != nil {
return nil, fmt.Errorf("ParseCertificate failed %s", err)
}
return cert.SerialNumber.Bytes(), nil
}
......@@ -12,6 +12,7 @@ import (
"encoding/pem"
"errors"
"fmt"
"math/big"
"reflect"
"time"
......@@ -100,7 +101,7 @@ func (validator *gmValidator) Validate(certByte []byte, pubKey []byte) error {
return fmt.Errorf("Could not obtain certification chain, err %s", err)
}
err = validator.validateCertAgainstChain(cert, validationChain)
err = validator.validateCertAgainstChain(cert.SerialNumber, validationChain)
if err != nil {
return fmt.Errorf("Could not validate identity against certification chain, err %s", err)
}
......@@ -292,10 +293,10 @@ func (validator *gmValidator) validateCAIdentity(cert *sm2.Certificate) error {
return nil
}
return validator.validateCertAgainstChain(cert, validationChain)
return validator.validateCertAgainstChain(cert.SerialNumber, validationChain)
}
func (validator *gmValidator) validateCertAgainstChain(cert *sm2.Certificate, validationChain []*sm2.Certificate) error {
func (validator *gmValidator) validateCertAgainstChain(serialNumber *big.Int, validationChain []*sm2.Certificate) error {
SKI, err := getSubjectKeyIdentifierFromSm2Cert(validationChain[1])
if err != nil {
return fmt.Errorf("Could not obtain Subject Key Identifier for signer cert, err %s", err)
......@@ -309,7 +310,7 @@ func (validator *gmValidator) validateCertAgainstChain(cert *sm2.Certificate, va
if bytes.Equal(aki, SKI) {
for _, rc := range crl.TBSCertList.RevokedCertificates {
if rc.SerialNumber.Cmp(cert.SerialNumber) == 0 {
if rc.SerialNumber.Cmp(serialNumber) == 0 {
err = validationChain[1].CheckCRLSignature(crl)
if err != nil {
authLogger.Warn(fmt.Sprintf("Invalid signature over the identified CRL, error %s", err))
......@@ -339,16 +340,31 @@ func (validator *gmValidator) getValidityOptsForCert(cert *sm2.Certificate) sm2.
func (validator *gmValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
// 从proto中解码signature
cert, _, err := utils.DecodeCertFromSignature(signature)
cert, err := utils.DecodeCertFromSignature(signature)
if err != nil {
authLogger.Error(fmt.Sprintf("unmashal certificate from signature failed. %s", err.Error()))
return nil, err
}
if len(cert) == 0 {
if len(cert.Cert) == 0 {
authLogger.Error("cert can not be null")
return nil, types.ErrInvalidParam
}
return cert, nil
return cert.Cert, nil
}
func (validator *gmValidator) GetCertSnFromSignature(signature []byte) ([]byte, error) {
certByte, err := validator.GetCertFromSignature(signature)
if err != nil {
authLogger.Error(fmt.Sprintf("GetCertSnFromSignature from signature failed. %s", err.Error()))
return nil, err
}
cert, err := validator.getCertFromPem(certByte)
if err != nil {
return nil, fmt.Errorf("ParseCertificate failed %s", err)
}
return cert.SerialNumber.Bytes(), nil
}
......@@ -23,3 +23,7 @@ func (validator *noneValidator) Validate(certByte []byte, pubKey []byte) error {
func (validator *noneValidator) GetCertFromSignature(signature []byte) ([]byte, error) {
return []byte(""), nil
}
func (validator *noneValidator) GetCertSnFromSignature(signature []byte) ([]byte, error) {
return []byte(""), nil
}
......@@ -11,6 +11,8 @@ type Validator interface {
Validate(cert []byte, pubKey []byte) error
GetCertFromSignature(signature []byte) ([]byte, error)
GetCertSnFromSignature(signature []byte) ([]byte, error)
}
// AuthConfig 校验器配置
......
-----BEGIN CERTIFICATE-----
MIIB6zCCAZGgAwIBAgIQVq9SxucwdINw2WUMlNFpdjAKBggqgRzPVQGDdTBHMQsw
MIIB7DCCAZGgAwIBAgIQETH0EMzvdWOEEg3FoAe/iDAKBggqgRzPVQGDdTBHMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwNjE4MDMxNDQ2WhcNMzAwNjE2MDMx
NDQ2WjBHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwODE0MDkyNTIwWhcNMzAwODEyMDky
NTIwWjBHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
BxMNU2FuIEZyYW5jaXNjbzELMAkGA1UEAxMCY2EwWTATBgcqhkjOPQIBBggqgRzP
VQGCLQNCAARACzXYM8dLleVhjAwyljePO1Vltf2YL2xGKCLAB1/YITkM4q3GVE8D
LZxsydaG0zncKUswQA97HM6F1qarbFuvo18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYD
VR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCDpAuHxKpzW
gxCIZxodcdzpHpzKFhlEJARmhKOPuN1yaTAKBggqgRzPVQGDdQNIADBFAiEAowXR
RYYCWcBT0gVSbHk7k+aJzG3uRdORTbbvmLgbG2QCIF3e0/m0aNRlvF6gPxBJ+JBR
R0sbv9eyrSEFMwx/ZyGJ
VQGCLQNCAAQlKmH6RVHN/nBE4qR+uF7lHmlc62jQA4kpoAwtJFRiFbczZx/KNDaD
9+USLAo9ecxcdOKR4lIcuT7jvKX6tXQ7o18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYD
VR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCC8fKlLiayf
+80blLEiRIzTyY7uYDUpP5K2RtOmfY0NKjAKBggqgRzPVQGDdQNJADBGAiEA8vh+
3joELxPxq0n1h07XFGeEnmpxutVoIocuky2HkF4CIQDnWIavlpJOq3tU76cmn3ur
KQeyi9GM7Uoi25S1QIxu9A==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg86AAL0bRgFW6RhFX
no7CVphI1U2csfrjwPuYn3FXaF2gCgYIKoEcz1UBgi2hRANCAASR8Yb//+y/GMLy
D36FLLO80oxUPtD6AtVoh9UIuC1b0QzA4+zkUDUk3zwdZ1pMZZKGZ48vE6KtAcFB
uqU7L784
-----END PRIVATE KEY-----
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg4Ork9oT6d6CRxg0f
EbHlr5eQPUcHWniEgRhDCi2dA/GgCgYIKoEcz1UBgi2hRANCAAQqXuEWh+sW/YtP
FlHmxiFhYi0o3Tb8He9NAaJ6uKe+OF5/eXa+VmRrKKGeE+dG8LrMiJ5+AlIj+ryd
blX5UKZ8
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIB4zCCAYmgAwIBAgIQdKBE3pdDBMaadMbZ30K7aTAKBggqgRzPVQGDdTBHMQsw
MIIB4zCCAYmgAwIBAgIQVs0txvOG+iVu/oISaV2KyzAKBggqgRzPVQGDdTBHMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwNjE4MDMxNDQ2WhcNMzAwNjE2MDMx
NDQ2WjBRMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwODE0MDkyNTIwWhcNMzAwODEyMDky
NTIwWjBRMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
BxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEAwwMVXNlckBDaGFpbjMzMFkwEwYHKoZI
zj0CAQYIKoEcz1UBgi0DQgAEkfGG///svxjC8g9+hSyzvNKMVD7Q+gLVaIfVCLgt
W9EMwOPs5FA1JN88HWdaTGWShmePLxOirQHBQbqlOy+/OKNNMEswDgYDVR0PAQH/
BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAg6QLh8Sqc1oMQiGcaHXHc
6R6cyhYZRCQEZoSjj7jdcmkwCgYIKoEcz1UBg3UDSAAwRQIgBSqSzSkoXopLR830
zMjWsMVlZERtUuW3+uYm+bCRjOgCIQDZf8dKxkBd155hiilDQ4RR4Xa8+ZGcPslm
Nm+S1txiqA==
zj0CAQYIKoEcz1UBgi0DQgAEKl7hFofrFv2LTxZR5sYhYWItKN02/B3vTQGierin
vjhef3l2vlZkayihnhPnRvC6zIiefgJSI/q8nW5V+VCmfKNNMEswDgYDVR0PAQH/
BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAgvHypS4msn/vNG5SxIkSM
08mO7mA1KT+StkbTpn2NDSowCgYIKoEcz1UBg3UDSAAwRQIhAND6HO/EN/dTeokX
mIvczQBcxPHTAq3+QIa2NHIC8bYvAiAZ5N4C4rwRJCqTw8J6As69MFO10XixWHxH
qrTJ9LnI3g==
-----END CERTIFICATE-----
......@@ -13,11 +13,10 @@ import (
"encoding/pem"
"math/big"
"encoding/asn1"
"github.com/33cn/chain33/types"
"fmt"
"github.com/33cn/chain33/common/crypto"
sm2_util "github.com/33cn/chain33/system/crypto/sm2"
ecdsa_util "github.com/33cn/plugin/plugin/crypto/ecdsa"
ty "github.com/33cn/plugin/plugin/dapp/cert/types"
......@@ -65,22 +64,23 @@ func GetPublicKeySKIFromCert(cert []byte, signType int) (string, error) {
}
// EncodeCertToSignature 证书编码进签名
func EncodeCertToSignature(signByte []byte, cert []byte) ([]byte, error) {
certSign := crypto.CertSignature{}
func EncodeCertToSignature(signByte []byte, cert []byte, uid []byte) []byte {
var certSign ty.CertSignature
certSign.Signature = append(certSign.Signature, signByte...)
certSign.Cert = append(certSign.Cert, cert...)
return asn1.Marshal(certSign)
certSign.Uid = append(certSign.Uid, uid...)
return types.Encode(&certSign)
}
// DecodeCertFromSignature 从签名中解码证书
func DecodeCertFromSignature(signByte []byte) ([]byte, []byte, error) {
var certSignature crypto.CertSignature
_, err := asn1.Unmarshal(signByte, &certSignature)
func DecodeCertFromSignature(signByte []byte) (*ty.CertSignature, error) {
var certSign ty.CertSignature
err := types.Decode(signByte, &certSign)
if err != nil {
return nil, nil, err
return nil, err
}
return certSignature.Cert, certSignature.Signature, nil
return &certSign, nil
}
// PrivKeyByteFromRaw pem结构转成byte类型私钥
......
......@@ -51,6 +51,7 @@ func newCert() drivers.Driver {
c := &Cert{}
c.SetChild(c)
c.SetIsFree(true)
c.SetExecutorType(types.LoadExecutorType(driverName))
return c
}
......
package executor
import (
"fmt"
"testing"
"time"
"github.com/33cn/chain33/account"
"github.com/33cn/chain33/client"
apimock "github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/common"
"github.com/33cn/chain33/common/address"
"github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
_ "github.com/33cn/chain33/system"
"github.com/33cn/chain33/system/dapp"
pty "github.com/33cn/chain33/system/dapp/manage/types"
"github.com/33cn/chain33/types"
"github.com/33cn/chain33/util"
_ "github.com/33cn/plugin/plugin/crypto/init"
"github.com/33cn/plugin/plugin/dapp/cert/authority"
"github.com/33cn/plugin/plugin/dapp/cert/authority/utils"
ct "github.com/33cn/plugin/plugin/dapp/cert/types"
pkt "github.com/33cn/plugin/plugin/dapp/collateralize/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
type execEnv struct {
blockTime int64
blockHeight int64
difficulty uint64
kvdb dbm.KVDB
api client.QueueProtocolAPI
db dbm.KV
execAddr string
cfg *types.Chain33Config
ldb dbm.DB
user *authority.User
}
var (
PrivKeyA = "0x6da92a632ab7deb67d38c0f6560bcfed28167998f6496db64c258d5e8393a81b" // 1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4
Nodes = [][]byte{
[]byte("1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"),
}
total = 100 * types.Coin
USERNAME = "User"
SIGNTYPE = ct.AuthSM2
transfer1 = &ct.CertAction{Value: &ct.CertAction_Normal{Normal: &ct.CertNormal{Key: "", Value: nil}}, Ty: ct.CertActionNormal}
tx1 = &types.Transaction{Execer: []byte("cert"), Payload: types.Encode(transfer1), Fee: 100000000, Expire: 0, To: dapp.ExecAddress("cert")}
transfer2 = &ct.CertAction{Value: &ct.CertAction_New{New: &ct.CertNew{Key: "", Value: nil}}, Ty: ct.CertActionNew}
tx2 = &types.Transaction{Execer: []byte("cert"), Payload: types.Encode(transfer2), Fee: 100000000, Expire: 0, To: dapp.ExecAddress("cert")}
transfer3 = &ct.CertAction{Value: &ct.CertAction_Update{Update: &ct.CertUpdate{Key: "", Value: nil}}, Ty: ct.CertActionUpdate}
tx3 = &types.Transaction{Execer: []byte("cert"), Payload: types.Encode(transfer3), Fee: 100000000, Expire: 0, To: dapp.ExecAddress("cert")}
)
func manageKeySet(key string, value string, db dbm.KV) {
var item types.ConfigItem
item.Key = key
item.Addr = value
item.Ty = pty.ConfigItemArrayConfig
emptyValue := &types.ArrayConfig{Value: make([]string, 0)}
arr := types.ConfigItem_Arr{Arr: emptyValue}
item.Value = &arr
item.GetArr().Value = append(item.GetArr().Value, value)
manageKey := types.ManageKey(key)
valueSave := types.Encode(&item)
db.Set([]byte(manageKey), valueSave)
}
func initEnv() (*execEnv, error) {
cfg := types.NewChain33Config(types.ReadFile("./test/chain33.toml"))
cfg.SetTitleOnlyForTest("chain33")
sub := cfg.GetSubConfig()
var subcfg ct.Authority
if sub.Exec["cert"] != nil {
types.MustDecode(sub.Exec["cert"], &subcfg)
}
Init(ct.CertX, cfg, sub.Exec["cert"])
userLoader := &authority.UserLoader{}
err := userLoader.Init(subcfg.CryptoPath, subcfg.SignType)
if err != nil {
fmt.Printf("Init user loader falied -> %v", err)
return nil, err
}
user, err := userLoader.Get(USERNAME)
if err != nil {
fmt.Printf("Get user failed")
return nil, err
}
_, ldb, kvdb := util.CreateTestDB()
accountA := types.Account{
Balance: total,
Frozen: 0,
Addr: string(Nodes[0]),
}
api := new(apimock.QueueProtocolAPI)
api.On("GetConfig", mock.Anything).Return(cfg, nil)
execAddr := dapp.ExecAddress(ct.CertX)
stateDB, _ := dbm.NewGoMemDB("1", "2", 100)
accA := account.NewCoinsAccount(cfg)
accA.SetDB(stateDB)
accA.SaveExecAccount(execAddr, &accountA)
manageKeySet(ct.AdminKey, accountA.Addr, stateDB)
return &execEnv{
blockTime: time.Now().Unix(),
blockHeight: cfg.GetDappFork(ct.CertX, "Enable"),
difficulty: 1539918074,
kvdb: kvdb,
api: api,
db: stateDB,
execAddr: execAddr,
cfg: cfg,
ldb: ldb,
user: user,
}, nil
}
func signCertTx(tx *types.Transaction, priv crypto.PrivKey, cert []byte) {
tx.Sign(int32(SIGNTYPE), priv)
tx.Signature.Signature = utils.EncodeCertToSignature(tx.Signature.Signature, cert, nil)
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
signType := types.SECP256K1
c, err := crypto.New(types.GetSignName(pkt.CollateralizeX, signType))
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 TestCert(t *testing.T) {
env, err := initEnv()
if err != nil {
panic(err)
}
signCertTx(tx1, env.user.Key, env.user.Cert)
// tx1
exec := newCert()
exec.SetAPI(env.api)
exec.SetStateDB(env.db)
assert.Equal(t, exec.GetCoinsAccount().LoadExecAccount(string(Nodes[0]), env.execAddr).GetBalance(), total)
exec.SetLocalDB(env.kvdb)
exec.SetEnv(env.blockHeight, env.blockTime, env.difficulty)
exec.SetEnv(env.blockHeight+1, env.blockTime+1, env.difficulty)
receipt, err := exec.Exec(tx1, int(1))
assert.Nil(t, err)
assert.NotNil(t, receipt)
t.Log(receipt)
for _, kv := range receipt.KV {
env.db.Set(kv.Key, kv.Value)
}
receiptData := &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err := exec.ExecLocal(tx1, receiptData, int(1))
assert.Nil(t, err)
assert.NotNil(t, set)
util.SaveKVList(env.ldb, set.KV)
addr := address.PubKeyToAddr(env.user.Key.PubKey().Bytes())
res, err := exec.Query("CertValidSNByAddr", types.Encode(&ct.ReqQueryValidCertSN{Addr: addr}))
assert.Nil(t, err)
assert.NotNil(t, res)
// tx2
signTx(tx2, PrivKeyA)
exec.SetEnv(env.blockHeight+1, env.blockTime+1, env.difficulty)
receipt, err = exec.Exec(tx2, int(1))
assert.Nil(t, err)
assert.NotNil(t, receipt)
t.Log(receipt)
for _, kv := range receipt.KV {
env.db.Set(kv.Key, kv.Value)
}
receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(tx2, receiptData, int(1))
assert.Nil(t, err)
assert.NotNil(t, set)
util.SaveKVList(env.ldb, set.KV)
// tx3
signTx(tx3, PrivKeyA)
exec.SetEnv(env.blockHeight+1, env.blockTime+1, env.difficulty)
receipt, err = exec.Exec(tx3, int(1))
assert.Nil(t, err)
assert.NotNil(t, receipt)
t.Log(receipt)
for _, kv := range receipt.KV {
env.db.Set(kv.Key, kv.Value)
}
receiptData = &types.ReceiptData{Ty: receipt.Ty, Logs: receipt.Logs}
set, err = exec.ExecLocal(tx3, receiptData, int(1))
assert.Nil(t, err)
assert.NotNil(t, set)
util.SaveKVList(env.ldb, set.KV)
}
package executor
import (
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/cert/authority"
ct "github.com/33cn/plugin/plugin/dapp/cert/types"
)
func CertUserStoreKey(addr string) (key []byte) {
key = append(key, []byte("mavl-"+ct.CertX+"-"+addr)...)
return key
}
func isAdminAddr(addr string, db dbm.KV) bool {
manageKey := types.ManageKey(ct.AdminKey)
data, err := db.Get([]byte(manageKey))
if err != nil {
clog.Error("getSuperAddr", "error", err)
return false
}
var item types.ConfigItem
err = types.Decode(data, &item)
if err != nil {
clog.Error("isSuperAddr", "Decode", data)
return false
}
for _, op := range item.GetArr().Value {
if op == addr {
return true
}
}
return false
}
func (c *Cert) Exec_New(payload *ct.CertNew, tx *types.Transaction, index int) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
var receipt *types.Receipt
if !isAdminAddr(tx.From(), c.GetStateDB()) {
clog.Error("Exec_New", "error", "Exec_New need admin address")
return nil, ct.ErrPermissionDeny
}
receipt = &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}
return receipt, nil
}
func (c *Cert) Exec_Update(payload *ct.CertUpdate, tx *types.Transaction, index int) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
var receipt *types.Receipt
if !isAdminAddr(tx.From(), c.GetStateDB()) {
clog.Error("Exec_Update", "error", "Exec_Update need admin address")
return nil, ct.ErrPermissionDeny
}
receipt = &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}
return receipt, nil
}
func (c *Cert) Exec_Normal(payload *ct.CertNormal, tx *types.Transaction, index int) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
var receipt *types.Receipt
// 从proto中解码signature
sn, err := authority.Author.GetSnFromByte(tx.Signature)
if err != nil {
clog.Error("Exec_Normal get sn from signature failed", "error", err)
return nil, err
}
storekv := &types.KeyValue{Key: CertUserStoreKey(tx.From()), Value: sn}
c.GetStateDB().Set(storekv.Key, storekv.Value)
kv = append(kv, storekv)
receipt = &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}
return receipt, nil
}
func (c *Cert) Query_CertValidSNByAddr(req *ct.ReqQueryValidCertSN) (types.Message, error) {
sn, err := c.GetStateDB().Get(CertUserStoreKey(req.Addr))
if err != nil {
clog.Error("Query_CertValidSNByAddr", "error", err)
return nil, err
}
return &ct.RepQueryValidCertSN{Sn: sn}, nil
}
-----BEGIN CERTIFICATE-----
MIIB7DCCAZGgAwIBAgIQETH0EMzvdWOEEg3FoAe/iDAKBggqgRzPVQGDdTBHMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwODE0MDkyNTIwWhcNMzAwODEyMDky
NTIwWjBHMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
BxMNU2FuIEZyYW5jaXNjbzELMAkGA1UEAxMCY2EwWTATBgcqhkjOPQIBBggqgRzP
VQGCLQNCAAQlKmH6RVHN/nBE4qR+uF7lHmlc62jQA4kpoAwtJFRiFbczZx/KNDaD
9+USLAo9ecxcdOKR4lIcuT7jvKX6tXQ7o18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYD
VR0lBAgwBgYEVR0lADAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCC8fKlLiayf
+80blLEiRIzTyY7uYDUpP5K2RtOmfY0NKjAKBggqgRzPVQGDdQNJADBGAiEA8vh+
3joELxPxq0n1h07XFGeEnmpxutVoIocuky2HkF4CIQDnWIavlpJOq3tU76cmn3ur
KQeyi9GM7Uoi25S1QIxu9A==
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg4Ork9oT6d6CRxg0f
EbHlr5eQPUcHWniEgRhDCi2dA/GgCgYIKoEcz1UBgi2hRANCAAQqXuEWh+sW/YtP
FlHmxiFhYi0o3Tb8He9NAaJ6uKe+OF5/eXa+VmRrKKGeE+dG8LrMiJ5+AlIj+ryd
blX5UKZ8
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIB4zCCAYmgAwIBAgIQVs0txvOG+iVu/oISaV2KyzAKBggqgRzPVQGDdTBHMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzELMAkGA1UEAxMCY2EwHhcNMjAwODE0MDkyNTIwWhcNMzAwODEyMDky
NTIwWjBRMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
BxMNU2FuIEZyYW5jaXNjbzEVMBMGA1UEAwwMVXNlckBDaGFpbjMzMFkwEwYHKoZI
zj0CAQYIKoEcz1UBgi0DQgAEKl7hFofrFv2LTxZR5sYhYWItKN02/B3vTQGierin
vjhef3l2vlZkayihnhPnRvC6zIiefgJSI/q8nW5V+VCmfKNNMEswDgYDVR0PAQH/
BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAgvHypS4msn/vNG5SxIkSM
08mO7mA1KT+StkbTpn2NDSowCgYIKoEcz1UBg3UDSAAwRQIhAND6HO/EN/dTeokX
mIvczQBcxPHTAq3+QIa2NHIC8bYvAiAZ5N4C4rwRJCqTw8J6As69MFO10XixWHxH
qrTJ9LnI3g==
-----END CERTIFICATE-----
Title="chain33"
TestNet=true
FixTime=false
version="6.3.0"
[log]
# 日志级别,支持debug(dbug)/info/warn/error(eror)/crit
loglevel = "debug"
logConsoleLevel = "info"
# 日志文件名,可带目录,所有生成的日志文件都放到此目录下
logFile = "logs/chain33.log"
# 单个日志文件的最大值(单位:兆)
maxFileSize = 300
# 最多保存的历史日志文件个数
maxBackups = 100
# 最多保存的历史日志消息(单位:天)
maxAge = 28
# 日志文件名是否使用本地事件(否则使用UTC时间)
localTime = true
# 历史日志文件是否压缩(压缩格式为gz)
compress = true
# 是否打印调用源文件和行号
callerFile = false
# 是否打印调用方法
callerFunction = false
[blockchain]
defCacheSize=128
maxFetchBlockNum=128
timeoutSeconds=5
batchBlockNum=128
driver="leveldb"
dbPath="datadir"
dbCache=64
isStrongConsistency=false
singleMode=true
batchsync=false
isRecordBlockSequence=true
isParaChain=false
enableTxQuickIndex=true
enableReExecLocal=true
[p2p]
# p2p类型
types=["dht", "gossip"]
# 是否启动P2P服务
enable=true
# 使用的数据库类型
driver="leveldb"
# 使用的数据库类型
dbPath="datadir/addrbook"
# 数据库缓存大小
dbCache=4
# GRPC请求日志文件
grpcLogFile="grpc33.log"
#waitPid 等待seed导入
waitPid=false
[p2p.sub.gossip]
seeds=[]
isSeed=false
serverStart=true
innerSeedEnable=true
useGithub=true
innerBounds=300
[p2p.sub.dht]
[rpc]
jrpcBindAddr="localhost:8801"
grpcBindAddr="localhost:8802"
whitelist=["127.0.0.1"]
jrpcFuncWhitelist=["*"]
grpcFuncWhitelist=["*"]
[mempool]
name="price"
poolCacheSize=10240
minTxFee=100000
maxTxNumPerAccount=100
maxTxFee=1000000000
isLevelFee=true
[mempool.sub.timeline]
poolCacheSize=10240
[mempool.sub.score]
poolCacheSize=10240
timeParam=1 #时间占价格比例
priceConstant=10 #手续费相对于时间的一个的常量,排队时手续费高1e3的分数~=快1h的分数
pricePower=1 #常量比例
[mempool.sub.price]
poolCacheSize=10240
[consensus]
name="solo"
minerstart=true
genesisBlockTime=1514533394
genesis="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
minerExecs=["ticket", "autonomy"]
[mver.consensus]
fundKeyAddr = "1BQXS6TxaYYG5mADaWij4AxhZZUTpw95a5"
powLimitBits="0x1f00ffff"
maxTxNumber = 1600 #160
[mver.consensus.ForkChainParamV1]
maxTxNumber = 1500
[mver.consensus.ForkTicketFundAddrV1]
fundKeyAddr = "1Ji3W12KGScCM7C2p8bg635sNkayDM8MGY"
[mver.consensus.ticket]
coinReward = 18
coinDevFund = 12
ticketPrice = 10000
retargetAdjustmentFactor = 4
futureBlockTime = 16
ticketFrozenTime = 5 #5s only for test
ticketWithdrawTime = 10 #10s only for test
ticketMinerWaitTime = 2 #2s only for test
targetTimespan=2304
targetTimePerBlock=16
[mver.consensus.ticket.ForkChainParamV1]
futureBlockTime = 15
ticketFrozenTime = 43200
ticketWithdrawTime = 172800
ticketMinerWaitTime = 7200
targetTimespan=2160
targetTimePerBlock=15
[mver.consensus.ticket.ForkChainParamV2]
coinReward = 5
coinDevFund = 3
targetTimespan=720
targetTimePerBlock=5
ticketPrice = 3000
[consensus.sub.ticket]
genesisBlockTime=1514533394
[[consensus.sub.ticket.genesis]]
minerAddr="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
returnAddr="14KEKbYtKKQm4wMthSK9J4La4nAiidGozt"
count=10000
[[consensus.sub.ticket.genesis]]
minerAddr="1PUiGcbsccfxW3zuvHXZBJfznziph5miAo"
returnAddr="1EbDHAXpoiewjPLX9uqoz38HsKqMXayZrF"
count=10000
[[consensus.sub.ticket.genesis]]
minerAddr="1EDnnePAZN48aC2hiTDzhkczfF39g1pZZX"
returnAddr="1KcCVZLSQYRUwE5EXTsAoQs9LuJW6xwfQa"
count=10000
[store]
name="kvmvccmavl"
driver="leveldb"
dbPath="datadir/mavltree"
dbCache=128
# store数据库版本
storedbVersion="2.0.0"
[store.sub.mavl]
enableMavlPrefix=false
enableMVCC=false
enableMavlPrune=false
pruneHeight=10000
# 是否使能mavl数据载入内存
enableMemTree=true
# 是否使能mavl叶子节点数据载入内存
enableMemVal=true
# 缓存close ticket数目,该缓存越大同步速度越快,最大设置到1500000
tkCloseCacheLen=100000
[store.sub.kvmvccmavl]
enableMVCCIter=true
enableMavlPrefix=false
enableMVCC=false
enableMavlPrune=false
pruneMavlHeight=10000
enableMVCCPrune=false
pruneMVCCHeight=10000
# 是否使能mavl数据载入内存
enableMemTree=true
# 是否使能mavl叶子节点数据载入内存
enableMemVal=true
# 缓存close ticket数目,该缓存越大同步速度越快,最大设置到1500000
tkCloseCacheLen=100000
# 该参数针对平行链,主链无需开启此功能
enableEmptyBlockHandle=false
[wallet]
minFee=100000
driver="leveldb"
dbPath="wallet"
dbCache=16
signType="secp256k1"
[wallet.sub.ticket]
minerdisable=false
minerwhitelist=["*"]
[wallet.sub.multisig]
rescanMultisigAddr=false
[exec]
isFree=false
minExecFee=100000
maxExecFee=1000000000
enableStat=false
enableMVCC=false
alias=["token1:token","token2:token","token3:token"]
[exec.sub.token]
saveTokenTxList=true
tokenApprs = [
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK",
"1LY8GFia5EiyoTodMLfkB5PHNNpXRqxhyB",
"1GCzJDS6HbgTQ2emade7mEJGGWFfA15pS9",
"1JYB8sxi4He5pZWHCd3Zi2nypQ4JMB6AxN",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"16ui7XJ1VLM7YXcNhWwWsWS6CRC3ZA2sJ1",
]
[exec.sub.cert]
# 是否启用证书验证和签名
enable=true
# 加密文件路径
cryptoPath="test/authdir/crypto"
# 带证书签名类型,支持"auth_ecdsa", "auth_sm2"
signType="auth_sm2"
[exec.sub.relay]
genesis="12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
[exec.sub.manage]
superManager=[
"1Bsg9j6gW83sShoee1fZAt9TkUjcrCgA9S",
"12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv",
"1Q8hGLfoGe63efeWa8fJ4Pnukhkngt6poK",
"16ui7XJ1VLM7YXcNhWwWsWS6CRC3ZA2sJ1",
]
[exec.sub.paracross]
nodeGroupFrozenCoins=0
#平行链共识停止后主链等待的高度
paraConsensusStopBlocks=30000
[exec.sub.autonomy]
total="16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp"
useBalance=false
#系统中所有的fork,默认用chain33的测试网络的
#但是我们可以替换
[fork.system]
ForkChainParamV1= 0
ForkCheckTxDup=0
ForkBlockHash= 1
ForkMinerTime= 0
ForkTransferExec=0
ForkExecKey=0
ForkTxGroup=0
ForkResetTx0=0
ForkWithdraw=0
ForkExecRollback=0
ForkCheckBlockTime=0
ForkTxHeight=0
ForkTxGroupPara=0
ForkChainParamV2=0
ForkMultiSignAddress=0
ForkStateDBSet=0
ForkLocalDBAccess=0
ForkBlockCheck=0
ForkBase58AddressCheck=0
#平行链上使能平行链执行器如user.p.x.coins执行器的注册,缺省为0,对已有的平行链需要设置一个fork高度
ForkEnableParaRegExec=0
ForkCacheDriver=0
ForkTicketFundAddrV1=-1 #fork6.3
#主链和平行链都使用同一个fork高度
ForkRootHash= 4500000
[fork.sub.cert]
Enable=0
[metrics]
#是否使能发送metrics数据的发送
enableMetrics=false
#数据保存模式
dataEmitMode="influxdb"
[metrics.sub.influxdb]
#以纳秒为单位的发送间隔
duration=1000000000
url="http://influxdb:8086"
database="chain33metrics"
username=""
password=""
namespace=""
\ No newline at end of file
......@@ -38,3 +38,17 @@ message Authority {
string cryptoPath = 2;
string signType = 3;
}
message CertSignature {
bytes signature = 1;
bytes cert = 2;
bytes uid = 3;
}
message ReqQueryValidCertSN {
string addr = 1;
}
message RepQueryValidCertSN {
bytes sn = 1;
}
\ No newline at end of file
......@@ -383,6 +383,139 @@ func (m *Authority) GetSignType() string {
return ""
}
type CertSignature struct {
Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"`
Cert []byte `protobuf:"bytes,2,opt,name=cert,proto3" json:"cert,omitempty"`
Uid []byte `protobuf:"bytes,3,opt,name=uid,proto3" json:"uid,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CertSignature) Reset() { *m = CertSignature{} }
func (m *CertSignature) String() string { return proto.CompactTextString(m) }
func (*CertSignature) ProtoMessage() {}
func (*CertSignature) Descriptor() ([]byte, []int) {
return fileDescriptor_a142e29cbef9b1cf, []int{6}
}
func (m *CertSignature) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CertSignature.Unmarshal(m, b)
}
func (m *CertSignature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CertSignature.Marshal(b, m, deterministic)
}
func (m *CertSignature) XXX_Merge(src proto.Message) {
xxx_messageInfo_CertSignature.Merge(m, src)
}
func (m *CertSignature) XXX_Size() int {
return xxx_messageInfo_CertSignature.Size(m)
}
func (m *CertSignature) XXX_DiscardUnknown() {
xxx_messageInfo_CertSignature.DiscardUnknown(m)
}
var xxx_messageInfo_CertSignature proto.InternalMessageInfo
func (m *CertSignature) GetSignature() []byte {
if m != nil {
return m.Signature
}
return nil
}
func (m *CertSignature) GetCert() []byte {
if m != nil {
return m.Cert
}
return nil
}
func (m *CertSignature) GetUid() []byte {
if m != nil {
return m.Uid
}
return nil
}
type ReqQueryValidCertSN struct {
Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *ReqQueryValidCertSN) Reset() { *m = ReqQueryValidCertSN{} }
func (m *ReqQueryValidCertSN) String() string { return proto.CompactTextString(m) }
func (*ReqQueryValidCertSN) ProtoMessage() {}
func (*ReqQueryValidCertSN) Descriptor() ([]byte, []int) {
return fileDescriptor_a142e29cbef9b1cf, []int{7}
}
func (m *ReqQueryValidCertSN) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_ReqQueryValidCertSN.Unmarshal(m, b)
}
func (m *ReqQueryValidCertSN) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_ReqQueryValidCertSN.Marshal(b, m, deterministic)
}
func (m *ReqQueryValidCertSN) XXX_Merge(src proto.Message) {
xxx_messageInfo_ReqQueryValidCertSN.Merge(m, src)
}
func (m *ReqQueryValidCertSN) XXX_Size() int {
return xxx_messageInfo_ReqQueryValidCertSN.Size(m)
}
func (m *ReqQueryValidCertSN) XXX_DiscardUnknown() {
xxx_messageInfo_ReqQueryValidCertSN.DiscardUnknown(m)
}
var xxx_messageInfo_ReqQueryValidCertSN proto.InternalMessageInfo
func (m *ReqQueryValidCertSN) GetAddr() string {
if m != nil {
return m.Addr
}
return ""
}
type RepQueryValidCertSN struct {
Sn []byte `protobuf:"bytes,1,opt,name=sn,proto3" json:"sn,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *RepQueryValidCertSN) Reset() { *m = RepQueryValidCertSN{} }
func (m *RepQueryValidCertSN) String() string { return proto.CompactTextString(m) }
func (*RepQueryValidCertSN) ProtoMessage() {}
func (*RepQueryValidCertSN) Descriptor() ([]byte, []int) {
return fileDescriptor_a142e29cbef9b1cf, []int{8}
}
func (m *RepQueryValidCertSN) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_RepQueryValidCertSN.Unmarshal(m, b)
}
func (m *RepQueryValidCertSN) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_RepQueryValidCertSN.Marshal(b, m, deterministic)
}
func (m *RepQueryValidCertSN) XXX_Merge(src proto.Message) {
xxx_messageInfo_RepQueryValidCertSN.Merge(m, src)
}
func (m *RepQueryValidCertSN) XXX_Size() int {
return xxx_messageInfo_RepQueryValidCertSN.Size(m)
}
func (m *RepQueryValidCertSN) XXX_DiscardUnknown() {
xxx_messageInfo_RepQueryValidCertSN.DiscardUnknown(m)
}
var xxx_messageInfo_RepQueryValidCertSN proto.InternalMessageInfo
func (m *RepQueryValidCertSN) GetSn() []byte {
if m != nil {
return m.Sn
}
return nil
}
func init() {
proto.RegisterType((*Cert)(nil), "types.Cert")
proto.RegisterType((*CertAction)(nil), "types.CertAction")
......@@ -390,6 +523,9 @@ func init() {
proto.RegisterType((*CertUpdate)(nil), "types.CertUpdate")
proto.RegisterType((*CertNormal)(nil), "types.CertNormal")
proto.RegisterType((*Authority)(nil), "types.Authority")
proto.RegisterType((*CertSignature)(nil), "types.CertSignature")
proto.RegisterType((*ReqQueryValidCertSN)(nil), "types.ReqQueryValidCertSN")
proto.RegisterType((*RepQueryValidCertSN)(nil), "types.RepQueryValidCertSN")
}
func init() {
......@@ -397,24 +533,29 @@ func init() {
}
var fileDescriptor_a142e29cbef9b1cf = []byte{
// 300 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0xcd, 0x4a, 0xf3, 0x40,
0x14, 0xed, 0x24, 0xfd, 0xbd, 0xfd, 0x28, 0x9f, 0x83, 0x48, 0x70, 0x21, 0x25, 0xab, 0x82, 0x10,
0xb0, 0xfa, 0x02, 0xd5, 0x4d, 0xdd, 0x14, 0x19, 0xea, 0x5a, 0xa6, 0xe9, 0xd5, 0x06, 0xd3, 0x4c,
0x98, 0xde, 0x58, 0xe6, 0x79, 0x7c, 0x51, 0x99, 0x1f, 0x25, 0x82, 0x0b, 0xdd, 0xe5, 0xdc, 0x73,
0x4e, 0xee, 0x39, 0xdc, 0x01, 0xc8, 0x51, 0x53, 0x56, 0x6b, 0x45, 0x8a, 0xf7, 0xc8, 0xd4, 0x78,
0x48, 0x9f, 0xa1, 0x7b, 0x87, 0x9a, 0xf8, 0x19, 0xf4, 0x2d, 0x79, 0xbf, 0x4d, 0xd8, 0x94, 0xcd,
0xfe, 0x89, 0x80, 0xf8, 0x05, 0x40, 0xae, 0x51, 0x12, 0xae, 0x8b, 0x3d, 0x26, 0xd1, 0x94, 0xcd,
0x62, 0xd1, 0x9a, 0xf0, 0xff, 0x10, 0xbf, 0xa2, 0x49, 0xe2, 0x29, 0x9b, 0x8d, 0x84, 0xfd, 0xe4,
0xa7, 0xd0, 0x7b, 0x93, 0x65, 0x83, 0x49, 0xd7, 0xfd, 0xc8, 0x83, 0xf4, 0x9d, 0x01, 0xd8, 0x45,
0x8b, 0x9c, 0x0a, 0x55, 0xf1, 0x14, 0xe2, 0x0a, 0x8f, 0x6e, 0xd7, 0x78, 0x3e, 0xc9, 0x5c, 0x96,
0xcc, 0xf2, 0x2b, 0x3c, 0x2e, 0x3b, 0xc2, 0x92, 0xfc, 0x12, 0xfa, 0x4d, 0xbd, 0x95, 0xe4, 0xd7,
0x8e, 0xe7, 0x27, 0x2d, 0xd9, 0xa3, 0x23, 0x96, 0x1d, 0x11, 0x24, 0x56, 0x5c, 0x29, 0xbd, 0x97,
0xa5, 0x8b, 0xf2, 0x5d, 0xbc, 0x72, 0x84, 0x15, 0x7b, 0x09, 0x9f, 0x40, 0x44, 0xc6, 0xe5, 0xeb,
0x89, 0x88, 0xcc, 0xed, 0x20, 0x44, 0x4e, 0xaf, 0x60, 0x10, 0x42, 0x7c, 0x16, 0x63, 0x3f, 0x14,
0x8b, 0xda, 0xc5, 0x6e, 0x7c, 0x2f, 0x1f, 0xe8, 0xaf, 0x2e, 0x9f, 0xec, 0xd7, 0xae, 0x27, 0x18,
0x2d, 0x1a, 0xda, 0x29, 0x5d, 0x90, 0xb1, 0x17, 0xc3, 0x4a, 0x6e, 0x4a, 0x74, 0xbe, 0xa1, 0x08,
0xc8, 0x5f, 0xcc, 0xd4, 0xa4, 0x1e, 0x24, 0xed, 0x9c, 0x7f, 0x24, 0x5a, 0x13, 0x7e, 0x0e, 0xc3,
0x43, 0xf1, 0x52, 0xad, 0x4d, 0x8d, 0xe1, 0x6c, 0x5f, 0x78, 0xd3, 0x77, 0x6f, 0xe3, 0xfa, 0x23,
0x00, 0x00, 0xff, 0xff, 0x1d, 0xbc, 0xa5, 0x33, 0x29, 0x02, 0x00, 0x00,
// 380 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x5d, 0x4b, 0xeb, 0x40,
0x10, 0x6d, 0x92, 0x7e, 0x65, 0xda, 0x5b, 0xee, 0xdd, 0x2b, 0x12, 0x44, 0xa4, 0x04, 0x84, 0x8a,
0x50, 0xb0, 0xfa, 0x07, 0xaa, 0x2f, 0xf5, 0xa5, 0xe8, 0xb6, 0xfa, 0x2a, 0xdb, 0x66, 0x6c, 0x83,
0xe9, 0x26, 0x6e, 0x36, 0x96, 0xfd, 0x3d, 0xfe, 0x51, 0xd9, 0xcd, 0x56, 0x23, 0xfa, 0xa0, 0x6f,
0x33, 0x3b, 0xe7, 0xec, 0x39, 0x87, 0x19, 0x80, 0x25, 0x0a, 0x39, 0xcc, 0x44, 0x2a, 0x53, 0xd2,
0x90, 0x2a, 0xc3, 0x3c, 0x7c, 0x84, 0xfa, 0x15, 0x0a, 0x49, 0xf6, 0xa1, 0xa9, 0x87, 0xd7, 0x51,
0xe0, 0xf4, 0x9d, 0x41, 0x97, 0xda, 0x8e, 0x1c, 0x01, 0x2c, 0x05, 0x32, 0x89, 0xf3, 0x78, 0x83,
0x81, 0xdb, 0x77, 0x06, 0x1e, 0xad, 0xbc, 0x90, 0xbf, 0xe0, 0x3d, 0xa1, 0x0a, 0xbc, 0xbe, 0x33,
0xf0, 0xa9, 0x2e, 0xc9, 0x1e, 0x34, 0x5e, 0x58, 0x52, 0x60, 0x50, 0x37, 0x1f, 0x95, 0x4d, 0xf8,
0xea, 0x00, 0x68, 0xa1, 0xf1, 0x52, 0xc6, 0x29, 0x27, 0x21, 0x78, 0x1c, 0xb7, 0x46, 0xab, 0x33,
0xea, 0x0d, 0x8d, 0x97, 0xa1, 0x9e, 0x4f, 0x71, 0x3b, 0xa9, 0x51, 0x3d, 0x24, 0xa7, 0xd0, 0x2c,
0xb2, 0x88, 0xc9, 0x52, 0xb6, 0x33, 0xfa, 0x57, 0x81, 0xdd, 0x99, 0xc1, 0xa4, 0x46, 0x2d, 0x44,
0x83, 0x79, 0x2a, 0x36, 0x2c, 0x31, 0x56, 0x3e, 0x83, 0xa7, 0x66, 0xa0, 0xc1, 0x25, 0x84, 0xf4,
0xc0, 0x95, 0xca, 0xf8, 0x6b, 0x50, 0x57, 0xaa, 0xcb, 0x96, 0xb5, 0x1c, 0x9e, 0x41, 0xcb, 0x9a,
0xd8, 0x05, 0x73, 0xbe, 0x09, 0xe6, 0x56, 0x83, 0x5d, 0x94, 0xb9, 0x4a, 0x43, 0xbf, 0x65, 0x95,
0xce, 0x7e, 0xcc, 0x7a, 0x00, 0x7f, 0x5c, 0xc8, 0x75, 0x2a, 0x62, 0xa9, 0xf4, 0xc6, 0x90, 0xb3,
0x45, 0x82, 0x86, 0xd7, 0xa6, 0xb6, 0x2b, 0x37, 0xa6, 0x32, 0x99, 0xde, 0x30, 0xb9, 0x36, 0x7c,
0x9f, 0x56, 0x5e, 0xc8, 0x01, 0xb4, 0xf3, 0x78, 0xc5, 0xe7, 0x2a, 0x43, 0xbb, 0xb6, 0xf7, 0x3e,
0x9c, 0xc1, 0x1f, 0x6d, 0x6b, 0x16, 0xaf, 0x38, 0x93, 0x85, 0x40, 0x72, 0x08, 0x7e, 0xbe, 0x6b,
0xec, 0x65, 0x7c, 0x3c, 0x10, 0x02, 0x75, 0x7d, 0x26, 0xd6, 0xa4, 0xa9, 0x75, 0x96, 0x22, 0x8e,
0xcc, 0xcf, 0x5d, 0xaa, 0xcb, 0xf0, 0x04, 0xfe, 0x53, 0x7c, 0xbe, 0x2d, 0x50, 0xa8, 0x7b, 0x96,
0xc4, 0x91, 0x51, 0x98, 0x6a, 0x32, 0x8b, 0x22, 0x61, 0x53, 0x9b, 0x3a, 0x3c, 0xd6, 0xd0, 0xec,
0x0b, 0xb4, 0x07, 0x6e, 0xce, 0xad, 0xbc, 0x9b, 0xf3, 0x45, 0xd3, 0x9c, 0xf0, 0xf9, 0x5b, 0x00,
0x00, 0x00, 0xff, 0xff, 0x7e, 0x07, 0x28, 0x2a, 0xd0, 0x02, 0x00, 0x00,
}
......@@ -14,4 +14,6 @@ var (
"Update": CertActionUpdate,
"Normal": CertActionNormal,
}
AdminKey = "Auth-cert-admin"
)
......@@ -15,4 +15,6 @@ var (
ErrUnknowAuthSignType = errors.New("ErrUnknowAuthSignType")
// ErrInitializeAuthority 初始化校验器失败
ErrInitializeAuthority = errors.New("ErrInitializeAuthority")
// ErrPermissionDeny 权限校验失败
ErrPermissionDeny = errors.New("ErrPermissionDeny")
)
......@@ -534,8 +534,8 @@ paracross_testBind() {
chain33_SignAndSendTxWait "$rawtx" "${priv1q9}" "${para_ip}"
echo "2. get bind"
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"data":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List.SuperNode| [has("1KSBd17H7Z"),true])' "$FUNCNAME" '(.result.List)'
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"data":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List.Miners| [has("1Q9sQw"),true])' "$FUNCNAME" '(.result.List)'
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"superNode":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List| [has("1KSBd17H7Z"),true])' "$FUNCNAME" '(.result.List)'
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"superNode":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List| [has("1Q9sQw"),true])' "$FUNCNAME" '(.result.List)'
}
paracross_testUnBind() {
......@@ -554,8 +554,8 @@ paracross_testUnBind() {
# superNode=$(jq -r ".result.List.SuperNode" <<<"$resp")
# miners=$(jq -r ".result.List.Miners" <<<"$resp")
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"data":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List.SuperNode| [has("1KSBd17H7Z"),true])' "$FUNCNAME" '(.result.List)'
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"data":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List.Miners| [has("1Q9sQw"),false])' "$FUNCNAME" '(.result.List)'
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"superNode":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List| [has("1KSBd17H7Z"),true])' "$FUNCNAME" '(.result.List)'
chain33_Http '{"method":"Chain33.Query","params":[{ "execer":"paracross", "funcName":"GetNodeBindMinerList","payload":{"superNode":"1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4"}}]}' "${para_ip}" '(.error|not) and (.result.List| [has("1Q9sQw"),false])' "$FUNCNAME" '(.result.List)'
}
paracross_testBindMiner() {
......
......@@ -581,19 +581,20 @@ func getNodeBindListCmd() *cobra.Command {
func addNodeBindCmdFlags(cmd *cobra.Command) {
cmd.Flags().StringP("node", "n", "", "super node addr to bind miner")
cmd.MarkFlagRequired("node")
cmd.Flags().StringP("miner", "m", "", "bind miner addr")
}
func nodeBindInfo(cmd *cobra.Command, args []string) {
rpcLaddr, _ := cmd.Flags().GetString("rpc_laddr")
addr, _ := cmd.Flags().GetString("node")
node, _ := cmd.Flags().GetString("node")
miner, _ := cmd.Flags().GetString("miner")
var params rpctypes.Query4Jrpc
params.Execer = pt.ParaX
params.FuncName = "GetNodeBindMinerList"
params.Payload = types.MustPBToJSON(&types.ReqString{Data: addr})
params.Payload = types.MustPBToJSON(&pt.ParaNodeBindOne{SuperNode: node, Miner: miner})
var res pt.RespParaNodeBindList
ctx := jsonclient.NewRPCCtx(rpcLaddr, "Chain33.Query", params, &res)
......
......@@ -1298,14 +1298,18 @@ func (a *action) Miner(miner *pt.ParacrossMinerAction) (*types.Receipt, error) {
if fundReward > 0 {
totalReward += fundReward
}
decimalMode := cfg.MIsEnable("mver.consensus.paracross.decimalMode", a.height)
if !decimalMode {
totalReward *= types.Coin
}
if totalReward > 0 {
issueReceipt, err := a.coinsAccount.ExecIssueCoins(a.execaddr, totalReward)
if err != nil {
clog.Error("paracross miner issue err", "height", miner.Status.Height,
"execAddr", a.execaddr, "amount", totalReward/types.Coin)
"execAddr", a.execaddr, "amount", totalReward)
return nil, err
}
minerReceipt = mergeReceipt(minerReceipt, issueReceipt)
......
......@@ -192,6 +192,6 @@ func calcParaBindMinerAddr(node, bind string) []byte {
return []byte(fmt.Sprintf(paraBindMinderAddr+"%s-%s", node, bind))
}
func calcParaBindMinerNode(node string) []byte {
return []byte(paraBindMinderNode + node)
func calcParaBindMinerNode() []byte {
return []byte(paraBindMinderNode)
}
......@@ -534,29 +534,63 @@ func (p *Paracross) Query_GetHeight(req *types.ReqString) (*pt.ParacrossConsensu
return nil, types.ErrDecode
}
func getMinerListResp(db dbm.KV, list *pt.ParaNodeBindList) (types.Message, error) {
var resp pt.RespParaNodeBindList
resp.List = list
for _, n := range list.Miners {
info, err := getBindAddrInfo(db, n.SuperNode, n.Miner)
if err != nil {
clog.Error("Query_GetNodeBindMinerList get addr", "err", err, "node", n.SuperNode, "addr", n.Miner)
return nil, errors.Cause(err)
}
resp.Details = append(resp.Details, info)
}
return &resp, nil
}
// Query_GetNodeBindMinerList query get super node bind miner list
func (p *Paracross) Query_GetNodeBindMinerList(in *types.ReqString) (types.Message, error) {
if in == nil || len(in.Data) == 0 {
func (p *Paracross) Query_GetNodeBindMinerList(in *pt.ParaNodeBindOne) (types.Message, error) {
if in == nil {
return nil, types.ErrInvalidParam
}
list, err := getBindNodeInfo(p.GetStateDB(), in.Data)
list, err := getBindNodeInfo(p.GetStateDB())
if err != nil {
clog.Error("Query_GetNodeBindMinerList get node", "err", err, "req", in.Data)
clog.Error("Query_GetNodeBindMinerList get node", "err", err)
return nil, errors.Cause(err)
}
var resp pt.RespParaNodeBindList
resp.List = list
var newList pt.ParaNodeBindList
//按node query
if len(in.SuperNode) != 0 && len(in.Miner) == 0 {
for _, n := range list.Miners {
if n.SuperNode == in.SuperNode {
newList.Miners = append(newList.Miners, n)
}
}
return getMinerListResp(p.GetStateDB(), &newList)
}
for _, addr := range list.Miners {
info, err := getBindAddrInfo(p.GetStateDB(), in.Data, addr)
if err != nil {
clog.Error("Query_GetNodeBindMinerList get addr", "err", err, "node", in.Data, "addr", addr)
return nil, errors.Cause(err)
//按miner query
if len(in.SuperNode) == 0 && len(in.Miner) != 0 {
for _, n := range list.Miners {
if n.Miner == in.Miner {
newList.Miners = append(newList.Miners, n)
}
resp.Details = append(resp.Details, info)
}
return getMinerListResp(p.GetStateDB(), &newList)
}
//按唯一绑定查询
if len(in.SuperNode) != 0 && len(in.Miner) != 0 {
for _, n := range list.Miners {
if n.SuperNode == in.SuperNode && n.Miner == in.Miner {
newList.Miners = append(newList.Miners, n)
}
}
return getMinerListResp(p.GetStateDB(), &newList)
}
return &resp, nil
//获取所有
return getMinerListResp(p.GetStateDB(), list)
}
......@@ -8,6 +8,7 @@ import (
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/chain33/types"
pt "github.com/33cn/plugin/plugin/dapp/paracross/types"
"github.com/golang/protobuf/proto"
)
const (
......@@ -15,36 +16,28 @@ const (
opUnBind = 2
)
//根据挖矿节点地址 获取委托挖矿地址
func (a *action) getBindAddrs(nodes []string, statusHeight int64) []*pt.ParaNodeBindList {
var lists []*pt.ParaNodeBindList
for _, m := range nodes {
list, err := getBindNodeInfo(a.db, m)
if isNotFound(errors.Cause(err)) {
continue
//根据挖矿共识节点地址 过滤整体共识节点映射列表, 获取委托挖矿地址
func (a *action) getBindAddrs(nodes []string, statusHeight int64) (*pt.ParaNodeBindList, error) {
nodesMap := make(map[string]bool)
for _, n := range nodes {
nodesMap[n] = true
}
var newLists pt.ParaNodeBindList
list, err := getBindNodeInfo(a.db)
if err != nil {
clog.Error("paracross getBindAddrs err", "height", statusHeight, "node", m)
continue
clog.Error("paracross getBindAddrs err", "height", statusHeight)
return nil, err
}
lists = append(lists, list)
//这样检索是按照list的映射顺序,不是按照nodes的顺序(需要循环嵌套)
for _, m := range list.Miners {
if nodesMap[m.SuperNode] {
newLists.Miners = append(newLists.Miners, m)
}
return lists
}
func isBindAddrFound(bindAddrs []*pt.ParaNodeBindList) bool {
if len(bindAddrs) <= 0 {
return false
}
for _, addr := range bindAddrs {
if len(addr.Miners) > 0 {
return true
}
}
return false
return &newLists, nil
}
func (a *action) rewardSuperNode(coinReward int64, miners []string, statusHeight int64) (*types.Receipt, int64, error) {
......@@ -70,22 +63,20 @@ func (a *action) rewardSuperNode(coinReward int64, miners []string, statusHeight
}
//奖励委托挖矿账户
func (a *action) rewardBindAddr(coinReward int64, bindList []*pt.ParaNodeBindList, statusHeight int64) (*types.Receipt, int64, error) {
func (a *action) rewardBindAddr(coinReward int64, bindList *pt.ParaNodeBindList, statusHeight int64) (*types.Receipt, int64, error) {
if coinReward <= 0 {
return nil, 0, nil
}
//有可能一个bindAddr 在多个node绑定,这里会累计上去
var bindAddrList []*pt.ParaBindMinerInfo
for _, node := range bindList {
for _, miner := range node.Miners {
info, err := getBindAddrInfo(a.db, node.SuperNode, miner)
for _, node := range bindList.Miners {
info, err := getBindAddrInfo(a.db, node.SuperNode, node.Miner)
if err != nil {
return nil, 0, err
}
bindAddrList = append(bindAddrList, info)
}
}
var totalCoins int64
for _, addr := range bindAddrList {
......@@ -116,9 +107,17 @@ func (a *action) rewardBindAddr(coinReward int64, bindList []*pt.ParaNodeBindLis
func (a *action) reward(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHeightStatus) (*types.Receipt, error) {
//获取挖矿相关配置,这里需注意是共识的高度,而不是交易的高度
cfg := a.api.GetConfig()
coinReward := cfg.MGInt("mver.consensus.paracross.coinReward", nodeStatus.Height) * types.Coin
coinBaseReward := cfg.MGInt("mver.consensus.paracross.coinBaseReward", nodeStatus.Height) * types.Coin
fundReward := cfg.MGInt("mver.consensus.paracross.coinDevFund", nodeStatus.Height) * types.Coin
coinReward := cfg.MGInt("mver.consensus.paracross.coinReward", nodeStatus.Height)
fundReward := cfg.MGInt("mver.consensus.paracross.coinDevFund", nodeStatus.Height)
coinBaseReward := cfg.MGInt("mver.consensus.paracross.coinBaseReward", nodeStatus.Height)
decimalMode := cfg.MIsEnable("mver.consensus.paracross.decimalMode", nodeStatus.Height)
if !decimalMode {
coinReward *= types.Coin
fundReward *= types.Coin
coinBaseReward *= types.Coin
}
fundAddr := cfg.MGStr("mver.consensus.fundKeyAddr", nodeStatus.Height)
//防止coinBaseReward 设置出错场景, coinBaseReward 一定要比coinReward小
......@@ -127,18 +126,21 @@ func (a *action) reward(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHe
}
//超级节点地址
minerAddrs := getMiners(stat.Details, nodeStatus.BlockHash)
nodeAddrs := getSuperNodes(stat.Details, nodeStatus.BlockHash)
//委托地址
bindAddrs := a.getBindAddrs(minerAddrs, nodeStatus.Height)
bindAddrs, err := a.getBindAddrs(nodeAddrs, nodeStatus.Height)
if err != nil {
return nil, err
}
//奖励超级节点
minderRewards := coinReward
//如果有委托挖矿地址,则超级节点分baseReward部分,否则全部
if isBindAddrFound(bindAddrs) {
if len(bindAddrs.Miners) > 0 {
minderRewards = coinBaseReward
}
receipt := &types.Receipt{Ty: types.ExecOk}
r, change, err := a.rewardSuperNode(minderRewards, minerAddrs, nodeStatus.Height)
r, change, err := a.rewardSuperNode(minderRewards, nodeAddrs, nodeStatus.Height)
if err != nil {
return nil, err
}
......@@ -167,8 +169,8 @@ func (a *action) reward(nodeStatus *pt.ParacrossNodeStatus, stat *pt.ParacrossHe
return receipt, nil
}
// getMiners 获取提交共识消息的矿工地址
func getMiners(detail *pt.ParacrossStatusDetails, blockHash []byte) []string {
// getSuperNodes 获取提交共识消息的矿工地址
func getSuperNodes(detail *pt.ParacrossStatusDetails, blockHash []byte) []string {
addrs := make([]string, 0)
for i, hash := range detail.BlockHash {
if bytes.Equal(hash, blockHash) {
......@@ -210,8 +212,8 @@ func makeAddrBindReceipt(node, addr string, prev, current *pt.ParaBindMinerInfo)
}
}
func makeNodeBindReceipt(addr string, prev, current *pt.ParaNodeBindList) *types.Receipt {
key := calcParaBindMinerNode(addr)
func makeNodeBindReceipt(prev, current *pt.ParaNodeBindList) *types.Receipt {
key := calcParaBindMinerNode()
log := &pt.ReceiptParaNodeBindListUpdate{
Prev: prev,
Current: current,
......@@ -233,51 +235,56 @@ func makeNodeBindReceipt(addr string, prev, current *pt.ParaNodeBindList) *types
//绑定到超级节点
func (a *action) bind2Node(node string) (*types.Receipt, error) {
info, err := getBindNodeInfo(a.db, node)
if err != nil && !isNotFound(errors.Cause(err)) {
list, err := getBindNodeInfo(a.db)
if err != nil {
return nil, errors.Wrap(err, "bind2Node")
}
//found
if info != nil {
listCopy := *info
info.Miners = append(info.Miners, a.fromaddr)
return makeNodeBindReceipt(node, &listCopy, info), nil
//由于kvmvcc内存架构,如果存储结构为nil,将回溯查找,这样在只有一个绑定时候,unbind后,有可能会回溯到更早状态,是错误的,title这里就是占位使用
if len(list.Title) <= 0 {
list.Title = a.api.GetConfig().GetTitle()
}
//unfound
var list pt.ParaNodeBindList
list.SuperNode = node
list.Miners = append(list.Miners, a.fromaddr)
return makeNodeBindReceipt(node, nil, &list), nil
old := proto.Clone(list).(*pt.ParaNodeBindList)
list.Miners = append(list.Miners, &pt.ParaNodeBindOne{SuperNode: node, Miner: a.fromaddr})
return makeNodeBindReceipt(old, list), nil
}
//从超级节点解绑
func (a *action) unbind2Node(node string) (*types.Receipt, error) {
list, err := getBindNodeInfo(a.db, node)
list, err := getBindNodeInfo(a.db)
if err != nil {
return nil, errors.Wrap(err, "unbind2Node")
}
newList := &pt.ParaNodeBindList{SuperNode: list.SuperNode}
newList := &pt.ParaNodeBindList{Title: a.api.GetConfig().GetTitle()}
old := proto.Clone(list).(*pt.ParaNodeBindList)
for _, m := range list.Miners {
if m != a.fromaddr {
newList.Miners = append(newList.Miners, m)
if m.SuperNode == node && m.Miner == a.fromaddr {
continue
}
newList.Miners = append(newList.Miners, m)
}
return makeNodeBindReceipt(node, list, newList), nil
return makeNodeBindReceipt(old, newList), nil
}
func getBindNodeInfo(db dbm.KV, node string) (*pt.ParaNodeBindList, error) {
key := calcParaBindMinerNode(node)
func getBindNodeInfo(db dbm.KV) (*pt.ParaNodeBindList, error) {
var list pt.ParaNodeBindList
key := calcParaBindMinerNode()
data, err := db.Get(key)
if isNotFound(err) {
return &list, nil
}
if err != nil {
return nil, errors.Wrapf(err, "get key failed node=%s", node)
return nil, errors.Wrapf(err, "get key failed")
}
var list pt.ParaNodeBindList
err = types.Decode(data, &list)
if err != nil {
return nil, errors.Wrapf(err, "decode failed node=%s", node)
return nil, errors.Wrapf(err, "decode failed")
}
return &list, nil
}
......@@ -380,6 +387,10 @@ func (a *action) unBindOp(cmd *pt.ParaBindMinerCmd) (*types.Receipt, error) {
return nil, errors.Wrapf(types.ErrNotAllow, "unBindOp unbind time=%d less %d hours than bind time =%d", a.blocktime, unBindHours, acct.BlockTime)
}
if acct.BindStatus != opBind {
return nil, errors.Wrapf(types.ErrNotAllow, "unBindOp,current addr is unbind status")
}
//unfrozen
receipt, err := a.coinsAccount.ExecActive(a.fromaddr, a.execaddr, acct.BindCoins*types.Coin)
if err != nil {
......
# 平行链共识节点挖矿奖励规则
>平行链共识节点是参与平行链共识安全的节点,发送共识交易,同时享受平行链挖矿奖励
## 共识节点资格
1. 共识节点需要加入共识节点账户组才具有发送共识交易的资格,不然即使发送也不会被接受
1. 新的共识节点需要共识节点账户组成员超过2/3投票通过才可以加入共识节点账户组
## 共识节点挖矿奖励
1. 共识节点根据本地计算的区块哈希发送共识交易参与共识,共识达成后促使达成共识的节点享受挖矿奖励
1. 比如共识账户组有4个挖矿账户A,B,C,D,其中A,B,C,D都依次发送共识交易,基于超过2/3的规则,在C的共识交易收到后即达成共识,那么奖励将分给A,B,C,而D是在达成共识后发送的,不享受挖矿奖励
## 绑定共识节点挖矿(矿池的概念)
1. 如果账户不是共识节点,但是想参与挖矿奖励,可以锁定平行链基础coins到paracross合约,并绑定到共识节点参与挖矿
1. 绑定账户可以绑定到一个或多个共识节点参与挖矿
1. 挖矿奖励按锁定coins数量的权重来分配挖矿奖励
1. 如果绑定的共识节点在某高度没有得到挖矿奖励,对应的绑定账户也得不到相应奖励
1. 绑定账户可以通过bind命令的coins 数量的修改来增加或减少锁定coins数量,可以通过unbind命令解除对某个共识节点的绑定
## 奖励规则和金额
>奖励规则和金额可配置
```
[mver.consensus.paracross]
#超级节点挖矿奖励
coinReward=18
#发展基金奖励
coinDevFund=12
#如果超级节点上绑定了委托账户,则奖励超级节点coinBaseReward,其余部分(coinReward-coinBaseReward)按权重分给委托账户
coinBaseReward=3
#委托账户最少解绑定时间(按小时)
unBindTime=24
```
1. 每个区块产生的挖矿总奖励如配置项是coinDevFund+coinReward=30,共识达成后,发展基金账户分走12,剩余的18个coin平均分给达成共识的节点
1. 如果有绑定挖矿的账户绑定了共识节点进行挖矿,则共识节点平分基础的coinBaseReward,剩余部分(coinReward-coinBaseReward)按绑定挖矿锁定币的权重数量分给绑定挖矿的节点。
## 绑定挖矿命令
1. 生成 绑定/解绑定 挖矿 的交易(未签名)
```
{
"method" : "Chain33.CreateTransaction",
"params" : [
{
"execer" : "{user.p.para}.paracross",
"actionName" : "ParaBindMiner",
"payload" : {
       "bindAction":"1"
"bindCoins" : 5,
"targetNode" : "1KSBd17H7ZK8iT37aJztFB22XGwsPTdwE4",
}
}
],
}
```
**参数说明:**
|参数|类型|说明|
|----|----|----|
|method|string|Chain33.CreateTransaction|
|execer|string|必须是平行链的执行器user.p.para.paracross,title:user.p.para.按需调整|
|actionName|string|ParaBindMiner|
|bindAction|string|绑定:1,解绑定:2|
|bindCoins|int|绑定挖矿冻结币的份额,需冻结平行链原生代币,解绑定不需要此配置|
|targetNode|string|绑定目标共识节点,需要是共识账户组的成员|
......@@ -83,14 +83,14 @@ func (suite *RewardTestSuite) TestRewardBindAddr() {
key = calcParaBindMinerAddr(node, addr2)
suite.stateDB.Set(key, data)
list := &pt.ParaNodeBindList{
SuperNode: node,
Miners: []string{addr, addr2},
}
node1 := &pt.ParaNodeBindOne{SuperNode: node, Miner: addr}
node2 := &pt.ParaNodeBindOne{SuperNode: node, Miner: addr2}
lists := []*pt.ParaNodeBindList{list}
list := &pt.ParaNodeBindList{}
list.Miners = append(list.Miners, node1)
list.Miners = append(list.Miners, node2)
recp, change, err := suite.action.rewardBindAddr(50000005, lists, 1)
recp, change, err := suite.action.rewardBindAddr(50000005, list, 1)
suite.Nil(err)
suite.Equal(int64(5), change)
suite.Equal(int32(types.ExecOk), recp.Ty)
......
......@@ -180,9 +180,14 @@ message ReceiptParaBindMinerInfo{
ParaBindMinerInfo current = 3;
}
message ParaNodeBindList{
message ParaNodeBindOne{
string superNode = 1;
repeated string miners = 2;
string miner = 2;
}
message ParaNodeBindList{
string title = 1;
repeated ParaNodeBindOne miners = 2;
}
message ReceiptParaNodeBindListUpdate{
......
This diff is collapsed.
......@@ -35,3 +35,8 @@ func (s *storage) Exec_EncryptShareStorage(payload *storagetypes.EncryptShareNot
action := newStorageAction(s, tx, index)
return action.EncryptShareStorage(payload)
}
func (s *storage) Exec_EncryptAdd(payload *storagetypes.EncryptNotaryAdd, tx *types.Transaction, index int) (*types.Receipt, error) {
action := newStorageAction(s, tx, index)
return action.EncryptAdd(payload)
}
......@@ -115,6 +115,27 @@ func (s *storage) ExecLocal_EncryptShareStorage(payload *ety.EncryptShareNotaryS
return s.addAutoRollBack(tx, dbSet.KV), nil
}
func (s *storage) ExecLocal_EncryptAdd(payload *ety.EncryptNotaryAdd, tx *types.Transaction, receiptData *types.ReceiptData, index int) (*types.LocalDBSet, error) {
dbSet := &types.LocalDBSet{}
cfg := s.GetAPI().GetConfig()
if cfg.IsDappFork(s.GetHeight(), ety.StorageX, ety.ForkStorageLocalDB) {
if receiptData.Ty == types.ExecOk {
for _, log := range receiptData.Logs {
switch log.Ty {
case ety.TyEncryptAddLog:
storage := &ety.Storage{}
if err := types.Decode(log.Log, storage); err != nil {
return nil, err
}
kv := &types.KeyValue{Key: getLocalDBKey(storage.GetEncryptStorage().Key), Value: types.Encode(storage)}
dbSet.KV = append(dbSet.KV, kv)
}
}
}
}
return s.addAutoRollBack(tx, dbSet.KV), nil
}
//设置自动回滚
func (s *storage) addAutoRollBack(tx *types.Transaction, kv []*types.KeyValue) *types.LocalDBSet {
......
......@@ -165,6 +165,28 @@ func TestStorage(t *testing.T) {
assert.Equal(t, common.Sha256(contents[0]), reply.GetEncryptStorage().ContentHash)
assert.Equal(t, crypted, reply.GetEncryptStorage().EncryptContent)
assert.Equal(t, ivs[0], reply.GetEncryptStorage().Nonce)
// 同态加密
c1, _ := common.FromHex("010076833cbc35c9b7a87eda9aab7aafec45bd7eb8c0e9306141e7d1e84ecd87a5cb9f80343551bd9b0d04669fd74d020fca8837d9b3b471e3e13c125a06663d820cabb36c243747a11ea2601a9cb32e61c697dcdc846c492d954fa8c3ca2be662e8c0142138b647ce5d9e7c4c4d2ace8ba3c5699fbec98beef24e3c740967ec0b72b1626ecd4a7ce54960ae9bc1e2ea5594b05778f4f772aa213a06421744ed8dd775fb8f212bcc7e0da5fe4949051e6aa09d47db7e8d5028ecc41cea2aed4e23aefd80714519662fae980e3a6ca3defc0dd5596cb7e90da29e1bdd84db82603aed78fb8f98687898cd675da74452052ff1761446bf2ee922fc8c56b7e1beb2d4b91042742837052b340e4afce1836badf4a56ef775bb6a94fd91686a44122543fdab3ee90488160068769fbce2e74ffd5e052bb4c651969c4755f6eb5d7ea0cee3e7fa58f4b38b1722535909bd0f325a0b8d0797c15300ab06095b305f46497bbd75c3682d379387f55f638cd10639db1f050090bfd5d291718cee9fc6894d04ba6ef0acb477184512984f435b13e9bffe630bbc8ceade6d269487bf219e25b3beecc46afb98fb8e1fec1a9ad0af0a16e70611f9a4337af05a2ff82d7c9dcebeea9d8e2070413e49e29ff564e6dcee5696e39dc590ff8f8f553834c66c5ae730d05441e3fcc59de0d6efb12fd8852e19f2e309e4ac4cbf0634655fcaab5a70b4eab49829190ea2862c2568e8b69ff0324055f92275de05f2de1d6a8a78333370da754708f7a827f5e9bbe2e58d58294cafef37898a5a5a4866678b6e07941a3bfcb3c3f2d150f830a12d8e0dd20d756099be48f10d51521b3ba0c49f2ab139724ae3962999d75b88bf572fbfd86b6eef3bad5a446b97949d95f9e742500f8609ecfe189d2b4d5a47ea997164f48b3872ec525f16ec23fa5700d10d3385019edfabfec780f15b639f6863332c69fe6b17895620821fe6aaf94caab29c0fec19ff1bebc59f5ed8f973a3b720257cce803541406ae8e75163cf0049f8fbf14d239e86089cdefba8bcbb03db284283a1ff572320aeb7d4a139d4429e00c8bb196539d7")
c2, _ := common.FromHex("010076833cbc35c9b7a87eda9aab7aafec45bd7eb8c0e9306141e7d1e84ecd87a5cb9f80343551bd9b0d04669fd74d020fca8837d9b3b471e3e13c125a06663d820cabb36c243747a11ea2601a9cb32e61c697dcdc846c492d954fa8c3ca2be662e8c0142138b647ce5d9e7c4c4d2ace8ba3c5699fbec98beef24e3c740967ec0b72b1626ecd4a7ce54960ae9bc1e2ea5594b05778f4f772aa213a06421744ed8dd775fb8f212bcc7e0da5fe4949051e6aa09d47db7e8d5028ecc41cea2aed4e23aefd80714519662fae980e3a6ca3defc0dd5596cb7e90da29e1bdd84db82603aed78fb8f98687898cd675da74452052ff1761446bf2ee922fc8c56b7e1beb2d4b9338ddba1f37e26ef7e0b9cb3bec18dc4b450d91a1a0901a3aca75000b58dd639635dce66553945a698b186c89443361ab4c1d3525de6bace217cd27fce0c8f6efc9e7c95269139487b5772182d8276ed6edfe0560537d18330aae4191af1dfae0a430b2021401bc17a111730f7114f514b7b84cb09bf717c67bb25c21a31b3a062f32dceb99103cdd622242148ec1799d04f4f3f4fc5af9e18cfaf356388b1413cc95b6f5bc0c293acf09ad0513e15d2ea525f120930e6072e0cf750e4e03bbf65b278ad92476f5e507bb51f01c3d2797931794cad156b5980fb5ec51fc82e99fde99e81dd85e9dba1d549aa8768c609e46171750b7bc636b709e47c92b076f1b7f71bff1fd690f8bfcdbf48559f777017b9ad300cbb3a1089f3eb6fed5632be9edecc33be09da7d43275640a097114f8f9e529289cce15d7b4ba613feda9e4d818743bf2741c5cd2aaaec7cc96ed835ee909ea0e9675f57bad4ad01688cc2a77e6181a0bca9a46d0ca160a1d94771e24db357e861e1f029104782445413c6d4861404df9ec3140b895083ebbb8a92bbc7decc8990353e9347a7933f85ef94ed325a331b3e6e6c752086adc7926abac3dfd8c8f3d7add64c80f327c1c4d74fde7a6c8981f79ede165f0584e5d6317d7272d9836098cd8ef82fbe85770962b709dfe1f2ae3454ac471e6ea24c6545f332a3eb4eecbc09e2276748d484a5216361")
c3, _ := common.FromHex("010076833cbc35c9b7a87eda9aab7aafec45bd7eb8c0e9306141e7d1e84ecd87a5cb9f80343551bd9b0d04669fd74d020fca8837d9b3b471e3e13c125a06663d820cabb36c243747a11ea2601a9cb32e61c697dcdc846c492d954fa8c3ca2be662e8c0142138b647ce5d9e7c4c4d2ace8ba3c5699fbec98beef24e3c740967ec0b72b1626ecd4a7ce54960ae9bc1e2ea5594b05778f4f772aa213a06421744ed8dd775fb8f212bcc7e0da5fe4949051e6aa09d47db7e8d5028ecc41cea2aed4e23aefd80714519662fae980e3a6ca3defc0dd5596cb7e90da29e1bdd84db82603aed78fb8f98687898cd675da74452052ff1761446bf2ee922fc8c56b7e1beb2d4b90a734625f41c1709ad56e8a801346d70f190e7080c805de1e380198a4ebaf86ca6e5b9dbdc6eacad7c545f78c718a6e0262bc61d68244f99255d0fc8126cfbc0449e935bf5ee81af5e600f7d5b23b4b2d1f48482e037642690035f0289d4d3c72662d63e958edf8d566c765bcbc44cedc618b31db5eebdc6fd5848d53161e3e01c6c73010c32391db709a71cedb4c45fb71ec85de48ace0cba009ef2c0a88386e62b9607faf36c9b219508281267c0df2a182a88ad8fd146101564f5a14c7fd5ed2d4ae547c8741a31c560501230edd5417c622a7aba8d7efb08c08d5b7c45508c766353f2d43bd092834461f0673196abc8ef56b9fd54bdf82c2a392ff8dedcef3d90d3e47370d31083c2d19cefe2ce83936fd881f4a38ef3e5aaf3b0d48842ded5e6a16fc2fb7b5379406c2889e1d9de1fe611645310ba5b5048e817f44c451b5ec557c0e3b8e64049a437b82f901866ba4c1994d3c3caf02f81582f7409d10480df2c353eb63db4ec57671b2ac6c28fce842c605bae902ac5bb649f08199307458b542849d663809c9980a7c939b4f1f6d2eddf3dfe02f70ee4cf8956bf7a6a29a307939cd17eebdbcc80fb830bd545351a12c275375feaf3f690c52cc76dc7521ce87f621163b551a70e06d5bd3274bdc144f61f4ff8f1cdb2fcf97c67df1935057fdadaa23bf675892b4db841a63d49cd788c34498c70fb4ea787f3f8c1")
tx, err = CreateTx("EncryptStorage", &oty.EncryptNotaryStorage{ContentHash: common.Sha256(c1), EncryptContent: c1, Nonce: ivs[0]}, PrivKeyA, cfg)
assert.Nil(t, err)
Exec_Block(t, stateDB, kvdb, env, tx)
txhash = common.ToHex(tx.Hash())
reply, err = QueryStorageByKey(stateDB, kvdb, txhash, cfg)
assert.Nil(t, err)
assert.Equal(t, common.Sha256(c1), reply.GetEncryptStorage().ContentHash)
assert.Equal(t, c1, reply.GetEncryptStorage().EncryptContent)
tx, err = CreateTx("EncryptAdd", &oty.EncryptNotaryAdd{Key: txhash, EncryptAdd: c2}, PrivKeyA, cfg)
assert.Nil(t, err)
Exec_Block(t, stateDB, kvdb, env, tx)
reply, err = QueryStorageByKey(stateDB, kvdb, txhash, cfg)
assert.Nil(t, err)
assert.Equal(t, c3, reply.GetEncryptStorage().EncryptContent)
}
func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error) {
......
......@@ -3,6 +3,8 @@ package executor
import (
"fmt"
"github.com/33cn/plugin/plugin/crypto/paillier"
"github.com/33cn/chain33/client"
"github.com/33cn/chain33/common"
dbm "github.com/33cn/chain33/common/db"
......@@ -190,6 +192,47 @@ func (s *StorageAction) EncryptShareStorage(payload *ety.EncryptShareNotaryStora
return receipt, nil
}
//EncryptAdd ...
func (s *StorageAction) EncryptAdd(payload *ety.EncryptNotaryAdd) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kvs []*types.KeyValue
cfg := s.api.GetConfig()
store, err := QueryStorage(s.db, s.localdb, payload.Key)
if err != nil {
return nil, fmt.Errorf("EncryptAdd.QueryStorage. err:%v", err)
}
cipherText := store.GetEncryptStorage().EncryptContent
res, err := paillier.CiphertextAddBytes(cipherText, payload.EncryptAdd)
if err != nil {
return nil, fmt.Errorf("EncryptAdd.CiphertextAddBytes. err:%v", err)
}
store.GetEncryptStorage().EncryptContent = res
newStore := &ety.EncryptNotaryStorage{
ContentHash: store.GetEncryptStorage().ContentHash,
EncryptContent: res,
Nonce: store.GetEncryptStorage().Nonce,
Key: store.GetEncryptStorage().Key,
Value: store.GetEncryptStorage().Value,
}
if cfg.IsDappFork(s.height, ety.StorageX, ety.ForkStorageLocalDB) {
stg := &ety.Storage{Value: &ety.Storage_EncryptStorage{EncryptStorage: newStore}, Ty: ety.TyEncryptStorageAction}
log := &types.ReceiptLog{Ty: ety.TyEncryptAddLog, Log: types.Encode(stg)}
logs = append(logs, log)
} else {
log := &types.ReceiptLog{Ty: ety.TyEncryptAddLog}
logs = append(logs, log)
kvs = append(kvs, &types.KeyValue{Key: Key(payload.Key), Value: types.Encode(newStore)})
}
receipt := &types.Receipt{Ty: types.ExecOk, KV: kvs, Logs: logs}
return receipt, nil
}
//QueryStorageByTxHash ...
func QueryStorageByTxHash(db dbm.KV, txhash string) (*ety.Storage, error) {
data, err := db.Get(Key(txhash))
......
......@@ -8,8 +8,9 @@ message Storage {
LinkNotaryStorage linkStorage = 3;
EncryptNotaryStorage encryptStorage = 4;
EncryptShareNotaryStorage encryptShareStorage = 5;
EncryptNotaryAdd encryptAdd = 6;
}
int32 ty = 6;
int32 ty = 7;
}
message StorageAction {
......@@ -19,8 +20,9 @@ message StorageAction {
LinkNotaryStorage linkStorage = 3;
EncryptNotaryStorage encryptStorage = 4;
EncryptShareNotaryStorage encryptShareStorage = 5;
EncryptNotaryAdd encryptAdd = 6;
}
int32 ty = 6;
int32 ty = 7;
}
// 内容存证模型
message ContentOnlyNotaryStorage {
......@@ -85,6 +87,14 @@ message EncryptShareNotaryStorage {
string value = 5;
}
// 加密存证数据运算
message EncryptNotaryAdd {
//源操作数存证索引
string key = 1;
//待操作数据
bytes encryptAdd = 2;
}
service storage {}
//根据txhash去状态数据库中查询存储内容
message QueryStorage {
......
......@@ -2,7 +2,6 @@ package rpc
import (
rpctypes "github.com/33cn/chain33/rpc/types"
storagetypes "github.com/33cn/plugin/plugin/dapp/storage/types"
)
/*
......@@ -30,5 +29,5 @@ func Init(name string, s rpctypes.RPCServer) {
grpc := &Grpc{channelClient: cli}
cli.Init(name, s, &Jrpc{cli: cli}, grpc)
//存在grpc service时注册grpc server,需要生成对应的pb.go文件
storagetypes.RegisterStorageServer(s.GRPC(), grpc)
//storagetypes.RegisterStorageServer(s.GRPC(), grpc)
}
......@@ -20,12 +20,14 @@ const (
TyLinkStorageAction
TyEncryptStorageAction
TyEncryptShareStorageAction
TyEncryptAddAction
NameContentStorageAction = "ContentStorage"
NameHashStorageAction = "HashStorage"
NameLinkStorageAction = "LinkStorage"
NameEncryptStorageAction = "EncryptStorage"
NameEncryptShareStorageAction = "EncryptShareStorage"
NameEncryptAddAction = "EncryptAdd"
FuncNameQueryStorage = "QueryStorage"
FuncNameBatchQueryStorage = "BatchQueryStorage"
......@@ -39,6 +41,7 @@ const (
TyLinkStorageLog
TyEncryptStorageLog
TyEncryptShareStorageLog
TyEncryptAddLog
)
//storage op
......@@ -61,6 +64,7 @@ var (
NameLinkStorageAction: TyLinkStorageAction,
NameEncryptStorageAction: TyEncryptStorageAction,
NameEncryptShareStorageAction: TyEncryptShareStorageAction,
NameEncryptAddAction: TyEncryptAddAction,
}
//定义log的id和具体log类型及名称,填入具体自定义log类型
logMap = map[int64]*types.LogInfo{
......@@ -69,6 +73,7 @@ var (
TyLinkStorageLog: {Ty: reflect.TypeOf(Storage{}), Name: "LogLinkStorage"},
TyEncryptStorageLog: {Ty: reflect.TypeOf(Storage{}), Name: "LogEncryptStorage"},
TyEncryptShareStorageLog: {Ty: reflect.TypeOf(Storage{}), Name: "LogEncryptShareStorage"},
TyEncryptAddLog: {Ty: reflect.TypeOf(Storage{}), Name: "LogEncryptAdd"},
}
)
......
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