Skip to content

Commit

Permalink
add quorum support (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
zouxyan authored Jan 15, 2021
1 parent 24e3d05 commit 182a2f7
Show file tree
Hide file tree
Showing 12 changed files with 1,012 additions and 6 deletions.
4 changes: 3 additions & 1 deletion native/service/cross_chain_manager/entrance.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package cross_chain_manager
import (
"encoding/hex"
"fmt"

"github.com/polynetwork/poly/native/service/cross_chain_manager/quorum"
"github.com/polynetwork/poly/native/service/governance/node_manager"

"github.com/polynetwork/poly/common"
Expand Down Expand Up @@ -64,6 +64,8 @@ func GetChainHandler(router uint64) (scom.ChainHandler, error) {
return neo.NewNEOHandler(), nil
case utils.COSMOS_ROUTER:
return cosmos.NewCosmosHandler(), nil
case utils.QUORUM_ROUTER:
return quorum.NewQuorumHandler(), nil
case utils.BSC_ROUTER:
return bsc.NewHandler(), nil
default:
Expand Down
10 changes: 5 additions & 5 deletions native/service/cross_chain_manager/eth/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ func verifyFromEthTx(native *native.NativeService, proof, extra []byte, fromChai

//todo 1. verify the proof with header
//determine where the k and v from
proofResult, err := verifyMerkleProof(ethProof, blockData, sideChain.CCMCAddress)
proofResult, err := VerifyMerkleProof(ethProof, blockData, sideChain.CCMCAddress)
if err != nil {
return nil, fmt.Errorf("VerifyFromEthProof, verifyMerkleProof error:%v", err)
}
if proofResult == nil {
return nil, fmt.Errorf("VerifyFromEthProof, verifyMerkleProof failed!")
}

if !checkProofResult(proofResult, extra) {
if !CheckProofResult(proofResult, extra) {
return nil, fmt.Errorf("VerifyFromEthProof, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra)
}

Expand All @@ -85,7 +85,7 @@ func verifyFromEthTx(native *native.NativeService, proof, extra []byte, fromChai
return txParam, nil
}

func verifyMerkleProof(ethProof *ETHProof, blockData *types.Header, contractAddr []byte) ([]byte, error) {
func VerifyMerkleProof(ethProof *ETHProof, blockData *types.Header, contractAddr []byte) ([]byte, error) {
//1. prepare verify account
nodeList := new(light.NodeList)

Expand All @@ -101,7 +101,7 @@ func verifyMerkleProof(ethProof *ETHProof, blockData *types.Header, contractAddr
}
acctKey := crypto.Keccak256(addr)

//2. verify account proof
// 2. verify account proof
acctVal, err := trie.VerifyProof(blockData.Root, acctKey, ns)
if err != nil {
return nil, fmt.Errorf("verifyMerkleProof, verify account proof error:%s\n", err)
Expand Down Expand Up @@ -160,7 +160,7 @@ func verifyMerkleProof(ethProof *ETHProof, blockData *types.Header, contractAddr
return val, nil
}

func checkProofResult(result, value []byte) bool {
func CheckProofResult(result, value []byte) bool {
var s_temp []byte
err := rlp.DecodeBytes(result, &s_temp)
if err != nil {
Expand Down
86 changes: 86 additions & 0 deletions native/service/cross_chain_manager/quorum/quorum_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (C) 2020 The poly network Authors
* This file is part of The poly network library.
*
* The poly network is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The poly network is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with The poly network . If not, see <http://www.gnu.org/licenses/>.
*/
package quorum

import (
"encoding/json"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/core/types"
pcom "github.com/polynetwork/poly/common"
"github.com/polynetwork/poly/native"
"github.com/polynetwork/poly/native/service/cross_chain_manager/common"
"github.com/polynetwork/poly/native/service/governance/side_chain_manager"
"github.com/polynetwork/poly/native/service/header_sync/quorum"
)

type QuorumHandler struct{}

func NewQuorumHandler() *QuorumHandler {
return &QuorumHandler{}
}

func (this *QuorumHandler) MakeDepositProposal(ns *native.NativeService) (*common.MakeTxParam, error) {
params := new(common.EntranceParam)
if err := params.Deserialization(pcom.NewZeroCopySource(ns.GetInput())); err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, contract params deserialize error: %v", err)
}

sideChain, err := side_chain_manager.GetSideChain(ns, params.SourceChainID)
if err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, side_chain_manager.GetSideChain error: %v", err)
}
if sideChain == nil {
return nil, errors.New("Quorum MakeDepositProposal, side chain not found")
}

val := &common.MakeTxParam{}
if err := val.Deserialization(pcom.NewZeroCopySource(params.Extra)); err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to deserialize MakeTxParam: %v", err)
}
if err := common.CheckDoneTx(ns, val.CrossChainID, params.SourceChainID); err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, check done transaction error: %v", err)
}
if err := common.PutDoneTx(ns, val.CrossChainID, params.SourceChainID); err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, PutDoneTx error: %v", err)
}

header := &types.Header{}
if err := json.Unmarshal(params.HeaderOrCrossChainMsg, header); err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, deserialize header err: %v", err)
}
valh, err := quorum.GetCurrentValHeight(ns, params.SourceChainID)
if err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to get current validators height: %v", err)
}
if header.Number.Uint64() < valh {
return nil, fmt.Errorf("Quorum MakeDepositProposal, height of header %d is less than epoch height %d", header.Number.Uint64(), valh)
}
vs, err := quorum.GetValSet(ns, params.SourceChainID)
if err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to get quorum validators: %v", err)
}
if _, err := quorum.VerifyQuorumHeader(vs, header, false); err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, failed to verify quorum header %s: %v", header.Hash().String(), err)
}

if err := verifyFromQuorumTx(params.Proof, params.Extra, header, sideChain); err != nil {
return nil, fmt.Errorf("Quorum MakeDepositProposal, verifyFromEthTx error: %s", err)
}

return val, nil
}
144 changes: 144 additions & 0 deletions native/service/cross_chain_manager/quorum/quorum_handler_test.go

Large diffs are not rendered by default.

46 changes: 46 additions & 0 deletions native/service/cross_chain_manager/quorum/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2020 The poly network Authors
* This file is part of The poly network library.
*
* The poly network is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The poly network is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with The poly network . If not, see <http://www.gnu.org/licenses/>.
*/
package quorum

import (
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/core/types"
eth2 "github.com/polynetwork/poly/native/service/cross_chain_manager/eth"
cmanager "github.com/polynetwork/poly/native/service/governance/side_chain_manager"
)

func verifyFromQuorumTx(proof, extra []byte, hdr *types.Header, sideChain *cmanager.SideChain) error {
ethProof := new(eth2.ETHProof)
if err := json.Unmarshal(proof, ethProof); err != nil {
return fmt.Errorf("VerifyFromEthProof, unmarshal proof error:%s", err)
}
if len(ethProof.StorageProofs) != 1 {
return fmt.Errorf("VerifyFromEthProof, incorrect proof format")
}
proofResult, err := eth2.VerifyMerkleProof(ethProof, hdr, sideChain.CCMCAddress)
if err != nil {
return fmt.Errorf("VerifyFromEthProof, verifyMerkleProof error:%v", err)
}
if proofResult == nil {
return fmt.Errorf("VerifyFromEthProof, verifyMerkleProof failed!")
}
if !eth2.CheckProofResult(proofResult, extra) {
return fmt.Errorf("VerifyFromEthProof, verify proof value hash failed, proof result:%x, extra:%x", proofResult, extra)
}
return nil
}
6 changes: 6 additions & 0 deletions native/service/header_sync/entrance.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
package header_sync

import (
"crypto/ecdsa"
"fmt"

"github.com/ethereum/go-ethereum/crypto"
"github.com/polynetwork/poly/common"
"github.com/polynetwork/poly/native"
"github.com/polynetwork/poly/native/service/governance/side_chain_manager"
Expand All @@ -30,6 +32,7 @@ import (
"github.com/polynetwork/poly/native/service/header_sync/eth"
"github.com/polynetwork/poly/native/service/header_sync/neo"
"github.com/polynetwork/poly/native/service/header_sync/ont"
"github.com/polynetwork/poly/native/service/header_sync/quorum"
"github.com/polynetwork/poly/native/service/utils"
)

Expand Down Expand Up @@ -58,6 +61,8 @@ func GetChainHandler(router uint64) (hscommon.HeaderSyncHandler, error) {
return neo.NewNEOHandler(), nil
case utils.COSMOS_ROUTER:
return cosmos.NewCosmosHandler(), nil
case utils.QUORUM_ROUTER:
return quorum.NewQuorumHandler(), nil
case utils.BSC_ROUTER:
return bsc.NewHandler(), nil
default:
Expand Down Expand Up @@ -90,6 +95,7 @@ func SyncGenesisHeader(native *native.NativeService) ([]byte, error) {
if err != nil {
return utils.BYTE_FALSE, err
}
crypto.PubkeyToAddress(ecdsa.PrivateKey{}.PublicKey)
return utils.BYTE_TRUE, nil
}

Expand Down
108 changes: 108 additions & 0 deletions native/service/header_sync/quorum/header_sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (C) 2020 The poly network Authors
* This file is part of The poly network library.
*
* The poly network is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The poly network is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License
* along with The poly network . If not, see <http://www.gnu.org/licenses/>.
*/
package quorum

import (
"encoding/json"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/core/types"
pcom "github.com/polynetwork/poly/common"
"github.com/polynetwork/poly/native"
"github.com/polynetwork/poly/native/service/governance/node_manager"
"github.com/polynetwork/poly/native/service/header_sync/common"
"github.com/polynetwork/poly/native/service/utils"
)

type QuorumHandler struct{}

func NewQuorumHandler() *QuorumHandler {
return &QuorumHandler{}
}

func (h *QuorumHandler) SyncGenesisHeader(ns *native.NativeService) error {
params := new(common.SyncGenesisHeaderParam)
if err := params.Deserialization(pcom.NewZeroCopySource(ns.GetInput())); err != nil {
return fmt.Errorf("QuorumHandler SyncGenesisHeader, contract params deserialize error: %v", err)
}
// Get current epoch operator
op, err := node_manager.GetCurConOperator(ns)
if err != nil {
return fmt.Errorf("QuorumHandler SyncGenesisHeader, get current consensus operator address error: %v", err)
}
//check witness
err = utils.ValidateOwner(ns, op)
if err != nil {
return fmt.Errorf("QuorumHandler SyncGenesisHeader, checkWitness error: %v", err)
}

header := &types.Header{}
if err = json.Unmarshal(params.GenesisHeader, header); err != nil {
return fmt.Errorf("QuorumHandler SyncGenesisHeader, deserialize header err: %v", err)
}
extra, err := ExtractIstanbulExtra(header)
if err != nil {
return fmt.Errorf("QuorumHandler SyncGenesisHeader, failed to ExtractIstanbulExtra: %v", err)
}

putValSet(ns, params.ChainID, header.Number.Uint64(), extra.Validators)
return nil
}

func (h *QuorumHandler) SyncBlockHeader(ns *native.NativeService) error {
params := new(common.SyncBlockHeaderParam)
err := params.Deserialization(pcom.NewZeroCopySource(ns.GetInput()))
if err != nil {
return fmt.Errorf("QuorumHandler SyncBlockHeader, contract params deserialize error: %v", err)
}
if len(params.Headers) == 0 {
return errors.New("QuorumHandler SyncBlockHeader, none headers in input")
}

currh, err := GetCurrentValHeight(ns, params.ChainID)
if err != nil {
return fmt.Errorf("QuorumHandler SyncBlockHeader, failed to get current validator height: %v", err)
}
vs, err := GetValSet(ns, params.ChainID)
if err != nil {
return fmt.Errorf("QuorumHandler SyncBlockHeader, failed to get validators: %v", err)
}
header := &types.Header{}
for i, v := range params.Headers {
if err := json.Unmarshal(v, header); err != nil {
return fmt.Errorf("QuorumHandler SyncBlockHeader, deserialize No.%d header err: %v", i, err)
}
h := header.Number.Uint64()
if currh >= h {
return fmt.Errorf("QuorumHandler SyncBlockHeader, wrong height of No.%d header: (curr: %d, commit: %d)", i, currh, h)
}

extra, err := VerifyQuorumHeader(vs, header, true)
if err != nil {
return fmt.Errorf("QuorumHandler SyncBlockHeader, failed to verify No.%d quorum header %s: %v", i, GetQuorumHeaderHash(header).String(), err)
}

currh, vs = h, extra.Validators
}

putValSet(ns, params.ChainID, currh, vs)
return nil
}

func (h *QuorumHandler) SyncCrossChainMsg(ns *native.NativeService) error {
return nil
}
Loading

0 comments on commit 182a2f7

Please sign in to comment.