polygon/heimdall: drop GRPC support (#9230)

This commit is contained in:
battlmonstr 2024-01-15 16:49:46 +01:00 committed by GitHub
parent f03d2665ff
commit cda48aeaf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 259 additions and 663 deletions

View File

@ -49,7 +49,7 @@ type NodeArgs struct {
MetricsAddr string `arg:"--metrics.addr" json:"metrics.addr,omitempty"`
StaticPeers string `arg:"--staticpeers" json:"staticpeers,omitempty"`
WithoutHeimdall bool `arg:"--bor.withoutheimdall" flag:"" default:"false" json:"bor.withoutheimdall,omitempty"`
HeimdallGrpcAddr string `arg:"--bor.heimdallgRPC" json:"bor.heimdallgRPC,omitempty"`
HeimdallURL string `arg:"--bor.heimdall" json:"bor.heimdall,omitempty"`
WithHeimdallMilestones bool `arg:"--bor.milestone" json:"bor.milestone"`
VMDebug bool `arg:"--vmdebug" flag:"" default:"false" json:"dmdebug"`

View File

@ -11,9 +11,8 @@ import (
"syscall"
"time"
"github.com/ledgerwatch/erigon/cmd/devnet/networks"
"github.com/ledgerwatch/erigon/cmd/devnet/services"
"github.com/ledgerwatch/erigon/cmd/devnet/services/polygon"
"github.com/ledgerwatch/log/v3"
"github.com/urfave/cli/v2"
"github.com/ledgerwatch/erigon-lib/chain/networkname"
"github.com/ledgerwatch/erigon-lib/common/metrics"
@ -23,16 +22,16 @@ import (
_ "github.com/ledgerwatch/erigon/cmd/devnet/contracts/steps"
"github.com/ledgerwatch/erigon/cmd/devnet/devnet"
"github.com/ledgerwatch/erigon/cmd/devnet/devnetutils"
"github.com/ledgerwatch/erigon/cmd/devnet/networks"
"github.com/ledgerwatch/erigon/cmd/devnet/requests"
"github.com/ledgerwatch/erigon/cmd/devnet/scenarios"
"github.com/ledgerwatch/log/v3"
"github.com/ledgerwatch/erigon/cmd/devnet/services"
"github.com/ledgerwatch/erigon/cmd/devnet/services/polygon"
"github.com/ledgerwatch/erigon/cmd/utils/flags"
"github.com/ledgerwatch/erigon/params"
erigon_app "github.com/ledgerwatch/erigon/turbo/app"
"github.com/ledgerwatch/erigon/turbo/debug"
"github.com/ledgerwatch/erigon/turbo/logging"
"github.com/urfave/cli/v2"
)
var (
@ -77,10 +76,10 @@ var (
Usage: "Run with a devnet local Heimdall service",
}
HeimdallGrpcAddressFlag = cli.StringFlag{
Name: "bor.heimdallgRPC",
Usage: "Address of Heimdall gRPC service",
Value: polygon.HeimdallGrpcAddressDefault,
HeimdallURLFlag = cli.StringFlag{
Name: "bor.heimdall",
Usage: "URL of Heimdall service",
Value: polygon.HeimdallURLDefault,
}
BorSprintSizeFlag = cli.IntFlag{
@ -166,7 +165,7 @@ func main() {
&BaseRpcPortFlag,
&WithoutHeimdallFlag,
&LocalHeimdallFlag,
&HeimdallGrpcAddressFlag,
&HeimdallURLFlag,
&BorSprintSizeFlag,
&MetricsEnabledFlag,
&MetricsNodeFlag,
@ -409,9 +408,9 @@ func initDevnet(ctx *cli.Context, logger log.Logger) (devnet.Devnet, error) {
if ctx.Bool(WithoutHeimdallFlag.Name) {
return networks.NewBorDevnetWithoutHeimdall(dataDir, baseRpcHost, baseRpcPort, gasLimit, logger, consoleLogLevel, dirLogLevel), nil
} else if ctx.Bool(LocalHeimdallFlag.Name) {
heimdallGrpcAddr := ctx.String(HeimdallGrpcAddressFlag.Name)
heimdallURL := ctx.String(HeimdallURLFlag.Name)
sprintSize := uint64(ctx.Int(BorSprintSizeFlag.Name))
return networks.NewBorDevnetWithLocalHeimdall(dataDir, baseRpcHost, baseRpcPort, heimdallGrpcAddr, sprintSize, producerCount, gasLimit, logger, consoleLogLevel, dirLogLevel), nil
return networks.NewBorDevnetWithLocalHeimdall(dataDir, baseRpcHost, baseRpcPort, heimdallURL, sprintSize, producerCount, gasLimit, logger, consoleLogLevel, dirLogLevel), nil
} else {
return networks.NewBorDevnetWithRemoteHeimdall(dataDir, baseRpcHost, baseRpcPort, producerCount, gasLimit, logger, consoleLogLevel, dirLogLevel), nil
}

View File

@ -74,7 +74,7 @@ func NewBorDevnetWithHeimdall(
baseRpcHost string,
baseRpcPort int,
heimdall *polygon.Heimdall,
heimdallGrpcAddr string,
heimdallURL string,
checkpointOwner *accounts.Account,
producerCount int,
gasLimit uint64,
@ -101,7 +101,7 @@ func NewBorDevnetWithHeimdall(
NodeArgs: args.NodeArgs{
ConsoleVerbosity: strconv.Itoa(int(consoleLogLevel)),
DirVerbosity: strconv.Itoa(int(dirLogLevel)),
HeimdallGrpcAddr: heimdallGrpcAddr,
HeimdallURL: heimdallURL,
},
AccountSlots: 20000,
})
@ -129,7 +129,7 @@ func NewBorDevnetWithHeimdall(
NodeArgs: args.NodeArgs{
ConsoleVerbosity: strconv.Itoa(int(consoleLogLevel)),
DirVerbosity: strconv.Itoa(int(dirLogLevel)),
HeimdallGrpcAddr: heimdallGrpcAddr,
HeimdallURL: heimdallURL,
},
}),
}
@ -185,7 +185,7 @@ func NewBorDevnetWithRemoteHeimdall(
consoleLogLevel log.Lvl,
dirLogLevel log.Lvl,
) devnet.Devnet {
heimdallGrpcAddr := ""
heimdallURL := ""
checkpointOwner := accounts.NewAccount("checkpoint-owner")
withMilestones := utils.WithHeimdallMilestones.Value
return NewBorDevnetWithHeimdall(
@ -193,7 +193,7 @@ func NewBorDevnetWithRemoteHeimdall(
baseRpcHost,
baseRpcPort,
nil,
heimdallGrpcAddr,
heimdallURL,
checkpointOwner,
producerCount,
gasLimit,
@ -207,7 +207,7 @@ func NewBorDevnetWithLocalHeimdall(
dataDir string,
baseRpcHost string,
baseRpcPort int,
heimdallGrpcAddr string,
heimdallURL string,
sprintSize uint64,
producerCount int,
gasLimit uint64,
@ -225,7 +225,7 @@ func NewBorDevnetWithLocalHeimdall(
heimdall := polygon.NewHeimdall(
&config,
heimdallGrpcAddr,
heimdallURL,
&polygon.CheckpointConfig{
CheckpointBufferTime: 60 * time.Second,
CheckpointAccount: checkpointOwner,
@ -237,7 +237,7 @@ func NewBorDevnetWithLocalHeimdall(
baseRpcHost,
baseRpcPort,
heimdall,
heimdallGrpcAddr,
heimdallURL,
checkpointOwner,
producerCount,
gasLimit,

View File

@ -2,16 +2,22 @@ package polygon
import (
"context"
"encoding/json"
"errors"
"fmt"
"math/big"
"net"
"net/http"
"strconv"
"strings"
"sync"
"time"
"github.com/go-chi/chi/v5"
"github.com/ledgerwatch/log/v3"
"github.com/ledgerwatch/erigon/polygon/heimdall"
"github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint"
"github.com/ledgerwatch/erigon/polygon/heimdall/heimdallgrpc"
"github.com/ledgerwatch/erigon/polygon/heimdall/milestone"
"github.com/ledgerwatch/erigon/polygon/heimdall/span"
@ -55,7 +61,7 @@ const (
DefaultCheckpointBufferTime time.Duration = 1000 * time.Second
)
const HeimdallGrpcAddressDefault = "localhost:8540"
const HeimdallURLDefault = "http://localhost:1317"
type CheckpointConfig struct {
RootChainTxConfirmations uint64
@ -71,7 +77,7 @@ type Heimdall struct {
sync.Mutex
chainConfig *chain.Config
borConfig *borcfg.BorConfig
grpcAddr string
listenAddr string
validatorSet *valset.ValidatorSet
pendingCheckpoint *checkpoint.Checkpoint
latestCheckpoint *CheckpointAck
@ -94,14 +100,14 @@ type Heimdall struct {
func NewHeimdall(
chainConfig *chain.Config,
grpcAddr string,
serverURL string,
checkpointConfig *CheckpointConfig,
logger log.Logger,
) *Heimdall {
heimdall := &Heimdall{
chainConfig: chainConfig,
borConfig: chainConfig.Bor.(*borcfg.BorConfig),
grpcAddr: grpcAddr,
listenAddr: serverURL[7:],
checkpointConfig: *checkpointConfig,
spans: map[uint64]*span.HeimdallSpan{},
pendingSyncRecords: map[syncRecordKey]*EventRecordWithBlock{},
@ -382,7 +388,154 @@ func (h *Heimdall) Start(ctx context.Context) error {
// if this is a restart
h.unsubscribe()
return heimdallgrpc.StartHeimdallServer(ctx, h, h.grpcAddr, h.logger)
server := &http.Server{Addr: h.listenAddr, Handler: makeHeimdallRouter(ctx, h)}
return startHTTPServer(ctx, server, "devnet Heimdall service", h.logger)
}
func makeHeimdallRouter(ctx context.Context, client heimdall.IHeimdallClient) *chi.Mux {
router := chi.NewRouter()
writeResponse := func(w http.ResponseWriter, result any, err error) {
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
var resultEnvelope struct {
Height string `json:"height"`
Result any `json:"result"`
}
resultEnvelope.Height = "0"
resultEnvelope.Result = result
response, err := json.Marshal(resultEnvelope)
if err != nil {
http.Error(w, http.StatusText(500), 500)
return
}
_, _ = w.Write(response)
}
wrapResult := func(result any) map[string]any {
return map[string]any{
"result": result,
}
}
router.Get("/clerk/event-record/list", func(w http.ResponseWriter, r *http.Request) {
fromIdStr := r.URL.Query().Get("from-id")
fromId, err := strconv.ParseUint(fromIdStr, 10, 64)
if err != nil {
http.Error(w, http.StatusText(400), 400)
return
}
toTimeStr := r.URL.Query().Get("to-time")
toTime, err := strconv.ParseInt(toTimeStr, 10, 64)
if err != nil {
http.Error(w, http.StatusText(400), 400)
return
}
result, err := client.StateSyncEvents(ctx, fromId, toTime)
writeResponse(w, result, err)
})
router.Get("/bor/span/{id}", func(w http.ResponseWriter, r *http.Request) {
idStr := chi.URLParam(r, "id")
id, err := strconv.ParseUint(idStr, 10, 64)
if err != nil {
http.Error(w, http.StatusText(400), 400)
return
}
result, err := client.Span(ctx, id)
writeResponse(w, result, err)
})
router.Get("/checkpoints/{number}", func(w http.ResponseWriter, r *http.Request) {
numberStr := chi.URLParam(r, "number")
number, err := strconv.ParseInt(numberStr, 10, 64)
if err != nil {
http.Error(w, http.StatusText(400), 400)
return
}
result, err := client.FetchCheckpoint(ctx, number)
writeResponse(w, result, err)
})
router.Get("/checkpoints/latest", func(w http.ResponseWriter, r *http.Request) {
result, err := client.FetchCheckpoint(ctx, -1)
writeResponse(w, result, err)
})
router.Get("/checkpoints/count", func(w http.ResponseWriter, r *http.Request) {
result, err := client.FetchCheckpointCount(ctx)
writeResponse(w, wrapResult(result), err)
})
router.Get("/milestone/{number}", func(w http.ResponseWriter, r *http.Request) {
numberStr := chi.URLParam(r, "number")
number, err := strconv.ParseInt(numberStr, 10, 64)
if err != nil {
http.Error(w, http.StatusText(400), 400)
return
}
result, err := client.FetchMilestone(ctx, number)
writeResponse(w, result, err)
})
router.Get("/milestone/latest", func(w http.ResponseWriter, r *http.Request) {
result, err := client.FetchMilestone(ctx, -1)
writeResponse(w, result, err)
})
router.Get("/milestone/count", func(w http.ResponseWriter, r *http.Request) {
result, err := client.FetchMilestoneCount(ctx)
writeResponse(w, milestone.MilestoneCount{Count: result}, err)
})
router.Get("/milestone/noAck/{id}", func(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
err := client.FetchNoAckMilestone(ctx, id)
result := err == nil
writeResponse(w, wrapResult(result), err)
})
router.Get("/milestone/lastNoAck", func(w http.ResponseWriter, r *http.Request) {
result, err := client.FetchLastNoAckMilestone(ctx)
writeResponse(w, wrapResult(result), err)
})
router.Get("/milestone/ID/{id}", func(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
err := client.FetchMilestoneID(ctx, id)
result := err == nil
writeResponse(w, wrapResult(result), err)
})
return router
}
func startHTTPServer(ctx context.Context, server *http.Server, serverName string, logger log.Logger) error {
listener, err := net.Listen("tcp", server.Addr)
if err != nil {
return err
}
go func() {
err := server.Serve(listener)
if (err != nil) && !errors.Is(err, http.ErrServerClosed) {
logger.Error("server.Serve error", "serverName", serverName, "err", err)
}
}()
go func() {
<-ctx.Done()
_ = server.Close()
}()
return nil
}
func (h *Heimdall) Stop() {

View File

@ -0,0 +1,64 @@
package polygon
import (
"context"
"math/big"
"net/http"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"github.com/ledgerwatch/erigon/polygon/bor/clerk"
"github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint"
heimdallmock "github.com/ledgerwatch/erigon/polygon/heimdall/mock"
heimdallspan "github.com/ledgerwatch/erigon/polygon/heimdall/span"
)
func TestHeimdallServer(t *testing.T) {
t.Skip()
ctx := context.Background()
ctrl := gomock.NewController(t)
client := heimdallmock.NewMockIHeimdallClient(ctrl)
events := []*clerk.EventRecordWithTime{
{
EventRecord: clerk.EventRecord{
ID: 1,
ChainID: "80001",
},
Time: time.Now(),
},
{
EventRecord: clerk.EventRecord{
ID: 2,
ChainID: "80001",
},
Time: time.Now(),
},
}
client.EXPECT().StateSyncEvents(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(events, nil)
span := &heimdallspan.HeimdallSpan{
Span: heimdallspan.Span{
ID: 1,
StartBlock: 1000,
EndBlock: 2000,
},
ChainID: "80001",
}
client.EXPECT().Span(gomock.Any(), gomock.Any()).AnyTimes().Return(span, nil)
checkpoint1 := &checkpoint.Checkpoint{
StartBlock: big.NewInt(1000),
EndBlock: big.NewInt(1999),
BorChainID: "80001",
}
client.EXPECT().FetchCheckpoint(gomock.Any(), gomock.Any()).AnyTimes().Return(checkpoint1, nil)
client.EXPECT().FetchCheckpointCount(gomock.Any()).AnyTimes().Return(int64(1), nil)
err := http.ListenAndServe(HeimdallURLDefault[7:], makeHeimdallRouter(ctx, client))
require.Nil(t, err)
}

View File

@ -42,7 +42,7 @@ func (h *Heimdall) startStateSyncSubscription() {
}
}
func (h *Heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64, limit int) (uint64, []*clerk.EventRecordWithTime, error) {
func (h *Heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) {
h.Lock()
defer h.Unlock()
@ -72,19 +72,14 @@ func (h *Heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64,
if len(events) == 0 {
h.logger.Info("Processed sync request", "from", fromID, "to", time.Unix(to, 0), "min-time", minEventTime,
"pending", len(h.pendingSyncRecords), "filtered", len(events))
return 0, nil, nil
return nil, nil
}
sort.Slice(events, func(i, j int) bool {
return events[i].ID < events[j].ID
})
if len(events) > limit {
events = events[0 : limit-1]
}
eventsWithTime := make([]*clerk.EventRecordWithTime, len(events))
for i, event := range events {
eventsWithTime[i] = &event.EventRecordWithTime
}
@ -98,7 +93,7 @@ func (h *Heimdall) StateSyncEvents(ctx context.Context, fromID uint64, to int64,
"pending", len(h.pendingSyncRecords), "filtered", len(events),
"sent", fmt.Sprintf("%d-%d", events[0].ID, events[len(events)-1].ID))
return events[len(events)-1].BlockNumber, eventsWithTime, nil
return eventsWithTime, nil
}
// handleStateSyncEvent - handle state sync event from rootchain

View File

@ -23,9 +23,9 @@ func initDevnet(chainName string, dataDir string, producerCount int, gasLimit ui
switch chainName {
case networkname.BorDevnetChainName:
heimdallGrpcAddr := polygon.HeimdallGrpcAddressDefault
heimdallURL := polygon.HeimdallURLDefault
const sprintSize uint64 = 0
return networks.NewBorDevnetWithLocalHeimdall(dataDir, baseRpcHost, baseRpcPort, heimdallGrpcAddr, sprintSize, producerCount, gasLimit, logger, consoleLogLevel, dirLogLevel), nil
return networks.NewBorDevnetWithLocalHeimdall(dataDir, baseRpcHost, baseRpcPort, heimdallURL, sprintSize, producerCount, gasLimit, logger, consoleLogLevel, dirLogLevel), nil
case networkname.DevChainName:
return networks.NewDevDevnet(dataDir, baseRpcHost, baseRpcPort, producerCount, gasLimit, logger, consoleLogLevel, dirLogLevel), nil

View File

@ -22,7 +22,6 @@ var (
migration string
integrityFast, integritySlow bool
file string
HeimdallgRPCAddress string
HeimdallURL string
txtrace bool // Whether to trace the execution (should only be used together with `block`)
pruneFlag string

View File

@ -19,7 +19,6 @@ import (
"golang.org/x/exp/slices"
"github.com/ledgerwatch/erigon/polygon/heimdall"
"github.com/ledgerwatch/erigon/polygon/heimdall/heimdallgrpc"
"github.com/ledgerwatch/erigon/core/rawdb/blockio"
"github.com/ledgerwatch/erigon/node/nodecfg"
@ -1682,11 +1681,7 @@ func initConsensusEngine(ctx context.Context, cc *chain2.Config, dir string, db
consensusConfig = cc.Bor
config.HeimdallURL = HeimdallURL
if !config.WithoutHeimdall {
if config.HeimdallgRPCAddress != "" {
heimdallClient = heimdallgrpc.NewHeimdallGRPCClient(config.HeimdallgRPCAddress, logger)
} else {
heimdallClient = heimdall.NewHeimdallClient(config.HeimdallURL, logger)
}
heimdallClient = heimdall.NewHeimdallClient(config.HeimdallURL, logger)
}
} else {
consensusConfig = &config.Ethash

View File

@ -760,18 +760,18 @@ var (
Usage: "Enabling grpc health check",
}
HeimdallURLFlag = cli.StringFlag{
Name: "bor.heimdall",
Usage: "URL of Heimdall service",
Value: "http://localhost:1317",
}
WebSeedsFlag = cli.StringFlag{
Name: "webseed",
Usage: "Comma-separated URL's, holding metadata about network-support infrastructure (like S3 buckets with snapshots, bootnodes, etc...)",
Value: "",
}
HeimdallURLFlag = cli.StringFlag{
Name: "bor.heimdall",
Usage: "URL of Heimdall service",
Value: "http://localhost:1317",
}
// WithoutHeimdallFlag no heimdall (for testing purpose)
WithoutHeimdallFlag = cli.BoolFlag{
Name: "bor.withoutheimdall",
@ -794,18 +794,12 @@ var (
Value: true,
}
// HeimdallgRPCAddressFlag flag for heimdall gRPC address
HeimdallgRPCAddressFlag = cli.StringFlag{
Name: "bor.heimdallgRPC",
Usage: "Address of Heimdall gRPC service",
Value: "",
}
ConfigFlag = cli.StringFlag{
Name: "config",
Usage: "Sets erigon flags from YAML/TOML file",
Value: "",
}
LightClientDiscoveryAddrFlag = cli.StringFlag{
Name: "lightclient.discovery.addr",
Usage: "Address for lightclient DISCV5 protocol",
@ -821,6 +815,7 @@ var (
Usage: "TCP Port for lightclient DISCV5 protocol",
Value: 4001,
}
SentinelAddrFlag = cli.StringFlag{
Name: "sentinel.addr",
Usage: "Address for sentinel",
@ -1497,7 +1492,6 @@ func setClique(ctx *cli.Context, cfg *params.ConsensusSnapshotConfig, datadir st
func setBorConfig(ctx *cli.Context, cfg *ethconfig.Config) {
cfg.HeimdallURL = ctx.String(HeimdallURLFlag.Name)
cfg.WithoutHeimdall = ctx.Bool(WithoutHeimdallFlag.Name)
cfg.HeimdallgRPCAddress = ctx.String(HeimdallgRPCAddressFlag.Name)
cfg.WithHeimdallMilestones = ctx.Bool(WithHeimdallMilestones.Name)
}

View File

@ -111,7 +111,6 @@ import (
"github.com/ledgerwatch/erigon/polygon/bor/finality/flags"
"github.com/ledgerwatch/erigon/polygon/bor/valset"
"github.com/ledgerwatch/erigon/polygon/heimdall"
"github.com/ledgerwatch/erigon/polygon/heimdall/heimdallgrpc"
"github.com/ledgerwatch/erigon/rpc"
"github.com/ledgerwatch/erigon/turbo/builder"
"github.com/ledgerwatch/erigon/turbo/engineapi"
@ -515,11 +514,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger
var heimdallClient heimdall.IHeimdallClient
if chainConfig.Bor != nil {
if !config.WithoutHeimdall {
if config.HeimdallgRPCAddress != "" {
heimdallClient = heimdallgrpc.NewHeimdallGRPCClient(config.HeimdallgRPCAddress, logger)
} else {
heimdallClient = heimdall.NewHeimdallClient(config.HeimdallURL, logger)
}
heimdallClient = heimdall.NewHeimdallClient(config.HeimdallURL, logger)
}
flags.Milestone = config.WithHeimdallMilestones

View File

@ -229,9 +229,6 @@ type Config struct {
// New DB and Snapshots format of history allows: parallel blocks execution, get state as of given transaction without executing whole block.",
HistoryV3 bool
// gRPC Address to connect to Heimdall node
HeimdallgRPCAddress string
// URL to connect to Heimdall node
HeimdallURL string

1
go.mod
View File

@ -65,7 +65,6 @@ require (
github.com/libp2p/go-libp2p-mplex v0.9.0
github.com/libp2p/go-libp2p-pubsub v0.9.3
github.com/maticnetwork/crand v1.0.2
github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53
github.com/multiformats/go-multiaddr v0.12.1
github.com/nxadm/tail v1.4.9-0.20211216163028-4472660a31a6
github.com/pelletier/go-toml v1.9.5

2
go.sum
View File

@ -598,8 +598,6 @@ github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU=
github.com/maticnetwork/crand v1.0.2 h1:Af0tAivC8zrxXDpGWNWVT/0s1fOz8w0eRbahZgURS8I=
github.com/maticnetwork/crand v1.0.2/go.mod h1:/NRNL3bj2eYdqpWmoIP5puxndTpi0XRxpj5ZKxfHjyg=
github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53 h1:PjYV+lghs106JKkrYgOnrsfDLoTc11BxZd4rUa4Rus4=
github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=

View File

@ -28,16 +28,3 @@ type IHeimdallClient interface {
FetchMilestoneID(ctx context.Context, milestoneID string) error //Fetch the bool value whether milestone corresponding to the given id is in process in Heimdall
Close()
}
type HeimdallServer interface {
StateSyncEvents(ctx context.Context, fromID uint64, to int64, limit int) (uint64, []*clerk.EventRecordWithTime, error)
Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error)
FetchCheckpoint(ctx context.Context, number int64) (*checkpoint.Checkpoint, error)
FetchCheckpointCount(ctx context.Context) (int64, error)
FetchMilestone(ctx context.Context, number int64) (*milestone.Milestone, error)
FetchMilestoneCount(ctx context.Context) (int64, error)
FetchNoAckMilestone(ctx context.Context, milestoneID string) error
FetchLastNoAckMilestone(ctx context.Context) (string, error)
FetchMilestoneID(ctx context.Context, milestoneID string) error
Close()
}

View File

@ -1,50 +0,0 @@
package heimdallgrpc
import (
"context"
"math/big"
"github.com/ledgerwatch/erigon/polygon/heimdall/checkpoint"
proto "github.com/maticnetwork/polyproto/heimdall"
protoutils "github.com/maticnetwork/polyproto/utils"
)
func (h *HeimdallGRPCClient) FetchCheckpointCount(ctx context.Context) (int64, error) {
h.logger.Info("Fetching checkpoint count")
res, err := h.client.FetchCheckpointCount(ctx, nil)
if err != nil {
return 0, err
}
h.logger.Info("Fetched checkpoint count")
return res.Result.Result, nil
}
func (h *HeimdallGRPCClient) FetchCheckpoint(ctx context.Context, number int64) (*checkpoint.Checkpoint, error) {
req := &proto.FetchCheckpointRequest{
ID: number,
}
h.logger.Info("Fetching checkpoint", "number", number)
res, err := h.client.FetchCheckpoint(ctx, req)
if err != nil {
return nil, err
}
h.logger.Info("Fetched checkpoint", "number", number)
checkpoint := &checkpoint.Checkpoint{
StartBlock: new(big.Int).SetUint64(res.Result.StartBlock),
EndBlock: new(big.Int).SetUint64(res.Result.EndBlock),
RootHash: protoutils.ConvertH256ToHash(res.Result.RootHash),
Proposer: protoutils.ConvertH160toAddress(res.Result.Proposer),
BorChainID: res.Result.BorChainID,
Timestamp: uint64(res.Result.Timestamp.GetSeconds()),
}
return checkpoint, nil
}

View File

@ -1,53 +0,0 @@
package heimdallgrpc
import (
"time"
grpc_retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
"github.com/ledgerwatch/log/v3"
proto "github.com/maticnetwork/polyproto/heimdall"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials/insecure"
)
const (
stateFetchLimit = 50
)
type HeimdallGRPCClient struct {
conn *grpc.ClientConn
client proto.HeimdallClient
logger log.Logger
}
func NewHeimdallGRPCClient(address string, logger log.Logger) *HeimdallGRPCClient {
opts := []grpc_retry.CallOption{
grpc_retry.WithMax(10000),
grpc_retry.WithBackoff(grpc_retry.BackoffLinear(5 * time.Second)),
grpc_retry.WithCodes(codes.Internal, codes.Unavailable, codes.Aborted, codes.NotFound),
}
conn, err := grpc.Dial(address,
grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(opts...)),
grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(opts...)),
grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
logger.Crit("Failed to connect to Heimdall gRPC", "error", err)
}
logger.Info("Connected to Heimdall gRPC server", "address", address)
return &HeimdallGRPCClient{
conn: conn,
client: proto.NewHeimdallClient(conn),
logger: logger,
}
}
func (h *HeimdallGRPCClient) Close() {
h.logger.Debug("Shutdown detected, Closing Heimdall gRPC client")
h.conn.Close()
}

View File

@ -1,103 +0,0 @@
package heimdallgrpc
import (
"context"
"fmt"
"math/big"
"github.com/ledgerwatch/erigon/polygon/heimdall/milestone"
proto "github.com/maticnetwork/polyproto/heimdall"
protoutils "github.com/maticnetwork/polyproto/utils"
)
func (h *HeimdallGRPCClient) FetchMilestoneCount(ctx context.Context) (int64, error) {
h.logger.Info("Fetching milestone count")
res, err := h.client.FetchMilestoneCount(ctx, nil)
if err != nil {
return 0, err
}
h.logger.Info("Fetched milestone count")
return res.Result.Count, nil
}
func (h *HeimdallGRPCClient) FetchMilestone(ctx context.Context, number int64) (*milestone.Milestone, error) {
h.logger.Info("Fetching milestone")
// TODO: use number
res, err := h.client.FetchMilestone(ctx, nil)
if err != nil {
return nil, err
}
h.logger.Info("Fetched milestone")
milestone := &milestone.Milestone{
StartBlock: new(big.Int).SetUint64(res.Result.StartBlock),
EndBlock: new(big.Int).SetUint64(res.Result.EndBlock),
Hash: protoutils.ConvertH256ToHash(res.Result.RootHash),
Proposer: protoutils.ConvertH160toAddress(res.Result.Proposer),
BorChainID: res.Result.BorChainID,
Timestamp: uint64(res.Result.Timestamp.GetSeconds()),
}
return milestone, nil
}
func (h *HeimdallGRPCClient) FetchLastNoAckMilestone(ctx context.Context) (string, error) {
h.logger.Info("Fetching latest no ack milestone Id")
res, err := h.client.FetchLastNoAckMilestone(ctx, nil)
if err != nil {
return "", err
}
h.logger.Info("Fetched last no-ack milestone")
return res.Result.Result, nil
}
func (h *HeimdallGRPCClient) FetchNoAckMilestone(ctx context.Context, milestoneID string) error {
req := &proto.FetchMilestoneNoAckRequest{
MilestoneID: milestoneID,
}
h.logger.Info("Fetching no ack milestone", "milestoneID", milestoneID)
res, err := h.client.FetchNoAckMilestone(ctx, req)
if err != nil {
return err
}
if !res.Result.Result {
return fmt.Errorf("Not in rejected list: milestoneID %q", milestoneID)
}
h.logger.Info("Fetched no ack milestone", "milestoneID", milestoneID)
return nil
}
func (h *HeimdallGRPCClient) FetchMilestoneID(ctx context.Context, milestoneID string) error {
req := &proto.FetchMilestoneIDRequest{
MilestoneID: milestoneID,
}
h.logger.Info("Fetching milestone id", "milestoneID", milestoneID)
res, err := h.client.FetchMilestoneID(ctx, req)
if err != nil {
return err
}
if !res.Result.Result {
return fmt.Errorf("This milestoneID %q does not exist", milestoneID)
}
h.logger.Info("Fetched milestone id", "milestoneID", milestoneID)
return nil
}

View File

@ -1,251 +0,0 @@
package heimdallgrpc
import (
"context"
"fmt"
"net"
"time"
"github.com/ledgerwatch/log/v3"
proto "github.com/maticnetwork/polyproto/heimdall"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/emptypb"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/ledgerwatch/erigon/polygon/heimdall"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
)
type HeimdallGRPCServer struct {
proto.UnimplementedHeimdallServer
heimdall heimdall.HeimdallServer
logger log.Logger
}
func (h *HeimdallGRPCServer) Span(ctx context.Context, in *proto.SpanRequest) (*proto.SpanResponse, error) {
result, err := h.heimdall.Span(ctx, in.ID)
if err != nil {
h.logger.Error("[bor.heimdall] Error while fetching span")
return nil, err
}
validators := make([]*proto.Validator, len(result.ValidatorSet.Validators))
for i, validator := range result.ValidatorSet.Validators {
h160 := gointerfaces.ConvertAddressToH160(validator.Address)
validators[i] = &proto.Validator{
ID: validator.ID,
Address: &proto.H160{
Hi: &proto.H128{
Hi: h160.Hi.Hi,
Lo: h160.Hi.Lo,
},
Lo: h160.Lo,
},
VotingPower: validator.VotingPower,
ProposerPriority: validator.ProposerPriority,
}
}
var proposer *proto.Validator
if vsp := result.ValidatorSet.Proposer; vsp != nil {
proposerH160 := gointerfaces.ConvertAddressToH160(vsp.Address)
proposer = &proto.Validator{
ID: vsp.ID,
Address: &proto.H160{
Hi: &proto.H128{
Hi: proposerH160.Hi.Hi,
Lo: proposerH160.Hi.Lo,
},
Lo: proposerH160.Lo,
},
VotingPower: vsp.VotingPower,
ProposerPriority: vsp.ProposerPriority,
}
}
producers := make([]*proto.Validator, len(result.SelectedProducers))
for i, producer := range result.SelectedProducers {
h160 := gointerfaces.ConvertAddressToH160(producer.Address)
producers[i] = &proto.Validator{
ID: producer.ID,
Address: &proto.H160{
Hi: &proto.H128{
Hi: h160.Hi.Hi,
Lo: h160.Hi.Lo,
},
Lo: h160.Lo,
},
VotingPower: producer.VotingPower,
ProposerPriority: producer.ProposerPriority,
}
}
resp := &proto.SpanResponse{
Result: &proto.Span{
ID: result.ID,
StartBlock: result.StartBlock,
EndBlock: result.EndBlock,
ValidatorSet: &proto.ValidatorSet{
Validators: validators,
Proposer: proposer,
},
SelectedProducers: producers,
ChainID: result.ChainID,
},
}
return resp, nil
}
func (h *HeimdallGRPCServer) FetchCheckpointCount(ctx context.Context, in *emptypb.Empty) (*proto.FetchCheckpointCountResponse, error) {
count, err := h.heimdall.FetchCheckpointCount(ctx)
if err != nil {
h.logger.Error("[bor.heimdall] Error while fetching checkpoint count")
return nil, err
}
resp := &proto.FetchCheckpointCountResponse{}
resp.Height = fmt.Sprint(count)
return resp, nil
}
func (h *HeimdallGRPCServer) FetchCheckpoint(ctx context.Context, in *proto.FetchCheckpointRequest) (*proto.FetchCheckpointResponse, error) {
_ /*checkpoint*/, err := h.heimdall.FetchCheckpoint(ctx, in.ID)
if err != nil {
h.logger.Error("[bor.heimdall] Error while fetching checkpoint")
return nil, err
}
/* TODO
var hash [32]byte
copy(hash[:], checkPoint.RootHash.Bytes())
var address [20]byte
copy(address[:], checkPoint.Proposer.Bytes())
*/
resp := &proto.FetchCheckpointResponse{}
/* TODO
resp.Height = fmt.Sprint(result.Height)
resp.Result = &proto.Checkpoint{
StartBlock: checkPoint.StartBlock,
EndBlock: checkPoint.EndBlock,
RootHash: protoutils.ConvertHashToH256(hash),
Proposer: protoutils.ConvertAddressToH160(address),
Timestamp: timestamppb.New(time.Unix(int64(checkPoint.TimeStamp), 0)),
BorChainID: checkPoint.BorChainID,
}
*/
return resp, nil
}
func (h *HeimdallGRPCServer) StateSyncEvents(req *proto.StateSyncEventsRequest, reply proto.Heimdall_StateSyncEventsServer) error {
fromId := req.FromID
for {
height, events, err := h.heimdall.StateSyncEvents(context.Background(), fromId, int64(req.ToTime), int(req.Limit))
if err != nil {
h.logger.Error("[bor.heimdall] Error while fetching event records", "error", err)
return status.Errorf(codes.Internal, err.Error())
}
eventRecords := make([]*proto.EventRecord, len(events))
for i, event := range events {
eventRecords[i] = &proto.EventRecord{
ID: event.ID,
Contract: event.Contract.Hex(),
Data: event.Data.String(),
TxHash: event.TxHash.Hex(),
LogIndex: event.LogIndex,
ChainID: event.ChainID,
Time: timestamppb.New(event.Time),
}
}
if len(eventRecords) == 0 {
break
}
err = reply.Send(&proto.StateSyncEventsResponse{
Height: fmt.Sprint(height),
Result: eventRecords,
})
if err != nil {
h.logger.Error("[bor.heimdall] Error while sending event record", "error", err)
return status.Errorf(codes.Internal, err.Error())
}
if len(eventRecords) < int(req.Limit) {
break
}
fromId += req.Limit
}
return nil
}
// StartHeimdallServer creates a heimdall GRPC server - which is implemented via the passed in client
// interface. It is intended for use in testing where more than a single test validator is required rather
// than to replace the maticnetwork implementation
func StartHeimdallServer(shutDownCtx context.Context, heimdall heimdall.HeimdallServer, addr string, logger log.Logger) error {
grpcServer := grpc.NewServer(withLoggingUnaryInterceptor(logger))
proto.RegisterHeimdallServer(grpcServer,
&HeimdallGRPCServer{
heimdall: heimdall,
logger: logger,
})
lis, err := net.Listen("tcp", addr)
if err != nil {
return err
}
go func() {
if err := grpcServer.Serve(lis); err != nil {
logger.Error("[bor.heimdall] failed to serve grpc server", "err", err)
}
<-shutDownCtx.Done()
grpcServer.Stop()
lis.Close()
logger.Info("[bor.heimdall] GRPC Server stopped", "addr", addr)
}()
logger.Info("[bor.heimdall] GRPC Server started", "addr", addr)
return nil
}
func withLoggingUnaryInterceptor(logger log.Logger) grpc.ServerOption {
return grpc.UnaryInterceptor(func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
start := time.Now()
h, err := handler(ctx, req)
if err != nil {
err = status.Errorf(codes.Internal, err.Error())
}
logger.Debug("[bor.heimdall] Request", "method", info.FullMethod, "duration", time.Since(start), "error", err)
return h, err
})
}

View File

@ -1,63 +0,0 @@
package heimdallgrpc
import (
"context"
"github.com/ledgerwatch/erigon/polygon/heimdall/span"
"github.com/ledgerwatch/erigon/polygon/bor/valset"
proto "github.com/maticnetwork/polyproto/heimdall"
protoutils "github.com/maticnetwork/polyproto/utils"
)
func (h *HeimdallGRPCClient) Span(ctx context.Context, spanID uint64) (*span.HeimdallSpan, error) {
req := &proto.SpanRequest{
ID: spanID,
}
h.logger.Info("Fetching span", "spanID", spanID)
res, err := h.client.Span(ctx, req)
if err != nil {
return nil, err
}
h.logger.Info("Fetched span", "spanID", spanID)
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: protoutils.ConvertH160toAddress(validator.Address),
VotingPower: validator.VotingPower,
ProposerPriority: validator.ProposerPriority,
}
}

View File

@ -1,58 +0,0 @@
package heimdallgrpc
import (
"context"
"errors"
"io"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon/polygon/bor/clerk"
proto "github.com/maticnetwork/polyproto/heimdall"
)
func (h *HeimdallGRPCClient) StateSyncEvents(ctx context.Context, fromID uint64, to int64) ([]*clerk.EventRecordWithTime, error) {
eventRecords := make([]*clerk.EventRecordWithTime, 0)
req := &proto.StateSyncEventsRequest{
FromID: fromID,
ToTime: uint64(to),
Limit: uint64(stateFetchLimit),
}
var (
res proto.Heimdall_StateSyncEventsClient
events *proto.StateSyncEventsResponse
err error
)
res, err = h.client.StateSyncEvents(ctx, req)
if err != nil {
return nil, err
}
for {
events, err = res.Recv()
if errors.Is(err, io.EOF) {
return eventRecords, nil
}
if err != nil {
return nil, err
}
for _, event := range events.Result {
eventRecord := &clerk.EventRecordWithTime{
EventRecord: clerk.EventRecord{
ID: event.ID,
Contract: libcommon.HexToAddress(event.Contract),
Data: libcommon.Hex2Bytes(event.Data[2:]),
TxHash: libcommon.HexToHash(event.TxHash),
LogIndex: event.LogIndex,
ChainID: event.ChainID,
},
Time: event.Time.AsTime(),
}
eventRecords = append(eventRecords, eventRecord)
}
}
}

View File

@ -149,7 +149,6 @@ var DefaultFlags = []cli.Flag{
&utils.HeimdallURLFlag,
&utils.WebSeedsFlag,
&utils.WithoutHeimdallFlag,
&utils.HeimdallgRPCAddressFlag,
&utils.BorBlockPeriodFlag,
&utils.BorBlockSizeFlag,
&utils.WithHeimdallMilestones,