Skip to content
This repository was archived by the owner on Oct 11, 2024. It is now read-only.

Commit a594359

Browse files
authored
Merge pull request #283 from 0xProject/release/1.0.6-beta
Release version 1.0.6-beta
2 parents f10f849 + c0bb26c commit a594359

File tree

13 files changed

+350
-21
lines changed

13 files changed

+350
-21
lines changed

DEPLOYMENT.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Version](https://img.shields.io/badge/version-1.0.5--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
1+
[![Version](https://img.shields.io/badge/version-1.0.6--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
22

33
# 0x Mesh Deployment Guide
44

@@ -25,7 +25,7 @@ docker run \
2525
-p 60557:60557 \
2626
-p 60558:60558 \
2727
-e ETHEREUM_NETWORK_ID="1" \
28-
-e ETHEREUM_RPC_URL="https://mainnet.infura.io/v3/a9a23d2566e542629179d6372ace13c9" \
28+
-e ETHEREUM_RPC_URL="ADD_YOUR_ETHEREUM_RPC_ENDPOINT_HERE" \
2929
-e VERBOSITY=5 \
3030
0xorg/mesh:latest
3131
```

DEVELOPMENT.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Version](https://img.shields.io/badge/version-1.0.5--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
1+
[![Version](https://img.shields.io/badge/version-1.0.6--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
22

33
# 0x Mesh Development Guide
44

Gopkg.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Version](https://img.shields.io/badge/version-1.0.5--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
1+
[![Version](https://img.shields.io/badge/version-1.0.6--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
22
[![Chat with us on Discord](https://img.shields.io/badge/chat-Discord-blueViolet.svg)](https://discord.gg/HF7fHwk)
33
[![GoDoc](https://godoc.org/github.com/0xProject/0x-mesh?status.svg)](https://godoc.org/github.com/0xProject/0x-mesh)
44
[![Circle CI](https://img.shields.io/circleci/project/0xProject/0x-mesh/master.svg)](https://circleci.com/gh/0xProject/0x-mesh/tree/master)
@@ -12,7 +12,7 @@
1212

1313
## Versions
1414

15-
You are looking at the documentation for version `1.0.5-beta`. To see the
15+
You are looking at the documentation for version `1.0.6-beta`. To see the
1616
documentation for a different version, visit the
1717
[Releases Page](https://github.com/0xProject/0x-mesh/releases).
1818

USAGE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[![Version](https://img.shields.io/badge/version-1.0.5--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
1+
[![Version](https://img.shields.io/badge/version-1.0.6--beta-orange.svg)](https://github.com/0xProject/0x-mesh/releases)
22

33
# 0x Mesh Usage Guide
44

cmd/mesh-bootstrap/main.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,15 @@ import (
1717
"github.com/0xProject/0x-mesh/p2p"
1818
libp2p "github.com/libp2p/go-libp2p"
1919
autonat "github.com/libp2p/go-libp2p-autonat-svc"
20-
relay "github.com/libp2p/go-libp2p-circuit"
20+
circuit "github.com/libp2p/go-libp2p-circuit"
2121
connmgr "github.com/libp2p/go-libp2p-connmgr"
2222
p2pcrypto "github.com/libp2p/go-libp2p-crypto"
2323
host "github.com/libp2p/go-libp2p-host"
2424
dht "github.com/libp2p/go-libp2p-kad-dht"
2525
p2pnet "github.com/libp2p/go-libp2p-net"
2626
peer "github.com/libp2p/go-libp2p-peer"
2727
routing "github.com/libp2p/go-libp2p-routing"
28+
"github.com/libp2p/go-libp2p/p2p/host/relay"
2829
ma "github.com/multiformats/go-multiaddr"
2930
"github.com/plaid/go-envvar/envvar"
3031
log "github.com/sirupsen/logrus"
@@ -59,6 +60,13 @@ type Config struct {
5960
PrivateKeyPath string `envvar:"PRIVATE_KEY_PATH" default:"0x_mesh/keys/privkey"`
6061
}
6162

63+
func init() {
64+
// Since we know that the bootstrap nodes are more stable, we can
65+
// safely reduce AdvertiseBootDelay. This will allow the bootstrap nodes to
66+
// advertise themselves as relays sooner.
67+
relay.AdvertiseBootDelay = 30 * time.Second
68+
}
69+
6270
func main() {
6371
ctx, cancel := context.WithCancel(context.Background())
6472
defer cancel()
@@ -73,6 +81,7 @@ func main() {
7381
// TODO(albrow): Don't use global settings for logger.
7482
log.SetFormatter(&log.JSONFormatter{})
7583
log.SetLevel(log.Level(config.Verbosity))
84+
log.AddHook(loghooks.NewKeySuffixHook())
7685

7786
// Parse private key file
7887
privKey, err := initPrivateKey(config.PrivateKeyPath)
@@ -114,7 +123,7 @@ func main() {
114123
libp2p.ListenAddrs(hostAddr),
115124
libp2p.Identity(privKey),
116125
libp2p.ConnectionManager(connManager),
117-
libp2p.EnableRelay(relay.OptHop),
126+
libp2p.EnableRelay(circuit.OptHop),
118127
libp2p.EnableAutoRelay(),
119128
libp2p.Routing(newDHT),
120129
libp2p.AddrsFactory(newAddrsFactory(advertiseAddrs)),

core/core.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ func New(config Config) (*App, error) {
104104
// Configure logger
105105
// TODO(albrow): Don't use global variables for log settings.
106106
log.SetLevel(log.Level(config.Verbosity))
107+
log.AddHook(loghooks.NewKeySuffixHook())
107108
log.WithFields(map[string]interface{}{
108109
"config": config,
109-
"version": "1.0.5-beta",
110+
"version": "1.0.6-beta",
110111
}).Info("Initializing new core.App")
111112

112113
if config.EthereumRPCMaxContentLength < maxOrderSizeInBytes {

examples/beta_telemetry_node/docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: '3'
22

33
services:
44
mesh:
5-
image: 0xorg/mesh:1.0.5-beta
5+
image: 0xorg/mesh:1.0.6-beta
66
restart: always
77
logging:
88
driver: fluentd

loghooks/key_suffix_hook.go

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
package loghooks
2+
3+
import (
4+
"bytes"
5+
"encoding"
6+
"encoding/json"
7+
"errors"
8+
"fmt"
9+
"reflect"
10+
"strings"
11+
12+
log "github.com/sirupsen/logrus"
13+
)
14+
15+
var errNestedMapType = errors.New("nested map types are not supported")
16+
17+
// KeySuffixHook is a logger hook that adds suffixes to all keys based on their
18+
// type.
19+
type KeySuffixHook struct{}
20+
21+
// NewKeySuffixHook creates and returns a new KeySuffixHook.
22+
func NewKeySuffixHook() *KeySuffixHook {
23+
return &KeySuffixHook{}
24+
}
25+
26+
// Ensure that KeySuffixHook implements log.Hook.
27+
var _ log.Hook = &KeySuffixHook{}
28+
29+
func (h *KeySuffixHook) Levels() []log.Level {
30+
return log.AllLevels
31+
}
32+
33+
func (h *KeySuffixHook) Fire(entry *log.Entry) error {
34+
for key, value := range entry.Data {
35+
typ, err := getTypeForValue(value)
36+
if err != nil {
37+
if err == errNestedMapType {
38+
// We can't safely log nested map types, so replace the value with a
39+
// string.
40+
newKey := fmt.Sprintf("%s_json_string", key)
41+
delete(entry.Data, key)
42+
mapString, err := json.Marshal(value)
43+
if err != nil {
44+
return err
45+
}
46+
entry.Data[newKey] = string(mapString)
47+
continue
48+
} else {
49+
return err
50+
}
51+
}
52+
newKey := fmt.Sprintf("%s_%s", key, typ)
53+
delete(entry.Data, key)
54+
entry.Data[newKey] = value
55+
}
56+
return nil
57+
}
58+
59+
// getTypeForValue returns a string representation of the type of the given val.
60+
func getTypeForValue(val interface{}) (string, error) {
61+
if _, ok := val.(json.Marshaler); ok {
62+
// If val implements json.Marshaler, return the type of json.Marshal(val)
63+
// instead of the type of val.
64+
buf := &bytes.Buffer{}
65+
if err := json.NewEncoder(buf).Encode(val); err != nil {
66+
return "", err
67+
}
68+
var holder interface{}
69+
if err := json.NewDecoder(buf).Decode(&holder); err != nil {
70+
return "", err
71+
}
72+
return getTypeForValue(holder)
73+
}
74+
if _, ok := val.(encoding.TextMarshaler); ok {
75+
// The json package always encodes values that implement
76+
// encoding.TextMarshaler as a string.
77+
return "string", nil
78+
}
79+
80+
underlyingType := getUnderlyingType(reflect.TypeOf(val))
81+
switch kind := underlyingType.Kind(); kind {
82+
case reflect.Bool:
83+
return "bool", nil
84+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64:
85+
return "number", nil
86+
case reflect.String, reflect.Complex64, reflect.Complex128, reflect.Func, reflect.Chan:
87+
return "string", nil
88+
case reflect.Array, reflect.Slice:
89+
return "array", nil
90+
case reflect.Map:
91+
// Nested map types can't be efficiently indexed because they allow for
92+
// arbitrary keys. We don't allow them.
93+
return "", errNestedMapType
94+
case reflect.Struct:
95+
return getSafeStructTypeName(underlyingType)
96+
default:
97+
return "", fmt.Errorf("cannot determine type suffix for kind: %s", kind)
98+
}
99+
}
100+
101+
// getUnderlyingType returns the underlying type for the given type by
102+
// recursively dereferencing pointer types.
103+
func getUnderlyingType(typ reflect.Type) reflect.Type {
104+
if typ.Kind() == reflect.Ptr {
105+
return getUnderlyingType(typ.Elem())
106+
}
107+
return typ
108+
}
109+
110+
// getSafeStructTypeName replaces dots in the name of the given type with
111+
// underscores. Elasticsearch does not allow dots in key names.
112+
func getSafeStructTypeName(typ reflect.Type) (string, error) {
113+
unsafeTypeName := typ.String()
114+
safeTypeName := strings.ReplaceAll(unsafeTypeName, ".", "_")
115+
return safeTypeName, nil
116+
}

loghooks/key_suffix_hook_test.go

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package loghooks
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/0xProject/0x-mesh/constants"
8+
9+
log "github.com/sirupsen/logrus"
10+
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
type myStruct struct {
15+
myInt int
16+
myString string
17+
}
18+
19+
func TestGetTypeForValue(t *testing.T) {
20+
testCases := []struct {
21+
input interface{}
22+
expected string
23+
}{
24+
{
25+
input: true,
26+
expected: "bool",
27+
},
28+
{
29+
input: int(42),
30+
expected: "number",
31+
},
32+
{
33+
input: int8(42),
34+
expected: "number",
35+
},
36+
{
37+
input: int16(42),
38+
expected: "number",
39+
},
40+
{
41+
input: int32(42),
42+
expected: "number",
43+
},
44+
{
45+
input: int64(42),
46+
expected: "number",
47+
},
48+
{
49+
input: uint(42),
50+
expected: "number",
51+
},
52+
{
53+
input: uint8(42),
54+
expected: "number",
55+
},
56+
{
57+
input: uint16(42),
58+
expected: "number",
59+
},
60+
{
61+
input: uint32(42),
62+
expected: "number",
63+
},
64+
{
65+
input: uint64(42),
66+
expected: "number",
67+
},
68+
{
69+
input: float32(42),
70+
expected: "number",
71+
},
72+
{
73+
input: float64(42),
74+
expected: "number",
75+
},
76+
{
77+
input: "foo",
78+
expected: "string",
79+
},
80+
{
81+
input: complex64(42i + 7),
82+
expected: "string",
83+
},
84+
{
85+
input: complex128(42i + 7),
86+
expected: "string",
87+
},
88+
{
89+
input: func() {},
90+
expected: "string",
91+
},
92+
{
93+
input: make(chan struct{}),
94+
expected: "string",
95+
},
96+
{
97+
input: []int{},
98+
expected: "array",
99+
},
100+
{
101+
input: [...]int{},
102+
expected: "array",
103+
},
104+
{
105+
input: myStruct{},
106+
expected: "loghooks_myStruct",
107+
},
108+
{
109+
// Implements encoding.TextUnmarshaler but not json.Marshaler.
110+
input: constants.NullAddress,
111+
expected: "string",
112+
},
113+
{
114+
// We don't expect the case of anonymous structs to come up often, but we
115+
// do handle it correcly. " ", "{", "}", and ";" are allowed in
116+
// Elasticsearch. The resulting string is ugly but at least it is
117+
// guaranteed to prevent field mapping conflicts.
118+
input: struct {
119+
myInt int
120+
myString string
121+
}{},
122+
expected: "struct { myInt int; myString string }",
123+
},
124+
}
125+
126+
for _, testCase := range testCases {
127+
testCaseInfo := fmt.Sprintf("input: (%T) %v", testCase.input, testCase.input)
128+
actual, err := getTypeForValue(testCase.input)
129+
require.NoError(t, err, testCaseInfo)
130+
assert.Equal(t, testCase.expected, actual, testCaseInfo)
131+
}
132+
}
133+
134+
func TestKeySuffixHookWithNestedMapType(t *testing.T) {
135+
hook := NewKeySuffixHook()
136+
entry := &log.Entry{
137+
Data: log.Fields{
138+
"myMap": map[string]int{"one": 1},
139+
},
140+
}
141+
require.NoError(t, hook.Fire(entry))
142+
expectedData := log.Fields{
143+
"myMap_json_string": `{"one":1}`,
144+
}
145+
assert.Equal(t, expectedData, entry.Data)
146+
}

0 commit comments

Comments
 (0)