Implemented heimdall gRPC client

This commit is contained in:
Krishna Upadhyaya 2022-07-26 02:18:37 +05:30
parent f184772b4d
commit 385aff85f0
13 changed files with 262 additions and 8 deletions

View file

@ -108,6 +108,7 @@ The dumpgenesis command dumps the genesis block configuration in JSON format to
// bor related flags
utils.HeimdallURLFlag,
utils.WithoutHeimdallFlag,
utils.HeimdallgRPCAddressFlag,
},
Category: "BLOCKCHAIN COMMANDS",
Description: `

View file

@ -31,10 +31,18 @@ var (
Usage: "Run without Heimdall service (for testing purpose)",
}
// HeimdallgRPCAddressFlag flag for heimdall gRPC address
HeimdallgRPCAddressFlag = cli.StringFlag{
Name: "bor.heimdallgRPC",
Usage: "Address of Heimdall gRPC service",
Value: ":3132",
}
// BorFlags all bor related flags
BorFlags = []cli.Flag{
HeimdallURLFlag,
WithoutHeimdallFlag,
HeimdallgRPCAddressFlag,
}
)
@ -57,6 +65,7 @@ func getGenesis(genesisPath string) (*core.Genesis, error) {
func SetBorConfig(ctx *cli.Context, cfg *eth.Config) {
cfg.HeimdallURL = ctx.GlobalString(HeimdallURLFlag.Name)
cfg.WithoutHeimdall = ctx.GlobalBool(WithoutHeimdallFlag.Name)
cfg.HeimdallgRPCAddress = ctx.GlobalString(HeimdallgRPCAddressFlag.Name)
}
// CreateBorEthereum Creates bor ethereum object from eth.Config

View file

@ -2027,6 +2027,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
Genesis: genesis,
HeimdallURL: ctx.GlobalString(HeimdallURLFlag.Name),
WithoutHeimdall: ctx.GlobalBool(WithoutHeimdallFlag.Name),
HeimdallgRPCAddress: ctx.GlobalString(HeimdallgRPCAddressFlag.Name),
})
engine = ethereum.Engine()
} else {

View file

@ -0,0 +1,41 @@
package heimdallgrpc
import (
"context"
"math/big"
"github.com/ethereum/go-ethereum/consensus/bor/heimdall/checkpoint"
proto "github.com/maticnetwork/polyproto/heimdall"
)
func (h *HeimdallGRPCClient) FetchCheckpointCount(ctx context.Context) (int64, error) {
res, err := h.client.FetchCheckpointCount(context.Background(), nil)
if err != nil {
return 0, err
}
return res.Result.Result, nil
}
func (h *HeimdallGRPCClient) FetchCheckpoint(ctx context.Context, number int64) (*checkpoint.Checkpoint, error) {
req := &proto.FetchCheckpointRequest{
ID: number,
}
res, err := h.client.FetchCheckpoint(context.Background(), req)
if err != nil {
return nil, err
}
checkpoint := &checkpoint.Checkpoint{
StartBlock: new(big.Int).SetUint64(res.Result.StartBlock),
EndBlock: new(big.Int).SetUint64(res.Result.EndBlock),
RootHash: ConvertH256ToHash(res.Result.RootHash),
Proposer: ConvertH160toAddress(res.Result.Proposer),
BorChainID: res.Result.BorChainID,
Timestamp: uint64(res.Result.Timestamp.GetSeconds()),
}
return checkpoint, nil
}

View file

@ -0,0 +1,37 @@
package heimdallgrpc
import (
"log"
proto "github.com/maticnetwork/polyproto/heimdall"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)
const (
stateFetchLimit = 50
)
type HeimdallGRPCClient struct {
conn *grpc.ClientConn
client proto.HeimdallClient
closeCh chan struct{}
}
func NewHeimdallGRPCClient(address string) *HeimdallGRPCClient {
conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("Failed to connect to Heimdall gRPC server: %v", err)
}
return &HeimdallGRPCClient{
conn: conn,
client: proto.NewHeimdallClient(conn),
closeCh: make(chan struct{}),
}
}
func (h *HeimdallGRPCClient) Close() {
close(h.closeCh)
h.conn.Close()
}

View file

@ -0,0 +1,57 @@
package heimdallgrpc
import (
"context"
"github.com/ethereum/go-ethereum/consensus/bor/heimdall/span"
"github.com/ethereum/go-ethereum/consensus/bor/valset"
proto "github.com/maticnetwork/polyproto/heimdall"
)
func (h *HeimdallGRPCClient) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error) {
req := &proto.SpanRequest{
ID: spanID,
}
res, err := h.client.Span(context.Background(), req)
if err != nil {
return nil, err
}
return parseSpan(res.Result), nil
}
func parseSpan(protoSpan *proto.Span) *span.HeimdallSpan {
resp := &span.HeimdallSpan{
Span: span.Span{
ID: protoSpan.ID,
StartBlock: protoSpan.StartBlock,
EndBlock: protoSpan.EndBlock,
},
ValidatorSet: valset.ValidatorSet{},
SelectedProducers: []valset.Validator{},
ChainID: protoSpan.ChainID,
}
for _, validator := range protoSpan.ValidatorSet.Validators {
resp.ValidatorSet.Validators = append(resp.ValidatorSet.Validators, parseValidator(validator))
}
resp.ValidatorSet.Proposer = parseValidator(protoSpan.ValidatorSet.Proposer)
for _, validator := range protoSpan.SelectedProducers {
resp.SelectedProducers = append(resp.SelectedProducers, *parseValidator(validator))
}
return resp
}
func parseValidator(validator *proto.Validator) *valset.Validator {
return &valset.Validator{
ID: validator.ID,
Address: ConvertH160toAddress(validator.Address),
VotingPower: validator.VotingPower,
ProposerPriority: validator.ProposerPriority,
}
}

View file

@ -0,0 +1,49 @@
package heimdallgrpc
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/bor/clerk"
proto "github.com/maticnetwork/polyproto/heimdall"
)
func (h *HeimdallGRPCClient) StateSyncEvents(fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) {
eventRecords := make([]*clerk.EventRecordWithTime, 0)
req := &proto.StateSyncEventsRequest{
FromID: fromID,
ToTime: uint64(to),
Limit: uint64(stateFetchLimit),
}
res, err := h.client.StateSyncEvents(context.Background(), req)
if err != nil {
return nil, err
}
for {
events, err := res.Recv()
if err != nil {
break
}
for _, event := range events.Result {
eventRecord := &clerk.EventRecordWithTime{
EventRecord: clerk.EventRecord{
ID: event.ID,
Contract: common.HexToAddress(event.Contract),
Data: common.Hex2Bytes(event.Data[2:]),
TxHash: common.HexToHash(event.TxHash),
LogIndex: event.LogIndex,
ChainID: event.ChainID,
},
Time: event.Time.AsTime(),
}
eventRecords = append(eventRecords, eventRecord)
}
}
return eventRecords, nil
}

View file

@ -0,0 +1,42 @@
package heimdallgrpc
import (
"encoding/binary"
proto "github.com/maticnetwork/polyproto/heimdall"
)
func ConvertH160toAddress(h160 *proto.H160) [20]byte {
var addr [20]byte
binary.BigEndian.PutUint64(addr[0:], h160.Hi.Hi)
binary.BigEndian.PutUint64(addr[8:], h160.Hi.Lo)
binary.BigEndian.PutUint32(addr[16:], h160.Lo)
return addr
}
func ConvertAddressToH160(addr [20]byte) *proto.H160 {
return &proto.H160{
Lo: binary.BigEndian.Uint32(addr[16:]),
Hi: &proto.H128{Lo: binary.BigEndian.Uint64(addr[8:]), Hi: binary.BigEndian.Uint64(addr[0:])},
}
}
func ConvertH256ToHash(h256 *proto.H256) [32]byte {
var hash [32]byte
binary.BigEndian.PutUint64(hash[0:], h256.Hi.Hi)
binary.BigEndian.PutUint64(hash[8:], h256.Hi.Lo)
binary.BigEndian.PutUint64(hash[16:], h256.Lo.Hi)
binary.BigEndian.PutUint64(hash[24:], h256.Lo.Lo)
return hash
}
func ConvertHashToH256(hash [32]byte) *proto.H256 {
return &proto.H256{
Lo: &proto.H128{Lo: binary.BigEndian.Uint64(hash[24:]), Hi: binary.BigEndian.Uint64(hash[16:])},
Hi: &proto.H128{Lo: binary.BigEndian.Uint64(hash[8:]), Hi: binary.BigEndian.Uint64(hash[0:])},
}
}

View file

@ -216,6 +216,9 @@ type Config struct {
// No heimdall service
WithoutHeimdall bool
// Address to connect to Heimdall gRPC server
HeimdallgRPCAddress string
// Bor logs flag
BorLogs bool

3
go.mod
View file

@ -44,6 +44,7 @@ require (
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e
github.com/julienschmidt/httprouter v1.3.0
github.com/karalabe/usb v0.0.2
github.com/maticnetwork/polyproto v0.0.1
github.com/mattn/go-colorable v0.1.8
github.com/mattn/go-isatty v0.0.12
github.com/mitchellh/cli v1.1.2
@ -71,7 +72,7 @@ require (
golang.org/x/text v0.3.7
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
golang.org/x/tools v0.1.10
google.golang.org/grpc v1.47.0
google.golang.org/grpc v1.48.0
google.golang.org/protobuf v1.28.0
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6

6
go.sum
View file

@ -337,6 +337,8 @@ github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/maticnetwork/polyproto v0.0.1 h1:qdxoyGd9EkYs910n4crEQqZETpvpRSrprlDYtdbZrqg=
github.com/maticnetwork/polyproto v0.0.1/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o=
github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@ -738,8 +740,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=

View file

@ -153,6 +153,9 @@ type HeimdallConfig struct {
// Without is used to disable remote heimdall during testing
Without bool `hcl:"without,optional"`
// GRPCAddress is the address of the heimdall grpc server
GRPCAddress string `hcl:"grpc-address,optional"`
}
type TxPoolConfig struct {
@ -411,6 +414,7 @@ func DefaultConfig() *Config {
Heimdall: &HeimdallConfig{
URL: "http://localhost:1317",
Without: false,
GRPCAddress: ":3132",
},
SyncMode: "full",
GcMode: "full",
@ -652,6 +656,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
}
n.HeimdallURL = c.Heimdall.URL
n.WithoutHeimdall = c.Heimdall.Without
n.HeimdallgRPCAddress = c.Heimdall.GRPCAddress
// gas price oracle
{

View file

@ -80,6 +80,12 @@ func (c *Command) Flags() *flagset.Flagset {
Value: &c.cliConfig.Heimdall.Without,
Default: c.cliConfig.Heimdall.Without,
})
f.StringFlag(&flagset.StringFlag{
Name: "bor.heimdallgRPC",
Usage: "Address of Heimdall gRPC service",
Value: &c.cliConfig.Heimdall.GRPCAddress,
Default: c.cliConfig.Heimdall.GRPCAddress,
})
// txpool options
f.SliceStringFlag(&flagset.SliceStringFlag{