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:
Adrià Cidre 2018-03-29 16:10:29 +02:00 committed by GitHub
commit 33c739fecf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1591 additions and 1573 deletions

View File

@ -5,9 +5,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"os"
"strings"
"time"
"github.com/ethereum/go-ethereum/common"
@ -85,67 +83,6 @@ func isNilOrEmpty(bytes hexutil.Bytes) bool {
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.
type StopRPCCallError struct {
Err error

View File

@ -2,7 +2,6 @@ package common
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
@ -10,7 +9,6 @@ import (
"path/filepath"
"reflect"
"runtime/debug"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/pborman/uuid"
@ -44,18 +42,6 @@ func ImportTestAccount(keystoreDir, accountFile string) error {
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)
func MessageIDFromContext(ctx context.Context) string {
if ctx == nil {
@ -68,17 +54,6 @@ func MessageIDFromContext(ctx context.Context) string {
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.
// When called the function prints stack end exits.
// Failure is logged into both StdErr and StdOut.

View File

@ -55,22 +55,22 @@ func StopNode() *C.char {
//ValidateNodeConfig validates config for status node
//export ValidateNodeConfig
func ValidateNodeConfig(configJSON *C.char) *C.char {
var resp common.APIDetailedResponse
var resp APIDetailedResponse
_, err := params.LoadNodeConfig(C.GoString(configJSON))
// Convert errors to common.APIDetailedResponse
// Convert errors to APIDetailedResponse
switch err := err.(type) {
case validator.ValidationErrors:
resp = common.APIDetailedResponse{
resp = APIDetailedResponse{
Message: "validation: validation failed",
FieldErrors: make([]common.APIFieldError, len(err)),
FieldErrors: make([]APIFieldError, len(err)),
}
for i, ve := range err {
resp.FieldErrors[i] = common.APIFieldError{
resp.FieldErrors[i] = APIFieldError{
Parameter: ve.Namespace(),
Errors: []common.APIError{
Errors: []APIError{
{
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:
resp = common.APIDetailedResponse{
resp = APIDetailedResponse{
Message: fmt.Sprintf("validation: %s", err.Error()),
}
case nil:
resp = common.APIDetailedResponse{
resp = APIDetailedResponse{
Status: true,
}
}
@ -121,7 +121,7 @@ func CreateAccount(password *C.char) *C.char {
errString = err.Error()
}
out := common.AccountInfo{
out := AccountInfo{
Address: address,
PubKey: pubKey,
Mnemonic: mnemonic,
@ -142,7 +142,7 @@ func CreateChildAccount(parentAddress, password *C.char) *C.char {
errString = err.Error()
}
out := common.AccountInfo{
out := AccountInfo{
Address: address,
PubKey: pubKey,
Error: errString,
@ -162,7 +162,7 @@ func RecoverAccount(password, mnemonic *C.char) *C.char {
errString = err.Error()
}
out := common.AccountInfo{
out := AccountInfo{
Address: address,
PubKey: pubKey,
Mnemonic: C.GoString(mnemonic),
@ -225,7 +225,7 @@ func CompleteTransactions(ids, password *C.char) *C.char {
out := common.CompleteTransactionsResult{}
out.Results = make(map[string]common.CompleteTransactionResult)
parsedIDs, err := common.ParseJSONArray(C.GoString(ids))
parsedIDs, err := ParseJSONArray(C.GoString(ids))
if err != nil {
out.Results["none"] = common.CompleteTransactionResult{
Error: err.Error(),
@ -288,7 +288,7 @@ func DiscardTransactions(ids *C.char) *C.char {
out := common.DiscardTransactionsResult{}
out.Results = make(map[string]common.DiscardTransactionResult)
parsedIDs, err := common.ParseJSONArray(C.GoString(ids))
parsedIDs, err := ParseJSONArray(C.GoString(ids))
if err != nil {
out.Results["none"] = common.DiscardTransactionResult{
Error: err.Error(),
@ -383,7 +383,7 @@ func makeJSONResponse(err error) *C.char {
errString = err.Error()
}
out := common.APIResponse{
out := APIResponse{
Error: errString,
}
outBytes, _ := json.Marshal(out)
@ -409,7 +409,7 @@ func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char)
errString := ""
defer func() {
out := common.NotifyResult{
out := NotifyResult{
Status: err == nil,
Error: errString,
}
@ -424,7 +424,7 @@ func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char)
outCBytes = C.CString(string(outBytes))
}()
tokens, err := common.ParseJSONArray(C.GoString(tokensArray))
tokens, err := ParseJSONArray(C.GoString(tokensArray))
if err != nil {
errString = err.Error()
return

View File

@ -9,7 +9,6 @@ package main
import (
"testing"
"github.com/status-im/status-go/geth/common"
"github.com/stretchr/testify/require"
)
@ -23,7 +22,7 @@ func TestExportedAPI(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.Empty(t, resp.FieldErrors)
require.Empty(t, resp.Message)
@ -32,7 +31,7 @@ func TestValidateNodeConfig(t *testing.T) {
testCases := []struct {
Name string
Config string
Callback func(common.APIDetailedResponse)
Callback func(APIDetailedResponse)
}{
{
Name: "response for valid config",
@ -45,7 +44,7 @@ func TestValidateNodeConfig(t *testing.T) {
{
Name: "response for invalid JSON string",
Config: `{"Network": }`,
Callback: func(resp common.APIDetailedResponse) {
Callback: func(resp APIDetailedResponse) {
require.False(t, resp.Status)
require.Contains(t, resp.Message, "validation: invalid character '}'")
},
@ -53,7 +52,7 @@ func TestValidateNodeConfig(t *testing.T) {
{
Name: "response for config with multiple errors",
Config: `{}`,
Callback: func(resp common.APIDetailedResponse) {
Callback: func(resp APIDetailedResponse) {
required := map[string]string{
"NodeConfig.NetworkID": "required",
"NodeConfig.DataDir": "required",

1479
lib/library_test_utils.go Normal file

File diff suppressed because it is too large Load Diff

77
lib/types.go Normal file
View File

@ -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"`
}

File diff suppressed because it is too large Load Diff