Skip to content

Commit

Permalink
Add support for better client version details (#229)
Browse files Browse the repository at this point in the history
# Description

This PR resolves a pending issue that doesn't return proper chain
information on the client version.

It removes the base `GET` endpoint to the JSON-RPC layer, as it's not by
the standard, nor should it be supported.
Users should use the `web3_clientVersion` endpoint instead, that is
outlined in the specification.

The PR is merging from PolygonEdge [PR
672](0xPolygon#672)

# Changes include

- [x] Bugfix (non-breaking change that solves an issue)

## Testing

- [x] I have tested this code with the official test suite
  • Loading branch information
DarianShawn authored Oct 25, 2022
1 parent 1960bf6 commit 45ccc44
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 38 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ jobs:
go-version: 1.17.x

- name: Build Dogechain
# run: go build -tags netgo -ldflags="-s -w -linkmode external -extldflags "-static" -X \"github.com/dogechain-lab/dogechain/versioning.Version=${GITHUB_REF_NAME}\" -X \"github.com/dogechain-lab/dogechain/versioning.Commit=${GITHUB_SHA}\"" && tar -czvf dogechain.tar.gz dogechain
run: go build -a -o dogechain . && tar -czvf dogechain.tar.gz dogechain
run: go build -ldflags="-X \"github.com/dogechain-lab/dogechain/versioning.Version=${GITHUB_REF_NAME}\" -X \"github.com/dogechain-lab/dogechain/versioning.Commit=${GITHUB_SHA}\"" -a -o dogechain . && tar -czvf dogechain.tar.gz dogechain
env:
CGO_ENABLED: 0
CC: gcc
Expand Down
10 changes: 7 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ protoc:
.PHONY: build
build:
$(eval LATEST_VERSION = $(shell git describe --tags --abbrev=0))
$(eval COMMIT_HASH = $(shell git rev-parse --short HEAD))
$(eval DATE = $(shell date +'%Y-%m-%d_%T'))
go build -o dogechain -ldflags="-X 'github.com/dogechain-lab/dogechain/versioning.Version=$(LATEST_VERSION)+$(COMMIT_HASH)+$(DATE)'" main.go
$(eval COMMIT_HASH = $(shell git rev-parse HEAD))
$(eval DATE = $(shell date -u +'%Y-%m-%dT%TZ'))
go build -o dogechain -ldflags="\
-X 'github.com/dogechain-lab/dogechain/versioning.Version=$(LATEST_VERSION)'\
-X 'github.com/dogechain-lab/dogechain/versioning.Commit=$(COMMIT_HASH)'\
-X 'github.com/dogechain-lab/dogechain/versioning.BuildTime=$(DATE)'" \
main.go

.PHONY: lint
lint:
Expand Down
22 changes: 20 additions & 2 deletions command/version/result.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,27 @@
package version

import (
"fmt"
"strings"

"github.com/dogechain-lab/dogechain/command/helper"
)

type VersionResult struct {
Version string `json:"version"`
Version string `json:"version"`
Commit string `json:"commit"`
BuildTime string `json:"buildTime"`
}

func (r *VersionResult) GetOutput() string {
return r.Version
var s strings.Builder

s.WriteString("Dogechain\n")
s.WriteString(helper.FormatKV([]string{
fmt.Sprintf("Version|%s", r.Version),
fmt.Sprintf("Commit|%s", r.Commit),
fmt.Sprintf("Build Time|%s", r.BuildTime),
}))

return s.String()
}
4 changes: 3 additions & 1 deletion command/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ func runCommand(cmd *cobra.Command, _ []string) {

outputter.SetCommandResult(
&VersionResult{
Version: versioning.Version,
Version: versioning.Version,
Commit: versioning.Commit,
BuildTime: versioning.BuildTime,
},
)
}
2 changes: 1 addition & 1 deletion jsonrpc/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (d *Dispatcher) initEndpoints(store JSONRPCStore) {
priceLimit: d.priceLimit,
}
d.endpoints.Net = &Net{store, d.chainID}
d.endpoints.Web3 = &Web3{}
d.endpoints.Web3 = &Web3{d.chainID}
d.endpoints.TxPool = &TxPool{store}
d.endpoints.Debug = &Debug{store}
}
Expand Down
63 changes: 44 additions & 19 deletions jsonrpc/jsonrpc.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package jsonrpc

import (
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"sync"
"time"

"github.com/dogechain-lab/dogechain/versioning"
"github.com/gorilla/websocket"
"github.com/hashicorp/go-hclog"
)
Expand All @@ -33,6 +35,10 @@ func (s serverType) String() string {
}
}

const (
_authoritativeChainName = "Dogechain"
)

