Merge pull request #786 from status-im/improvement/issue-785/common-logic-to-lib
[#785] Extract lib specific code from geth/common
This commit is contained in:
commit
33c739fecf
|
@ -5,9 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
@ -85,67 +83,6 @@ func isNilOrEmpty(bytes hexutil.Bytes) bool {
|
||||||
return bytes == nil || len(bytes) == 0
|
return bytes == nil || len(bytes) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIResponse generic response from API
|
|
||||||
type APIResponse struct {
|
|
||||||
Error string `json:"error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIDetailedResponse represents a generic response
|
|
||||||
// with possible errors.
|
|
||||||
type APIDetailedResponse struct {
|
|
||||||
Status bool `json:"status"`
|
|
||||||
Message string `json:"message,omitempty"`
|
|
||||||
FieldErrors []APIFieldError `json:"field_errors,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r APIDetailedResponse) Error() string {
|
|
||||||
buf := bytes.NewBufferString("")
|
|
||||||
|
|
||||||
for _, err := range r.FieldErrors {
|
|
||||||
buf.WriteString(err.Error() + "\n") // nolint: gas
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.TrimSpace(buf.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIFieldError represents a set of errors
|
|
||||||
// related to a parameter.
|
|
||||||
type APIFieldError struct {
|
|
||||||
Parameter string `json:"parameter,omitempty"`
|
|
||||||
Errors []APIError `json:"errors"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e APIFieldError) Error() string {
|
|
||||||
if len(e.Errors) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := bytes.NewBufferString(fmt.Sprintf("Parameter: %s\n", e.Parameter))
|
|
||||||
|
|
||||||
for _, err := range e.Errors {
|
|
||||||
buf.WriteString(err.Error() + "\n") // nolint: gas
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.TrimSpace(buf.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// APIError represents a single error.
|
|
||||||
type APIError struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e APIError) Error() string {
|
|
||||||
return fmt.Sprintf("message=%s", e.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AccountInfo represents account's info
|
|
||||||
type AccountInfo struct {
|
|
||||||
Address string `json:"address"`
|
|
||||||
PubKey string `json:"pubkey"`
|
|
||||||
Mnemonic string `json:"mnemonic"`
|
|
||||||
Error string `json:"error"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// StopRPCCallError defines a error type specific for killing a execution process.
|
// StopRPCCallError defines a error type specific for killing a execution process.
|
||||||
type StopRPCCallError struct {
|
type StopRPCCallError struct {
|
||||||
Err error
|
Err error
|
||||||
|
|
|
@ -2,7 +2,6 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -10,7 +9,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/pborman/uuid"
|
"github.com/pborman/uuid"
|
||||||
|
@ -44,18 +42,6 @@ func ImportTestAccount(keystoreDir, accountFile string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// PanicAfter throws panic() after waitSeconds, unless abort channel receives notification
|
|
||||||
func PanicAfter(waitSeconds time.Duration, abort chan struct{}, desc string) {
|
|
||||||
go func() {
|
|
||||||
select {
|
|
||||||
case <-abort:
|
|
||||||
return
|
|
||||||
case <-time.After(waitSeconds):
|
|
||||||
panic("whatever you were doing takes toooo long: " + desc)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessageIDFromContext returns message id from context (if exists)
|
// MessageIDFromContext returns message id from context (if exists)
|
||||||
func MessageIDFromContext(ctx context.Context) string {
|
func MessageIDFromContext(ctx context.Context) string {
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
|
@ -68,17 +54,6 @@ func MessageIDFromContext(ctx context.Context) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseJSONArray parses JSON array into Go array of string
|
|
||||||
func ParseJSONArray(items string) ([]string, error) {
|
|
||||||
var parsedItems []string
|
|
||||||
err := json.Unmarshal([]byte(items), &parsedItems)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsedItems, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fatalf is used to halt the execution.
|
// Fatalf is used to halt the execution.
|
||||||
// When called the function prints stack end exits.
|
// When called the function prints stack end exits.
|
||||||
// Failure is logged into both StdErr and StdOut.
|
// Failure is logged into both StdErr and StdOut.
|
||||||
|
|
|
@ -55,22 +55,22 @@ func StopNode() *C.char {
|
||||||
//ValidateNodeConfig validates config for status node
|
//ValidateNodeConfig validates config for status node
|
||||||
//export ValidateNodeConfig
|
//export ValidateNodeConfig
|
||||||
func ValidateNodeConfig(configJSON *C.char) *C.char {
|
func ValidateNodeConfig(configJSON *C.char) *C.char {
|
||||||
var resp common.APIDetailedResponse
|
var resp APIDetailedResponse
|
||||||
|
|
||||||
_, err := params.LoadNodeConfig(C.GoString(configJSON))
|
_, err := params.LoadNodeConfig(C.GoString(configJSON))
|
||||||
|
|
||||||
// Convert errors to common.APIDetailedResponse
|
// Convert errors to APIDetailedResponse
|
||||||
switch err := err.(type) {
|
switch err := err.(type) {
|
||||||
case validator.ValidationErrors:
|
case validator.ValidationErrors:
|
||||||
resp = common.APIDetailedResponse{
|
resp = APIDetailedResponse{
|
||||||
Message: "validation: validation failed",
|
Message: "validation: validation failed",
|
||||||
FieldErrors: make([]common.APIFieldError, len(err)),
|
FieldErrors: make([]APIFieldError, len(err)),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, ve := range err {
|
for i, ve := range err {
|
||||||
resp.FieldErrors[i] = common.APIFieldError{
|
resp.FieldErrors[i] = APIFieldError{
|
||||||
Parameter: ve.Namespace(),
|
Parameter: ve.Namespace(),
|
||||||
Errors: []common.APIError{
|
Errors: []APIError{
|
||||||
{
|
{
|
||||||
Message: fmt.Sprintf("field validation failed on the '%s' tag", ve.Tag()),
|
Message: fmt.Sprintf("field validation failed on the '%s' tag", ve.Tag()),
|
||||||
},
|
},
|
||||||
|
@ -78,11 +78,11 @@ func ValidateNodeConfig(configJSON *C.char) *C.char {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case error:
|
case error:
|
||||||
resp = common.APIDetailedResponse{
|
resp = APIDetailedResponse{
|
||||||
Message: fmt.Sprintf("validation: %s", err.Error()),
|
Message: fmt.Sprintf("validation: %s", err.Error()),
|
||||||
}
|
}
|
||||||
case nil:
|
case nil:
|
||||||
resp = common.APIDetailedResponse{
|
resp = APIDetailedResponse{
|
||||||
Status: true,
|
Status: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ func CreateAccount(password *C.char) *C.char {
|
||||||
errString = err.Error()
|
errString = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
out := common.AccountInfo{
|
out := AccountInfo{
|
||||||
Address: address,
|
Address: address,
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
Mnemonic: mnemonic,
|
Mnemonic: mnemonic,
|
||||||
|
@ -142,7 +142,7 @@ func CreateChildAccount(parentAddress, password *C.char) *C.char {
|
||||||
errString = err.Error()
|
errString = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
out := common.AccountInfo{
|
out := AccountInfo{
|
||||||
Address: address,
|
Address: address,
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
Error: errString,
|
Error: errString,
|
||||||
|
@ -162,7 +162,7 @@ func RecoverAccount(password, mnemonic *C.char) *C.char {
|
||||||
errString = err.Error()
|
errString = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
out := common.AccountInfo{
|
out := AccountInfo{
|
||||||
Address: address,
|
Address: address,
|
||||||
PubKey: pubKey,
|
PubKey: pubKey,
|
||||||
Mnemonic: C.GoString(mnemonic),
|
Mnemonic: C.GoString(mnemonic),
|
||||||
|
@ -225,7 +225,7 @@ func CompleteTransactions(ids, password *C.char) *C.char {
|
||||||
out := common.CompleteTransactionsResult{}
|
out := common.CompleteTransactionsResult{}
|
||||||
out.Results = make(map[string]common.CompleteTransactionResult)
|
out.Results = make(map[string]common.CompleteTransactionResult)
|
||||||
|
|
||||||
parsedIDs, err := common.ParseJSONArray(C.GoString(ids))
|
parsedIDs, err := ParseJSONArray(C.GoString(ids))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
out.Results["none"] = common.CompleteTransactionResult{
|
out.Results["none"] = common.CompleteTransactionResult{
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
|
@ -288,7 +288,7 @@ func DiscardTransactions(ids *C.char) *C.char {
|
||||||
out := common.DiscardTransactionsResult{}
|
out := common.DiscardTransactionsResult{}
|
||||||
out.Results = make(map[string]common.DiscardTransactionResult)
|
out.Results = make(map[string]common.DiscardTransactionResult)
|
||||||
|
|
||||||
parsedIDs, err := common.ParseJSONArray(C.GoString(ids))
|
parsedIDs, err := ParseJSONArray(C.GoString(ids))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
out.Results["none"] = common.DiscardTransactionResult{
|
out.Results["none"] = common.DiscardTransactionResult{
|
||||||
Error: err.Error(),
|
Error: err.Error(),
|
||||||
|
@ -383,7 +383,7 @@ func makeJSONResponse(err error) *C.char {
|
||||||
errString = err.Error()
|
errString = err.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
out := common.APIResponse{
|
out := APIResponse{
|
||||||
Error: errString,
|
Error: errString,
|
||||||
}
|
}
|
||||||
outBytes, _ := json.Marshal(out)
|
outBytes, _ := json.Marshal(out)
|
||||||
|
@ -409,7 +409,7 @@ func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char)
|
||||||
errString := ""
|
errString := ""
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
out := common.NotifyResult{
|
out := NotifyResult{
|
||||||
Status: err == nil,
|
Status: err == nil,
|
||||||
Error: errString,
|
Error: errString,
|
||||||
}
|
}
|
||||||
|
@ -424,7 +424,7 @@ func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char)
|
||||||
outCBytes = C.CString(string(outBytes))
|
outCBytes = C.CString(string(outBytes))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
tokens, err := common.ParseJSONArray(C.GoString(tokensArray))
|
tokens, err := ParseJSONArray(C.GoString(tokensArray))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errString = err.Error()
|
errString = err.Error()
|
||||||
return
|
return
|
||||||
|
|
|
@ -9,7 +9,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/status-im/status-go/geth/common"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ func TestExportedAPI(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateNodeConfig(t *testing.T) {
|
func TestValidateNodeConfig(t *testing.T) {
|
||||||
noErrorsCallback := func(resp common.APIDetailedResponse) {
|
noErrorsCallback := func(resp APIDetailedResponse) {
|
||||||
require.True(t, resp.Status, "expected status equal true")
|
require.True(t, resp.Status, "expected status equal true")
|
||||||
require.Empty(t, resp.FieldErrors)
|
require.Empty(t, resp.FieldErrors)
|
||||||
require.Empty(t, resp.Message)
|
require.Empty(t, resp.Message)
|
||||||
|
@ -32,7 +31,7 @@ func TestValidateNodeConfig(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Name string
|
Name string
|
||||||
Config string
|
Config string
|
||||||
Callback func(common.APIDetailedResponse)
|
Callback func(APIDetailedResponse)
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
Name: "response for valid config",
|
Name: "response for valid config",
|
||||||
|
@ -45,7 +44,7 @@ func TestValidateNodeConfig(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "response for invalid JSON string",
|
Name: "response for invalid JSON string",
|
||||||
Config: `{"Network": }`,
|
Config: `{"Network": }`,
|
||||||
Callback: func(resp common.APIDetailedResponse) {
|
Callback: func(resp APIDetailedResponse) {
|
||||||
require.False(t, resp.Status)
|
require.False(t, resp.Status)
|
||||||
require.Contains(t, resp.Message, "validation: invalid character '}'")
|
require.Contains(t, resp.Message, "validation: invalid character '}'")
|
||||||
},
|
},
|
||||||
|
@ -53,7 +52,7 @@ func TestValidateNodeConfig(t *testing.T) {
|
||||||
{
|
{
|
||||||
Name: "response for config with multiple errors",
|
Name: "response for config with multiple errors",
|
||||||
Config: `{}`,
|
Config: `{}`,
|
||||||
Callback: func(resp common.APIDetailedResponse) {
|
Callback: func(resp APIDetailedResponse) {
|
||||||
required := map[string]string{
|
required := map[string]string{
|
||||||
"NodeConfig.NetworkID": "required",
|
"NodeConfig.NetworkID": "required",
|
||||||
"NodeConfig.DataDir": "required",
|
"NodeConfig.DataDir": "required",
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,77 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// APIResponse generic response from API.
|
||||||
|
type APIResponse struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIDetailedResponse represents a generic response
|
||||||
|
// with possible errors.
|
||||||
|
type APIDetailedResponse struct {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
FieldErrors []APIFieldError `json:"field_errors,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error string representation of APIDetailedResponse.
|
||||||
|
func (r APIDetailedResponse) Error() string {
|
||||||
|
buf := bytes.NewBufferString("")
|
||||||
|
|
||||||
|
for _, err := range r.FieldErrors {
|
||||||
|
buf.WriteString(err.Error() + "\n") // nolint: gas
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimSpace(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIFieldError represents a set of errors
|
||||||
|
// related to a parameter.
|
||||||
|
type APIFieldError struct {
|
||||||
|
Parameter string `json:"parameter,omitempty"`
|
||||||
|
Errors []APIError `json:"errors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error string representation of APIFieldError.
|
||||||
|
func (e APIFieldError) Error() string {
|
||||||
|
if len(e.Errors) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBufferString(fmt.Sprintf("Parameter: %s\n", e.Parameter))
|
||||||
|
|
||||||
|
for _, err := range e.Errors {
|
||||||
|
buf.WriteString(err.Error() + "\n") // nolint: gas
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimSpace(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// APIError represents a single error.
|
||||||
|
type APIError struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error string representation of APIError.
|
||||||
|
func (e APIError) Error() string {
|
||||||
|
return fmt.Sprintf("message=%s", e.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccountInfo represents account's info.
|
||||||
|
type AccountInfo struct {
|
||||||
|
Address string `json:"address"`
|
||||||
|
PubKey string `json:"pubkey"`
|
||||||
|
Mnemonic string `json:"mnemonic"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotifyResult is a JSON returned from notify message.
|
||||||
|
type NotifyResult struct {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
}
|
1479
lib/utils.go
1479
lib/utils.go
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue