Commit 4af57f5f authored by vicotor's avatar vicotor

add withdrawal tx related.

parent c0c14ca1
......@@ -3,6 +3,7 @@ package engine
import (
"context"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/exchain/go-exchain/exchain"
......@@ -21,6 +22,7 @@ import (
"math/big"
)
// ExChainAPI wrapper all api for rollup.
type ExChainAPI struct {
rollup *rollup.Config
chain chaindb.ChainDB
......@@ -37,6 +39,52 @@ func (e *ExChainAPI) FetchReceipts(ctx context.Context, blockHash common.Hash) (
return nil, nil, errors.New("FetchReceipts is not implemented in exchain currently")
}
func (e *ExChainAPI) GetWDTRoot(ctx context.Context, blockHash common.Hash) (common.Hash, error) {
block := e.chain.BlockByHash(blockHash)
if block == nil {
return common.Hash{}, errors.New("block not found in exchain")
}
tree, err := e.chain.GetWDT(*uint256.NewInt(block.Header.Height))
if err != nil {
return common.Hash{}, err
}
return common.BytesToHash(tree.Root()), nil
}
func (e *ExChainAPI) WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth.WithdrawalProof, error) {
block := e.chain.BlockByHash(txHash)
if block == nil {
return nil, errors.New("block not found in exchain")
}
wblk := wrapper.NewBlkWrapper(block)
var res = &eth.WithdrawalProof{}
tx, _ := e.chain.GetTransaction(txHash)
receipt := e.chain.GetReceipt(txHash)
if receipt == nil {
return nil, errors.New("not found tx receipt")
}
tree, err := e.chain.GetWDT(*uint256.NewInt(receipt.BlockHeight))
if err != nil {
return nil, err
}
item := wrapper.NewTxWrapper(tx).WithdrawlHash()
proof, err := tree.MerkleProof(item.Bytes())
if err != nil {
return nil, errors.New(fmt.Sprintf("failed to get proof (%s)", err.Error()))
}
res.Proof = make([]eth.Bytes32, len(proof))
for i, p := range proof {
copy(res.Proof[i][:], p[:])
}
oo, err := e.OutputV0AtBlock(ctx, wblk.Hash())
if err != nil {
log.WithField("error", err).Error("failed to get output for withdrawal proof")
return nil, err
}
res.Output = *oo
return res, nil
}
func (e *ExChainAPI) OutputV0AtBlock(ctx context.Context, blockHash common.Hash) (*eth.OutputV0, error) {
blk := e.chain.BlockByHash(blockHash)
if blk == nil {
......@@ -44,11 +92,16 @@ func (e *ExChainAPI) OutputV0AtBlock(ctx context.Context, blockHash common.Hash)
}
wblk := wrapper.NewBlkWrapper(blk)
root := eth.Bytes32{}
storageRoot := eth.Bytes32{}
wdtroot, err := e.GetWDTRoot(ctx, blockHash)
if err != nil {
log.WithField("error", err).Error("failed to get wdt root")
return nil, err
}
storageRoot := eth.Bytes32(wdtroot[:])
// todo: vicotor implement this.
copy(root[:], wblk.Header().AppRoot)
copy(storageRoot[:], wblk.Header().AppRoot)
return &eth.OutputV0{
BlockHash: wblk.Hash(),
......
......@@ -3,8 +3,12 @@ package chaindb
import (
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/exchain/go-exchain/exchain"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/exchain/wdt"
"github.com/exchain/go-exchain/exchain/wrapper"
"github.com/exchain/go-exchain/metadb"
"github.com/golang/protobuf/proto"
lru "github.com/hashicorp/golang-lru"
......@@ -22,6 +26,7 @@ type ChainReader interface {
BlockByHash(hash common.Hash) *nebulav1.Block
GetTransaction(hash common.Hash) (*nebulav1.Transaction, error)
GetReceipt(hash common.Hash) *nebulav1.TransactionReceipt
GetWDT(number uint256.Int) (*wdt.MerkleTree, error)
}
func NewChainReader(log log.Logger, database metadb.Database) ChainReader {
......@@ -42,6 +47,9 @@ func NewChainReader(log log.Logger, database metadb.Database) ChainReader {
if chain.headerCache, err = lru.New(1000); err != nil {
panic(err)
}
if chain.wdtCache, err = lru.New(100); err != nil {
log.Error("failed to create mdt cache, ", err)
}
return chain
}
......@@ -51,6 +59,7 @@ type chainReader struct {
receiptCache *lru.Cache
blkCache *lru.Cache
headerCache *lru.Cache
wdtCache *lru.Cache
database metadb.Database
chainId *uint256.Int
}
......@@ -187,6 +196,53 @@ func (m *chainReader) GetBlockReceipts(num *uint256.Int) *nebulav1.TransactionRe
return m.getBlockReceipts(num)
}
func (m *chainReader) GetWDT(number uint256.Int) (*wdt.MerkleTree, error) {
cp := exchain.ToCheckpoint(number)
latest := m.CurrentHeight()
if latest.Cmp(cp.End()) < 0 {
return nil, errors.New("checkpoint not ready")
}
if t, _ := m.wdtCache.Get(cp); t != nil {
return t.(*wdt.MerkleTree), nil
}
nt, err := m.generateWDT(cp)
if err != nil {
return nil, err
}
m.wdtCache.Add(cp, nt)
return nt, nil
}
func (m *chainReader) generateWDT(cp exchain.Checkpoint) (*wdt.MerkleTree, error) {
withdrawalTxs := &nebulav1.TransactionList{
Txs: make([]*nebulav1.Transaction, 0),
}
for i := cp.Start().Uint64(); i <= cp.End().Uint64(); i++ {
blk := m.GetBlock(uint256.NewInt(i))
if blk == nil {
return nil, errors.New("block not found in exchain")
}
wblk := wrapper.NewBlkWrapper(blk)
withdrawalTxs.Txs = append(withdrawalTxs.Txs, wblk.FilterTransactions(wrapper.TxTypeFilter(nebulav1.TxType_WithdrawTx))...)
}
leaves := make([][]byte, len(withdrawalTxs.Txs))
for _, tx := range withdrawalTxs.Txs {
content := tx.GetWithdrawTx()
data := make([]byte, 0)
data = append(data, content.User...)
data = append(data, content.Coin...)
data = append(data, content.Amount...)
leaves = append(leaves, crypto.Keccak256Hash(data).Bytes())
}
tree, err := wdt.GenerateTreeFromHashedItems(leaves)
if err != nil {
m.log.Error("failed to generate wdt tree", "err", err)
return nil, err
}
return tree, nil
}
func (m *chainReader) blockNumberByHash(hash common.Hash) *uint256.Int {
k := blockNumKey(hash)
if number, exist := m.txCache.Get(k); exist {
......
......@@ -4,10 +4,12 @@ import (
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
"github.com/exchain/go-exchain/exchain"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/exchain/go-exchain/exchain/wdt"
"github.com/exchain/go-exchain/exchain/wrapper"
"github.com/exchain/go-exchain/metadb"
"github.com/exchain/go-exchain/metadb/memdb"
......@@ -39,6 +41,7 @@ type ChainDB interface {
SubscribeChainEvent(ch chan<- exchain.ChainEvent) event.Subscription
EmitChain(block *nebulav1.Block, hash common.Hash)
ResetHeight(*uint256.Int, bool) error
GetWDT(number uint256.Int) (*wdt.MerkleTree, error)
}
var (
......@@ -69,6 +72,9 @@ func NewChainDB(log log.Logger, database metadb.Database) ChainDB {
if chain.receiptCache, err = lru.New(1000000); err != nil {
panic(err)
}
if chain.wdtCache, err = lru.New(100); err != nil {
log.Error("failed to create mdt cache, ", err)
}
chain.storeTask()
return chain
}
......@@ -81,6 +87,7 @@ type chainData struct {
type chaindb struct {
log log.Logger
cache metadb.CacheKV
wdtCache *lru.Cache
txCache *lru.Cache
receiptCache *lru.Cache
database metadb.Database
......@@ -116,6 +123,53 @@ func (m *chaindb) ChainId() (*uint256.Int, error) {
}
}
func (m *chaindb) GetWDT(number uint256.Int) (*wdt.MerkleTree, error) {
cp := exchain.ToCheckpoint(number)
latest := m.CurrentHeight()
if latest.Cmp(cp.End()) < 0 {
return nil, errors.New("checkpoint not ready")
}
if t, _ := m.wdtCache.Get(cp); t != nil {
return t.(*wdt.MerkleTree), nil
}
nt, err := m.generateWDT(cp)
if err != nil {
return nil, err
}
m.wdtCache.Add(cp, nt)
return nt, nil
}
func (m *chaindb) generateWDT(cp exchain.Checkpoint) (*wdt.MerkleTree, error) {
withdrawalTxs := &nebulav1.TransactionList{
Txs: make([]*nebulav1.Transaction, 0),
}
for i := cp.Start().Uint64(); i <= cp.End().Uint64(); i++ {
blk := m.GetBlock(uint256.NewInt(i))
if blk == nil {
return nil, errors.New("block not found in exchain")
}
wblk := wrapper.NewBlkWrapper(blk)
withdrawalTxs.Txs = append(withdrawalTxs.Txs, wblk.FilterTransactions(wrapper.TxTypeFilter(nebulav1.TxType_WithdrawTx))...)
}
leaves := make([][]byte, len(withdrawalTxs.Txs))
for _, tx := range withdrawalTxs.Txs {
content := tx.GetWithdrawTx()
data := make([]byte, 0)
data = append(data, content.User...)
data = append(data, content.Coin...)
data = append(data, content.Amount...)
leaves = append(leaves, crypto.Keccak256Hash(data).Bytes())
}
tree, err := wdt.GenerateTreeFromHashedItems(leaves)
if err != nil {
m.log.Error("failed to generate wdt tree", "err", err)
return nil, err
}
return tree, nil
}
func (m *chaindb) SaveChainId(chainid *uint256.Int) error {
k := chainIdKey()
return m.database.Put([]byte(k), chainid.Bytes())
......
package chaindb
import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
"strings"
......@@ -17,6 +18,7 @@ const (
ReceiptKeyPrefix = "re-"
HeightKey = "hei-chain"
ChainIdKey = "chain-id"
WithdrawalKeyPrefix = "wd-"
)
func chainIdKey() string {
......@@ -82,3 +84,17 @@ func receiptKey(hash common.Hash) string {
s = append(s, h...)
return string(s)
}
var (
checkpointInterval = uint256.NewInt(120)
)
func withdrawalKey(number *uint256.Int, hash common.Hash) string {
h := hash.String()
cp := new(uint256.Int).Div(number, checkpointInterval).Uint64()
s := make([]byte, 0)
checkPointPrefix := fmt.Sprintf("%s-%d-", WithdrawalKeyPrefix, cp+1)
s = append(s, checkPointPrefix...)
s = append(s, h...)
return string(s)
}
package exchain
import "github.com/holiman/uint256"
const (
ChainCheckpointInterval = 120 // 1 checkpoint every 120 blocks, from 1 to 120, 121 to 240, etc.
)
var (
big1 = uint256.NewInt(1)
)
type Checkpoint uint64
func (c Checkpoint) Start() *uint256.Int {
// start = interval * cp + 1
start := new(uint256.Int).Add(big1, new(uint256.Int).Mul(uint256.NewInt(uint64(c)), uint256.NewInt(ChainCheckpointInterval)))
return start
}
func (c Checkpoint) End() *uint256.Int {
// end = interval * (cp + 1)
end := new(uint256.Int).Mul(new(uint256.Int).Add(big1, uint256.NewInt(uint64(c))), uint256.NewInt(ChainCheckpointInterval))
return end
}
func ToCheckpoint(number uint256.Int) Checkpoint {
if number.IsZero() {
return 0
}
cp := new(uint256.Int).Div(new(uint256.Int).SubUint64(&number, 1), uint256.NewInt(ChainCheckpointInterval))
return Checkpoint(cp.Uint64())
}
......@@ -2,11 +2,13 @@ package exchainapi
import (
"context"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/exchain/go-exchain/exchain/chaindb"
nodev1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/node/v1"
"github.com/exchain/go-exchain/exchain/wrapper"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/holiman/uint256"
"google.golang.org/grpc"
......@@ -102,6 +104,26 @@ func (s *server) GetCoinInfo(ctx context.Context, request *nodev1.GetCoinInfoReq
panic("implement me")
}
func (s *server) GetWithdrawalProof(ctx context.Context, request *nodev1.WithdrawalProofRequest) (*nodev1.WithdrawalProofResponse, error) {
res := &nodev1.WithdrawalProofResponse{}
tx, _ := s.chain.GetTransaction(common.HexToHash(request.Txhash))
receipt := s.chain.GetReceipt(common.HexToHash(request.Txhash))
if receipt == nil {
return nil, errors.New("not found tx receipt")
}
tree, err := s.chain.GetWDT(*uint256.NewInt(receipt.BlockHeight))
if err != nil {
return nil, err
}
item := wrapper.NewTxWrapper(tx).WithdrawlHash()
proof, err := tree.MerkleProof(item.Bytes())
if err != nil {
return nil, errors.New(fmt.Sprintf("failed to get proof (%s)", err.Error()))
}
res.Proof = proof
return res, nil
}
func StartServer(logger log.Logger, grpcPort int, gwPort int, chain chaindb.ChainReader) error {
defer logger.Info("grpc and gateway server stopped")
logger.Info("starting grpc and gateway server", "grpcPort", grpcPort, "gwPort", gwPort)
......
......@@ -2,6 +2,7 @@ package exchainclient
import (
"context"
"github.com/exchain/go-exchain/exchain"
nodev1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/node/v1"
"github.com/exchain/go-exchain/exchain/wrapper"
"google.golang.org/grpc"
......@@ -37,6 +38,17 @@ func (e *ExClient) BlockByNumber(ctx context.Context, number *big.Int) (*wrapper
return wrapper.NewBlkWrapper(res.Block), nil
}
func (e *ExClient) GetWithdrawalProof(ctx context.Context, param exchain.ExChainWithdrawalParam) ([][]byte, error) {
req := &nodev1.WithdrawalProofRequest{
Txhash: param.TxHash.String(),
}
res, err := e.ins.GetWithdrawalProof(ctx, req)
if err != nil {
return nil, err
}
return res.Proof, nil
}
func (e *ExClient) Close() {
e.conn.Close()
return
......
......@@ -862,6 +862,100 @@ func (x *GetCoinInfoResponse) GetCoin() *v1.Coin {
return nil
}
type WithdrawalProofRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Txhash string `protobuf:"bytes,1,opt,name=txhash,proto3" json:"txhash,omitempty"`
}
func (x *WithdrawalProofRequest) Reset() {
*x = WithdrawalProofRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_node_v1_node_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *WithdrawalProofRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*WithdrawalProofRequest) ProtoMessage() {}
func (x *WithdrawalProofRequest) ProtoReflect() protoreflect.Message {
mi := &file_node_v1_node_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use WithdrawalProofRequest.ProtoReflect.Descriptor instead.
func (*WithdrawalProofRequest) Descriptor() ([]byte, []int) {
return file_node_v1_node_proto_rawDescGZIP(), []int{18}
}
func (x *WithdrawalProofRequest) GetTxhash() string {
if x != nil {
return x.Txhash
}
return ""
}
type WithdrawalProofResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Proof [][]byte `protobuf:"bytes,1,rep,name=proof,proto3" json:"proof,omitempty"`
}
func (x *WithdrawalProofResponse) Reset() {
*x = WithdrawalProofResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_node_v1_node_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *WithdrawalProofResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*WithdrawalProofResponse) ProtoMessage() {}
func (x *WithdrawalProofResponse) ProtoReflect() protoreflect.Message {
mi := &file_node_v1_node_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use WithdrawalProofResponse.ProtoReflect.Descriptor instead.
func (*WithdrawalProofResponse) Descriptor() ([]byte, []int) {
return file_node_v1_node_proto_rawDescGZIP(), []int{19}
}
func (x *WithdrawalProofResponse) GetProof() [][]byte {
if x != nil {
return x.Proof
}
return nil
}
var File_node_v1_node_proto protoreflect.FileDescriptor
var file_node_v1_node_proto_rawDesc = []byte{
......@@ -952,106 +1046,122 @@ var file_node_v1_node_proto_rawDesc = []byte{
0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x2b, 0x0a, 0x04, 0x63, 0x6f, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x65, 0x62, 0x75, 0x6c, 0x61, 0x2e,
0x76, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x04, 0x63, 0x6f, 0x69, 0x6e, 0x32, 0xdd, 0x0a,
0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x75, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x41, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e,
0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e,
0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x12,
0x1c, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64,
0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x94, 0x01,
0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
0x42, 0x79, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61,
0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x48, 0x65,
0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x65, 0x78,
0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x12, 0x2b, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c,
0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x5f, 0x6e, 0x75,
0x6d, 0x62, 0x65, 0x72, 0x12, 0x85, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63,
0x6b, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x65, 0x78, 0x63, 0x68,
0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x78,
0x76, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x04, 0x63, 0x6f, 0x69, 0x6e, 0x22, 0x30, 0x0a,
0x16, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6f, 0x66,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x78, 0x68, 0x61, 0x73,
0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x78, 0x68, 0x61, 0x73, 0x68, 0x22,
0x2f, 0x0a, 0x17, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x50, 0x72, 0x6f,
0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x72,
0x6f, 0x6f, 0x66, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x70, 0x72, 0x6f, 0x6f, 0x66,
0x32, 0xf6, 0x0b, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x75, 0x0a, 0x0a, 0x47, 0x65, 0x74,
0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61,
0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f,
0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x12, 0x94, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x61,
0x64, 0x65, 0x72, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x21, 0x2e, 0x65, 0x78,
0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e,
0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f,
0x63, 0x6b, 0x5f, 0x62, 0x79, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x81, 0x01, 0x0a,
0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12,
0x20, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x21, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12, 0x22, 0x2f, 0x65,
0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67,
0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x62, 0x79, 0x5f, 0x68, 0x61, 0x73, 0x68,
0x12, 0x99, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x26, 0x2e, 0x65, 0x78, 0x63, 0x68,
0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54,
0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x27, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x2a, 0x12, 0x28, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f,
0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x79, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x12, 0x92, 0x01, 0x0a,
0x15, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x22, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e,
0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65,
0x69, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x65, 0x78, 0x63,
0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x72,
0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x70,
0x74, 0x12, 0x80, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69, 0x72, 0x4c, 0x69, 0x73,
0x74, 0x12, 0x23, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65,
0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e,
0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69, 0x72,
0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76,
0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x5f,
0x6c, 0x69, 0x73, 0x74, 0x12, 0x80, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69, 0x72,
0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e,
0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69, 0x72, 0x49, 0x6e,
0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65, 0x78, 0x63, 0x68,
0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22,
0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x65, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x12, 0x2b, 0x2f, 0x65, 0x78, 0x63,
0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74,
0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79,
0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x85, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x42,
0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x79, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x20, 0x2e, 0x65,
0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21,
0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31,
0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x65, 0x78, 0x63, 0x68,
0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f,
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x62, 0x79, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12,
0x81, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x42, 0x79, 0x48, 0x61,
0x73, 0x68, 0x12, 0x20, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e,
0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x12,
0x22, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64,
0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x62, 0x79, 0x5f, 0x68,
0x61, 0x73, 0x68, 0x12, 0x99, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x26, 0x2e, 0x65,
0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e,
0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f,
0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e,
0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x79, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x12,
0x92, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x12, 0x22, 0x2e, 0x65, 0x78, 0x63, 0x68,
0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52,
0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e,
0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x65, 0x78, 0x63,
0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74,
0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63,
0x65, 0x69, 0x70, 0x74, 0x12, 0x80, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69, 0x72,
0x4c, 0x69, 0x73, 0x74, 0x12, 0x23, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e,
0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69, 0x72, 0x4c, 0x69,
0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65, 0x78, 0x63, 0x68,
0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50,
0x61, 0x69, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x61, 0x69, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x70, 0x61,
0x69, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x80, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43,
0x6f, 0x69, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x23, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69,
0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65,
0x69, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x80, 0x01, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x50,
0x61, 0x69, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x69,
0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65,
0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x65, 0x74, 0x50, 0x61, 0x69, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x65, 0x78, 0x63,
0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74,
0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x80, 0x01, 0x0a, 0x0b, 0x47,
0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x2e, 0x65, 0x78, 0x63,
0x5f, 0x70, 0x61, 0x69, 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x80, 0x01, 0x0a, 0x0b, 0x47,
0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x23, 0x2e, 0x65, 0x78, 0x63,
0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74,
0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x43, 0x6f, 0x69, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x24, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73,
0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f,
0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f,
0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x42, 0xc4, 0x01,
0x0a, 0x13, 0x63, 0x6f, 0x6d, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f,
0x64, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f,
0x50, 0x01, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65,
0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
0x6f, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76,
0x31, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x45, 0x4e, 0x58, 0xaa, 0x02,
0x0f, 0x45, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x56, 0x31,
0xca, 0x02, 0x0f, 0x45, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c,
0x56, 0x31, 0xe2, 0x02, 0x1b, 0x45, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5c, 0x4e, 0x6f, 0x64,
0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
0xea, 0x02, 0x11, 0x45, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65,
0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x80, 0x01,
0x0a, 0x0b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x2e,
0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e,
0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x24, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64,
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x66, 0x6f,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20,
0x12, 0x1e, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x6e, 0x6f,
0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f,
0x12, 0x96, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77,
0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x12, 0x27, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69,
0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72,
0x61, 0x77, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x28, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
0x76, 0x31, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x50, 0x72, 0x6f,
0x6f, 0x66, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x27, 0x12, 0x25, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x76, 0x31, 0x2f,
0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x67, 0x65, 0x74, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61,
0x77, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x42, 0xc4, 0x01, 0x0a, 0x13, 0x63, 0x6f,
0x6d, 0x2e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x76,
0x31, 0x42, 0x09, 0x4e, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x44,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x63, 0x68, 0x61,
0x69, 0x6e, 0x2f, 0x67, 0x6f, 0x2d, 0x65, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x65, 0x78,
0x63, 0x68, 0x61, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67,
0x65, 0x6e, 0x2f, 0x67, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x76, 0x31, 0x3b, 0x6e, 0x6f,
0x64, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x45, 0x4e, 0x58, 0xaa, 0x02, 0x0f, 0x45, 0x78, 0x63,
0x68, 0x61, 0x69, 0x6e, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x0f, 0x45,
0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02,
0x1b, 0x45, 0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5c, 0x4e, 0x6f, 0x64, 0x65, 0x5c, 0x56, 0x31,
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x11, 0x45,
0x78, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x3a, 0x3a, 0x4e, 0x6f, 0x64, 0x65, 0x3a, 0x3a, 0x56, 0x31,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
......@@ -1066,44 +1176,46 @@ func file_node_v1_node_proto_rawDescGZIP() []byte {
return file_node_v1_node_proto_rawDescData
}
var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 18)
var file_node_v1_node_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_node_v1_node_proto_goTypes = []interface{}{
(*AccountRequest)(nil), // 0: exchain.node.v1.AccountRequest
(*AccountResponse)(nil), // 1: exchain.node.v1.AccountResponse
(*GetHeaderRequest)(nil), // 2: exchain.node.v1.GetHeaderRequest
(*GetHeaderResponse)(nil), // 3: exchain.node.v1.GetHeaderResponse
(*GetBlockRequest)(nil), // 4: exchain.node.v1.GetBlockRequest
(*GetBlockResponse)(nil), // 5: exchain.node.v1.GetBlockResponse
(*GetTransactionRequest)(nil), // 6: exchain.node.v1.GetTransactionRequest
(*GetTransactionResponse)(nil), // 7: exchain.node.v1.GetTransactionResponse
(*GetReceiptRequest)(nil), // 8: exchain.node.v1.GetReceiptRequest
(*GetReceiptResponse)(nil), // 9: exchain.node.v1.GetReceiptResponse
(*GetPairListRequest)(nil), // 10: exchain.node.v1.GetPairListRequest
(*GetPairListResponse)(nil), // 11: exchain.node.v1.GetPairListResponse
(*GetPairInfoRequest)(nil), // 12: exchain.node.v1.GetPairInfoRequest
(*GetPairInfoResponse)(nil), // 13: exchain.node.v1.GetPairInfoResponse
(*GetCoinListRequest)(nil), // 14: exchain.node.v1.GetCoinListRequest
(*GetCoinListResponse)(nil), // 15: exchain.node.v1.GetCoinListResponse
(*GetCoinInfoRequest)(nil), // 16: exchain.node.v1.GetCoinInfoRequest
(*GetCoinInfoResponse)(nil), // 17: exchain.node.v1.GetCoinInfoResponse
(*v1.Account)(nil), // 18: exchain.nebula.v1.Account
(*v1.BlockHeader)(nil), // 19: exchain.nebula.v1.BlockHeader
(*v1.Block)(nil), // 20: exchain.nebula.v1.Block
(*v1.Transaction)(nil), // 21: exchain.nebula.v1.Transaction
(*v1.TransactionReceipt)(nil), // 22: exchain.nebula.v1.TransactionReceipt
(*v1.Pair)(nil), // 23: exchain.nebula.v1.Pair
(*v1.Coin)(nil), // 24: exchain.nebula.v1.Coin
(*AccountRequest)(nil), // 0: exchain.node.v1.AccountRequest
(*AccountResponse)(nil), // 1: exchain.node.v1.AccountResponse
(*GetHeaderRequest)(nil), // 2: exchain.node.v1.GetHeaderRequest
(*GetHeaderResponse)(nil), // 3: exchain.node.v1.GetHeaderResponse
(*GetBlockRequest)(nil), // 4: exchain.node.v1.GetBlockRequest
(*GetBlockResponse)(nil), // 5: exchain.node.v1.GetBlockResponse
(*GetTransactionRequest)(nil), // 6: exchain.node.v1.GetTransactionRequest
(*GetTransactionResponse)(nil), // 7: exchain.node.v1.GetTransactionResponse
(*GetReceiptRequest)(nil), // 8: exchain.node.v1.GetReceiptRequest
(*GetReceiptResponse)(nil), // 9: exchain.node.v1.GetReceiptResponse
(*GetPairListRequest)(nil), // 10: exchain.node.v1.GetPairListRequest
(*GetPairListResponse)(nil), // 11: exchain.node.v1.GetPairListResponse
(*GetPairInfoRequest)(nil), // 12: exchain.node.v1.GetPairInfoRequest
(*GetPairInfoResponse)(nil), // 13: exchain.node.v1.GetPairInfoResponse
(*GetCoinListRequest)(nil), // 14: exchain.node.v1.GetCoinListRequest
(*GetCoinListResponse)(nil), // 15: exchain.node.v1.GetCoinListResponse
(*GetCoinInfoRequest)(nil), // 16: exchain.node.v1.GetCoinInfoRequest
(*GetCoinInfoResponse)(nil), // 17: exchain.node.v1.GetCoinInfoResponse
(*WithdrawalProofRequest)(nil), // 18: exchain.node.v1.WithdrawalProofRequest
(*WithdrawalProofResponse)(nil), // 19: exchain.node.v1.WithdrawalProofResponse
(*v1.Account)(nil), // 20: exchain.nebula.v1.Account
(*v1.BlockHeader)(nil), // 21: exchain.nebula.v1.BlockHeader
(*v1.Block)(nil), // 22: exchain.nebula.v1.Block
(*v1.Transaction)(nil), // 23: exchain.nebula.v1.Transaction
(*v1.TransactionReceipt)(nil), // 24: exchain.nebula.v1.TransactionReceipt
(*v1.Pair)(nil), // 25: exchain.nebula.v1.Pair
(*v1.Coin)(nil), // 26: exchain.nebula.v1.Coin
}
var file_node_v1_node_proto_depIdxs = []int32{
18, // 0: exchain.node.v1.AccountResponse.account:type_name -> exchain.nebula.v1.Account
19, // 1: exchain.node.v1.GetHeaderResponse.header:type_name -> exchain.nebula.v1.BlockHeader
20, // 2: exchain.node.v1.GetBlockResponse.block:type_name -> exchain.nebula.v1.Block
21, // 3: exchain.node.v1.GetTransactionResponse.transaction:type_name -> exchain.nebula.v1.Transaction
22, // 4: exchain.node.v1.GetReceiptResponse.receipt:type_name -> exchain.nebula.v1.TransactionReceipt
23, // 5: exchain.node.v1.GetPairListResponse.pairs:type_name -> exchain.nebula.v1.Pair
23, // 6: exchain.node.v1.GetPairInfoResponse.pair:type_name -> exchain.nebula.v1.Pair
24, // 7: exchain.node.v1.GetCoinListResponse.coins:type_name -> exchain.nebula.v1.Coin
24, // 8: exchain.node.v1.GetCoinInfoResponse.coin:type_name -> exchain.nebula.v1.Coin
20, // 0: exchain.node.v1.AccountResponse.account:type_name -> exchain.nebula.v1.Account
21, // 1: exchain.node.v1.GetHeaderResponse.header:type_name -> exchain.nebula.v1.BlockHeader
22, // 2: exchain.node.v1.GetBlockResponse.block:type_name -> exchain.nebula.v1.Block
23, // 3: exchain.node.v1.GetTransactionResponse.transaction:type_name -> exchain.nebula.v1.Transaction
24, // 4: exchain.node.v1.GetReceiptResponse.receipt:type_name -> exchain.nebula.v1.TransactionReceipt
25, // 5: exchain.node.v1.GetPairListResponse.pairs:type_name -> exchain.nebula.v1.Pair
25, // 6: exchain.node.v1.GetPairInfoResponse.pair:type_name -> exchain.nebula.v1.Pair
26, // 7: exchain.node.v1.GetCoinListResponse.coins:type_name -> exchain.nebula.v1.Coin
26, // 8: exchain.node.v1.GetCoinInfoResponse.coin:type_name -> exchain.nebula.v1.Coin
0, // 9: exchain.node.v1.Node.GetAccount:input_type -> exchain.node.v1.AccountRequest
2, // 10: exchain.node.v1.Node.GetBlockHeaderByNumber:input_type -> exchain.node.v1.GetHeaderRequest
4, // 11: exchain.node.v1.Node.GetBlockByNumber:input_type -> exchain.node.v1.GetBlockRequest
......@@ -1114,18 +1226,20 @@ var file_node_v1_node_proto_depIdxs = []int32{
12, // 16: exchain.node.v1.Node.GetPairInfo:input_type -> exchain.node.v1.GetPairInfoRequest
14, // 17: exchain.node.v1.Node.GetCoinList:input_type -> exchain.node.v1.GetCoinListRequest
16, // 18: exchain.node.v1.Node.GetCoinInfo:input_type -> exchain.node.v1.GetCoinInfoRequest
1, // 19: exchain.node.v1.Node.GetAccount:output_type -> exchain.node.v1.AccountResponse
3, // 20: exchain.node.v1.Node.GetBlockHeaderByNumber:output_type -> exchain.node.v1.GetHeaderResponse
5, // 21: exchain.node.v1.Node.GetBlockByNumber:output_type -> exchain.node.v1.GetBlockResponse
5, // 22: exchain.node.v1.Node.GetBlockByHash:output_type -> exchain.node.v1.GetBlockResponse
7, // 23: exchain.node.v1.Node.GetTransactionByHash:output_type -> exchain.node.v1.GetTransactionResponse
9, // 24: exchain.node.v1.Node.GetTransactionReceipt:output_type -> exchain.node.v1.GetReceiptResponse
11, // 25: exchain.node.v1.Node.GetPairList:output_type -> exchain.node.v1.GetPairListResponse
13, // 26: exchain.node.v1.Node.GetPairInfo:output_type -> exchain.node.v1.GetPairInfoResponse
15, // 27: exchain.node.v1.Node.GetCoinList:output_type -> exchain.node.v1.GetCoinListResponse
17, // 28: exchain.node.v1.Node.GetCoinInfo:output_type -> exchain.node.v1.GetCoinInfoResponse
19, // [19:29] is the sub-list for method output_type
9, // [9:19] is the sub-list for method input_type
18, // 19: exchain.node.v1.Node.GetWithdrawalProof:input_type -> exchain.node.v1.WithdrawalProofRequest
1, // 20: exchain.node.v1.Node.GetAccount:output_type -> exchain.node.v1.AccountResponse
3, // 21: exchain.node.v1.Node.GetBlockHeaderByNumber:output_type -> exchain.node.v1.GetHeaderResponse
5, // 22: exchain.node.v1.Node.GetBlockByNumber:output_type -> exchain.node.v1.GetBlockResponse
5, // 23: exchain.node.v1.Node.GetBlockByHash:output_type -> exchain.node.v1.GetBlockResponse
7, // 24: exchain.node.v1.Node.GetTransactionByHash:output_type -> exchain.node.v1.GetTransactionResponse
9, // 25: exchain.node.v1.Node.GetTransactionReceipt:output_type -> exchain.node.v1.GetReceiptResponse
11, // 26: exchain.node.v1.Node.GetPairList:output_type -> exchain.node.v1.GetPairListResponse
13, // 27: exchain.node.v1.Node.GetPairInfo:output_type -> exchain.node.v1.GetPairInfoResponse
15, // 28: exchain.node.v1.Node.GetCoinList:output_type -> exchain.node.v1.GetCoinListResponse
17, // 29: exchain.node.v1.Node.GetCoinInfo:output_type -> exchain.node.v1.GetCoinInfoResponse
19, // 30: exchain.node.v1.Node.GetWithdrawalProof:output_type -> exchain.node.v1.WithdrawalProofResponse
20, // [20:31] is the sub-list for method output_type
9, // [9:20] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension type_name
9, // [9:9] is the sub-list for extension extendee
0, // [0:9] is the sub-list for field type_name
......@@ -1353,6 +1467,30 @@ func file_node_v1_node_proto_init() {
return nil
}
}
file_node_v1_node_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WithdrawalProofRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_node_v1_node_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*WithdrawalProofResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
......@@ -1360,7 +1498,7 @@ func file_node_v1_node_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_node_v1_node_proto_rawDesc,
NumEnums: 0,
NumMessages: 18,
NumMessages: 20,
NumExtensions: 0,
NumServices: 1,
},
......
......@@ -357,6 +357,42 @@ func local_request_Node_GetCoinInfo_0(ctx context.Context, marshaler runtime.Mar
}
var (
filter_Node_GetWithdrawalProof_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Node_GetWithdrawalProof_0(ctx context.Context, marshaler runtime.Marshaler, client NodeClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq WithdrawalProofRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Node_GetWithdrawalProof_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.GetWithdrawalProof(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Node_GetWithdrawalProof_0(ctx context.Context, marshaler runtime.Marshaler, server NodeServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq WithdrawalProofRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Node_GetWithdrawalProof_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.GetWithdrawalProof(ctx, &protoReq)
return msg, metadata, err
}
// RegisterNodeHandlerServer registers the http handlers for service Node to "mux".
// UnaryRPC :call NodeServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
......@@ -593,6 +629,29 @@ func RegisterNodeHandlerServer(ctx context.Context, mux *runtime.ServeMux, serve
})
mux.Handle("GET", pattern_Node_GetWithdrawalProof_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Node_GetWithdrawalProof_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Node_GetWithdrawalProof_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
......@@ -834,6 +893,26 @@ func RegisterNodeHandlerClient(ctx context.Context, mux *runtime.ServeMux, clien
})
mux.Handle("GET", pattern_Node_GetWithdrawalProof_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Node_GetWithdrawalProof_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Node_GetWithdrawalProof_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
......@@ -857,6 +936,8 @@ var (
pattern_Node_GetCoinList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"exchain", "v1", "node", "get_coin_list"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Node_GetCoinInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"exchain", "v1", "node", "get_coin_info"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Node_GetWithdrawalProof_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"exchain", "v1", "node", "get_withdrawal_proof"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
......@@ -879,4 +960,6 @@ var (
forward_Node_GetCoinList_0 = runtime.ForwardResponseMessage
forward_Node_GetCoinInfo_0 = runtime.ForwardResponseMessage
forward_Node_GetWithdrawalProof_0 = runtime.ForwardResponseMessage
)
......@@ -33,6 +33,7 @@ type NodeClient interface {
GetPairInfo(ctx context.Context, in *GetPairInfoRequest, opts ...grpc.CallOption) (*GetPairInfoResponse, error)
GetCoinList(ctx context.Context, in *GetCoinListRequest, opts ...grpc.CallOption) (*GetCoinListResponse, error)
GetCoinInfo(ctx context.Context, in *GetCoinInfoRequest, opts ...grpc.CallOption) (*GetCoinInfoResponse, error)
GetWithdrawalProof(ctx context.Context, in *WithdrawalProofRequest, opts ...grpc.CallOption) (*WithdrawalProofResponse, error)
}
type nodeClient struct {
......@@ -133,6 +134,15 @@ func (c *nodeClient) GetCoinInfo(ctx context.Context, in *GetCoinInfoRequest, op
return out, nil
}
func (c *nodeClient) GetWithdrawalProof(ctx context.Context, in *WithdrawalProofRequest, opts ...grpc.CallOption) (*WithdrawalProofResponse, error) {
out := new(WithdrawalProofResponse)
err := c.cc.Invoke(ctx, "/exchain.node.v1.Node/GetWithdrawalProof", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// NodeServer is the server API for Node service.
// All implementations must embed UnimplementedNodeServer
// for forward compatibility
......@@ -148,6 +158,7 @@ type NodeServer interface {
GetPairInfo(context.Context, *GetPairInfoRequest) (*GetPairInfoResponse, error)
GetCoinList(context.Context, *GetCoinListRequest) (*GetCoinListResponse, error)
GetCoinInfo(context.Context, *GetCoinInfoRequest) (*GetCoinInfoResponse, error)
GetWithdrawalProof(context.Context, *WithdrawalProofRequest) (*WithdrawalProofResponse, error)
mustEmbedUnimplementedNodeServer()
}
......@@ -185,6 +196,9 @@ func (UnimplementedNodeServer) GetCoinList(context.Context, *GetCoinListRequest)
func (UnimplementedNodeServer) GetCoinInfo(context.Context, *GetCoinInfoRequest) (*GetCoinInfoResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetCoinInfo not implemented")
}
func (UnimplementedNodeServer) GetWithdrawalProof(context.Context, *WithdrawalProofRequest) (*WithdrawalProofResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetWithdrawalProof not implemented")
}
func (UnimplementedNodeServer) mustEmbedUnimplementedNodeServer() {}
// UnsafeNodeServer may be embedded to opt out of forward compatibility for this service.
......@@ -378,6 +392,24 @@ func _Node_GetCoinInfo_Handler(srv interface{}, ctx context.Context, dec func(in
return interceptor(ctx, in, info, handler)
}
func _Node_GetWithdrawalProof_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(WithdrawalProofRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(NodeServer).GetWithdrawalProof(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/exchain.node.v1.Node/GetWithdrawalProof",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(NodeServer).GetWithdrawalProof(ctx, req.(*WithdrawalProofRequest))
}
return interceptor(ctx, in, info, handler)
}
// Node_ServiceDesc is the grpc.ServiceDesc for Node service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
......@@ -425,6 +457,10 @@ var Node_ServiceDesc = grpc.ServiceDesc{
MethodName: "GetCoinInfo",
Handler: _Node_GetCoinInfo_Handler,
},
{
MethodName: "GetWithdrawalProof",
Handler: _Node_GetWithdrawalProof_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "node/v1/node.proto",
......
......@@ -61,6 +61,10 @@ service Node {
rpc GetCoinInfo(GetCoinInfoRequest) returns (GetCoinInfoResponse) {
option (google.api.http) = {get: "/exchain/v1/node/get_coin_info"};
}
rpc GetWithdrawalProof(WithdrawalProofRequest) returns (WithdrawalProofResponse) {
option (google.api.http) = {get: "/exchain/v1/node/get_withdrawal_proof"};
}
}
message AccountRequest {
......@@ -131,3 +135,11 @@ message GetCoinInfoRequest {
message GetCoinInfoResponse {
exchain.nebula.v1.Coin coin = 1;
}
message WithdrawalProofRequest {
string txhash = 1;
}
message WithdrawalProofResponse {
repeated bytes proof = 1;
}
package wdt
import "bytes"
// Sorts2Bytes by contents.
func Sort2Bytes(i []byte, j []byte) ([]byte, []byte) {
if lessThanBytes(i, j) {
return i, j
} else {
return j, i
}
}
func lessThanBytes(i []byte, j []byte) bool {
return bytes.Compare(i, j) <= 0
}
func safeCopyBytes(cp []byte) []byte {
if cp != nil {
copied := make([]byte, len(cp))
copy(copied, cp)
return copied
}
return nil
}
func copy2dBytes(ary [][]byte) [][]byte {
if ary != nil {
copied := make([][]byte, len(ary))
for i, a := range ary {
copied[i] = safeCopyBytes(a)
}
return copied
}
return nil
}
func padTo(b []byte, size int) []byte {
if len(b) > size {
return b
}
return append(b, make([]byte, size-len(b))...)
}
// Find the next power of 2 unless n is already a power of 2.
func nextPowerOf2(n uint64) uint64 {
var count uint64 = 0
if isPowerOfTwo(n) {
return n
}
for n != 0 {
n >>= 1
count += 1
}
return 1 << count
}
func isPowerOfTwo(n uint64) bool {
return (n & (n - 1)) == 0
}
package wdt
import (
"bytes"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/crypto"
"math"
"sort"
)
// WithdrawalTree (wdt) is a merkle tree that stores all the withdrawal information.
type WithdrawalTree struct {
}
// MerkleTree implements a general purpose Merkle tree.
type MerkleTree struct {
branches [][][]byte
depth uint64
}
func GenerateTreeFromItems(items [][]byte) (*MerkleTree, error) {
// Pad all items to 32 bytes.
leaves := copy2dBytes(items)
for i := range leaves {
leaves[i] = hash(padTo(leaves[i], 32))
}
return GenerateTreeFromHashedItems(leaves)
}
// GenerateTreeFromItems constructs a Merkle tree from a sequence of byte slices.
func GenerateTreeFromHashedItems(items [][]byte) (*MerkleTree, error) {
if len(items) == 0 {
return nil, errors.New("no items provided to generate Merkle tree")
}
// Clone the slice to prevent mutation.
leaves := copy2dBytes(items)
// Sort by byte contents.
sort.Slice(leaves, func(i, j int) bool {
return lessThanBytes(leaves[i], leaves[j])
})
// Even out if uneven.
if len(leaves)%2 == 1 {
duplicate := safeCopyBytes(leaves[len(leaves)-1])
leaves = append(leaves, duplicate)
}
// Append duplicate nodes until even.
nextPowOfItems := nextPowerOf2(uint64(len(leaves)))
for len(leaves) < int(nextPowOfItems) {
leaves = append(leaves, leaves[len(leaves)-2], leaves[len(leaves)-1])
}
depth := uint64(math.Log2(float64(len(leaves)) + 1))
layers := make([][][]byte, depth+1)
layers[0] = leaves
for i := uint64(0); i < depth; i++ {
var updatedValues [][]byte
for j := 0; j < len(layers[i]); j += 2 {
concat := SortAndHash(layers[i][j], layers[i][j+1])
updatedValues = append(updatedValues, concat[:])
}
layers[i+1] = updatedValues
}
return &MerkleTree{
branches: layers,
depth: depth,
}, nil
}
// Items returns the original items passed in when creating the Merkle tree.
func (m *MerkleTree) Items() [][]byte {
return m.branches[0]
}
// Root returns the top-most, Merkle root of the tree.
func (m *MerkleTree) Root() []byte {
return m.branches[len(m.branches)-1][0]
}
// MerkleProof computes a Proof for a leaf from a tree's branches.
func (m *MerkleTree) MerkleProof(leaf []byte) ([][]byte, error) {
nextLeaf := leaf
proof := make([][]byte, m.depth)
for i := uint64(0); i < m.depth; i++ {
leftLeaf, rightLeaf, err := leafPair(m.branches[i], nextLeaf)
if err != nil {
return nil, fmt.Errorf("could not find pair: %v", err)
}
if bytes.Equal(leftLeaf, nextLeaf) {
proof[i] = rightLeaf
} else {
proof[i] = leftLeaf
}
nextLeaf = hash(leftLeaf, rightLeaf)
}
return proof, nil
}
func (m *MerkleTree) MerkleProofOfIndex(indexOfLeaf uint64) ([][]byte, error) {
if int(indexOfLeaf) > len(m.branches[0]) {
return nil, fmt.Errorf("could not find index %d, greater than length %d", indexOfLeaf, m.branches[0])
}
return m.MerkleProof(m.branches[0][indexOfLeaf])
}
// VerifyMerkleBranch verifies a Merkle branch against a root of a tree.
func VerifyMerkleBranch(root, item []byte, proof [][]byte) bool {
node := safeCopyBytes(item)
for i := 0; i < len(proof); i++ {
if lessThanBytes(node, proof[i]) {
node = hash(node[:], proof[i])
} else {
node = hash(proof[i], node[:])
}
}
return bytes.Equal(root, node[:])
}
func leafPair(leaves [][]byte, leaf []byte) ([]byte, []byte, error) {
var found bool
var indexOfLeaf int
for i, item := range leaves {
if bytes.Equal(item, leaf) {
indexOfLeaf = i
found = true
break
}
}
if !found {
return nil, nil, fmt.Errorf("could not find leaf %#x", leaf)
}
var otherLeaf []byte
// Chcek if the leaf is on the left side.
if indexOfLeaf%2 == 0 {
otherLeaf = safeCopyBytes(leaves[indexOfLeaf+1])
} else {
otherLeaf = safeCopyBytes(leaves[indexOfLeaf-1])
}
leftLeaf, rightLeaf := Sort2Bytes(leaf, otherLeaf)
return leftLeaf, rightLeaf, nil
}
// SortAndHash sorts the 2 bytes and keccak256 hashes them.
func SortAndHash(i []byte, j []byte) []byte {
sorted1, sorted2 := Sort2Bytes(i, j)
return hash(sorted1, sorted2)
}
func hash(data ...[]byte) []byte {
return crypto.Keccak256(data...)
}
package exchain
import (
"github.com/ethereum/go-ethereum/common"
"math/big"
)
type ExChainWithdrawalParam struct {
Value *big.Int
User common.Address
Coin string
TxHash common.Hash
}
......@@ -42,6 +42,22 @@ func (b *BlkWrapper) Transactions() []*nebulav1.Transaction {
return []*nebulav1.Transaction{}
}
func TxTypeFilter(txType nebulav1.TxType) func(*nebulav1.Transaction) bool {
return func(tx *nebulav1.Transaction) bool {
return tx.TxType == txType
}
}
func (b *BlkWrapper) FilterTransactions(filter func(*nebulav1.Transaction) bool) []*nebulav1.Transaction {
var filtered []*nebulav1.Transaction
for _, tx := range b.Transactions() {
if filter(tx) {
filtered = append(filtered, tx)
}
}
return filtered
}
func (b *BlkWrapper) ParentHash() common.Hash {
return common.BytesToHash(b.blk.Header.ParentHash)
}
......
......@@ -21,6 +21,7 @@ type l2Client interface {
// Optionally keys of the account storage trie can be specified to include with corresponding values in the proof.
//GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error)
OutputV0AtBlock(ctx context.Context, blockHash common.Hash) (*eth.OutputV0, error)
WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth.WithdrawalProof, error)
}
type driverClient interface {
......@@ -147,6 +148,17 @@ func (n *nodeAPI) OutputAtBlock(ctx context.Context, number hexutil.Uint64) (*et
}, nil
}
func (n *nodeAPI) WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth.WithdrawalProof, error) {
recordDur := n.m.RecordRPCServerRequest("optimism_withdrawalProof")
defer recordDur()
output, err := n.client.WithdrawalProof(ctx, txHash)
if err != nil {
return nil, fmt.Errorf("failed to get withdrawal proof at tx %s: %w", txHash, err)
}
return output, nil
}
func (n *nodeAPI) SafeHeadAtL1Block(ctx context.Context, number hexutil.Uint64) (*eth.SafeHeadResponse, error) {
recordDur := n.m.RecordRPCServerRequest("optimism_safeHeadAtL1Block")
defer recordDur()
......
......@@ -8,6 +8,12 @@ import (
"sync"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/exchain/go-exchain/op-proposer/bindings"
"github.com/exchain/go-exchain/op-proposer/contracts"
"github.com/exchain/go-exchain/op-proposer/metrics"
......@@ -15,12 +21,6 @@ import (
"github.com/exchain/go-exchain/op-service/eth"
"github.com/exchain/go-exchain/op-service/sources/batching"
"github.com/exchain/go-exchain/op-service/txmgr"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
)
var (
......@@ -53,6 +53,7 @@ type DGFContract interface {
type RollupClient interface {
SyncStatus(ctx context.Context) (*eth.SyncStatus, error)
OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error)
WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth.WithdrawalProof, error)
}
type DriverSetup struct {
......
......@@ -2,6 +2,7 @@ package dial
import (
"context"
"github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain/wrapper"
"math/big"
)
......@@ -10,5 +11,6 @@ import (
// It does not describe all of the functions an ethclient.Client has, only the ones used by callers of the L2 Providers
type ExchainClientInterface interface {
BlockByNumber(ctx context.Context, number *big.Int) (*wrapper.BlkWrapper, error)
GetWithdrawalProof(ctx context.Context, param exchain.ExChainWithdrawalParam) ([][]byte, error)
Close()
}
package eth
type WithdrawalProof struct {
Output OutputV0
Proof []Bytes32
}
......@@ -20,6 +20,12 @@ func NewRollupClient(rpc client.RPC) *RollupClient {
return &RollupClient{rpc}
}
func (r *RollupClient) WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth.WithdrawalProof, error) {
var output *eth.WithdrawalProof
err := r.rpc.CallContext(ctx, &output, "optimism_withdrawalProof", txHash)
return output, err
}
func (r *RollupClient) OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) {
var output *eth.OutputResponse
err := r.rpc.CallContext(ctx, &output, "optimism_outputAtBlock", hexutil.Uint64(blockNum))
......
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