Skip to content

Commit

Permalink
Support tm v0.34 (#85)
Browse files Browse the repository at this point in the history
* Add tendermint v0.34

* Differentiate hashing between tm >=v0.34 and before

* Clean go.sum

* Use tm33 as default, and convert types only when needed

* Add some comments

* Supress namespace conflict error.

Starting with v1.26.0 of the google.golang.org/protobuf module, a hard error will be reported
when a Go program starts up that has multiple conflicting protobuf names linked into it.

This reverts the issue to a warning until the problem is resolved by Zilliqa.

See: https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict

* Add tm34 proofs and header sign bytes

* Remove unneccesary replace directive

* Revert "Remove unneccesary replace directive"

This reverts commit af5c7fd.

* Remove logs

* Add license
  • Loading branch information
RavenXce authored Nov 17, 2021
1 parent f14dc60 commit 07408cf
Show file tree
Hide file tree
Showing 10 changed files with 821 additions and 83 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ temp/*
temp/
idea/
build/
tools/
wsl/*
*.patch
.idea/
Expand All @@ -20,6 +21,7 @@ Chain/*
nodectl
ontology
wallet.dat
poly
cscope*
*.exe
**/*.log
Expand Down
14 changes: 7 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
GOFMT=gofmt
GC=go build
VERSION := $(shell git describe --always --tags --long)
BUILD_NODE_PAR = -ldflags "-X github.com/polynetwork/poly/common/config.Version=$(VERSION)" #-race
BUILD_NODE_PAR = -ldflags "-X github.com/polynetwork/poly/common/config.Version=$(VERSION) -X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn" #-race

ARCH=$(shell uname -m)
DBUILD=docker build
Expand All @@ -16,13 +16,13 @@ NATIVE_ABI_SCRIPT=./cmd/abi/native_abi_script

poly: $(SRC_FILES)
$(GC) $(BUILD_NODE_PAR) -o poly main.go
sigsvr: $(SRC_FILES) abi

sigsvr: $(SRC_FILES) abi
$(GC) $(BUILD_NODE_PAR) -o sigsvr sigsvr.go
@if [ ! -d $(TOOLS) ];then mkdir -p $(TOOLS) ;fi
@mv sigsvr $(TOOLS)

abi:
abi:
@if [ ! -d $(ABI) ];then mkdir -p $(ABI) ;fi
@cp $(NATIVE_ABI_SCRIPT)/*.json $(ABI)

Expand All @@ -43,17 +43,17 @@ poly-darwin:

tools-cross: tools-windows tools-linux tools-darwin

tools-windows: abi
tools-windows: abi
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 $(GC) $(BUILD_NODE_PAR) -o sigsvr-windows-amd64.exe sigsvr.go
@if [ ! -d $(TOOLS) ];then mkdir -p $(TOOLS) ;fi
@mv sigsvr-windows-amd64.exe $(TOOLS)

tools-linux: abi
tools-linux: abi
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GC) $(BUILD_NODE_PAR) -o sigsvr-linux-amd64 sigsvr.go
@if [ ! -d $(TOOLS) ];then mkdir -p $(TOOLS) ;fi
@mv sigsvr-linux-amd64 $(TOOLS)

tools-darwin: abi
tools-darwin: abi
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 $(GC) $(BUILD_NODE_PAR) -o sigsvr-darwin-amd64 sigsvr.go
@if [ ! -d $(TOOLS) ];then mkdir -p $(TOOLS) ;fi
@mv sigsvr-darwin-amd64 $(TOOLS)
Expand Down
10 changes: 7 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.14

require (
github.com/Zilliqa/gozilliqa-sdk v1.2.1-0.20210927032600-4c733f2cb879
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcd v0.21.0-beta
github.com/btcsuite/btcutil v1.0.2
github.com/cosmos/cosmos-sdk v0.39.1
github.com/ethereum/go-ethereum v1.9.15
Expand All @@ -13,6 +13,7 @@ require (
github.com/gorilla/websocket v1.4.2
github.com/gosuri/uiprogress v0.0.1
github.com/hashicorp/golang-lru v0.5.4
github.com/confio/ics23/go v0.6.6
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c
github.com/itchyny/base58-go v0.1.0
github.com/joeqian10/neo-gogogo v1.1.0
Expand All @@ -26,12 +27,15 @@ require (
github.com/polynetwork/poly-io-test v0.0.0-20200819093740-8cf514b07750
github.com/renlulu/gozilliqa-sdklegacy v0.0.0-20210926114807-88a08c5ab803
github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d
github.com/switcheo/tendermint v0.34.14-2
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca
github.com/tendermint/go-amino v0.15.1
github.com/tendermint/tendermint v0.33.7
github.com/urfave/cli v1.22.4
github.com/valyala/bytebufferpool v1.0.0
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f
gotest.tools v2.2.0+incompatible
)

replace github.com/tendermint/tm-db/064 => github.com/tendermint/tm-db v0.6.4
553 changes: 523 additions & 30 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions native/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package native

import (
"fmt"

"github.com/polynetwork/poly/common"
"github.com/polynetwork/poly/common/log"
"github.com/polynetwork/poly/core/types"
Expand Down
32 changes: 6 additions & 26 deletions native/service/cross_chain_manager/cosmos/cosmos_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,12 @@ package cosmos
import (
"bytes"
"fmt"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/rootmulti"

"github.com/polynetwork/poly/common"
"github.com/polynetwork/poly/native"
scom "github.com/polynetwork/poly/native/service/cross_chain_manager/common"
"github.com/polynetwork/poly/native/service/header_sync/cosmos"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/merkle"
"github.com/tendermint/tendermint/crypto/multisig"
"github.com/tendermint/tendermint/crypto/secp256k1"
)

type CosmosHandler struct{}
Expand All @@ -43,19 +38,6 @@ type CosmosProofValue struct {
Value []byte
}

func newCDC() *codec.Codec {
cdc := codec.New()
cdc.RegisterInterface((*crypto.PubKey)(nil), nil)
cdc.RegisterConcrete(ed25519.PubKeyEd25519{}, ed25519.PubKeyAminoName, nil)
cdc.RegisterConcrete(secp256k1.PubKeySecp256k1{}, secp256k1.PubKeyAminoName, nil)
cdc.RegisterConcrete(multisig.PubKeyMultisigThreshold{}, multisig.PubKeyMultisigThresholdAminoRoute, nil)

cdc.RegisterInterface((*crypto.PrivKey)(nil), nil)
cdc.RegisterConcrete(ed25519.PrivKeyEd25519{}, ed25519.PrivKeyAminoName, nil)
cdc.RegisterConcrete(secp256k1.PrivKeySecp256k1{}, secp256k1.PrivKeyAminoName, nil)
return cdc
}

func (this *CosmosHandler) MakeDepositProposal(service *native.NativeService) (*scom.MakeTxParam, error) {
params := new(scom.EntranceParam)
if err := params.Deserialization(common.NewZeroCopySource(service.GetInput())); err != nil {
Expand All @@ -73,9 +55,8 @@ func (this *CosmosHandler) MakeDepositProposal(service *native.NativeService) (*
if len(params.HeaderOrCrossChainMsg) == 0 {
return nil, fmt.Errorf("you must commit the header used to verify transaction's proof and get none")
}
cdc := newCDC()
var myHeader cosmos.CosmosHeader
if err := cdc.UnmarshalBinaryBare(params.HeaderOrCrossChainMsg, &myHeader); err != nil {
if err := cosmos.Cdc.UnmarshalBinaryBare(params.HeaderOrCrossChainMsg, &myHeader); err != nil {
return nil, fmt.Errorf("Cosmos MakeDepositProposal, unmarshal cosmos header failed: %v", err)
}
if myHeader.Header.Height != int64(params.Height) {
Expand All @@ -89,29 +70,28 @@ func (this *CosmosHandler) MakeDepositProposal(service *native.NativeService) (*
myHeader.Header.Height > info.Height {
cosmos.PutEpochSwitchInfo(service, params.SourceChainID, &cosmos.CosmosEpochSwitchInfo{
Height: myHeader.Header.Height,
BlockHash: myHeader.Header.Hash(),
BlockHash: cosmos.HashCosmosHeader(myHeader.Header),
NextValidatorsHash: myHeader.Header.NextValidatorsHash,
ChainID: myHeader.Header.ChainID,
})
}

var proofValue CosmosProofValue
if err = cdc.UnmarshalBinaryBare(params.Extra, &proofValue); err != nil {
if err = cosmos.Cdc.UnmarshalBinaryBare(params.Extra, &proofValue); err != nil {
return nil, fmt.Errorf("Cosmos MakeDepositProposal, unmarshal proof value err: %v", err)
}
var proof merkle.Proof
err = cdc.UnmarshalBinaryBare(params.Proof, &proof)
err = cosmos.Cdc.UnmarshalBinaryBare(params.Proof, &proof)
if err != nil {
return nil, fmt.Errorf("Cosmos MakeDepositProposal, unmarshal proof err: %v", err)
}
prt := ProofRuntime()
if len(proofValue.Kp) != 0 {
prt := rootmulti.DefaultProofRuntime()
err = prt.VerifyValue(&proof, myHeader.Header.AppHash, proofValue.Kp, proofValue.Value)
if err != nil {
return nil, fmt.Errorf("Cosmos MakeDepositProposal, proof error: %s", err)
}
} else {
prt := rootmulti.DefaultProofRuntime()
err = prt.VerifyAbsence(&proof, myHeader.Header.AppHash, string(proofValue.Value))
if err != nil {
return nil, fmt.Errorf("Cosmos MakeDepositProposal, proof error: %s", err)
Expand Down
139 changes: 139 additions & 0 deletions native/service/cross_chain_manager/cosmos/proof.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (C) 2021 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 cosmos

import (
"fmt"

ics23 "github.com/confio/ics23/go"
"github.com/cosmos/cosmos-sdk/store/rootmulti"
"github.com/tendermint/tendermint/crypto/merkle"
)

// See: https://pkg.go.dev/github.com/cosmos/[email protected]/store/types

const (
ProofOpIAVLCommitment = "ics23:iavl"
ProofOpSimpleMerkleCommitment = "ics23:simple"
)

func ProofRuntime() *merkle.ProofRuntime {
prt := rootmulti.DefaultProofRuntime()
prt.RegisterOpDecoder(ProofOpIAVLCommitment, CommitmentOpDecoder)
prt.RegisterOpDecoder(ProofOpSimpleMerkleCommitment, CommitmentOpDecoder)

return prt
}

// CommitmentOp implements merkle.ProofOperator by wrapping an ics23 CommitmentProof
// It also contains a Key field to determine which key the proof is proving.
// NOTE: CommitmentProof currently can either be ExistenceProof or NonexistenceProof
//
// Type and Spec are classified by the kind of merkle proof it represents allowing
// the code to be reused by more types. Spec is never on the wire, but mapped from type in the code.
type CommitmentOp struct {
Type string
Spec *ics23.ProofSpec
Key []byte
Proof *ics23.CommitmentProof
}

func (op CommitmentOp) GetKey() []byte {
return op.Key
}

// Run takes in a list of arguments and attempts to run the proof op against these arguments
// Returns the root wrapped in [][]byte if the proof op succeeds with given args. If not,
// it will return an error.
//
// CommitmentOp will accept args of length 1 or length 0
// If length 1 args is passed in, then CommitmentOp will attempt to prove the existence of the key
// with the value provided by args[0] using the embedded CommitmentProof and return the CommitmentRoot of the proof
// If length 0 args is passed in, then CommitmentOp will attempt to prove the absence of the key
// in the CommitmentOp and return the CommitmentRoot of the proof
func (op CommitmentOp) Run(args [][]byte) ([][]byte, error) {
// calculate root from proof
root, err := op.Proof.Calculate()
if err != nil {
return nil, fmt.Errorf("could not calculate root for proof: %v", err)
}
// Only support an existence proof or nonexistence proof (batch proofs currently unsupported)
switch len(args) {
case 0:
// Args are nil, so we verify the absence of the key.
absent := ics23.VerifyNonMembership(op.Spec, root, op.Proof, op.Key)
if !absent {
return nil, fmt.Errorf("proof did not verify absence of key: %s", string(op.Key))
}

case 1:
// Args is length 1, verify existence of key with value args[0]
if !ics23.VerifyMembership(op.Spec, root, op.Proof, op.Key, args[0]) {
return nil, fmt.Errorf("proof did not verify existence of key %s with given value %x", op.Key, args[0])
}
default:
return nil, fmt.Errorf("args must be length 0 or 1, got: %d", len(args))
}

return [][]byte{root}, nil
}

// ProofOp implements ProofOperator interface and converts a CommitmentOp
// into a merkle.ProofOp format that can later be decoded by CommitmentOpDecoder
// back into a CommitmentOp for proof verification
func (op CommitmentOp) ProofOp() merkle.ProofOp {
bz, err := op.Proof.Marshal()
if err != nil {
panic(err.Error())
}
return merkle.ProofOp{
Type: op.Type,
Key: op.Key,
Data: bz,
}
}

// See: https://pkg.go.dev/github.com/cosmos/[email protected]/store/rootmulti

// CommitmentOpDecoder takes a merkle.ProofOp and attempts to decode it into a CommitmentOp ProofOperator
// The proofOp.Data is just a marshalled CommitmentProof. The Key of the CommitmentOp is extracted
// from the unmarshalled proof.
func CommitmentOpDecoder(pop merkle.ProofOp) (merkle.ProofOperator, error) {
var spec *ics23.ProofSpec
switch pop.Type {
case ProofOpIAVLCommitment:
spec = ics23.IavlSpec
case ProofOpSimpleMerkleCommitment:
spec = ics23.TendermintSpec
default:
return nil, fmt.Errorf("unexpected ProofOp.Type; got %s, want supported ics23 subtypes 'ProofOpIAVLCommitment' or 'ProofOpSimpleMerkleCommitment'", pop.Type)
}

proof := &ics23.CommitmentProof{}
err := proof.Unmarshal(pop.Data)
if err != nil {
return nil, err
}

op := CommitmentOp{
Type: pop.Type,
Key: pop.Key,
Spec: spec,
Proof: proof,
}
return op, nil
}
Loading

0 comments on commit 07408cf

Please sign in to comment.