Merge pull request #323 from meshplus/feat/inter-relay
feat/inter relay
This commit is contained in:
commit
f1000a1fe4
|
@ -24,3 +24,7 @@ mock_*/
|
|||
coverage.txt
|
||||
docs/.vuepress/dist
|
||||
testdata/storage
|
||||
|
||||
imports/imports.go
|
||||
goent.mod
|
||||
goent.sum
|
3
go.mod
3
go.mod
|
@ -25,10 +25,11 @@ require (
|
|||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
|
||||
github.com/lestrrat-go/strftime v1.0.3 // indirect
|
||||
github.com/libp2p/go-libp2p-core v0.5.6
|
||||
github.com/libp2p/go-libp2p-crypto v0.1.0
|
||||
github.com/magiconair/properties v1.8.4
|
||||
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210126064930-8245c5b45956
|
||||
github.com/meshplus/bitxhub-kit v1.1.2-0.20210112075018-319e668d6359
|
||||
github.com/meshplus/bitxhub-model v1.1.2-0.20210107045700-cee670a2e117
|
||||
github.com/meshplus/bitxhub-model v1.1.2-0.20210120083349-c7a006b03fcb
|
||||
github.com/meshplus/go-libp2p-cert v0.0.0-20210125063330-7c25fd5b7a49
|
||||
github.com/meshplus/go-lightp2p v0.0.0-20210120082108-df5a536a6192
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -701,6 +701,8 @@ github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210112105719-497a79914e4e h1:gQf
|
|||
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210112105719-497a79914e4e/go.mod h1:MHf0waxqnW4Qwfpq66jqvJP+FritN5OTs/8wlQcNlJY=
|
||||
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210126064930-8245c5b45956 h1:f1CXhJSLo/JuTXLjv5PRtvLvzq7mxzD58Aet27k5QlU=
|
||||
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210126064930-8245c5b45956/go.mod h1:MHf0waxqnW4Qwfpq66jqvJP+FritN5OTs/8wlQcNlJY=
|
||||
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210202024251-5a1c2b3eaf0c h1:BPQrfOSEWb5Qi0Bsp5lSwg9ceqQ5T23Ex16pAY+6l0c=
|
||||
github.com/meshplus/bitxhub-core v0.1.0-rc1.0.20210202024251-5a1c2b3eaf0c/go.mod h1:MHf0waxqnW4Qwfpq66jqvJP+FritN5OTs/8wlQcNlJY=
|
||||
github.com/meshplus/bitxhub-kit v1.0.0-rc1/go.mod h1:ra/AhOkPvpElI+wXrB9G6DjdcrdxFU3vMwA5MYKr9D0=
|
||||
github.com/meshplus/bitxhub-kit v1.0.0/go.mod h1:7cWyhXWZfrQ3+EaxkRoXfuiG3Y5R9DXYJomeZKkETW8=
|
||||
github.com/meshplus/bitxhub-kit v1.1.1 h1:vkPO88oA3+Kpc0N8lIgfj/U52KBuI+633hPbMYt1xm8=
|
||||
|
@ -714,6 +716,8 @@ github.com/meshplus/bitxhub-kit v1.1.2-0.20210112075018-319e668d6359/go.mod h1:K
|
|||
github.com/meshplus/bitxhub-model v1.1.2-0.20201021152621-0b3c17c54b23/go.mod h1:4qWBZx5wv7WZzUqiuBsbkQqQ2Ju8aOFpsoNpBBNy8Us=
|
||||
github.com/meshplus/bitxhub-model v1.1.2-0.20210107045700-cee670a2e117 h1:q1FT1DYWg2Ntf6A6wWiEx2WIEaEGBVgaIE1gAIVJKeI=
|
||||
github.com/meshplus/bitxhub-model v1.1.2-0.20210107045700-cee670a2e117/go.mod h1:x3H+TL24wcByzHegenLfs+5PQkQGNsk8eCm31QJMa+Q=
|
||||
github.com/meshplus/bitxhub-model v1.1.2-0.20210120083349-c7a006b03fcb h1:PxGQL22OVxozkvEgVvxHol9WDqCZlhyvnd0Bu0HBX1Y=
|
||||
github.com/meshplus/bitxhub-model v1.1.2-0.20210120083349-c7a006b03fcb/go.mod h1:x3H+TL24wcByzHegenLfs+5PQkQGNsk8eCm31QJMa+Q=
|
||||
github.com/meshplus/go-libp2p-cert v0.0.0-20210120021632-1578cf63e06a h1:eg1BDjSOsz3cdH49kPE8c2XnIFlLTPEMJLqpofV/OEY=
|
||||
github.com/meshplus/go-libp2p-cert v0.0.0-20210120021632-1578cf63e06a/go.mod h1:rS4AYMqKypLn2IPEnHICP//V2v16SZo4CWUbwMdihl0=
|
||||
github.com/meshplus/go-libp2p-cert v0.0.0-20210125063330-7c25fd5b7a49 h1:F8dpLJZW6FxqinAQcZKTkoymZgxnqlNvTebNqWVMEYI=
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
github.com/bitxhub/did-method-registry v0.0.0-20201125025610-feb20d69f302
|
||||
github.com/bitxhub/parallel-executor v0.0.0-20201027053703-4bec95aa1cda
|
||||
github.com/bitxhub/service-mng v0.0.0-20201125031105-f345beee1b42
|
||||
github.com/bitxhub/did-method-registry v0.0.0-20210203031156-4397b27db24d // indirect
|
||||
github.com/bitxhub/parallel-executor v0.0.0-20201027053703-4bec95aa1cda
|
||||
github.com/bitxhub/service-mng v0.0.0-20201125031105-f345beee1b42
|
|
@ -422,7 +422,23 @@ func TestInterchainManager_HandleIBTP(t *testing.T) {
|
|||
|
||||
f2 := mockStub.EXPECT().Get(appchainMgr.PREFIX+from).Return(true, data0).AnyTimes()
|
||||
mockStub.EXPECT().Get(appchainMgr.PREFIX+to).Return(true, data0).AnyTimes()
|
||||
mockStub.EXPECT().CrossInvoke(gomock.Any(), gomock.Any(), gomock.Any()).Return(boltvm.Success(nil)).AnyTimes()
|
||||
|
||||
appchain := &appchainMgr.Appchain{
|
||||
ID: "",
|
||||
Name: "Relay1",
|
||||
Validators: "",
|
||||
ConsensusType: 0,
|
||||
ChainType: "appchain",
|
||||
Desc: "Relay1",
|
||||
Version: "1",
|
||||
PublicKey: "",
|
||||
}
|
||||
appchainData, err := json.Marshal(appchain)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// mockStub.EXPECT().IsRelayIBTP(gomock.Any()).Return(true).AnyTimes()
|
||||
mockStub.EXPECT().CrossInvoke(gomock.Any(), gomock.Eq("GetAppchain"), gomock.Any()).Return(boltvm.Success(appchainData)).AnyTimes()
|
||||
mockStub.EXPECT().CrossInvoke(gomock.Any(), gomock.Not("GetAppchain"), gomock.Any()).Return(boltvm.Success(nil)).AnyTimes()
|
||||
mockStub.EXPECT().AddObject(gomock.Any(), gomock.Any()).AnyTimes()
|
||||
mockStub.EXPECT().GetTxIndex().Return(uint64(1)).AnyTimes()
|
||||
mockStub.EXPECT().PostInterchainEvent(gomock.Any()).AnyTimes()
|
||||
|
@ -435,6 +451,12 @@ func TestInterchainManager_HandleIBTP(t *testing.T) {
|
|||
From: from,
|
||||
}
|
||||
|
||||
// srcChain := &appchainMgr.Appchain{}
|
||||
// ress := im.CrossInvoke(constant.AppchainMgrContractAddr.String(), "GetAppchain", pb.String(ibtp.From))
|
||||
// t.Log("ress: ", ress)
|
||||
// if err := json.Unmarshal(ress.Result, srcChain); err != nil {
|
||||
// t.Log("err: ", err)
|
||||
// }
|
||||
res := im.HandleIBTP(ibtp)
|
||||
assert.False(t, res.Ok)
|
||||
assert.Equal(t, "this appchain does not exist", string(res.Result))
|
||||
|
@ -658,7 +680,7 @@ func TestInterchainManager_HandleUnionIBTP(t *testing.T) {
|
|||
data, err := json.Marshal(relayChain)
|
||||
assert.Nil(t, err)
|
||||
|
||||
mockStub.EXPECT().Get(appchainMgr.PREFIX+appchainMgr.PREFIX+from+"-"+from).Return(true, data0).AnyTimes()
|
||||
mockStub.EXPECT().Get(appchainMgr.PREFIX+from+"-"+from).Return(true, data0).AnyTimes()
|
||||
mockStub.EXPECT().CrossInvoke(gomock.Any(), gomock.Any(), gomock.Any()).Return(boltvm.Success(data)).AnyTimes()
|
||||
mockStub.EXPECT().AddObject(gomock.Any(), gomock.Any()).AnyTimes()
|
||||
mockStub.EXPECT().GetTxIndex().Return(uint64(1)).AnyTimes()
|
||||
|
|
|
@ -103,6 +103,7 @@ func (x *InterchainManager) GetInterchain(id string) *boltvm.Response {
|
|||
}
|
||||
|
||||
func (x *InterchainManager) HandleIBTP(ibtp *pb.IBTP) *boltvm.Response {
|
||||
|
||||
if len(strings.Split(ibtp.From, "-")) == 2 {
|
||||
return x.handleUnionIBTP(ibtp)
|
||||
}
|
||||
|
@ -169,6 +170,8 @@ func (x *InterchainManager) HandleIBTPs(data []byte) *boltvm.Response {
|
|||
}
|
||||
|
||||
func (x *InterchainManager) checkIBTP(ibtp *pb.IBTP, interchain *pb.Interchain) error {
|
||||
isRelayIBTP := x.isRelayIBTP(ibtp.From)
|
||||
|
||||
if ibtp.To == "" {
|
||||
return fmt.Errorf("empty destination chain id")
|
||||
}
|
||||
|
@ -181,8 +184,10 @@ func (x *InterchainManager) checkIBTP(ibtp *pb.IBTP, interchain *pb.Interchain)
|
|||
pb.IBTP_ASSET_EXCHANGE_INIT == ibtp.Type ||
|
||||
pb.IBTP_ASSET_EXCHANGE_REDEEM == ibtp.Type ||
|
||||
pb.IBTP_ASSET_EXCHANGE_REFUND == ibtp.Type {
|
||||
if ibtp.From != x.Caller() {
|
||||
return fmt.Errorf("ibtp from != caller")
|
||||
if !isRelayIBTP {
|
||||
if ibtp.From != x.Caller() {
|
||||
return fmt.Errorf("ibtp from != caller")
|
||||
}
|
||||
}
|
||||
|
||||
idx := interchain.InterchainCounter[ibtp.To]
|
||||
|
@ -193,8 +198,10 @@ func (x *InterchainManager) checkIBTP(ibtp *pb.IBTP, interchain *pb.Interchain)
|
|||
return fmt.Errorf(fmt.Sprintf("wrong index, required %d, but %d", idx+1, ibtp.Index))
|
||||
}
|
||||
} else {
|
||||
if ibtp.To != x.Caller() {
|
||||
return fmt.Errorf("ibtp to != caller")
|
||||
if !isRelayIBTP {
|
||||
if ibtp.To != x.Caller() {
|
||||
return fmt.Errorf("ibtp to != caller")
|
||||
}
|
||||
}
|
||||
|
||||
idx := interchain.ReceiptCounter[ibtp.To]
|
||||
|
@ -210,13 +217,26 @@ func (x *InterchainManager) checkIBTP(ibtp *pb.IBTP, interchain *pb.Interchain)
|
|||
return nil
|
||||
}
|
||||
|
||||
// isRelayIBTP returns whether ibtp.from is relaychain type
|
||||
func (x *InterchainManager) isRelayIBTP(from string) bool {
|
||||
srcChain := &appchainMgr.Appchain{}
|
||||
res := x.CrossInvoke(constant.AppchainMgrContractAddr.String(), "GetAppchain", pb.String(from))
|
||||
if err := json.Unmarshal(res.Result, srcChain); err != nil {
|
||||
return false
|
||||
}
|
||||
return srcChain.ChainType == appchainMgr.RelaychainType
|
||||
}
|
||||
|
||||
func (x *InterchainManager) ProcessIBTP(ibtp *pb.IBTP, interchain *pb.Interchain) {
|
||||
m := make(map[string]uint64)
|
||||
|
||||
if pb.IBTP_INTERCHAIN == ibtp.Type ||
|
||||
pb.IBTP_ASSET_EXCHANGE_INIT == ibtp.Type ||
|
||||
pb.IBTP_ASSET_EXCHANGE_REDEEM == ibtp.Type ||
|
||||
pb.IBTP_ASSET_EXCHANGE_REFUND == ibtp.Type {
|
||||
if interchain.InterchainCounter == nil {
|
||||
x.Logger().Info("interchain counter is nil, make one")
|
||||
interchain.InterchainCounter = make(map[string]uint64)
|
||||
}
|
||||
interchain.InterchainCounter[ibtp.To]++
|
||||
x.setInterchain(ibtp.From, interchain)
|
||||
x.AddObject(x.indexMapKey(ibtp.ID()), x.GetTxHash())
|
||||
|
@ -326,7 +346,7 @@ func (x *InterchainManager) handleUnionIBTP(ibtp *pb.IBTP) *boltvm.Response {
|
|||
return boltvm.Error(err.Error())
|
||||
}
|
||||
|
||||
interchain, ok := x.getInterchain(AppchainKey(ibtp.From))
|
||||
interchain, ok := x.getInterchain(ibtp.From)
|
||||
if !ok {
|
||||
interchain = &pb.Interchain{
|
||||
ID: ibtp.From,
|
||||
|
@ -361,12 +381,18 @@ func (x *InterchainManager) checkUnionIBTP(app *appchainMgr.Appchain, ibtp *pb.I
|
|||
}
|
||||
}
|
||||
|
||||
// _, err := verifyMultiSign(app, ibtp, ibtp.Proof)
|
||||
return nil
|
||||
}
|
||||
|
||||
// verifyMultiSign .
|
||||
func verifyMultiSign(app *appchainMgr.Appchain, ibtp *pb.IBTP, proof []byte) (bool, error) {
|
||||
if "" == app.Validators {
|
||||
return fmt.Errorf("empty validators in relay chain:%s", app.ID)
|
||||
return false, fmt.Errorf("empty validators in relay chain:%s", app.ID)
|
||||
}
|
||||
var validators BxhValidators
|
||||
if err := json.Unmarshal([]byte(app.Validators), &validators); err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
m := make(map[string]struct{}, 0)
|
||||
|
@ -376,17 +402,17 @@ func (x *InterchainManager) checkUnionIBTP(app *appchainMgr.Appchain, ibtp *pb.I
|
|||
|
||||
var signs pb.SignResponse
|
||||
if err := signs.Unmarshal(ibtp.Proof); err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
|
||||
threshold := (len(validators.Addresses) - 1) / 3
|
||||
threshold := (len(validators.Addresses) - 1) / 3 // TODO be dynamic
|
||||
counter := 0
|
||||
|
||||
ibtpHash := ibtp.Hash()
|
||||
hash := sha256.Sum256([]byte(ibtpHash.String()))
|
||||
for v, sign := range signs.Sign {
|
||||
if _, ok := m[v]; !ok {
|
||||
return fmt.Errorf("wrong validator: %s", v)
|
||||
return false, fmt.Errorf("wrong validator: %s", v)
|
||||
}
|
||||
delete(m, v)
|
||||
addr := types.NewAddressByStr(v)
|
||||
|
@ -395,11 +421,10 @@ func (x *InterchainManager) checkUnionIBTP(app *appchainMgr.Appchain, ibtp *pb.I
|
|||
counter++
|
||||
}
|
||||
if counter > threshold {
|
||||
return nil
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("multi signs verify fail, counter:%d", counter)
|
||||
|
||||
return false, fmt.Errorf("multi signs verify fail, counter: %d", counter)
|
||||
}
|
||||
|
||||
func AppchainKey(id string) string {
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
package contracts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/meshplus/bitxhub-core/boltvm"
|
||||
"github.com/meshplus/bitxhub-model/constant"
|
||||
"github.com/meshplus/bitxhub-model/pb"
|
||||
)
|
||||
|
||||
// InterRelayBroker manages all interchain ibtp meta data produced on
|
||||
// relaychain, similar to broker contract on appchain.
|
||||
type InterRelayBroker struct {
|
||||
boltvm.Stub
|
||||
}
|
||||
|
||||
func combineKey(key1 string, key2 uint64) string {
|
||||
return fmt.Sprintf("ibroker-%s-%d", key1, key2)
|
||||
}
|
||||
|
||||
const (
|
||||
InCounterKey = "InCounter"
|
||||
OutCounterKey = "OutCounter"
|
||||
InMessageKey = "InMessage"
|
||||
OutMessageKey = "OutMessage"
|
||||
Locked = true
|
||||
)
|
||||
|
||||
// IncInCounter increases InCounter[from] by once
|
||||
func (ibroker *InterRelayBroker) IncInCounter(from string) *boltvm.Response {
|
||||
ibroker.incInCounter(from)
|
||||
return boltvm.Success(nil)
|
||||
}
|
||||
|
||||
// IncInCounter increases InCounter[from] by once
|
||||
func (ibroker *InterRelayBroker) incInCounter(from string) {
|
||||
InCounterMap := make(map[string]uint64)
|
||||
ibroker.GetObject(InCounterKey, &InCounterMap)
|
||||
InCounterMap[from]++
|
||||
ibroker.SetObject(InCounterKey, InCounterMap)
|
||||
// ibroker.Logger().Info("InCounterMap: ", InCounterMap)
|
||||
}
|
||||
|
||||
// GetInCouterMap .
|
||||
func (ibroker *InterRelayBroker) GetInCouterMap() *boltvm.Response {
|
||||
InCounterMap := make(map[string]uint64)
|
||||
ibroker.GetObject(InCounterKey, &InCounterMap)
|
||||
data, err := json.Marshal(InCounterMap)
|
||||
if err != nil {
|
||||
return boltvm.Error(err.Error())
|
||||
}
|
||||
return boltvm.Success(data)
|
||||
}
|
||||
|
||||
// GetOutCouterMap gets an index map, which implicates the greatest index of
|
||||
func (ibroker *InterRelayBroker) GetOutCouterMap() *boltvm.Response {
|
||||
OutCounterMap := make(map[string]uint64)
|
||||
ibroker.GetObject(OutCounterKey, &OutCounterMap)
|
||||
data, err := json.Marshal(OutCounterMap)
|
||||
if err != nil {
|
||||
return boltvm.Error(err.Error())
|
||||
}
|
||||
return boltvm.Success(data)
|
||||
}
|
||||
|
||||
// GetOutMessageMap returns interchain-message(ibtp) map
|
||||
func (ibroker *InterRelayBroker) GetOutMessageMap() *boltvm.Response {
|
||||
OutMessage := make(map[string]*pb.IBTP)
|
||||
ibroker.GetObject(OutMessageKey, &OutMessage)
|
||||
data, err := json.Marshal(OutMessage)
|
||||
if err != nil {
|
||||
return boltvm.Error(err.Error())
|
||||
}
|
||||
return boltvm.Success(data)
|
||||
}
|
||||
|
||||
// GetOutMessage returns interchain ibtp by index and target chain_id
|
||||
func (ibroker *InterRelayBroker) GetOutMessage(destChain string, index uint64) *boltvm.Response {
|
||||
OutMessage := make(map[string]*pb.IBTP)
|
||||
ibroker.GetObject(OutMessageKey, &OutMessage)
|
||||
data, err := json.Marshal(OutMessage[combineKey(destChain, index)])
|
||||
if err != nil {
|
||||
return boltvm.Error(err.Error())
|
||||
}
|
||||
return boltvm.Success(data)
|
||||
}
|
||||
|
||||
// RecordIBTPs receives ibtps, adds index for them, and stores in counter and message maps,
|
||||
// called by inter-relaychain ibtp producer contracts
|
||||
func (ibroker *InterRelayBroker) RecordIBTPs(ibtpsBytes []byte) *boltvm.Response {
|
||||
OutCounterMap := make(map[string]uint64)
|
||||
OutMessageMap := make(map[string]*pb.IBTP)
|
||||
ibroker.GetObject(OutCounterKey, &OutCounterMap)
|
||||
ibroker.GetObject(OutMessageKey, &OutMessageMap)
|
||||
|
||||
ibtps := &pb.IBTPs{}
|
||||
err := ibtps.Unmarshal(ibtpsBytes)
|
||||
if err != nil {
|
||||
return boltvm.Error(err.Error())
|
||||
}
|
||||
|
||||
for _, ibtp := range ibtps.Ibtps {
|
||||
OutCounterMap[ibtp.To] = OutCounterMap[ibtp.To] + 1
|
||||
ibtp.Index = OutCounterMap[ibtp.To]
|
||||
OutMessageMap[combineKey(ibtp.To, ibtp.Index)] = ibtp
|
||||
}
|
||||
|
||||
ibroker.SetObject(OutCounterKey, OutCounterMap)
|
||||
ibroker.SetObject(OutMessageKey, OutMessageMap)
|
||||
|
||||
newIbtps, err := ibtps.Marshal()
|
||||
if err != nil {
|
||||
return boltvm.Error(err.Error())
|
||||
}
|
||||
|
||||
return boltvm.Success(newIbtps)
|
||||
}
|
||||
|
||||
// InvokeInterRelayContract receives inter-relaychain execution call and invokes
|
||||
func (ibroker *InterRelayBroker) InvokeInterRelayContract(addr string, fun string, args []byte) *boltvm.Response {
|
||||
// ibroker.Logger().Info("In InvokeInterRelayContract....")
|
||||
realArgs := [][]byte{}
|
||||
invokeArgs := []*pb.Arg{}
|
||||
err := json.Unmarshal(args, &realArgs)
|
||||
if err != nil {
|
||||
return boltvm.Error(err.Error())
|
||||
}
|
||||
switch addr {
|
||||
case constant.MethodRegistryContractAddr.String():
|
||||
switch fun {
|
||||
case "Synchronize":
|
||||
invokeArgs = append(invokeArgs, pb.String(string(realArgs[0])))
|
||||
invokeArgs = append(invokeArgs, pb.Bytes(realArgs[1]))
|
||||
res := ibroker.CrossInvoke(addr, fun, invokeArgs...)
|
||||
if res.Ok {
|
||||
ibroker.incInCounter(string(realArgs[0]))
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
return boltvm.Error("Invoke " + addr + "." + fun + " is no supported")
|
||||
}
|
|
@ -262,6 +262,12 @@ func registerBoltContracts() map[string]agency.Contract {
|
|||
Address: constant.AssetExchangeContractAddr.Address().String(),
|
||||
Contract: &contracts.AssetExchange{},
|
||||
},
|
||||
{
|
||||
Enabled: true,
|
||||
Name: "interchain broker service",
|
||||
Address: constant.InterRelayBrokerContractAddr.Address().String(),
|
||||
Contract: &contracts.InterRelayBroker{},
|
||||
},
|
||||
}
|
||||
|
||||
ContractsInfo := agency.GetRegisteredContractInfo()
|
||||
|
|
|
@ -23,6 +23,9 @@ func (router *InterchainRouter) queryAllAppchains() (map[string]*appchain_mgr.Ap
|
|||
router.logger.Errorf("unmarshal appchain error:%v", err)
|
||||
return nil, fmt.Errorf("unmarshal appchain error:%v", err)
|
||||
}
|
||||
if chain.ChainType == appchain_mgr.RelaychainType {
|
||||
continue
|
||||
}
|
||||
ret[chain.ID] = chain
|
||||
}
|
||||
return ret, nil
|
||||
|
|
|
@ -6,10 +6,10 @@ new = false
|
|||
account = ""
|
||||
hosts = ["/ip4/127.0.0.1/tcp/5002/p2p/"]
|
||||
id = 2
|
||||
pid = "QmVLs6DAcTZ9F8zkkK9Vi2u3jJ5PoUQss67VjStoYauXNR"
|
||||
pid = "QmWzsQzgxNwE9ei2nGk6NxPtNy1BJYrBuiTa4ivRwRuYUJ"
|
||||
|
||||
[[nodes]]
|
||||
account = ""
|
||||
hosts = ["/ip4/127.0.0.1/tcp/5003/p2p/"]
|
||||
id = 3
|
||||
pid = "QmYvk2UM9EDPXJwZZFxGdVTYsf9NQyoRerNNgW1WJo5PvJ"
|
||||
pid = "QmeR2M39nxULfjkAbLVxr9zVzoYJQ8mwuSz932Rn8rnx7o"
|
||||
|
|
|
@ -5,10 +5,13 @@ import (
|
|||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
crypto "github.com/libp2p/go-libp2p-crypto"
|
||||
appchainMgr "github.com/meshplus/bitxhub-core/appchain-mgr"
|
||||
"github.com/meshplus/bitxhub-core/validator"
|
||||
"github.com/meshplus/bitxhub-kit/crypto/asym"
|
||||
"github.com/meshplus/bitxhub-kit/log"
|
||||
"github.com/meshplus/bitxhub-kit/types"
|
||||
"github.com/meshplus/bitxhub-model/constant"
|
||||
|
@ -25,6 +28,8 @@ type VerifyPool struct {
|
|||
logger logrus.FieldLogger
|
||||
}
|
||||
|
||||
var _ Verify = (*VerifyPool)(nil)
|
||||
|
||||
func New(ledger ledger.Ledger, logger logrus.FieldLogger) Verify {
|
||||
ve := validator.NewValidationEngine(ledger, &sync.Map{}, log.NewWithModule("validator"))
|
||||
proofPool := &VerifyPool{
|
||||
|
@ -61,6 +66,52 @@ func (pl *VerifyPool) CheckProof(tx *pb.Transaction) (bool, error) {
|
|||
return true, nil
|
||||
}
|
||||
|
||||
type bxhValidators struct {
|
||||
Addresses []string `json:"addresses"`
|
||||
}
|
||||
|
||||
// verifyMultiSign .
|
||||
func verifyMultiSign(app *appchainMgr.Appchain, ibtp *pb.IBTP, proof []byte) (bool, error) {
|
||||
if "" == app.Validators {
|
||||
return false, fmt.Errorf("empty validators in relay chain:%s", app.ID)
|
||||
}
|
||||
var validators bxhValidators
|
||||
if err := json.Unmarshal([]byte(app.Validators), &validators); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
m := make(map[string]struct{}, 0)
|
||||
for _, validator := range validators.Addresses {
|
||||
m[validator] = struct{}{}
|
||||
}
|
||||
|
||||
var signs pb.SignResponse
|
||||
if err := signs.Unmarshal(ibtp.Proof); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
threshold := (len(validators.Addresses) - 1) / 3 // TODO be dynamic
|
||||
counter := 0
|
||||
|
||||
ibtpHash := ibtp.Hash()
|
||||
hash := sha256.Sum256([]byte(ibtpHash.String()))
|
||||
for v, sign := range signs.Sign {
|
||||
if _, ok := m[v]; !ok {
|
||||
return false, fmt.Errorf("wrong validator: %s", v)
|
||||
}
|
||||
delete(m, v)
|
||||
addr := types.NewAddressByStr(v)
|
||||
ok, _ := asym.Verify(crypto.Secp256k1, sign, hash[:], *addr)
|
||||
if ok {
|
||||
counter++
|
||||
}
|
||||
if counter > threshold {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, fmt.Errorf("multi signs verify fail, counter: %d", counter)
|
||||
}
|
||||
|
||||
func (pl *VerifyPool) verifyProof(ibtp *pb.IBTP, proof []byte) (bool, error) {
|
||||
if proof == nil {
|
||||
return false, fmt.Errorf("empty proof")
|
||||
|
@ -70,8 +121,15 @@ func (pl *VerifyPool) verifyProof(ibtp *pb.IBTP, proof []byte) (bool, error) {
|
|||
return false, fmt.Errorf("proof hash is not correct")
|
||||
}
|
||||
|
||||
// get real appchain id for union ibtp
|
||||
from := ibtp.From
|
||||
if len(strings.Split(ibtp.From, "-")) == 2 {
|
||||
from = strings.Split(ibtp.From, "-")[1]
|
||||
return true, nil
|
||||
}
|
||||
|
||||
app := &appchainMgr.Appchain{}
|
||||
ok, data := pl.getAccountState(constant.AppchainMgrContractAddr, contracts.AppchainKey(ibtp.From))
|
||||
ok, data := pl.getAccountState(constant.AppchainMgrContractAddr, contracts.AppchainKey(from)) // ibtp.From
|
||||
if !ok {
|
||||
return false, fmt.Errorf("cannot get registered appchain")
|
||||
}
|
||||
|
@ -80,21 +138,25 @@ func (pl *VerifyPool) verifyProof(ibtp *pb.IBTP, proof []byte) (bool, error) {
|
|||
return false, fmt.Errorf("unmarshal appchain data fail: %w", err)
|
||||
}
|
||||
|
||||
if len(strings.Split(ibtp.From, "-")) == 2 {
|
||||
return verifyMultiSign(app, ibtp, proof)
|
||||
}
|
||||
|
||||
validateAddr := validator.FabricRuleAddr
|
||||
rl := &contracts.Rule{}
|
||||
ok, data = pl.getAccountState(constant.RuleManagerContractAddr, contracts.RuleKey(ibtp.From))
|
||||
ok, data = pl.getAccountState(constant.RuleManagerContractAddr, contracts.RuleKey(from))
|
||||
if ok {
|
||||
if err := json.Unmarshal(data, rl); err != nil {
|
||||
return false, fmt.Errorf("unmarshal rule data error: %w", err)
|
||||
}
|
||||
validateAddr = rl.Address
|
||||
} else {
|
||||
if app.ChainType != "fabric" {
|
||||
if app.ChainType != appchainMgr.FabricType {
|
||||
return false, fmt.Errorf("appchain didn't register rule")
|
||||
}
|
||||
}
|
||||
|
||||
ok, err = pl.ve.Validate(validateAddr, ibtp.From, proof, ibtp.Payload, app.Validators)
|
||||
ok, err = pl.ve.Validate(validateAddr, from, proof, ibtp.Payload, app.Validators) // ibtp.From
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue