Commit 3eb5918e authored by QM's avatar QM

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

parents 45a28de2 e7c1e4ab
......@@ -94,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”
......
......@@ -3,7 +3,7 @@ module github.com/33cn/plugin
go 1.12
require (
github.com/33cn/chain33 v1.65.1-0.20201022110501-fde367b8c955
github.com/33cn/chain33 v1.65.1-0.20201111090506-e2d7705ea453
github.com/BurntSushi/toml v0.3.1
github.com/NebulousLabs/Sia v1.3.7
github.com/NebulousLabs/errors v0.0.0-20181203160057-9f787ce8f69e // indirect
......@@ -37,7 +37,7 @@ require (
github.com/rs/cors v1.6.0
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.6.1
github.com/tjfoc/gmsm v1.3.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
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
......
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/33cn/chain33 v1.65.1-0.20201022110501-fde367b8c955 h1:MOk2yEDeJhUlTVl/QjjaazkT5AAxOIVLfFEYFut7uMk=
github.com/33cn/chain33 v1.65.1-0.20201022110501-fde367b8c955/go.mod h1:wHcOzFsfp0f0Zio+RHAUgUYyJhyVQyPbvmL0MYFBTng=
github.com/33cn/chain33 v1.65.1-0.20201111090506-e2d7705ea453 h1:vbQZFz5fRiU6P8HH4fnbuSJY7Iybjvv+MV8mGPJXWoI=
github.com/33cn/chain33 v1.65.1-0.20201111090506-e2d7705ea453/go.mod h1:wHcOzFsfp0f0Zio+RHAUgUYyJhyVQyPbvmL0MYFBTng=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9 h1:HD8gA2tkByhMAwYaFAX9w2l7vxvBQ5NMoxDrkhqhtn4=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
......@@ -711,6 +711,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
github.com/tjfoc/gmsm v1.3.1 h1:+k3IAlF81c31/TllJmIfuCYnjl8ziMdTWGWJcP9J1uo=
github.com/tjfoc/gmsm v1.3.1/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tjfoc/gmsm v1.3.2 h1:7JVkAn5bvUJ7HtU08iW6UiD+UTmJTIToHCfeFzkcCxM=
github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
......
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")
)
......@@ -1444,14 +1444,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)
......
......@@ -107,9 +107,17 @@ func (a *action) rewardBindAddr(coinReward int64, bindList *pt.ParaNodeBindList,
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小
......
......@@ -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.
......@@ -187,6 +187,9 @@ func (action *tokenAction) preCreate(token *pty.TokenPreCreate) (*types.Receipt,
if cfg.IsDappFork(action.height, pty.TokenX, pty.ForkTokenBlackListX) {
found, err := inBlacklist(token.GetSymbol(), blacklist, action.db)
if err != nil {
if err == types.ErrNotFound {
return nil, pty.ErrTokenBlacklistNotInit
}
return nil, err
}
if found {
......@@ -402,7 +405,7 @@ func checkTokenHasPrecreateWithHeight(cfg *types.Chain33Config, token, owner str
}
func validFinisher(addr string, db dbm.KV) (bool, error) {
return validOperator(addr, finisherKey, db)
return hasConfiged(addr, finisherKey, db)
}
func getManageKey(key string, db dbm.KV) ([]byte, error) {
......@@ -425,7 +428,7 @@ func getConfigKey(key string, db dbm.KV) ([]byte, error) {
return value, nil
}
func validOperator(addr, key string, db dbm.KV) (bool, error) {
func hasConfiged(v1, key string, db dbm.KV) (bool, error) {
value, err := getManageKey(key, db)
if err != nil {
tokenlog.Info("tokendb", "get db key", "not found", "key", key)
......@@ -443,8 +446,8 @@ func validOperator(addr, key string, db dbm.KV) (bool, error) {
return false, err // types.ErrBadConfigValue
}
for _, op := range item.GetArr().Value {
if op == addr {
for _, v := range item.GetArr().Value {
if v == v1 {
return true, nil
}
}
......@@ -501,7 +504,7 @@ func AddTokenToAssets(addr string, db dbm.KVDB, symbol string) []*types.KeyValue
}
func inBlacklist(symbol, key string, db dbm.KV) (bool, error) {
found, err := validOperator(symbol, key, db)
found, err := hasConfiged(symbol, key, db)
return found, err
}
......
......@@ -35,4 +35,6 @@ var (
ErrTokenBlacklist = errors.New("ErrTokenBlacklist")
// ErrTokenNotExist error token symbol not exist
ErrTokenNotExist = errors.New("ErrTokenSymbolNotExist")
// ErrTokenBlacklistNotInit error token hasn't init blacklist
ErrTokenBlacklistNotInit = errors.New("ErrTokenBlacklistNotInit")
)
......@@ -64,7 +64,8 @@ const (
const (
DefaultLtTxBroadCastTTL = 3
DefaultMaxTxBroadCastTTL = 25
DefaultMinLtBlockTxNum = 5
// 100KB
defaultMinLtBlockSize = 100
)
// P2pCacheTxSize p2pcache size of transaction
......
......@@ -152,8 +152,12 @@ func (na *NetAddress) DialTimeout(version int32) (*grpc.ClientConn, error) {
keepaliveOp := grpc.WithKeepaliveParams(cliparm)
timeoutOp := grpc.WithTimeout(time.Second * 3)
log.Debug("NetAddress", "Dial", na.String())
maxMsgSize := pb.MaxBlockSize + 1024*1024
conn, err := grpc.Dial(na.String(), grpc.WithInsecure(),
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")), grpc.WithServiceConfig(ch), keepaliveOp, timeoutOp)
grpc.WithDefaultCallOptions(grpc.UseCompressor("gzip")),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMsgSize)),
grpc.WithDefaultCallOptions(grpc.MaxCallSendMsgSize(maxMsgSize)),
grpc.WithServiceConfig(ch), keepaliveOp, timeoutOp)
if err != nil {
log.Debug("grpc DialCon", "did not connect", err, "addr", na.String())
return nil, err
......
......@@ -57,8 +57,8 @@ type subConfig struct {
MaxTTL int32 `protobuf:"varint,10,opt,name=maxTTL" json:"maxTTL,omitempty"`
// p2p网络频道,用于区分主网/测试网/其他网络
Channel int32 `protobuf:"varint,11,opt,name=channel" json:"channel,omitempty"`
//区块轻广播的最低打包交易数, 大于该值时区块内交易采用短哈希广播
MinLtBlockTxNum int32 `protobuf:"varint,12,opt,name=minLtBlockTxNum" json:"minLtBlockTxNum,omitempty"`
//触发区块轻广播最小大小, KB
MinLtBlockSize int32 `protobuf:"varint,12,opt,name=minLtBlockSize" json:"minLtBlockSize,omitempty"`
//指定p2p类型, 支持gossip, dht
}
......@@ -100,8 +100,8 @@ func New(mgr *p2p.Manager, subCfg []byte) p2p.IP2P {
mcfg.MaxTTL = DefaultMaxTxBroadCastTTL
}
if mcfg.MinLtBlockTxNum <= 0 {
mcfg.MinLtBlockTxNum = DefaultMinLtBlockTxNum
if mcfg.MinLtBlockSize <= 0 {
mcfg.MinLtBlockSize = defaultMinLtBlockSize
}
log.Info("p2p", "Channel", mcfg.Channel, "Version", VERSION, "IsTest", cfg.IsTestNet())
......
......@@ -136,7 +136,6 @@ func newP2p(cfg *types.Chain33Config, port int32, dbpath string, q queue.Queue)
pcfg.Port = port
pcfg.Channel = testChannel
pcfg.ServerStart = true
pcfg.MinLtBlockTxNum = 1
subCfgBytes, _ := json.Marshal(pcfg)
p2pcli := New(p2pMgr, subCfgBytes).(*P2p)
......
......@@ -114,7 +114,7 @@ func (n *Node) sendBlock(block *types.P2PBlock, p2pData *types.BroadCastData, pe
return false
}
if peerVersion >= lightBroadCastVersion && len(block.Block.Txs) >= int(n.nodeInfo.cfg.MinLtBlockTxNum) {
if peerVersion >= lightBroadCastVersion && types.Size(block.GetBlock()) >= int(n.nodeInfo.cfg.MinLtBlockSize*1024) {
ltBlock := &types.LightBlock{}
ltBlock.Size = int64(types.Size(block.Block))
......@@ -156,26 +156,20 @@ func (n *Node) sendTx(tx *types.P2PTx, p2pData *types.BroadCastData, peerVersion
txHash := hex.EncodeToString(tx.Tx.Hash())
ttl := tx.GetRoute().GetTTL()
isLightSend := peerVersion >= lightBroadCastVersion && ttl >= n.nodeInfo.cfg.LightTxTTL
//检测冗余发送
ignoreSend := false
//短哈希广播不记录发送过滤
if !isLightSend {
ignoreSend = n.addIgnoreSendPeerAtomic(txSendFilter, txHash, pid)
}
log.Debug("P2PSendTx", "txHash", txHash, "ttl", ttl, "isLightSend", isLightSend,
"peerAddr", peerAddr, "ignoreSend", ignoreSend)
if ignoreSend {
return false
}
//超过最大的ttl, 不再发送
if ttl > n.nodeInfo.cfg.MaxTTL {
return false
}
isLightSend := peerVersion >= lightBroadCastVersion && ttl >= n.nodeInfo.cfg.LightTxTTL
//检测冗余发送
if n.addIgnoreSendPeerAtomic(txSendFilter, txHash, pid) {
return false
}
//log.Debug("P2PSendTx", "txHash", txHash, "ttl", ttl, "isLightSend", isLightSend, "peerAddr", peerAddr, "ignoreSend", ignoreSend)
//新版本且ttl达到设定值
if isLightSend {
p2pData.Value = &types.BroadCastData_LtTx{ //超过最大的ttl, 不再发送
......@@ -199,7 +193,7 @@ func (n *Node) recvTx(tx *types.P2PTx, pid, peerAddr string) {
n.addIgnoreSendPeerAtomic(txSendFilter, txHash, pid)
//重复接收
isDuplicate := txHashFilter.AddWithCheckAtomic(txHash, true)
log.Debug("recvTx", "tx", txHash, "ttl", tx.GetRoute().GetTTL(), "peerAddr", peerAddr, "duplicateTx", isDuplicate)
//log.Debug("recvTx", "tx", txHash, "ttl", tx.GetRoute().GetTTL(), "peerAddr", peerAddr, "duplicateTx", isDuplicate)
if isDuplicate {
return
}
......@@ -222,7 +216,7 @@ func (n *Node) recvLtTx(tx *types.LightTx, pid, peerAddr string, pubPeerFunc pub
//将节点id添加到发送过滤, 避免冗余发送
n.addIgnoreSendPeerAtomic(txSendFilter, txHash, pid)
exist := txHashFilter.Contains(txHash)
log.Debug("recvLtTx", "txHash", txHash, "ttl", tx.GetRoute().GetTTL(), "peerAddr", peerAddr, "exist", exist)
//log.Debug("recvLtTx", "txHash", txHash, "ttl", tx.GetRoute().GetTTL(), "peerAddr", peerAddr, "exist", exist)
//本地不存在, 需要向对端节点发起完整交易请求. 如果存在则表示本地已经接收过此交易, 不做任何操作
if !exist {
......@@ -354,10 +348,10 @@ func (n *Node) recvLtBlock(ltBlock *types.LightBlock, pid, peerAddr string, pubP
},
},
}
//pub to specified peer
pubPeerFunc(query, pid)
//需要将不完整的block预存
ltBlockCache.Add(blockHash, block, block.Size())
//pub to specified peer
pubPeerFunc(query, pid)
}
func (n *Node) recvQueryData(query *types.P2PQueryData, pid, peerAddr string, pubPeerFunc pubFuncType) {
......@@ -382,6 +376,7 @@ func (n *Node) recvQueryData(query *types.P2PQueryData, pid, peerAddr string, pu
p2pTx := &types.P2PTx{Tx: txList.Txs[0]}
//再次发送完整交易至节点, ttl重设为1
p2pTx.Route = &types.P2PRoute{TTL: 1}
n.removeIgnoreSendPeerAtomic(txSendFilter, txHash, pid)
pubPeerFunc(p2pTx, pid)
} else if blcReq := query.GetBlockTxReq(); blcReq != nil {
......@@ -442,10 +437,10 @@ func (n *Node) recvQueryReply(rep *types.P2PBlockTxReply, pid, peerAddr string,
},
},
}
//pub to specified peer
pubPeerFunc(query, pid)
block.Txs = nil
ltBlockCache.Add(rep.BlockHash, block, block.Size())
//pub to specified peer
pubPeerFunc(query, pid)
}
}
......@@ -490,3 +485,15 @@ func (n *Node) addIgnoreSendPeerAtomic(filter *utils.Filterdata, key, pid string
info.ignoreSendPeers[pid] = true
return exist
}
// 删除发送过滤器记录
func (n *Node) removeIgnoreSendPeerAtomic(filter *utils.Filterdata, key, pid string) {
filter.GetAtomicLock()
defer filter.ReleaseAtomicLock()
if filter.Contains(key) {
data, _ := filter.Get(key)
info := data.(*sendFilterInfo)
delete(info.ignoreSendPeers, pid)
}
}
......@@ -27,6 +27,7 @@ func Test_processP2P(t *testing.T) {
q.SetConfig(cfg)
go q.Start()
p2p := newP2p(cfg, 12345, "testProcessP2p", q)
p2p.subCfg.MinLtBlockSize = 0
defer freeP2p(p2p)
defer q.Close()
node := p2p.node
......@@ -34,7 +35,6 @@ func Test_processP2P(t *testing.T) {
pid := "testPid"
sendChan := make(chan interface{}, 1)
recvChan := make(chan *types.BroadCastData, 1)
testDone := make(chan struct{})
payload := []byte("testpayload")
minerTx := &types.Transaction{Execer: []byte("coins"), Payload: payload, Fee: 14600, Expire: 200}
......@@ -106,41 +106,43 @@ func Test_processP2P(t *testing.T) {
}()
//data test
go func() {
subChan := node.pubsub.Sub(pid)
//normal
//全数据广播
sendChan <- &versionData{peerName: pid + "1", rawData: &types.P2PTx{Tx: tx, Route: &types.P2PRoute{}}, version: lightBroadCastVersion - 1}
p2p.mgr.PubSub.Pub(client.NewMessage("p2p", types.EventTxBroadcast, tx), P2PTypeName)
sendChan <- &versionData{peerName: pid + "1", rawData: &types.P2PBlock{Block: block}, version: lightBroadCastVersion - 1}
//light broadcast
//交易发送过滤
txHashFilter.Add(hex.EncodeToString(tx1.Hash()), &types.P2PRoute{TTL: DefaultLtTxBroadCastTTL})
p2p.mgr.PubSub.Pub(client.NewMessage("p2p", types.EventTxBroadcast, tx1), P2PTypeName)
//交易短哈希广播
sendChan <- &versionData{peerName: pid + "2", rawData: &types.P2PTx{Tx: tx, Route: &types.P2PRoute{TTL: DefaultLtTxBroadCastTTL}}, version: lightBroadCastVersion}
<-subChan //query tx
recvWithTimeout(t, subChan, "case 1") //缺失交易,从对端获取
//区块短哈希广播
sendChan <- &versionData{peerName: pid + "2", rawData: &types.P2PBlock{Block: block}, version: lightBroadCastVersion}
<-subChan //query block
for !ltBlockCache.Contains(blockHash) {
}
recvWithTimeout(t, subChan, "case 2")
assert.True(t, ltBlockCache.Contains(blockHash))
cpBlock := *ltBlockCache.Get(blockHash).(*types.Block)
assert.True(t, bytes.Equal(rootHash, merkle.CalcMerkleRoot(cfg, cpBlock.Height, cpBlock.Txs)))
//query tx
sendChan <- &versionData{rawData: &types.P2PQueryData{Value: &types.P2PQueryData_TxReq{TxReq: &types.P2PTxReq{TxHash: tx.Hash()}}}}
_, ok := (<-subChan).(*types.P2PTx)
data := recvWithTimeout(t, subChan, "case 3")
_, ok := data.(*types.P2PTx)
assert.True(t, ok)
sendChan <- &versionData{rawData: &types.P2PQueryData{Value: &types.P2PQueryData_BlockTxReq{BlockTxReq: &types.P2PBlockTxReq{
BlockHash: blockHash,
TxIndices: []int32{1, 2},
}}}}
rep, ok := (<-subChan).(*types.P2PBlockTxReply)
data = recvWithTimeout(t, subChan, "case 4")
rep, ok := data.(*types.P2PBlockTxReply)
assert.True(t, ok)
assert.Equal(t, 2, int(rep.TxIndices[1]))
sendChan <- &versionData{rawData: &types.P2PQueryData{Value: &types.P2PQueryData_BlockTxReq{BlockTxReq: &types.P2PBlockTxReq{
BlockHash: blockHash,
TxIndices: nil,
}}}}
rep, ok = (<-subChan).(*types.P2PBlockTxReply)
data = recvWithTimeout(t, subChan, "case 5")
rep, ok = data.(*types.P2PBlockTxReply)
assert.True(t, ok)
assert.Nil(t, rep.TxIndices)
......@@ -150,7 +152,7 @@ func Test_processP2P(t *testing.T) {
TxIndices: []int32{1},
Txs: txList[1:2],
}}
rep1, ok := (<-subChan).(*types.P2PQueryData)
rep1, ok := recvWithTimeout(t, subChan, "case 6").(*types.P2PQueryData)
assert.True(t, ok)
assert.Nil(t, rep1.GetBlockTxReq().GetTxIndices())
sendChan <- &versionData{rawData: &types.P2PBlockTxReply{
......@@ -158,21 +160,21 @@ func Test_processP2P(t *testing.T) {
Txs: txList[0:],
}}
for ltBlockCache.Contains(blockHash) {
time.Sleep(time.Millisecond)
}
//max ttl
//send tx with max ttl
_, doSend := node.processSendP2P(&types.P2PTx{Tx: tx, Route: &types.P2PRoute{TTL: node.nodeInfo.cfg.MaxTTL + 1}}, lightBroadCastVersion, pid+"5", "testIP:port")
assert.False(t, doSend)
close(testDone)
}()
ticker := time.NewTicker(time.Minute)
defer ticker.Stop()
for {
}
// 等待接收channel数据,超时报错
func recvWithTimeout(t *testing.T, ch chan interface{}, testCase string) interface{} {
select {
case <-testDone:
return
case <-ticker.C:
t.Error("TestP2PProcessTimeout")
return
}
case data := <-ch:
return data
case <-time.After(time.Second * 10):
t.Error(testCase, "waitChanTimeout")
t.FailNow()
}
return nil
}
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