diff --git a/eth/bor_api_backend.go b/eth/bor_api_backend.go index 93e93bb137..88f5e1f34d 100644 --- a/eth/bor_api_backend.go +++ b/eth/bor_api_backend.go @@ -39,7 +39,7 @@ func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr uint64, end return root, nil } -// GetRootHash returns root hash for given start and end block +// GetVoteOnHash returns the vote on hash func (b *EthAPIBackend) GetVoteOnHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64, hash string, milestoneId string) (bool, error) { var api *bor.API diff --git a/eth/filters/IBackend.go b/eth/filters/IBackend.go index 3a69c90d2e..7dfd509f83 100644 --- a/eth/filters/IBackend.go +++ b/eth/filters/IBackend.go @@ -132,7 +132,7 @@ func (mr *MockBackendMockRecorder) GetBorBlockLogs(arg0, arg1 interface{}) *gomo // GetBorBlockReceipt mocks base method. func (m *MockBackend) GetBorBlockReceipt(arg0 context.Context, arg1 common.Hash) (*types.Receipt, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBorBlockReceipt", arg0, arg1) + ret := m.ctrl.Call(m, "BorBlockReceipt", arg0, arg1) ret0, _ := ret[0].(*types.Receipt) ret1, _ := ret[1].(error) return ret0, ret1 @@ -141,7 +141,7 @@ func (m *MockBackend) GetBorBlockReceipt(arg0 context.Context, arg1 common.Hash) // GetBorBlockReceipt indicates an expected call of GetBorBlockReceipt. func (mr *MockBackendMockRecorder) GetBorBlockReceipt(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBorBlockReceipt", reflect.TypeOf((*MockBackend)(nil).GetBorBlockReceipt), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BorBlockReceipt", reflect.TypeOf((*MockBackend)(nil).GetBorBlockReceipt), arg0, arg1) } // GetLogs mocks base method. diff --git a/go.mod b/go.mod index 616a299f3c..a976c95e21 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,7 @@ require ( github.com/kylelemons/godebug v1.1.0 github.com/maticnetwork/crand v1.0.2 github.com/maticnetwork/heimdall v1.0.7 - github.com/maticnetwork/polyproto v0.0.3-0.20230216113155-340ea926ca53 + github.com/maticnetwork/polyproto v0.0.3 github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-isatty v0.0.20 github.com/mitchellh/cli v1.1.5 diff --git a/go.sum b/go.sum index ce93e54d7f..4ed86b6fc1 100644 --- a/go.sum +++ b/go.sum @@ -1706,8 +1706,9 @@ github.com/maticnetwork/crand v1.0.2/go.mod h1:/NRNL3bj2eYdqpWmoIP5puxndTpi0XRxp github.com/maticnetwork/heimdall v1.0.4/go.mod h1:Xh7KFvtbs/SVNjOI8IgYmk6JdzYx89eU/XUwH0AgHLs= github.com/maticnetwork/heimdall v1.0.7 h1:QStn+hbZKxfE+PqecaorA/uATDPuQoi+U9Z7IIonb60= github.com/maticnetwork/heimdall v1.0.7/go.mod h1:+ANI5+VV28ahwfdl7oMzrcNwaTEs1Fn6z39BqBGcvaA= -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/maticnetwork/polyproto v0.0.3 h1:a69rIp97fcl3ABY4LlVX9B2t1qhLa0Jhny3HNOzReBU= +github.com/maticnetwork/polyproto v0.0.3/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o= github.com/maticnetwork/tendermint v0.33.0 h1:f+vORM02BoUOlCvnu3Zjw5rv6l6JSNVchWjH03rUuR8= github.com/maticnetwork/tendermint v0.33.0/go.mod h1:D2fcnxGk6bje+LoPwImuKSSYLiK7/G06IynGNDSEcJk= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= diff --git a/internal/cli/server/api_service.go b/internal/cli/server/api_service.go new file mode 100644 index 0000000000..67e7c0924c --- /dev/null +++ b/internal/cli/server/api_service.go @@ -0,0 +1,93 @@ +package server + +import ( + "context" + "errors" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + + protobor "github.com/maticnetwork/polyproto/bor" + protoutil "github.com/maticnetwork/polyproto/utils" +) + +func (s *Server) GetRootHash(ctx context.Context, req *protobor.GetRootHashRequest) (*protobor.GetRootHashResponse, error) { + rootHash, err := s.backend.APIBackend.GetRootHash(ctx, req.StartBlockNumber, req.EndBlockNumber) + if err != nil { + return nil, err + } + + return &protobor.GetRootHashResponse{RootHash: rootHash}, nil +} + +func (s *Server) GetVoteOnHash(ctx context.Context, req *protobor.GetVoteOnHashRequest) (*protobor.GetVoteOnHashResponse, error) { + vote, err := s.backend.APIBackend.GetVoteOnHash(ctx, req.StartBlockNumber, req.EndBlockNumber, req.Hash, req.MilestoneId) + if err != nil { + return nil, err + } + + return &protobor.GetVoteOnHashResponse{Response: vote}, nil +} + +func headerToProtoborHeader(h *types.Header) *protobor.Header { + return &protobor.Header{ + Number: h.Number.Uint64(), + ParentHash: protoutil.ConvertHashToH256(h.ParentHash), + Time: h.Time, + } +} + +func (s *Server) HeaderByNumber(ctx context.Context, req *protobor.GetHeaderByNumberRequest) (*protobor.GetHeaderByNumberResponse, error) { + header, err := s.backend.APIBackend.HeaderByNumber(ctx, rpc.BlockNumber(req.Number)) + if err != nil { + return nil, err + } + + return &protobor.GetHeaderByNumberResponse{Header: headerToProtoborHeader(header)}, nil +} + +func (s *Server) BlockByNumber(ctx context.Context, req *protobor.GetBlockByNumberRequest) (*protobor.GetBlockByNumberResponse, error) { + block, err := s.backend.APIBackend.BlockByNumber(ctx, rpc.BlockNumber(req.Number)) + if err != nil { + return nil, err + } + + return &protobor.GetBlockByNumberResponse{Block: blockToProtoBlock(block)}, nil +} + +func blockToProtoBlock(h *types.Block) *protobor.Block { + return &protobor.Block{ + Header: headerToProtoborHeader(h.Header()), + } +} + +func (s *Server) TransactionReceipt(ctx context.Context, req *protobor.ReceiptRequest) (*protobor.ReceiptResponse, error) { + _, _, blockHash, _, txnIndex, err := s.backend.APIBackend.GetTransaction(ctx, protoutil.ConvertH256ToHash(req.Hash)) + if err != nil { + return nil, err + } + + receipts, err := s.backend.APIBackend.GetReceipts(ctx, blockHash) + if err != nil { + return nil, err + } + + if receipts == nil { + return nil, errors.New("no receipts found") + } + + if len(receipts) <= int(txnIndex) { + return nil, errors.New("transaction index out of bounds") + } + + return &protobor.ReceiptResponse{Receipt: ConvertReceiptToProtoReceipt(receipts[txnIndex])}, nil +} + +func (s *Server) BorBlockReceipt(ctx context.Context, req *protobor.ReceiptRequest) (*protobor.ReceiptResponse, error) { + receipt, err := s.backend.APIBackend.GetBorBlockReceipt(ctx, protoutil.ConvertH256ToHash(req.Hash)) + if err != nil { + return nil, err + } + + return &protobor.ReceiptResponse{Receipt: ConvertReceiptToProtoReceipt(receipt)}, nil +} diff --git a/internal/cli/server/server.go b/internal/cli/server/server.go index 4d87d64608..33b89e2b57 100644 --- a/internal/cli/server/server.go +++ b/internal/cli/server/server.go @@ -11,16 +11,6 @@ import ( "runtime" "time" - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" - "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - semconv "go.opentelemetry.io/otel/semconv/v1.4.0" - "google.golang.org/grpc" - "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/cmd/utils" @@ -40,14 +30,28 @@ import ( "github.com/ethereum/go-ethereum/metrics/prometheus" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/rpc" + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" // Force-load the tracer engines to trigger registration _ "github.com/ethereum/go-ethereum/eth/tracers/js" _ "github.com/ethereum/go-ethereum/eth/tracers/native" + + protobor "github.com/maticnetwork/polyproto/bor" ) type Server struct { proto.UnimplementedBorServer + protobor.UnimplementedBorApiServer + node *node.Node backend *eth.Ethereum grpcServer *grpc.Server @@ -439,6 +443,8 @@ func (s *Server) gRPCServerByAddress(addr string) error { func (s *Server) gRPCServerByListener(listener net.Listener) error { s.grpcServer = grpc.NewServer(s.withLoggingUnaryInterceptor()) proto.RegisterBorServer(s.grpcServer, s) + protobor.RegisterBorApiServer(s.grpcServer, s) + reflection.Register(s.grpcServer) go func() { if err := s.grpcServer.Serve(listener); err != nil { diff --git a/internal/cli/server/utils.go b/internal/cli/server/utils.go new file mode 100644 index 0000000000..aa461c9e92 --- /dev/null +++ b/internal/cli/server/utils.go @@ -0,0 +1,78 @@ +package server + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/cli/server/proto" + "github.com/ethereum/go-ethereum/p2p" + + protobor "github.com/maticnetwork/polyproto/bor" + protocommon "github.com/maticnetwork/polyproto/common" + protoutil "github.com/maticnetwork/polyproto/utils" +) + +func PeerInfoToPeer(info *p2p.PeerInfo) *proto.Peer { + return &proto.Peer{ + Id: info.ID, + Enode: info.Enode, + Enr: info.ENR, + Caps: info.Caps, + Name: info.Name, + Trusted: info.Network.Trusted, + Static: info.Network.Static, + } +} + +func ConvertBloomToProtoBloom(bloom types.Bloom) *protobor.Bloom { + return &protobor.Bloom{ + Bloom: bloom.Bytes(), + } +} + +func ConvertLogsToProtoLogs(logs []*types.Log) []*protobor.Log { + var protoLogs []*protobor.Log + for _, log := range logs { + protoLog := &protobor.Log{ + Address: protoutil.ConvertAddressToH160(log.Address), + Topics: ConvertTopicsToProtoTopics(log.Topics), + Data: log.Data, + BlockNumber: log.BlockNumber, + TxHash: protoutil.ConvertHashToH256(log.TxHash), + TxIndex: uint64(log.TxIndex), + BlockHash: protoutil.ConvertHashToH256(log.BlockHash), + Index: uint64(log.Index), + Removed: log.Removed, + } + protoLogs = append(protoLogs, protoLog) + } + + return protoLogs +} + +func ConvertTopicsToProtoTopics(topics []common.Hash) []*protocommon.H256 { + var protoTopics []*protocommon.H256 + for _, topic := range topics { + protoTopics = append(protoTopics, protoutil.ConvertHashToH256(topic)) + } + + return protoTopics +} + +func ConvertReceiptToProtoReceipt(receipt *types.Receipt) *protobor.Receipt { + return &protobor.Receipt{ + Type: uint64(receipt.Type), + PostState: receipt.PostState, + Status: receipt.Status, + CumulativeGasUsed: receipt.CumulativeGasUsed, + Bloom: ConvertBloomToProtoBloom(receipt.Bloom), + Logs: ConvertLogsToProtoLogs(receipt.Logs), + TxHash: protoutil.ConvertHashToH256(receipt.TxHash), + ContractAddress: protoutil.ConvertAddressToH160(receipt.ContractAddress), + GasUsed: receipt.GasUsed, + EffectiveGasPrice: receipt.EffectiveGasPrice.Int64(), + BlobGasUsed: receipt.BlobGasUsed, + BlockHash: protoutil.ConvertHashToH256(receipt.BlockHash), + BlockNumber: receipt.BlockNumber.Int64(), + TransactionIndex: uint64(receipt.TransactionIndex), + } +}