Skip to content

Commit

Permalink
Merge branch 'develop' into query-pending-nonces-by-chainID
Browse files Browse the repository at this point in the history
  • Loading branch information
kingpinXD authored Sep 20, 2023
2 parents 7ff2123 + b896e3c commit 53d4897
Show file tree
Hide file tree
Showing 48 changed files with 1,710 additions and 1,264 deletions.
990 changes: 908 additions & 82 deletions common/common.pb.go

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions common/headers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package common

import (
"bytes"
"encoding/hex"
"errors"
"fmt"

ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
)

// NewEthereumHeader returns a new HeaderData containing an Ethereum header
func NewEthereumHeader(header []byte) HeaderData {
return HeaderData{
Data: &HeaderData_EthereumHeader{
EthereumHeader: header,
},
}
}

// ParentHash extracts the parent hash from the header
func (h HeaderData) ParentHash() ([]byte, error) {
switch data := h.Data.(type) {
case *HeaderData_EthereumHeader:
var header ethtypes.Header
if err := rlp.DecodeBytes(data.EthereumHeader, &header); err != nil {
return nil, err
}
return header.ParentHash.Bytes(), nil
default:
return nil, errors.New("unrecognized header type")
}
}

// Validate performs a basic validation of the HeaderData
func (h HeaderData) Validate(blockHash []byte, height int64) error {
switch data := h.Data.(type) {
case *HeaderData_EthereumHeader:
return validateEthereumHeader(data.EthereumHeader, blockHash, height)
default:
return errors.New("unrecognized header type")
}
}

// validateEthereumHeader performs a basic validation of the Ethereum header
func validateEthereumHeader(headerBytes []byte, blockHash []byte, height int64) error {
// on ethereum the block header is ~538 bytes in RLP encoding
if len(headerBytes) > 1024 {
return fmt.Errorf("header too long (%d)", len(headerBytes))
}

// RLP encoded block header
var header ethtypes.Header
if err := rlp.DecodeBytes(headerBytes, &header); err != nil {
return fmt.Errorf("cannot decode RLP (%s)", err)
}
if err := header.SanityCheck(); err != nil {
return fmt.Errorf("sanity check failed (%s)", err)
}
if bytes.Compare(blockHash, header.Hash().Bytes()) != 0 {
return fmt.Errorf("tx hash mismatch (%s) vs (%s)", hex.EncodeToString(blockHash), header.Hash().Hex())
}
if height != header.Number.Int64() {
return fmt.Errorf("height mismatch (%d) vs (%d)", height, header.Number.Int64())
}
return nil
}
61 changes: 61 additions & 0 deletions common/proof.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package common

import (
"errors"

ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/zeta-chain/zetacore/common/ethereum"
)

// ErrInvalidProof is a error type for invalid proofs embedding the underlying error
type ErrInvalidProof struct {
Err error
}

func NewErrInvalidProof(err error) ErrInvalidProof {
return ErrInvalidProof{
Err: err,
}
}

func (e ErrInvalidProof) Error() string {
return e.Err.Error()
}

// IsErrorInvalidProof returns true if the error is an ErrInvalidProof
func IsErrorInvalidProof(err error) bool {
return errors.As(err, &ErrInvalidProof{})
}

// NewEthereumProof returns a new Proof containing an Ethereum proof
func NewEthereumProof(proof *ethereum.Proof) *Proof {
return &Proof{
Proof: &Proof_EthereumProof{
EthereumProof: proof,
},
}
}

// Verify verifies the proof against the header
func (p Proof) Verify(headerData HeaderData, txIndex int) ([]byte, error) {
switch proof := p.Proof.(type) {
case *Proof_EthereumProof:
ethHeaderBytes := headerData.GetEthereumHeader()
if ethHeaderBytes == nil {
return nil, errors.New("can't verify ethereum proof against non-ethereum header")
}
var ethHeader ethtypes.Header
err := rlp.DecodeBytes(ethHeaderBytes, &ethHeader)
if err != nil {
return nil, err
}
val, err := proof.EthereumProof.Verify(ethHeader.TxHash, txIndex)
if err != nil {
return nil, NewErrInvalidProof(err)
}
return val, nil
default:
return nil, errors.New("unrecognized proof type")
}
}
15 changes: 15 additions & 0 deletions common/proof_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package common_test

import (
"errors"
"testing"

"github.com/stretchr/testify/require"
"github.com/zeta-chain/zetacore/common"
)

