diff --git a/cmd/devnet/args/node_args.go b/cmd/devnet/args/node_args.go index 1fba7caaf..1bbf71456 100644 --- a/cmd/devnet/args/node_args.go +++ b/cmd/devnet/args/node_args.go @@ -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"` diff --git a/cmd/devnet/main.go b/cmd/devnet/main.go index 92a41aca1..b8f5ff4ae 100644 --- a/cmd/devnet/main.go +++ b/cmd/devnet/main.go @@ -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 } diff --git a/cmd/devnet/networks/devnet_bor.go b/cmd/devnet/networks/devnet_bor.go index 41d4993ea..ce81a45a0 100644 --- a/cmd/devnet/networks/devnet_bor.go +++ b/cmd/devnet/networks/devnet_bor.go @@ -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, diff --git a/cmd/devnet/services/polygon/heimdall.go b/cmd/devnet/services/polygon/heimdall.go index 81426a68e..1288f67c6 100644 --- a/cmd/devnet/services/polygon/heimdall.go +++ b/cmd/devnet/services/polygon/heimdall.go @@ -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() { diff --git a/cmd/devnet/services/polygon/heimdall_test.go b/cmd/devnet/services/polygon/heimdall_test.go new file mode 100644 index 000000000..a9b34d3bd --- /dev/null +++ b/cmd/devnet/services/polygon/heimdall_test.go @@ -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) +} diff --git a/cmd/devnet/services/polygon/statesync.go b/cmd/devnet/services/polygon/statesync.go index ed7232ae5..cf4bbd186 100644 --- a/cmd/devnet/services/polygon/statesync.go +++ b/cmd/devnet/services/polygon/statesync.go @@ -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 diff --git a/cmd/devnet/tests/context.go b/cmd/devnet/tests/context.go index af92c3a0d..554bf99d0 100644 --- a/cmd/devnet/tests/context.go +++ b/cmd/devnet/tests/context.go @@ -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 diff --git a/cmd/integration/commands/flags.go b/cmd/integration/commands/flags.go index ea80e1241..70036f554 100644 --- a/cmd/integration/commands/flags.go +++ b/cmd/integration/commands/flags.go @@ -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 diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 386fc86f9..ab9851c2d 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -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 diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 1700d5a85..23bb4fa55 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -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) } diff --git a/eth/backend.go b/eth/backend.go index 1b2e1baee..12fd08639 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -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 diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index a75b5783a..a66e54cf4 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -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 diff --git a/go.mod b/go.mod index 514e8f519..f2ab6ea44 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 4de0d41ea..afc6c4286 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/polygon/heimdall/heimdall.go b/polygon/heimdall/heimdall.go index 673a5ff4a..e72cf25ec 100644 --- a/polygon/heimdall/heimdall.go +++ b/polygon/heimdall/heimdall.go @@ -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() -} diff --git a/polygon/heimdall/heimdallgrpc/checkpoint.go b/polygon/heimdall/heimdallgrpc/checkpoint.go deleted file mode 100644 index f02398a3b..000000000 --- a/polygon/heimdall/heimdallgrpc/checkpoint.go +++ /dev/null @@ -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 -} diff --git a/polygon/heimdall/heimdallgrpc/client.go b/polygon/heimdall/heimdallgrpc/client.go deleted file mode 100644 index 6c5799d04..000000000 --- a/polygon/heimdall/heimdallgrpc/client.go +++ /dev/null @@ -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() -} diff --git a/polygon/heimdall/heimdallgrpc/milestone.go b/polygon/heimdall/heimdallgrpc/milestone.go deleted file mode 100644 index a20b4d7dc..000000000 --- a/polygon/heimdall/heimdallgrpc/milestone.go +++ /dev/null @@ -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 -} diff --git a/polygon/heimdall/heimdallgrpc/server.go b/polygon/heimdall/heimdallgrpc/server.go deleted file mode 100644 index ea0ee45ad..000000000 --- a/polygon/heimdall/heimdallgrpc/server.go +++ /dev/null @@ -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 - }) -} diff --git a/polygon/heimdall/heimdallgrpc/span.go b/polygon/heimdall/heimdallgrpc/span.go deleted file mode 100644 index 9d9a24b78..000000000 --- a/polygon/heimdall/heimdallgrpc/span.go +++ /dev/null @@ -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, - } -} diff --git a/polygon/heimdall/heimdallgrpc/state_sync.go b/polygon/heimdall/heimdallgrpc/state_sync.go deleted file mode 100644 index 0d32a1908..000000000 --- a/polygon/heimdall/heimdallgrpc/state_sync.go +++ /dev/null @@ -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) - } - } -} diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index d5ab5f85a..45a39a2a9 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -149,7 +149,6 @@ var DefaultFlags = []cli.Flag{ &utils.HeimdallURLFlag, &utils.WebSeedsFlag, &utils.WithoutHeimdallFlag, - &utils.HeimdallgRPCAddressFlag, &utils.BorBlockPeriodFlag, &utils.BorBlockSizeFlag, &utils.WithHeimdallMilestones,