Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for better client version details #229

Merged
merged 9 commits into from
Oct 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -275,29 +281,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 @@ -310,15 +311,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
)