func Test_IsErrorInvalidProof(t *testing.T) {
require.False(t, common.IsErrorInvalidProof(nil))
require.False(t, common.IsErrorInvalidProof(errors.New("foo")))
require.True(t, common.IsErrorInvalidProof(common.NewErrInvalidProof(errors.New("foo"))))
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (sm *SmokeTest) TestDepositEtherIntoZRC20() {
BlockHash: blockHash.Hex(),
TxIndex: int64(txIndex),
TxHash: txHash.Hex(),
Proof: txProof,
Proof: common.NewEthereumProof(txProof),
ChainId: 0,
})
if err != nil {
Expand Down
57 changes: 34 additions & 23 deletions docs/openapi/openapi.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27610,15 +27610,15 @@ paths:
in: query
required: false
type: string
- name: proof.keys
- name: proof.ethereum_proof.keys
in: query
required: false
type: array
items:
type: string
format: byte
collectionFormat: multi
- name: proof.values
- name: proof.ethereum_proof.values
in: query
required: false
type: array
Expand Down Expand Up @@ -50202,6 +50202,24 @@ definitions:
- VOTE_OPTION_ABSTAIN: VOTE_OPTION_ABSTAIN defines an abstain vote option.
- VOTE_OPTION_NO: VOTE_OPTION_NO defines a no vote option.
- VOTE_OPTION_NO_WITH_VETO: VOTE_OPTION_NO_WITH_VETO defines a no with veto vote option.
commonBlockHeader:
type: object
properties:
height:
type: string
format: int64
hash:
type: string
format: byte
parent_hash:
type: string
format: byte
chain_id:
type: string
format: int64
header:
$ref: '#/definitions/commonHeaderData'
title: chain specific header
commonChain:
type: object
properties:
Expand Down Expand Up @@ -50247,6 +50265,18 @@ definitions:
- Gas: Ether, BNB, Matic, Klay, BTC, etc
- ERC20: ERC20 token
- Cmd: not a real coin, rather a command
commonHeaderData:
type: object
properties:
ethereum_header:
type: string
format: byte
title: binary encoded headers; RLP for ethereum
commonProof:
type: object
properties:
ethereum_proof:
$ref: '#/definitions/ethereumProof'
commonPubKeySet:
type: object
properties:
Expand Down Expand Up @@ -50849,25 +50879,6 @@ definitions:
items:
type: object
$ref: '#/definitions/observerNode'
observerBlockHeader:
type: object
properties:
header:
type: string
format: byte
title: binary encoded headers; RLP for ethereum
height:
type: string
format: int64
hash:
type: string
format: byte
parentHash:
type: string
format: byte
chain_id:
type: string
format: int64
observerCoreParams:
type: object
properties:
Expand Down Expand Up @@ -51047,7 +51058,7 @@ definitions:
type: array
items:
type: object
$ref: '#/definitions/observerBlockHeader'
$ref: '#/definitions/commonBlockHeader'
pagination:
$ref: '#/definitions/v1beta1PageResponse'
observerQueryAllNodeAccountResponse:
Expand Down Expand Up @@ -51091,7 +51102,7 @@ definitions:
type: object
properties:
block_header:
$ref: '#/definitions/observerBlockHeader'
$ref: '#/definitions/commonBlockHeader'
observerQueryGetCoreParamsForChainResponse:
type: object
properties:
Expand Down
13 changes: 5 additions & 8 deletions docs/spec/crosschain/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,25 @@

## MsgAddToOutTxTracker

Adds a new record to the outbound transaction tracker.

Only the admin policy account and the observer validators are authorized to
broadcast this message.
AddToOutTxTracker adds a new record to the outbound transaction tracker.
only the admin policy account and the observer validators are authorized to broadcast this message.

```proto
message MsgAddToOutTxTracker {
string creator = 1;
int64 chain_id = 2;
uint64 nonce = 3;
string tx_hash = 4;
ethereum.Proof proof = 5;
common.Proof proof = 5;
string block_hash = 6;
int64 tx_index = 7;
}
```

## MsgRemoveFromOutTxTracker

Removes a record from the outbound transaction tracker by chain ID and nonce.

Only the admin policy account is authorized to broadcast this message.
RemoveFromOutTxTracker removes a record from the outbound transaction tracker by chain ID and nonce.
only the admin policy account is authorized to broadcast this message.

```proto
message MsgRemoveFromOutTxTracker {
Expand Down
6 changes: 3 additions & 3 deletions docs/spec/observer/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ message MsgUpdateKeygen {

## MsgAddBlockHeader

MsgAddBlockHeader handles adding a block header to the store, through majority voting of observers
AddBlockHeader handles adding a block header to the store, through majority voting of observers

```proto
message MsgAddBlockHeader {
string creator = 1;
int64 chain_id = 2;
bytes block_hash = 3;
bytes block_header = 4;
int64 height = 5;
int64 height = 4;
common.HeaderData header = 5;
}
```

23 changes: 22 additions & 1 deletion proto/common/common.proto
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
syntax = "proto3";
package common;

import "common/ethereum/ethereum.proto";
//option (gogoproto.goproto_stringer_all) = false;
//option (gogoproto.stringer_all) = false;
//option (gogoproto.goproto_getters_all) = false;

import "gogoproto/gogo.proto";

option go_package = "github.com/zeta-chain/zetacore/common";
Expand Down Expand Up @@ -62,3 +62,24 @@ message Chain {
ChainName chain_name = 1;
int64 chain_id = 2;
}

message BlockHeader {
int64 height = 1;
bytes hash = 2;
bytes parent_hash = 3;
int64 chain_id = 4;
// chain specific header
HeaderData header = 5 [(gogoproto.nullable) = false];
}

message HeaderData {
oneof data {
bytes ethereum_header = 1; // binary encoded headers; RLP for ethereum
}
}

message Proof {
oneof proof {
ethereum.Proof ethereum_proof = 1;
}
}
4 changes: 2 additions & 2 deletions proto/crosschain/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ syntax = "proto3";
package zetachain.zetacore.crosschain;

import "common/common.proto";
import "common/ethereum/ethereum.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/zeta-chain/zetacore/x/crosschain/types";
Expand All @@ -27,6 +26,7 @@ message MsgUpdateTssAddress {
}

message MsgUpdateTssAddressResponse {}

message MsgWhitelistERC20 {
string creator = 1;
string erc20_address = 2;
Expand All @@ -44,7 +44,7 @@ message MsgAddToOutTxTracker {
int64 chain_id = 2;
uint64 nonce = 3;
string tx_hash = 4;
ethereum.Proof proof = 5;
common.Proof proof = 5;
string block_hash = 6;
int64 tx_index = 7;
}
Expand Down
15 changes: 0 additions & 15 deletions proto/observer/headers.proto

This file was deleted.

Loading

0 comments on commit 53d4897

Please sign in to comment.