// JSONRPC is an API backend
type JSONRPC struct {
logger hclog.Logger
Expand Down Expand Up @@ -286,29 +292,24 @@ func (j *JSONRPC) handle(w http.ResponseWriter, req *http.Request) {
"Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization",
)

if (*req).Method == "OPTIONS" {
return
}

if req.Method == "GET" {
w.Write([]byte("Dogechain-Lab Dogechain JSON-RPC"))
switch req.Method {
case http.MethodPost:
j.handleJSONRPCRequest(w, req)
case http.MethodGet:
j.handleGetRequest(w)
case http.MethodOptions:
// nothing to return
default:
j.metrics.Errors.Add(1.0)

return
}

if req.Method != "POST" {
w.Write([]byte("method " + req.Method + " not allowed"))
j.metrics.Errors.Add(1.0)

return
}
}

func (j *JSONRPC) handleJSONRPCRequest(w http.ResponseWriter, req *http.Request) {
data, err := io.ReadAll(req.Body)

if err != nil {
w.Write([]byte(err.Error()))
j.metrics.Errors.Add(1.0)
w.Write([]byte(err.Error()))

return
}
Expand All @@ -321,15 +322,39 @@ func (j *JSONRPC) handle(w http.ResponseWriter, req *http.Request) {
// handle request
resp, err := j.dispatcher.Handle(data)

endT := time.Now()
j.metrics.ResponseTime.Observe(endT.Sub(startT).Seconds())
j.metrics.ResponseTime.Observe(time.Since(startT).Seconds())

if err != nil {
w.Write([]byte(err.Error()))
j.metrics.Errors.Add(1.0)
w.Write([]byte(err.Error()))
} else {
w.Write(resp)
}

j.logger.Debug("handle", "response", string(resp))
}

type GetResponse struct {
Name string `json:"name"`
ChainID uint64 `json:"chain_id"`
Version string `json:"version"`
}

func (j *JSONRPC) handleGetRequest(writer io.Writer) {
data := &GetResponse{
Name: _authoritativeChainName,
ChainID: j.config.ChainID,
Version: versioning.Version,
}

resp, err := json.Marshal(data)
if err != nil {
j.metrics.Errors.Add(1.0)
writer.Write([]byte(err.Error()))
}

if _, err = writer.Write(resp); err != nil {
j.metrics.Errors.Add(1.0)
writer.Write([]byte(err.Error()))
}
}
38 changes: 38 additions & 0 deletions jsonrpc/jsonrpc_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package jsonrpc

import (
"bytes"
"encoding/json"
"net"
"testing"

"github.com/dogechain-lab/dogechain/helper/tests"
"github.com/dogechain-lab/dogechain/versioning"
"github.com/stretchr/testify/assert"

"github.com/hashicorp/go-hclog"
)
Expand All @@ -27,3 +31,37 @@ func TestHTTPServer(t *testing.T) {
t.Fatal(err)
}
}

func Test_handleGetRequest(t *testing.T) {
var (
chainName = _authoritativeChainName
chainID = uint64(200)
)

jsonRPC := &JSONRPC{
config: &Config{
ChainID: chainID,
},
}

mockWriter := bytes.NewBuffer(nil)

jsonRPC.handleGetRequest(mockWriter)

response := &GetResponse{}

assert.NoError(
t,
json.Unmarshal(mockWriter.Bytes(), response),
)

assert.Equal(
t,
&GetResponse{
Name: chainName,
ChainID: chainID,
Version: versioning.Version,
},
response,
)
}
12 changes: 10 additions & 2 deletions jsonrpc/web3_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ import (
)

// Web3 is the web3 jsonrpc endpoint
type Web3 struct{}
type Web3 struct {
chainID uint64
}

var _clientVersionTemplate = "dogechain [chain-id: %d] [version: %s]"

// ClientVersion returns the version of the web3 client (web3_clientVersion)
func (w *Web3) ClientVersion() (interface{}, error) {
return fmt.Sprintf("dogechain [%s]", versioning.Version), nil
return fmt.Sprintf(
_clientVersionTemplate,
w.chainID,
versioning.Version,
), nil
}

// Sha3 returns Keccak-256 (not the standardized SHA3-256) of the given data
Expand Down
24 changes: 20 additions & 4 deletions jsonrpc/web3_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,19 @@ func TestWeb3EndpointSha3(t *testing.T) {
}

func TestWeb3EndpointClientVersion(t *testing.T) {
dispatcher := newDispatcher(hclog.NewNullLogger(), newMockStore(), 0, 20, 1000, 0, []Namespace{
NamespaceWeb3,
})
chainID := uint64(100)

dispatcher := newDispatcher(
hclog.NewNullLogger(),
newMockStore(),
chainID,
20,
1000,
0,
[]Namespace{
NamespaceWeb3,
},
)

resp, err := dispatcher.Handle([]byte(`{
"method": "web3_clientVersion",
Expand All @@ -40,5 +50,11 @@ func TestWeb3EndpointClientVersion(t *testing.T) {
var res string

assert.NoError(t, expectJSONResult(resp, &res))
assert.Contains(t, res, fmt.Sprintf("dogechain [%v]", versioning.Version))
assert.Contains(t, res,
fmt.Sprintf(
_clientVersionTemplate,
chainID,
versioning.Version,
),
)
}
10 changes: 6 additions & 4 deletions versioning/versioning.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package versioning

// Embedded by --ldflags on build time
// Versioning should follow the SemVer guidelines
// https://semver.org/
var (
// Version is the main version at the moment.
// Embedded by --ldflags on build time
// Versioning should follow the SemVer guidelines
// https://semver.org/
Version = "v0.1.0"
Version string // the main version at the moment
Commit string // the git commit that the binary was built on
BuildTime string // the timestamp of the build
)

0 comments on commit 45ccc44

Please sign in to comment.