mirror of
https://github.com/status-im/status-console-client.git
synced 2025-02-22 07:38:12 +00:00
Use new status-go/eth-node module
This commit is contained in:
parent
9aa22fc2b2
commit
861f1289c7
4
.gitignore
vendored
4
.gitignore
vendored
@ -22,7 +22,7 @@ status-console-client
|
|||||||
|
|
||||||
# Nimbus-related stuff
|
# Nimbus-related stuff
|
||||||
# We build Nimbus and place the libraries in vendor/github.com/status-im/nimbus
|
# We build Nimbus and place the libraries in vendor/github.com/status-im/nimbus
|
||||||
# and header files in vendor/github.com/status-im/status-protocol-go/bridge/nimbus
|
# and header files in vendor/github.com/status-im/status-go/eth-node/bridge/nimbus
|
||||||
# but we don't want to add that to source code control
|
# but we don't want to add that to source code control
|
||||||
vendor/github.com/status-im/nimbus
|
vendor/github.com/status-im/nimbus
|
||||||
vendor/github.com/status-im/status-protocol-go/bridge/nimbus/libnimbus.*
|
vendor/github.com/status-im/status-go/eth-node/bridge/nimbus/libnimbus.*
|
||||||
|
9
Makefile
9
Makefile
@ -16,9 +16,12 @@ build:
|
|||||||
# XXX: Multiple ldflags a bit brittle, keeping it simple by having separate build target for now.
|
# XXX: Multiple ldflags a bit brittle, keeping it simple by having separate build target for now.
|
||||||
# See https://github.com/golang/go/issues/29053
|
# See https://github.com/golang/go/issues/29053
|
||||||
build-nimbus: GOFLAGS ?= "-mod=vendor"
|
build-nimbus: GOFLAGS ?= "-mod=vendor"
|
||||||
|
build-nimbus: _NIMBUS_DIR := "./vendor/github.com/status-im/status-go/eth-node/bridge/nimbus"
|
||||||
build-nimbus:
|
build-nimbus:
|
||||||
scripts/build-nimbus.sh
|
chmod u+x $(_NIMBUS_DIR)/build-nimbus.sh
|
||||||
GOFLAGS=$(GOFLAGS) go build -ldflags="-r ./vendor/github.com/status-im/status-protocol-go/bridge/nimbus" -tags "nimbus geth" -o ./bin/status-term-client .
|
$(_NIMBUS_DIR)/build-nimbus.sh
|
||||||
|
chmod u-x $(_NIMBUS_DIR)/build-nimbus.sh
|
||||||
|
GOFLAGS=$(GOFLAGS) go build -ldflags="-r $(_NIMBUS_DIR)" -tags "nimbus geth" -o ./bin/status-term-client .
|
||||||
.PHONY: build-nimbus
|
.PHONY: build-nimbus
|
||||||
|
|
||||||
run: ARGS ?=
|
run: ARGS ?=
|
||||||
@ -45,7 +48,7 @@ lint-v110:
|
|||||||
vendor:
|
vendor:
|
||||||
go mod tidy
|
go mod tidy
|
||||||
go mod vendor
|
go mod vendor
|
||||||
modvendor -copy="**/*.c **/*.h" -v
|
modvendor -copy="**/*.c **/*.h **/build-nimbus.sh" -v
|
||||||
.PHONY: vendor
|
.PHONY: vendor
|
||||||
|
|
||||||
install-linter:
|
install-linter:
|
||||||
|
@ -58,11 +58,6 @@ The main package contains the console user interface.
|
|||||||
|
|
||||||
2. This C API is consumed as a standard shared library, `libnimbus_api.so`.
|
2. This C API is consumed as a standard shared library, `libnimbus_api.so`.
|
||||||
|
|
||||||
3. [status-nim](https://github.com/status-im/status-nim) wraps this library to
|
|
||||||
expose a Go API. Currently, this "API" is more like a hacky spike. The goal is
|
|
||||||
for this to library to hide the integration details with Nim and provide a clean
|
|
||||||
Go interface for consumers.
|
|
||||||
|
|
||||||
## Building and running
|
## Building and running
|
||||||
|
|
||||||
The changes are isolated and won't impact `status-console-client` unless the
|
The changes are isolated and won't impact `status-console-client` unless the
|
||||||
|
@ -3,19 +3,19 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/jroimartin/gocui"
|
"github.com/jroimartin/gocui"
|
||||||
status "github.com/status-im/status-protocol-go"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
|
"github.com/status-im/status-go/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
// chatToString returns a string representation.
|
// chatToString returns a string representation.
|
||||||
func chatToString(c *status.Chat) string {
|
func chatToString(c *protocol.Chat) string {
|
||||||
switch c.ChatType {
|
switch c.ChatType {
|
||||||
case status.ChatTypePublic:
|
case protocol.ChatTypePublic:
|
||||||
return fmt.Sprintf("#%s", c.Name)
|
return fmt.Sprintf("#%s", c.Name)
|
||||||
case status.ChatTypeOneToOne:
|
case protocol.ChatTypeOneToOne:
|
||||||
return fmt.Sprintf("@%s (%#x)", c.Name, crypto.FromECDSAPub(c.PublicKey)[:8])
|
return fmt.Sprintf("@%s (%#x)", c.Name, crypto.FromECDSAPub(c.PublicKey)[:8])
|
||||||
default:
|
default:
|
||||||
return c.Name
|
return c.Name
|
||||||
@ -25,13 +25,13 @@ func chatToString(c *status.Chat) string {
|
|||||||
// ChatsViewController manages chats view.
|
// ChatsViewController manages chats view.
|
||||||
type ChatsViewController struct {
|
type ChatsViewController struct {
|
||||||
*ViewController
|
*ViewController
|
||||||
messenger *status.Messenger
|
messenger *protocol.Messenger
|
||||||
chats []*status.Chat
|
chats []*protocol.Chat
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewChatsViewController returns a new chat view controller.
|
// NewChatsViewController returns a new chat view controller.
|
||||||
func NewChatsViewController(vm *ViewController, m *status.Messenger, logger *zap.Logger) *ChatsViewController {
|
func NewChatsViewController(vm *ViewController, m *protocol.Messenger, logger *zap.Logger) *ChatsViewController {
|
||||||
return &ChatsViewController{
|
return &ChatsViewController{
|
||||||
ViewController: vm,
|
ViewController: vm,
|
||||||
messenger: m,
|
messenger: m,
|
||||||
@ -49,7 +49,7 @@ func (c *ChatsViewController) LoadAndRefresh() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ChatByIdx allows to retrieve a chat for a given index.
|
// ChatByIdx allows to retrieve a chat for a given index.
|
||||||
func (c *ChatsViewController) ChatByIdx(idx int) (*status.Chat, bool) {
|
func (c *ChatsViewController) ChatByIdx(idx int) (*protocol.Chat, bool) {
|
||||||
if idx > -1 && idx < len(c.chats) {
|
if idx > -1 && idx < len(c.chats) {
|
||||||
return c.chats[idx], true
|
return c.chats[idx], true
|
||||||
}
|
}
|
||||||
@ -57,7 +57,7 @@ func (c *ChatsViewController) ChatByIdx(idx int) (*status.Chat, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add adds a new chat to the list.
|
// Add adds a new chat to the list.
|
||||||
func (c *ChatsViewController) Add(chat status.Chat) error {
|
func (c *ChatsViewController) Add(chat protocol.Chat) error {
|
||||||
if err := c.messenger.SaveChat(chat); err != nil {
|
if err := c.messenger.SaveChat(chat); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ func (c *ChatsViewController) Add(chat status.Chat) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes a chat from the list.
|
// Remove removes a chat from the list.
|
||||||
func (c *ChatsViewController) Remove(chat status.Chat) error {
|
func (c *ChatsViewController) Remove(chat protocol.Chat) error {
|
||||||
if err := c.messenger.DeleteChat(chat.ID); err != nil {
|
if err := c.messenger.DeleteChat(chat.ID); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
17
geth.go
17
geth.go
@ -9,13 +9,13 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/status-im/status-console-client/internal/gethservice"
|
"github.com/status-im/status-console-client/internal/gethservice"
|
||||||
|
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/node"
|
"github.com/status-im/status-go/node"
|
||||||
status "github.com/status-im/status-protocol-go"
|
"github.com/status-im/status-go/protocol"
|
||||||
gethbridge "github.com/status-im/status-protocol-go/bridge/geth"
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func newGethWhisperWrapper(pk *ecdsa.PrivateKey) (whispertypes.Whisper, error) {
|
func newGethNodeWrapper(pk *ecdsa.PrivateKey) (types.Node, error) {
|
||||||
nodeConfig, err := generateStatusNodeConfig(*dataDir, *fleet, *listenAddr, *configFile)
|
nodeConfig, err := generateStatusNodeConfig(*dataDir, *fleet, *listenAddr, *configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
exitErr(errors.Wrap(err, "failed to generate node config"))
|
exitErr(errors.Wrap(err, "failed to generate node config"))
|
||||||
@ -38,15 +38,10 @@ func newGethWhisperWrapper(pk *ecdsa.PrivateKey) (whispertypes.Whisper, error) {
|
|||||||
return nil, errors.Wrap(err, "failed to start node")
|
return nil, errors.Wrap(err, "failed to start node")
|
||||||
}
|
}
|
||||||
|
|
||||||
shhService, err := statusNode.WhisperService()
|
return gethbridge.NewNodeBridge(statusNode.GethNode()), nil
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to get Whisper service")
|
|
||||||
}
|
|
||||||
|
|
||||||
return gethbridge.NewGethWhisperWrapper(shhService), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMessengerWithURI(uri string) (*status.Messenger, error) {
|
func createMessengerWithURI(uri string) (*protocol.Messenger, error) {
|
||||||
_, err := rpc.Dial(uri)
|
_, err := rpc.Dial(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "failed to dial")
|
return nil, errors.Wrap(err, "failed to dial")
|
||||||
|
@ -5,16 +5,16 @@ package main
|
|||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
|
||||||
status "github.com/status-im/status-protocol-go"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
const noGethError = "executable needs to be built without -tags nimbus or with -tags geth"
|
const noGethError = "executable needs to be built without -tags nimbus or with -tags geth"
|
||||||
|
|
||||||
func newGethWhisperWrapper(pk *ecdsa.PrivateKey) (whispertypes.Whisper, error) {
|
func newGethWhisperWrapper(pk *ecdsa.PrivateKey) (types.Whisper, error) {
|
||||||
panic(noGethError)
|
panic(noGethError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMessengerWithURI(uri string) (*status.Messenger, error) {
|
func createMessengerWithURI(uri string) (*protocol.Messenger, error) {
|
||||||
panic(noGethError)
|
panic(noGethError)
|
||||||
}
|
}
|
||||||
|
11
go.mod
11
go.mod
@ -2,7 +2,7 @@ module github.com/status-im/status-console-client
|
|||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.4
|
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.6
|
||||||
|
|
||||||
replace github.com/Sirupsen/logrus v1.4.2 => github.com/sirupsen/logrus v1.4.2
|
replace github.com/Sirupsen/logrus v1.4.2 => github.com/sirupsen/logrus v1.4.2
|
||||||
|
|
||||||
@ -10,6 +10,8 @@ replace github.com/docker/docker => github.com/docker/engine v1.4.2-0.2019071716
|
|||||||
|
|
||||||
replace github.com/gomarkdown/markdown => github.com/status-im/markdown v0.0.0-20191113114344-af599402d015
|
replace github.com/gomarkdown/markdown => github.com/status-im/markdown v0.0.0-20191113114344-af599402d015
|
||||||
|
|
||||||
|
replace github.com/status-im/status-go/eth-node => github.com/status-im/status-go/eth-node v0.36.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/go-winio v0.4.12 // indirect
|
github.com/Microsoft/go-winio v0.4.12 // indirect
|
||||||
github.com/allegro/bigcache v1.2.1 // indirect
|
github.com/allegro/bigcache v1.2.1 // indirect
|
||||||
@ -25,10 +27,11 @@ require (
|
|||||||
github.com/nsf/termbox-go v0.0.0-20190624072549-eeb6cd0a1762 // indirect
|
github.com/nsf/termbox-go v0.0.0-20190624072549-eeb6cd0a1762 // indirect
|
||||||
github.com/peterbourgon/ff v1.2.0
|
github.com/peterbourgon/ff v1.2.0
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
github.com/status-im/status-go v0.34.0-beta.9.0.20191118133003-2dd74da23d9f
|
github.com/status-im/status-go v0.36.0
|
||||||
github.com/status-im/status-protocol-go v0.5.2
|
github.com/status-im/status-go/eth-node v0.36.0
|
||||||
|
github.com/status-im/status-go/protocol v0.36.0
|
||||||
github.com/stretchr/objx v0.2.0 // indirect
|
github.com/stretchr/objx v0.2.0 // indirect
|
||||||
go.uber.org/zap v1.10.0
|
go.uber.org/zap v1.13.0
|
||||||
google.golang.org/genproto v0.0.0-20190701230453-710ae3a149df // indirect
|
google.golang.org/genproto v0.0.0-20190701230453-710ae3a149df // indirect
|
||||||
google.golang.org/grpc v1.22.0 // indirect
|
google.golang.org/grpc v1.22.0 // indirect
|
||||||
)
|
)
|
||||||
|
65
go.sum
65
go.sum
@ -50,14 +50,14 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
|
||||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
|
||||||
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
||||||
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
||||||
github.com/btcsuite/btcd v0.0.0-20190418232430-6867ff32788a/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
github.com/btcsuite/btcd v0.0.0-20190418232430-6867ff32788a/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8=
|
||||||
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||||
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI=
|
||||||
github.com/btcsuite/btcd v0.0.0-20191011042131-c3151ef50de9 h1:wYYywOGk2jIXV+yt1zIiKl64c/4WLKMh4KET7K8FXFY=
|
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||||
github.com/btcsuite/btcd v0.0.0-20191011042131-c3151ef50de9/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
|
||||||
|
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||||
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
|
||||||
@ -134,8 +134,9 @@ github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt
|
|||||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
github.com/elastic/gosigar v0.10.4 h1:6jfw75dsoflhBMRdO6QPzQUgLqUYTsQQQRkkcsHsuPo=
|
|
||||||
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.10.4/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo=
|
||||||
|
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||||
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||||
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
github.com/ethereum/go-ethereum v1.9.2/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||||
@ -182,7 +183,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
|||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
|
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||||
github.com/golang/protobuf v0.0.0-20170726212829-748d386b5c1e/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
@ -201,6 +201,7 @@ github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO
|
|||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@ -551,6 +552,7 @@ github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w
|
|||||||
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
|
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
|
||||||
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
||||||
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||||
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
github.com/rs/cors v1.6.0 h1:G9tHG9lebljV9mfp9SNPDL36nCDxmo3zTlAf1YgvzmI=
|
||||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
@ -585,8 +587,8 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
|
|||||||
github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc=
|
github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc=
|
||||||
github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY=
|
github.com/status-im/doubleratchet v3.0.0+incompatible h1:aJ1ejcSERpSzmWZBgtfYtiU2nF0Q8ZkGyuEPYETXkCY=
|
||||||
github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU=
|
github.com/status-im/doubleratchet v3.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU=
|
||||||
github.com/status-im/go-ethereum v1.9.5-status.4 h1:F5VrxH9LmTxWl4qwQjs0TI5TgG9dVuZKqGmdwHJ0cWk=
|
github.com/status-im/go-ethereum v1.9.5-status.6 h1:ytuTO1yBIAuTVRtRQoc2mrdyngtP+XOQ9IHIibbz7/I=
|
||||||
github.com/status-im/go-ethereum v1.9.5-status.4/go.mod h1:Ulij8LMpMvXnbnPcmDqrpI+iXoXSjxItuY/wmbasTZU=
|
github.com/status-im/go-ethereum v1.9.5-status.6/go.mod h1:08JvQWE+IOnAFSe4UD4ACLNe2fDd9XmWMCq5Yzy9mk0=
|
||||||
github.com/status-im/go-multiaddr-ethv4 v1.2.0 h1:OT84UsUzTCwguqCpJqkrCMiL4VZ1SvUtH9a5MsZupBk=
|
github.com/status-im/go-multiaddr-ethv4 v1.2.0 h1:OT84UsUzTCwguqCpJqkrCMiL4VZ1SvUtH9a5MsZupBk=
|
||||||
github.com/status-im/go-multiaddr-ethv4 v1.2.0/go.mod h1:2VQ3C+9zEurcceasz12gPAtmEzCeyLUGPeKLSXYQKHo=
|
github.com/status-im/go-multiaddr-ethv4 v1.2.0/go.mod h1:2VQ3C+9zEurcceasz12gPAtmEzCeyLUGPeKLSXYQKHo=
|
||||||
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 h1:ju5UTwk5Odtm4trrY+4Ca4RMj5OyXbmVeDAVad2T0Jw=
|
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 h1:ju5UTwk5Odtm4trrY+4Ca4RMj5OyXbmVeDAVad2T0Jw=
|
||||||
@ -597,12 +599,17 @@ github.com/status-im/migrate/v4 v4.6.2-status.2 h1:SdC+sMDl/aI7vUlwD2qj2p7KsK4T6
|
|||||||
github.com/status-im/migrate/v4 v4.6.2-status.2/go.mod h1:c/kc90n47GZu/58nnz1OMLTf7uE4Da4gZP5qmU+A/v8=
|
github.com/status-im/migrate/v4 v4.6.2-status.2/go.mod h1:c/kc90n47GZu/58nnz1OMLTf7uE4Da4gZP5qmU+A/v8=
|
||||||
github.com/status-im/rendezvous v1.3.0 h1:7RK/MXXW+tlm0asKm1u7Qp7Yni6AO29a7j8+E4Lbjg4=
|
github.com/status-im/rendezvous v1.3.0 h1:7RK/MXXW+tlm0asKm1u7Qp7Yni6AO29a7j8+E4Lbjg4=
|
||||||
github.com/status-im/rendezvous v1.3.0/go.mod h1:+hzjuP+j/XzLPeF6E50b88pWOTLdTcwjvNYt+Gh1W1s=
|
github.com/status-im/rendezvous v1.3.0/go.mod h1:+hzjuP+j/XzLPeF6E50b88pWOTLdTcwjvNYt+Gh1W1s=
|
||||||
github.com/status-im/status-go v0.34.0-beta.9.0.20191118133003-2dd74da23d9f h1:A67yhEIRFXB+d5/5XfQ7ST7nP2Ios3zlb/vMJnAfQlQ=
|
github.com/status-im/status-go v0.36.0 h1:91qDMJjHv+T3Li9FwxsWQ2JBVcYtvVDT0nGFSMnmM+8=
|
||||||
github.com/status-im/status-go v0.34.0-beta.9.0.20191118133003-2dd74da23d9f/go.mod h1:UPM+mYKxOQki9uS3eyUVsjWg0iugdd/LyGZl0UO1uO4=
|
github.com/status-im/status-go v0.36.0/go.mod h1:1O+FK3YK3BXzEufXbhf9V/0j1GTSjThRt2atMD/SU7A=
|
||||||
github.com/status-im/status-protocol-go v0.5.2 h1:C6m6N6TLzJbuJmV4u8iNzs0cj+Q1CfBWdS0LZLtGkN8=
|
github.com/status-im/status-go/eth-node v0.36.0 h1:tni6UhenZ/rej50J0rFkOyxkGN6cJL7ksXOTK+8PdZI=
|
||||||
github.com/status-im/status-protocol-go v0.5.2/go.mod h1:L5/7fKnycEBOiLm3TuCHDUNcn0kNNhSNsYLkqbUQngg=
|
github.com/status-im/status-go/eth-node v0.36.0/go.mod h1:i//qqd7GhK1LJhY3FiVvrCjdXBwByo+R78q19P0bdCY=
|
||||||
|
github.com/status-im/status-go/extkeys v1.0.0 h1:Qyirsoi5Ye5UFfisgPtCjPb/RkBxyK+UsSiEcr2PVlM=
|
||||||
|
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
|
||||||
|
github.com/status-im/status-go/protocol v0.5.2 h1:L8c5o71pnPRZQwBlAMpQafS5e+cH766HT0bw52/nw2U=
|
||||||
|
github.com/status-im/status-go/protocol v0.5.2/go.mod h1:nH5Gx4YEw3kovKsiXczsXsRMJYeeQJUWCJOCwldUtEM=
|
||||||
|
github.com/status-im/status-go/protocol v0.36.0 h1:UF71TD8AVYeVeGe8GobJriBSq2JHTC20oPakRalu9ls=
|
||||||
|
github.com/status-im/status-go/protocol v0.36.0/go.mod h1:w1YlbooEzi/RTVvpV8xy2L2AFuU7a7XM0KB5lMw8IEA=
|
||||||
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501/go.mod h1:RYo/itke1oU5k/6sj9DNM3QAwtE5rZSgg5JnkOv83hk=
|
||||||
github.com/status-im/whisper v1.5.2 h1:26NgiKusmPic38eQdtXnaY+iaQ/LuQ3Dh0kCGYT/Uxs=
|
|
||||||
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
github.com/status-im/whisper v1.5.2/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
||||||
github.com/status-im/whisper v1.6.1 h1:C/T1HQHZfUI2jbccf3yIe8yfkl435I3BILIKeNASJDc=
|
github.com/status-im/whisper v1.6.1 h1:C/T1HQHZfUI2jbccf3yIe8yfkl435I3BILIKeNASJDc=
|
||||||
github.com/status-im/whisper v1.6.1/go.mod h1:lygchT4p9Y1/hR451OhNNqfinvy9EYEDxtXU2T/U30Q=
|
github.com/status-im/whisper v1.6.1/go.mod h1:lygchT4p9Y1/hR451OhNNqfinvy9EYEDxtXU2T/U30Q=
|
||||||
@ -634,8 +641,9 @@ github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZl
|
|||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
github.com/vacp2p/mvds v0.0.23 h1:BKdn7tyGvl/J/Pwv6FlcW6Xbzm+17jv141GB1mFXyOU=
|
github.com/vacp2p/mvds v0.0.23 h1:BKdn7tyGvl/J/Pwv6FlcW6Xbzm+17jv141GB1mFXyOU=
|
||||||
github.com/vacp2p/mvds v0.0.23/go.mod h1:uUmtiahU7efOVl/5w5yk9jOze5xYpDZDrSrT8TvHXjQ=
|
github.com/vacp2p/mvds v0.0.23/go.mod h1:uUmtiahU7efOVl/5w5yk9jOze5xYpDZDrSrT8TvHXjQ=
|
||||||
github.com/wealdtech/go-ens/v3 v3.0.7 h1:0iZ7yfuN5MSshCTDZB2i2vLyARs6+ybiiNz1Z8QKiGU=
|
|
||||||
github.com/wealdtech/go-ens/v3 v3.0.7/go.mod h1:P2OEBvgkhXLrPzPN+eR5z2/wFIGwHyijTDvpuC1xLlo=
|
github.com/wealdtech/go-ens/v3 v3.0.7/go.mod h1:P2OEBvgkhXLrPzPN+eR5z2/wFIGwHyijTDvpuC1xLlo=
|
||||||
|
github.com/wealdtech/go-ens/v3 v3.0.9 h1:gXMBNXikJ/XV9k6ybPOZMXIMPjBGSCC9N10dxe8Y2Xk=
|
||||||
|
github.com/wealdtech/go-ens/v3 v3.0.9/go.mod h1:P2OEBvgkhXLrPzPN+eR5z2/wFIGwHyijTDvpuC1xLlo=
|
||||||
github.com/wealdtech/go-multicodec v1.2.0 h1:9AHSxcSE9F9r6ZvQLAO0EXCdM08QfYohaXmW3k6sSh4=
|
github.com/wealdtech/go-multicodec v1.2.0 h1:9AHSxcSE9F9r6ZvQLAO0EXCdM08QfYohaXmW3k6sSh4=
|
||||||
github.com/wealdtech/go-multicodec v1.2.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4=
|
github.com/wealdtech/go-multicodec v1.2.0/go.mod h1:aedGMaTeYkIqi/KCPre1ho5rTb3hGpu/snBOS3GQLw4=
|
||||||
github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOFspt82UJs=
|
github.com/wealdtech/go-string2eth v1.0.0 h1:jY6b1MVqU6k2Uw/kvcU1Y9/3dDyXfPzZrOFspt82UJs=
|
||||||
@ -664,12 +672,17 @@ go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
|||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=
|
go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=
|
||||||
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
||||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
|
||||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
|
||||||
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
|
||||||
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||||
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
|
go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
|
||||||
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
||||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
@ -680,19 +693,23 @@ golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnf
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=
|
|
||||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
||||||
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||||
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@ -717,7 +734,6 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG
|
|||||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
@ -733,7 +749,6 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190102155601-82a175fd1598/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190214214411-e77772198cdc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -745,11 +760,9 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190927073244-c990c680b611/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
|
|
||||||
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056 h1:dHtDnRWQtSx0Hjq9kvKFpBh9uPPKfQN70NZZmvssGwk=
|
||||||
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.0.0-20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
@ -757,7 +770,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20170215214335-be0fcc31ae23/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@ -770,6 +782,10 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
|
|||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190425222832-ad9eeb80039a/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=
|
||||||
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||||
@ -796,6 +812,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
|||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||||
@ -826,3 +843,5 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||||
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
15
input.go
15
input.go
@ -5,11 +5,10 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
|
|
||||||
"github.com/jroimartin/gocui"
|
"github.com/jroimartin/gocui"
|
||||||
status "github.com/status-im/status-protocol-go"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DefaultMultiplexerPrefix = "default"
|
const DefaultMultiplexerPrefix = "default"
|
||||||
@ -65,12 +64,12 @@ func bytesToArgs(b []byte) []string {
|
|||||||
return argsStr
|
return argsStr
|
||||||
}
|
}
|
||||||
|
|
||||||
func chatAddCmdHandler(args []string) (chat status.Chat, err error) {
|
func chatAddCmdHandler(args []string) (chat protocol.Chat, err error) {
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
name := args[0]
|
name := args[0]
|
||||||
chat = status.CreatePublicChat(name)
|
chat = protocol.CreatePublicChat(name)
|
||||||
} else if len(args) == 2 {
|
} else if len(args) == 2 {
|
||||||
publicKeyBytes, err := statusproto.DecodeHex(args[0])
|
publicKeyBytes, err := types.DecodeHex(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return chat, err
|
return chat, err
|
||||||
}
|
}
|
||||||
@ -78,7 +77,7 @@ func chatAddCmdHandler(args []string) (chat status.Chat, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return chat, err
|
return chat, err
|
||||||
}
|
}
|
||||||
chat = status.CreateOneToOneChat(args[1], publicKey)
|
chat = protocol.CreateOneToOneChat(args[1], publicKey)
|
||||||
} else {
|
} else {
|
||||||
err = errors.New("/chat: incorrect arguments to add subcommand")
|
err = errors.New("/chat: incorrect arguments to add subcommand")
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
status "github.com/status-im/status-protocol-go"
|
"github.com/status-im/status-go/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -20,12 +20,12 @@ var (
|
|||||||
// MessagesParams is an object with JSON-serializable parameters
|
// MessagesParams is an object with JSON-serializable parameters
|
||||||
// for Messages method.
|
// for Messages method.
|
||||||
type MessagesParams struct {
|
type MessagesParams struct {
|
||||||
status.Chat
|
protocol.Chat
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendParams is an object with JSON-serializable parameters for Send method.
|
// SendParams is an object with JSON-serializable parameters for Send method.
|
||||||
type SendParams struct {
|
type SendParams struct {
|
||||||
status.Chat
|
protocol.Chat
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicAPI provides an JSON-RPC API to interact with
|
// PublicAPI provides an JSON-RPC API to interact with
|
||||||
@ -43,7 +43,7 @@ func NewPublicAPI(s *Service) *PublicAPI {
|
|||||||
// Send sends payload to specified chat.
|
// Send sends payload to specified chat.
|
||||||
// Chat should be added before sending message,
|
// Chat should be added before sending message,
|
||||||
// otherwise error will be received.
|
// otherwise error will be received.
|
||||||
func (api *PublicAPI) Send(ctx context.Context, chatID string, payload string) ([]hexutil.Bytes, error) {
|
func (api *PublicAPI) Send(ctx context.Context, chatID string, payload string) ([]types.HexBytes, error) {
|
||||||
if api.service.messenger == nil {
|
if api.service.messenger == nil {
|
||||||
return nil, ErrMessengerNotSet
|
return nil, ErrMessengerNotSet
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ func (api *PublicAPI) Send(ctx context.Context, chatID string, payload string) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := make([]hexutil.Bytes, len(ids))
|
result := make([]types.HexBytes, len(ids))
|
||||||
for idx, id := range ids {
|
for idx, id := range ids {
|
||||||
result[idx] = id
|
result[idx] = id
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p"
|
"github.com/ethereum/go-ethereum/p2p"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
|
||||||
status "github.com/status-im/status-protocol-go"
|
"github.com/status-im/status-go/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -32,7 +32,7 @@ type KeysGetter interface {
|
|||||||
type Service struct {
|
type Service struct {
|
||||||
node *node.StatusNode
|
node *node.StatusNode
|
||||||
keys KeysGetter
|
keys KeysGetter
|
||||||
messenger *status.Messenger
|
messenger *protocol.Messenger
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Service.
|
// New creates a new Service.
|
||||||
@ -44,7 +44,7 @@ func New(node *node.StatusNode, keys KeysGetter) *Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetMessenger sets a Messenger.
|
// SetMessenger sets a Messenger.
|
||||||
func (s *Service) SetMessenger(m *status.Messenger) {
|
func (s *Service) SetMessenger(m *protocol.Messenger) {
|
||||||
s.messenger = m
|
s.messenger = m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
79
main.go
79
main.go
@ -15,17 +15,17 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/jroimartin/gocui"
|
"github.com/jroimartin/gocui"
|
||||||
"github.com/peterbourgon/ff"
|
"github.com/peterbourgon/ff"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/logutils"
|
"github.com/status-im/status-go/logutils"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
|
"github.com/status-im/status-go/protocol"
|
||||||
|
"github.com/status-im/status-go/protocol/zaputil"
|
||||||
"github.com/status-im/status-go/signal"
|
"github.com/status-im/status-go/signal"
|
||||||
status "github.com/status-im/status-protocol-go"
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
|
||||||
"github.com/status-im/status-protocol-go/zaputil"
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"go.uber.org/zap/zapcore"
|
"go.uber.org/zap/zapcore"
|
||||||
)
|
)
|
||||||
@ -148,7 +148,7 @@ func main() {
|
|||||||
|
|
||||||
// initialize protocol
|
// initialize protocol
|
||||||
var (
|
var (
|
||||||
messenger *status.Messenger
|
messenger *protocol.Messenger
|
||||||
pollFunc func()
|
pollFunc func()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ func (k keysGetter) PrivateKey() (*ecdsa.PrivateKey, error) {
|
|||||||
return k.privateKey, nil
|
return k.privateKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMessengerInProc(pk *ecdsa.PrivateKey, dbPath string, logger *zap.Logger) (*status.Messenger, func(), error) {
|
func createMessengerInProc(pk *ecdsa.PrivateKey, dbPath string, logger *zap.Logger) (*protocol.Messenger, func(), error) {
|
||||||
// collect mail server request signals
|
// collect mail server request signals
|
||||||
signalsForwarder := newSignalForwarder()
|
signalsForwarder := newSignalForwarder()
|
||||||
go signalsForwarder.Start()
|
go signalsForwarder.Start()
|
||||||
@ -232,37 +232,39 @@ func createMessengerInProc(pk *ecdsa.PrivateKey, dbPath string, logger *zap.Logg
|
|||||||
filterMailTypesHandler(signalsForwarder.in),
|
filterMailTypesHandler(signalsForwarder.in),
|
||||||
)
|
)
|
||||||
|
|
||||||
var whisper whispertypes.Whisper
|
var (
|
||||||
|
node types.Node
|
||||||
|
err error
|
||||||
|
)
|
||||||
if *useNimbus {
|
if *useNimbus {
|
||||||
whisper = newNimbusWhisperWrapper()
|
node = newNimbusNodeWrapper()
|
||||||
} else {
|
} else {
|
||||||
var err error
|
if node, err = newGethNodeWrapper(pk); err != nil {
|
||||||
if whisper, err = newGethWhisperWrapper(pk); err != nil {
|
|
||||||
exitErr(err)
|
exitErr(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
options := []status.Option{
|
options := []protocol.Option{
|
||||||
status.WithCustomLogger(logger),
|
protocol.WithCustomLogger(logger),
|
||||||
status.WithDatabaseConfig(dbPath, ""),
|
protocol.WithDatabaseConfig(dbPath, ""),
|
||||||
status.WithMessagesPersistenceEnabled(),
|
protocol.WithMessagesPersistenceEnabled(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if *genericDiscoveryTopic {
|
if *genericDiscoveryTopic {
|
||||||
options = append(options, status.WithGenericDiscoveryTopicSupport())
|
options = append(options, protocol.WithGenericDiscoveryTopicSupport())
|
||||||
}
|
}
|
||||||
|
|
||||||
if *datasync {
|
if *datasync {
|
||||||
options = append(options, status.WithDatasync())
|
options = append(options, protocol.WithDatasync())
|
||||||
}
|
}
|
||||||
|
|
||||||
if *sendV1Messages {
|
if *sendV1Messages {
|
||||||
options = append(options, status.WithSendV1Messages())
|
options = append(options, protocol.WithSendV1Messages())
|
||||||
}
|
}
|
||||||
|
|
||||||
messenger, err := status.NewMessenger(
|
messenger, err := protocol.NewMessenger(
|
||||||
pk,
|
pk,
|
||||||
whisper,
|
node,
|
||||||
*installationID,
|
*installationID,
|
||||||
options...,
|
options...,
|
||||||
)
|
)
|
||||||
@ -276,10 +278,15 @@ func createMessengerInProc(pk *ecdsa.PrivateKey, dbPath string, logger *zap.Logg
|
|||||||
|
|
||||||
// protocolGethService.SetMessenger(messenger)
|
// protocolGethService.SetMessenger(messenger)
|
||||||
|
|
||||||
|
var whisper types.Whisper
|
||||||
|
if whisper, err = node.GetWhisper(nil); err != nil {
|
||||||
|
exitErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
return messenger, whisper.Poll, nil
|
return messenger, whisper.Poll, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger *zap.Logger) error {
|
func setupGUI(privateKey *ecdsa.PrivateKey, messenger *protocol.Messenger, logger *zap.Logger) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
// global
|
// global
|
||||||
@ -326,7 +333,7 @@ func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger
|
|||||||
// inputMultiplexer.AddHandler("/request", RequestCmdFactory(chatVC))
|
// inputMultiplexer.AddHandler("/request", RequestCmdFactory(chatVC))
|
||||||
|
|
||||||
views := []*View{
|
views := []*View{
|
||||||
&View{
|
{
|
||||||
Name: ViewChats,
|
Name: ViewChats,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Cursor: true,
|
Cursor: true,
|
||||||
@ -338,17 +345,17 @@ func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger
|
|||||||
return int(math.Floor(float64(maxX) * 0.2)), maxY - 4
|
return int(math.Floor(float64(maxX) * 0.2)), maxY - 4
|
||||||
},
|
},
|
||||||
Keybindings: []Binding{
|
Keybindings: []Binding{
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyArrowDown,
|
Key: gocui.KeyArrowDown,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: CursorDownHandler,
|
Handler: CursorDownHandler,
|
||||||
},
|
},
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyArrowUp,
|
Key: gocui.KeyArrowUp,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: CursorUpHandler,
|
Handler: CursorUpHandler,
|
||||||
},
|
},
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyEnter,
|
Key: gocui.KeyEnter,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: GetLineHandler(func(idx int, _ string) error {
|
Handler: GetLineHandler(func(idx int, _ string) error {
|
||||||
@ -369,7 +376,7 @@ func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&View{
|
{
|
||||||
Name: ViewChat,
|
Name: ViewChat,
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Cursor: true,
|
Cursor: true,
|
||||||
@ -385,31 +392,31 @@ func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger
|
|||||||
return maxX - 1, maxY - 4
|
return maxX - 1, maxY - 4
|
||||||
},
|
},
|
||||||
Keybindings: []Binding{
|
Keybindings: []Binding{
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyArrowDown,
|
Key: gocui.KeyArrowDown,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: CursorDownHandler,
|
Handler: CursorDownHandler,
|
||||||
},
|
},
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyArrowUp,
|
Key: gocui.KeyArrowUp,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: CursorUpHandler,
|
Handler: CursorUpHandler,
|
||||||
},
|
},
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyHome,
|
Key: gocui.KeyHome,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: func(g *gocui.Gui, v *gocui.View) error {
|
Handler: func(g *gocui.Gui, v *gocui.View) error {
|
||||||
return HomeHandler(g, v)
|
return HomeHandler(g, v)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyEnd,
|
Key: gocui.KeyEnd,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: EndHandler,
|
Handler: EndHandler,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&View{
|
{
|
||||||
Name: ViewInput,
|
Name: ViewInput,
|
||||||
Title: fmt.Sprintf(
|
Title: fmt.Sprintf(
|
||||||
"%s (as %#x)",
|
"%s (as %#x)",
|
||||||
@ -427,19 +434,19 @@ func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger
|
|||||||
return maxX - 1, maxY - 1
|
return maxX - 1, maxY - 1
|
||||||
},
|
},
|
||||||
Keybindings: []Binding{
|
Keybindings: []Binding{
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyEnter,
|
Key: gocui.KeyEnter,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: inputMultiplexer.BindingHandler,
|
Handler: inputMultiplexer.BindingHandler,
|
||||||
},
|
},
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyEnter,
|
Key: gocui.KeyEnter,
|
||||||
Mod: gocui.ModAlt,
|
Mod: gocui.ModAlt,
|
||||||
Handler: MoveToNewLineHandler,
|
Handler: MoveToNewLineHandler,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&View{
|
{
|
||||||
Name: ViewNotification,
|
Name: ViewNotification,
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
Editable: false,
|
Editable: false,
|
||||||
@ -452,7 +459,7 @@ func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger
|
|||||||
return maxX/2 + 50, maxY/2 + 2
|
return maxX/2 + 50, maxY/2 + 2
|
||||||
},
|
},
|
||||||
Keybindings: []Binding{
|
Keybindings: []Binding{
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyEnter,
|
Key: gocui.KeyEnter,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: func(g *gocui.Gui, v *gocui.View) error {
|
Handler: func(g *gocui.Gui, v *gocui.View) error {
|
||||||
@ -474,12 +481,12 @@ func setupGUI(privateKey *ecdsa.PrivateKey, messenger *status.Messenger, logger
|
|||||||
}
|
}
|
||||||
|
|
||||||
bindings := []Binding{
|
bindings := []Binding{
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyCtrlC,
|
Key: gocui.KeyCtrlC,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: QuitHandler,
|
Handler: QuitHandler,
|
||||||
},
|
},
|
||||||
Binding{
|
{
|
||||||
Key: gocui.KeyTab,
|
Key: gocui.KeyTab,
|
||||||
Mod: gocui.ModNone,
|
Mod: gocui.ModNone,
|
||||||
Handler: NextViewHandler(vm),
|
Handler: NextViewHandler(vm),
|
||||||
|
@ -12,12 +12,12 @@ import (
|
|||||||
|
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/jroimartin/gocui"
|
"github.com/jroimartin/gocui"
|
||||||
|
|
||||||
status "github.com/status-im/status-protocol-go"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
protocol "github.com/status-im/status-protocol-go/v1"
|
"github.com/status-im/status-go/protocol"
|
||||||
|
v1protocol "github.com/status-im/status-go/protocol/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MessagesViewController manages chat view.
|
// MessagesViewController manages chat view.
|
||||||
@ -25,13 +25,13 @@ type MessagesViewController struct {
|
|||||||
*ViewController
|
*ViewController
|
||||||
|
|
||||||
identity *ecdsa.PrivateKey
|
identity *ecdsa.PrivateKey
|
||||||
messenger *status.Messenger
|
messenger *protocol.Messenger
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
|
|
||||||
activeChat *status.Chat
|
activeChat *protocol.Chat
|
||||||
onError func(error)
|
onError func(error)
|
||||||
onMessages func()
|
onMessages func()
|
||||||
changeChat chan *status.Chat
|
changeChat chan *protocol.Chat
|
||||||
|
|
||||||
cancel chan struct{} // cancel the current chat loop
|
cancel chan struct{} // cancel the current chat loop
|
||||||
done chan struct{} // wait for the current chat loop to finish
|
done chan struct{} // wait for the current chat loop to finish
|
||||||
@ -41,7 +41,7 @@ type MessagesViewController struct {
|
|||||||
func NewMessagesViewController(
|
func NewMessagesViewController(
|
||||||
vc *ViewController,
|
vc *ViewController,
|
||||||
id Identity,
|
id Identity,
|
||||||
m *status.Messenger,
|
m *protocol.Messenger,
|
||||||
logger *zap.Logger,
|
logger *zap.Logger,
|
||||||
onMessages func(),
|
onMessages func(),
|
||||||
onError func(error),
|
onError func(error),
|
||||||
@ -60,7 +60,7 @@ func NewMessagesViewController(
|
|||||||
logger: logger.With(zap.Namespace("MessagesViewController")),
|
logger: logger.With(zap.Namespace("MessagesViewController")),
|
||||||
onMessages: onMessages,
|
onMessages: onMessages,
|
||||||
onError: onError,
|
onError: onError,
|
||||||
changeChat: make(chan *status.Chat, 1),
|
changeChat: make(chan *protocol.Chat, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ func (c *MessagesViewController) readMessagesLoop() {
|
|||||||
|
|
||||||
// TODO: It should be a round buffer instead.
|
// TODO: It should be a round buffer instead.
|
||||||
// It is a map with chatID as a key and a list of messages.
|
// It is a map with chatID as a key and a list of messages.
|
||||||
store := make(map[string][]*protocol.Message)
|
store := make(map[string][]*v1protocol.Message)
|
||||||
|
|
||||||
t := time.NewTicker(time.Second)
|
t := time.NewTicker(time.Second)
|
||||||
defer t.Stop()
|
defer t.Stop()
|
||||||
@ -86,7 +86,7 @@ func (c *MessagesViewController) readMessagesLoop() {
|
|||||||
select {
|
select {
|
||||||
case <-t.C:
|
case <-t.C:
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
|
||||||
allLatest, err := c.messenger.RetrieveAll(ctx, status.RetrieveLatest)
|
allLatest, err := c.messenger.RetrieveAll(ctx, protocol.RetrieveLatest)
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Error("failed to retrieve messages", zap.Error(err))
|
c.logger.Error("failed to retrieve messages", zap.Error(err))
|
||||||
@ -105,7 +105,7 @@ func (c *MessagesViewController) readMessagesLoop() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
var latestForActive []*protocol.Message
|
var latestForActive []*v1protocol.Message
|
||||||
for _, m := range allLatest {
|
for _, m := range allLatest {
|
||||||
if m.ChatID == c.activeChat.ID {
|
if m.ChatID == c.activeChat.ID {
|
||||||
latestForActive = append(latestForActive, m)
|
latestForActive = append(latestForActive, m)
|
||||||
@ -116,7 +116,7 @@ func (c *MessagesViewController) readMessagesLoop() {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
var messagesToDraw []*protocol.Message
|
var messagesToDraw []*v1protocol.Message
|
||||||
|
|
||||||
repaint := isRepaintNeeded(latestForActive, store[c.activeChat.ID])
|
repaint := isRepaintNeeded(latestForActive, store[c.activeChat.ID])
|
||||||
if repaint {
|
if repaint {
|
||||||
@ -137,13 +137,13 @@ func (c *MessagesViewController) readMessagesLoop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sortMessages(messages []*protocol.Message) {
|
func sortMessages(messages []*v1protocol.Message) {
|
||||||
sort.SliceStable(messages, func(i, j int) bool {
|
sort.SliceStable(messages, func(i, j int) bool {
|
||||||
return messages[i].Clock < messages[j].Clock
|
return messages[i].Clock < messages[j].Clock
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func isRepaintNeeded(latest, messages []*protocol.Message) bool {
|
func isRepaintNeeded(latest, messages []*v1protocol.Message) bool {
|
||||||
lastClock := int64(0)
|
lastClock := int64(0)
|
||||||
if len(messages) > 0 {
|
if len(messages) > 0 {
|
||||||
lastClock = messages[len(messages)-1].Clock
|
lastClock = messages[len(messages)-1].Clock
|
||||||
@ -157,13 +157,13 @@ func isRepaintNeeded(latest, messages []*protocol.Message) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ActiveChat returns the active chat, if any
|
// ActiveChat returns the active chat, if any
|
||||||
func (c *MessagesViewController) ActiveChat() *status.Chat {
|
func (c *MessagesViewController) ActiveChat() *protocol.Chat {
|
||||||
return c.activeChat
|
return c.activeChat
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select informs the chat view controller about a selected contact.
|
// Select informs the chat view controller about a selected contact.
|
||||||
// The chat view controller setup subscribers and request recent messages.
|
// The chat view controller setup subscribers and request recent messages.
|
||||||
func (c *MessagesViewController) Select(chat *status.Chat) {
|
func (c *MessagesViewController) Select(chat *protocol.Chat) {
|
||||||
c.logger.Info("selected chat", zap.String("chatID", chat.ID))
|
c.logger.Info("selected chat", zap.String("chatID", chat.ID))
|
||||||
c.changeChat <- chat
|
c.changeChat <- chat
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ func (c *MessagesViewController) Send(ctx context.Context, data []byte) ([][]byt
|
|||||||
return c.messenger.Send(ctx, c.activeChat.ID, data)
|
return c.messenger.Send(ctx, c.activeChat.ID, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MessagesViewController) printMessages(clear bool, messages ...*protocol.Message) {
|
func (c *MessagesViewController) printMessages(clear bool, messages ...*v1protocol.Message) {
|
||||||
c.logger.Debug("printing messages", zap.Int("count", len(messages)))
|
c.logger.Debug("printing messages", zap.Int("count", len(messages)))
|
||||||
c.g.Update(func(*gocui.Gui) error {
|
c.g.Update(func(*gocui.Gui) error {
|
||||||
if clear {
|
if clear {
|
||||||
@ -195,7 +195,7 @@ func (c *MessagesViewController) printMessages(clear bool, messages ...*protocol
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *MessagesViewController) writeMessage(message *protocol.Message) error {
|
func (c *MessagesViewController) writeMessage(message *v1protocol.Message) error {
|
||||||
myPubKey := c.identity.PublicKey
|
myPubKey := c.identity.PublicKey
|
||||||
pubKey := message.SigPubKey
|
pubKey := message.SigPubKey
|
||||||
|
|
||||||
|
@ -8,8 +8,8 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
|
||||||
"github.com/jroimartin/gocui"
|
"github.com/jroimartin/gocui"
|
||||||
nimbusbridge "github.com/status-im/status-protocol-go/bridge/nimbus"
|
nimbusbridge "github.com/status-im/status-go/eth-node/bridge/nimbus"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -47,6 +47,6 @@ func schedulePoll(g *gocui.Gui, pollFunc func()) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNimbusWhisperWrapper() whispertypes.Whisper {
|
func newNimbusNodeWrapper() types.Node {
|
||||||
return nimbusbridge.NewNimbusWhisperWrapper()
|
return nimbusbridge.NewNodeBridge()
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jroimartin/gocui"
|
"github.com/jroimartin/gocui"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const noNimbusError = "executable needs to be built with -tags nimbus"
|
const noNimbusError = "executable needs to be built with -tags nimbus"
|
||||||
@ -18,6 +18,6 @@ func startNimbus(privateKey *ecdsa.PrivateKey, listenAddr string, staging bool)
|
|||||||
|
|
||||||
func startPolling(g *gocui.Gui, pollFunc func(), delay time.Duration, cancel <-chan struct{}) {}
|
func startPolling(g *gocui.Gui, pollFunc func(), delay time.Duration, cancel <-chan struct{}) {}
|
||||||
|
|
||||||
func newNimbusWhisperWrapper() whispertypes.Whisper {
|
func newNimbusNodeWrapper() types.Node {
|
||||||
panic(noNimbusError)
|
panic(noNimbusError)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/signal"
|
"github.com/status-im/status-go/signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,9 +16,9 @@ type signalEnvelope struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type mailTypeEvent struct {
|
type mailTypeEvent struct {
|
||||||
RequestID common.Hash `json:"requestID"`
|
RequestID types.Hash `json:"requestID"`
|
||||||
Hash common.Hash `json:"hash"`
|
Hash types.Hash `json:"hash"`
|
||||||
LastEnvelopeHash common.Hash `json:"lastEnvelopeHash"`
|
LastEnvelopeHash types.Hash `json:"lastEnvelopeHash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type mailTypeSignal struct {
|
type mailTypeSignal struct {
|
||||||
@ -75,14 +75,14 @@ func filterMailTypesHandler(in chan<- mailTypeSignal) func(string) {
|
|||||||
return func(event string) {
|
return func(event string) {
|
||||||
var envelope signalEnvelope
|
var envelope signalEnvelope
|
||||||
if err := json.Unmarshal([]byte(event), &envelope); err != nil {
|
if err := json.Unmarshal([]byte(event), &envelope); err != nil {
|
||||||
log.Printf("faild to unmarshal signal Envelope: %v", err)
|
log.Printf("failed to unmarshal signal Envelope: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch envelope.Type {
|
switch envelope.Type {
|
||||||
case signal.EventMailServerRequestCompleted:
|
case signal.EventMailServerRequestCompleted:
|
||||||
var event mailTypeEvent
|
var event mailTypeEvent
|
||||||
if err := json.Unmarshal(envelope.Event, &event); err != nil {
|
if err := json.Unmarshal(envelope.Event, &event); err != nil {
|
||||||
log.Printf("faild to unmarshal signal event: %v", err)
|
log.Printf("failed to unmarshal signal event: %v", err)
|
||||||
}
|
}
|
||||||
in <- mailTypeSignal{
|
in <- mailTypeSignal{
|
||||||
envelope.Type,
|
envelope.Type,
|
||||||
@ -92,7 +92,7 @@ func filterMailTypesHandler(in chan<- mailTypeSignal) func(string) {
|
|||||||
case signal.EventMailServerRequestExpired:
|
case signal.EventMailServerRequestExpired:
|
||||||
var event mailTypeEvent
|
var event mailTypeEvent
|
||||||
if err := json.Unmarshal(envelope.Event, &event); err != nil {
|
if err := json.Unmarshal(envelope.Event, &event); err != nil {
|
||||||
log.Printf("faild to unmarshal signal event: %v", err)
|
log.Printf("failed to unmarshal signal event: %v", err)
|
||||||
}
|
}
|
||||||
in <- mailTypeSignal{
|
in <- mailTypeSignal{
|
||||||
envelope.Type,
|
envelope.Type,
|
||||||
|
5
vendor/github.com/BurntSushi/toml/.gitignore
generated
vendored
Normal file
5
vendor/github.com/BurntSushi/toml/.gitignore
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
TAGS
|
||||||
|
tags
|
||||||
|
.*.swp
|
||||||
|
tomlcheck/tomlcheck
|
||||||
|
toml.test
|
15
vendor/github.com/BurntSushi/toml/.travis.yml
generated
vendored
Normal file
15
vendor/github.com/BurntSushi/toml/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
language: go
|
||||||
|
go:
|
||||||
|
- 1.1
|
||||||
|
- 1.2
|
||||||
|
- 1.3
|
||||||
|
- 1.4
|
||||||
|
- 1.5
|
||||||
|
- 1.6
|
||||||
|
- tip
|
||||||
|
install:
|
||||||
|
- go install ./...
|
||||||
|
- go get github.com/BurntSushi/toml-test
|
||||||
|
script:
|
||||||
|
- export PATH="$PATH:$HOME/gopath/bin"
|
||||||
|
- make test
|
3
vendor/github.com/BurntSushi/toml/COMPATIBLE
generated
vendored
Normal file
3
vendor/github.com/BurntSushi/toml/COMPATIBLE
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Compatible with TOML version
|
||||||
|
[v0.4.0](https://github.com/toml-lang/toml/blob/v0.4.0/versions/en/toml-v0.4.0.md)
|
||||||
|
|
21
vendor/github.com/BurntSushi/toml/COPYING
generated
vendored
Normal file
21
vendor/github.com/BurntSushi/toml/COPYING
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 TOML authors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
19
vendor/github.com/BurntSushi/toml/Makefile
generated
vendored
Normal file
19
vendor/github.com/BurntSushi/toml/Makefile
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
install:
|
||||||
|
go install ./...
|
||||||
|
|
||||||
|
test: install
|
||||||
|
go test -v
|
||||||
|
toml-test toml-test-decoder
|
||||||
|
toml-test -encoder toml-test-encoder
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
gofmt -w *.go */*.go
|
||||||
|
colcheck *.go */*.go
|
||||||
|
|
||||||
|
tags:
|
||||||
|
find ./ -name '*.go' -print0 | xargs -0 gotags > TAGS
|
||||||
|
|
||||||
|
push:
|
||||||
|
git push origin master
|
||||||
|
git push github master
|
||||||
|
|
218
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
Normal file
218
vendor/github.com/BurntSushi/toml/README.md
generated
vendored
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
## TOML parser and encoder for Go with reflection
|
||||||
|
|
||||||
|
TOML stands for Tom's Obvious, Minimal Language. This Go package provides a
|
||||||
|
reflection interface similar to Go's standard library `json` and `xml`
|
||||||
|
packages. This package also supports the `encoding.TextUnmarshaler` and
|
||||||
|
`encoding.TextMarshaler` interfaces so that you can define custom data
|
||||||
|
representations. (There is an example of this below.)
|
||||||
|
|
||||||
|
Spec: https://github.com/toml-lang/toml
|
||||||
|
|
||||||
|
Compatible with TOML version
|
||||||
|
[v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md)
|
||||||
|
|
||||||
|
Documentation: https://godoc.org/github.com/BurntSushi/toml
|
||||||
|
|
||||||
|
Installation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/BurntSushi/toml
|
||||||
|
```
|
||||||
|
|
||||||
|
Try the toml validator:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/BurntSushi/toml/cmd/tomlv
|
||||||
|
tomlv some-toml-file.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
[](https://travis-ci.org/BurntSushi/toml) [](https://godoc.org/github.com/BurntSushi/toml)
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
This package passes all tests in
|
||||||
|
[toml-test](https://github.com/BurntSushi/toml-test) for both the decoder
|
||||||
|
and the encoder.
|
||||||
|
|
||||||
|
### Examples
|
||||||
|
|
||||||
|
This package works similarly to how the Go standard library handles `XML`
|
||||||
|
and `JSON`. Namely, data is loaded into Go values via reflection.
|
||||||
|
|
||||||
|
For the simplest example, consider some TOML file as just a list of keys
|
||||||
|
and values:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
Age = 25
|
||||||
|
Cats = [ "Cauchy", "Plato" ]
|
||||||
|
Pi = 3.14
|
||||||
|
Perfection = [ 6, 28, 496, 8128 ]
|
||||||
|
DOB = 1987-07-05T05:45:00Z
|
||||||
|
```
|
||||||
|
|
||||||
|
Which could be defined in Go as:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Config struct {
|
||||||
|
Age int
|
||||||
|
Cats []string
|
||||||
|
Pi float64
|
||||||
|
Perfection []int
|
||||||
|
DOB time.Time // requires `import time`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And then decoded with:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var conf Config
|
||||||
|
if _, err := toml.Decode(tomlData, &conf); err != nil {
|
||||||
|
// handle error
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use struct tags if your struct field name doesn't map to a TOML
|
||||||
|
key value directly:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
some_key_NAME = "wat"
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
type TOML struct {
|
||||||
|
ObscureKey string `toml:"some_key_NAME"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the `encoding.TextUnmarshaler` interface
|
||||||
|
|
||||||
|
Here's an example that automatically parses duration strings into
|
||||||
|
`time.Duration` values:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[[song]]
|
||||||
|
name = "Thunder Road"
|
||||||
|
duration = "4m49s"
|
||||||
|
|
||||||
|
[[song]]
|
||||||
|
name = "Stairway to Heaven"
|
||||||
|
duration = "8m03s"
|
||||||
|
```
|
||||||
|
|
||||||
|
Which can be decoded with:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type song struct {
|
||||||
|
Name string
|
||||||
|
Duration duration
|
||||||
|
}
|
||||||
|
type songs struct {
|
||||||
|
Song []song
|
||||||
|
}
|
||||||
|
var favorites songs
|
||||||
|
if _, err := toml.Decode(blob, &favorites); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range favorites.Song {
|
||||||
|
fmt.Printf("%s (%s)\n", s.Name, s.Duration)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And you'll also need a `duration` type that satisfies the
|
||||||
|
`encoding.TextUnmarshaler` interface:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type duration struct {
|
||||||
|
time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *duration) UnmarshalText(text []byte) error {
|
||||||
|
var err error
|
||||||
|
d.Duration, err = time.ParseDuration(string(text))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### More complex usage
|
||||||
|
|
||||||
|
Here's an example of how to load the example from the official spec page:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# This is a TOML document. Boom.
|
||||||
|
|
||||||
|
title = "TOML Example"
|
||||||
|
|
||||||
|
[owner]
|
||||||
|
name = "Tom Preston-Werner"
|
||||||
|
organization = "GitHub"
|
||||||
|
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
||||||
|
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
||||||
|
|
||||||
|
[database]
|
||||||
|
server = "192.168.1.1"
|
||||||
|
ports = [ 8001, 8001, 8002 ]
|
||||||
|
connection_max = 5000
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[servers]
|
||||||
|
|
||||||
|
# You can indent as you please. Tabs or spaces. TOML don't care.
|
||||||
|
[servers.alpha]
|
||||||
|
ip = "10.0.0.1"
|
||||||
|
dc = "eqdc10"
|
||||||
|
|
||||||
|
[servers.beta]
|
||||||
|
ip = "10.0.0.2"
|
||||||
|
dc = "eqdc10"
|
||||||
|
|
||||||
|
[clients]
|
||||||
|
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
|
||||||
|
|
||||||
|
# Line breaks are OK when inside arrays
|
||||||
|
hosts = [
|
||||||
|
"alpha",
|
||||||
|
"omega"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
And the corresponding Go types are:
|
||||||
|
|
||||||
|
```go
|
||||||
|
type tomlConfig struct {
|
||||||
|
Title string
|
||||||
|
Owner ownerInfo
|
||||||
|
DB database `toml:"database"`
|
||||||
|
Servers map[string]server
|
||||||
|
Clients clients
|
||||||
|
}
|
||||||
|
|
||||||
|
type ownerInfo struct {
|
||||||
|
Name string
|
||||||
|
Org string `toml:"organization"`
|
||||||
|
Bio string
|
||||||
|
DOB time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type database struct {
|
||||||
|
Server string
|
||||||
|
Ports []int
|
||||||
|
ConnMax int `toml:"connection_max"`
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type server struct {
|
||||||
|
IP string
|
||||||
|
DC string
|
||||||
|
}
|
||||||
|
|
||||||
|
type clients struct {
|
||||||
|
Data [][]interface{}
|
||||||
|
Hosts []string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that a case insensitive match will be tried if an exact match can't be
|
||||||
|
found.
|
||||||
|
|
||||||
|
A working example of the above can be found in `_examples/example.{go,toml}`.
|
509
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
Normal file
509
vendor/github.com/BurntSushi/toml/decode.go
generated
vendored
Normal file
@ -0,0 +1,509 @@
|
|||||||
|
package toml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func e(format string, args ...interface{}) error {
|
||||||
|
return fmt.Errorf("toml: "+format, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshaler is the interface implemented by objects that can unmarshal a
|
||||||
|
// TOML description of themselves.
|
||||||
|
type Unmarshaler interface {
|
||||||
|
UnmarshalTOML(interface{}) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal decodes the contents of `p` in TOML format into a pointer `v`.
|
||||||
|
func Unmarshal(p []byte, v interface{}) error {
|
||||||
|
_, err := Decode(string(p), v)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primitive is a TOML value that hasn't been decoded into a Go value.
|
||||||
|
// When using the various `Decode*` functions, the type `Primitive` may
|
||||||
|
// be given to any value, and its decoding will be delayed.
|
||||||
|
//
|
||||||
|
// A `Primitive` value can be decoded using the `PrimitiveDecode` function.
|
||||||
|
//
|
||||||
|
// The underlying representation of a `Primitive` value is subject to change.
|
||||||
|
// Do not rely on it.
|
||||||
|
//
|
||||||
|
// N.B. Primitive values are still parsed, so using them will only avoid
|
||||||
|
// the overhead of reflection. They can be useful when you don't know the
|
||||||
|
// exact type of TOML data until run time.
|
||||||
|
type Primitive struct {
|
||||||
|
undecoded interface{}
|
||||||
|
context Key
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED!
|
||||||
|
//
|
||||||
|
// Use MetaData.PrimitiveDecode instead.
|
||||||
|
func PrimitiveDecode(primValue Primitive, v interface{}) error {
|
||||||
|
md := MetaData{decoded: make(map[string]bool)}
|
||||||
|
return md.unify(primValue.undecoded, rvalue(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrimitiveDecode is just like the other `Decode*` functions, except it
|
||||||
|
// decodes a TOML value that has already been parsed. Valid primitive values
|
||||||
|
// can *only* be obtained from values filled by the decoder functions,
|
||||||
|
// including this method. (i.e., `v` may contain more `Primitive`
|
||||||
|
// values.)
|
||||||
|
//
|
||||||
|
// Meta data for primitive values is included in the meta data returned by
|
||||||
|
// the `Decode*` functions with one exception: keys returned by the Undecoded
|
||||||
|
// method will only reflect keys that were decoded. Namely, any keys hidden
|
||||||
|
// behind a Primitive will be considered undecoded. Executing this method will
|
||||||
|
// update the undecoded keys in the meta data. (See the example.)
|
||||||
|
func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error {
|
||||||
|
md.context = primValue.context
|
||||||
|
defer func() { md.context = nil }()
|
||||||
|
return md.unify(primValue.undecoded, rvalue(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode will decode the contents of `data` in TOML format into a pointer
|
||||||
|
// `v`.
|
||||||
|
//
|
||||||
|
// TOML hashes correspond to Go structs or maps. (Dealer's choice. They can be
|
||||||
|
// used interchangeably.)
|
||||||
|
//
|
||||||
|
// TOML arrays of tables correspond to either a slice of structs or a slice
|
||||||
|
// of maps.
|
||||||
|
//
|
||||||
|
// TOML datetimes correspond to Go `time.Time` values.
|
||||||
|
//
|
||||||
|
// All other TOML types (float, string, int, bool and array) correspond
|
||||||
|
// to the obvious Go types.
|
||||||
|
//
|
||||||
|
// An exception to the above rules is if a type implements the
|
||||||
|
// encoding.TextUnmarshaler interface. In this case, any primitive TOML value
|
||||||
|
// (floats, strings, integers, booleans and datetimes) will be converted to
|
||||||
|
// a byte string and given to the value's UnmarshalText method. See the
|
||||||
|
// Unmarshaler example for a demonstration with time duration strings.
|
||||||
|
//
|
||||||
|
// Key mapping
|
||||||
|
//
|
||||||
|
// TOML keys can map to either keys in a Go map or field names in a Go
|
||||||
|
// struct. The special `toml` struct tag may be used to map TOML keys to
|
||||||
|
// struct fields that don't match the key name exactly. (See the example.)
|
||||||
|
// A case insensitive match to struct names will be tried if an exact match
|
||||||
|
// can't be found.
|
||||||
|
//
|
||||||
|
// The mapping between TOML values and Go values is loose. That is, there
|
||||||
|
// may exist TOML values that cannot be placed into your representation, and
|
||||||
|
// there may be parts of your representation that do not correspond to
|
||||||
|
// TOML values. This loose mapping can be made stricter by using the IsDefined
|
||||||
|
// and/or Undecoded methods on the MetaData returned.
|
||||||
|
//
|
||||||
|
// This decoder will not handle cyclic types. If a cyclic type is passed,
|
||||||
|
// `Decode` will not terminate.
|
||||||
|
func Decode(data string, v interface{}) (MetaData, error) {
|
||||||
|
rv := reflect.ValueOf(v)
|
||||||
|
if rv.Kind() != reflect.Ptr {
|
||||||
|
return MetaData{}, e("Decode of non-pointer %s", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
if rv.IsNil() {
|
||||||
|
return MetaData{}, e("Decode of nil %s", reflect.TypeOf(v))
|
||||||
|
}
|
||||||
|
p, err := parse(data)
|
||||||
|
if err != nil {
|
||||||
|
return MetaData{}, err
|
||||||
|
}
|
||||||
|
md := MetaData{
|
||||||
|
p.mapping, p.types, p.ordered,
|
||||||
|
make(map[string]bool, len(p.ordered)), nil,
|
||||||
|
}
|
||||||
|
return md, md.unify(p.mapping, indirect(rv))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeFile is just like Decode, except it will automatically read the
|
||||||
|
// contents of the file at `fpath` and decode it for you.
|
||||||
|
func DecodeFile(fpath string, v interface{}) (MetaData, error) {
|
||||||
|
bs, err := ioutil.ReadFile(fpath)
|
||||||
|
if err != nil {
|
||||||
|
return MetaData{}, err
|
||||||
|
}
|
||||||
|
return Decode(string(bs), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeReader is just like Decode, except it will consume all bytes
|
||||||
|
// from the reader and decode it for you.
|
||||||
|
func DecodeReader(r io.Reader, v interface{}) (MetaData, error) {
|
||||||
|
bs, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
return MetaData{}, err
|
||||||
|
}
|
||||||
|
return Decode(string(bs), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// unify performs a sort of type unification based on the structure of `rv`,
|
||||||
|
// which is the client representation.
|
||||||
|
//
|
||||||
|
// Any type mismatch produces an error. Finding a type that we don't know
|
||||||
|
// how to handle produces an unsupported type error.
|
||||||
|
func (md *MetaData) unify(data interface{}, rv reflect.Value) error {
|
||||||
|
|
||||||
|
// Special case. Look for a `Primitive` value.
|
||||||
|
if rv.Type() == reflect.TypeOf((*Primitive)(nil)).Elem() {
|
||||||
|
// Save the undecoded data and the key context into the primitive
|
||||||
|
// value.
|
||||||
|
context := make(Key, len(md.context))
|
||||||
|
copy(context, md.context)
|
||||||
|
rv.Set(reflect.ValueOf(Primitive{
|
||||||
|
undecoded: data,
|
||||||
|
context: context,
|
||||||
|
}))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case. Unmarshaler Interface support.
|
||||||
|
if rv.CanAddr() {
|
||||||
|
if v, ok := rv.Addr().Interface().(Unmarshaler); ok {
|
||||||
|
return v.UnmarshalTOML(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case. Handle time.Time values specifically.
|
||||||
|
// TODO: Remove this code when we decide to drop support for Go 1.1.
|
||||||
|
// This isn't necessary in Go 1.2 because time.Time satisfies the encoding
|
||||||
|
// interfaces.
|
||||||
|
if rv.Type().AssignableTo(rvalue(time.Time{}).Type()) {
|
||||||
|
return md.unifyDatetime(data, rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case. Look for a value satisfying the TextUnmarshaler interface.
|
||||||
|
if v, ok := rv.Interface().(TextUnmarshaler); ok {
|
||||||
|
return md.unifyText(data, v)
|
||||||
|
}
|
||||||
|
// BUG(burntsushi)
|
||||||
|
// The behavior here is incorrect whenever a Go type satisfies the
|
||||||
|
// encoding.TextUnmarshaler interface but also corresponds to a TOML
|
||||||
|
// hash or array. In particular, the unmarshaler should only be applied
|
||||||
|
// to primitive TOML values. But at this point, it will be applied to
|
||||||
|
// all kinds of values and produce an incorrect error whenever those values
|
||||||
|
// are hashes or arrays (including arrays of tables).
|
||||||
|
|
||||||
|
k := rv.Kind()
|
||||||
|
|
||||||
|
// laziness
|
||||||
|
if k >= reflect.Int && k <= reflect.Uint64 {
|
||||||
|
return md.unifyInt(data, rv)
|
||||||
|
}
|
||||||
|
switch k {
|
||||||
|
case reflect.Ptr:
|
||||||
|
elem := reflect.New(rv.Type().Elem())
|
||||||
|
err := md.unify(data, reflect.Indirect(elem))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rv.Set(elem)
|
||||||
|
return nil
|
||||||
|
case reflect.Struct:
|
||||||
|
return md.unifyStruct(data, rv)
|
||||||
|
case reflect.Map:
|
||||||
|
return md.unifyMap(data, rv)
|
||||||
|
case reflect.Array:
|
||||||
|
return md.unifyArray(data, rv)
|
||||||
|
case reflect.Slice:
|
||||||
|
return md.unifySlice(data, rv)
|
||||||
|
case reflect.String:
|
||||||
|
return md.unifyString(data, rv)
|
||||||
|
case reflect.Bool:
|
||||||
|
return md.unifyBool(data, rv)
|
||||||
|
case reflect.Interface:
|
||||||
|
// we only support empty interfaces.
|
||||||
|
if rv.NumMethod() > 0 {
|
||||||
|
return e("unsupported type %s", rv.Type())
|
||||||
|
}
|
||||||
|
return md.unifyAnything(data, rv)
|
||||||
|
case reflect.Float32:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Float64:
|
||||||
|
return md.unifyFloat64(data, rv)
|
||||||
|
}
|
||||||
|
return e("unsupported type %s", rv.Kind())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error {
|
||||||
|
tmap, ok := mapping.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
if mapping == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return e("type mismatch for %s: expected table but found %T",
|
||||||
|
rv.Type().String(), mapping)
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, datum := range tmap {
|
||||||
|
var f *field
|
||||||
|
fields := cachedTypeFields(rv.Type())
|
||||||
|
for i := range fields {
|
||||||
|
ff := &fields[i]
|
||||||
|
if ff.name == key {
|
||||||
|
f = ff
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if f == nil && strings.EqualFold(ff.name, key) {
|
||||||
|
f = ff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if f != nil {
|
||||||
|
subv := rv
|
||||||
|
for _, i := range f.index {
|
||||||
|
subv = indirect(subv.Field(i))
|
||||||
|
}
|
||||||
|
if isUnifiable(subv) {
|
||||||
|
md.decoded[md.context.add(key).String()] = true
|
||||||
|
md.context = append(md.context, key)
|
||||||
|
if err := md.unify(datum, subv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
md.context = md.context[0 : len(md.context)-1]
|
||||||
|
} else if f.name != "" {
|
||||||
|
// Bad user! No soup for you!
|
||||||
|
return e("cannot write unexported field %s.%s",
|
||||||
|
rv.Type().String(), f.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error {
|
||||||
|
tmap, ok := mapping.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
if tmap == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("map", mapping)
|
||||||
|
}
|
||||||
|
if rv.IsNil() {
|
||||||
|
rv.Set(reflect.MakeMap(rv.Type()))
|
||||||
|
}
|
||||||
|
for k, v := range tmap {
|
||||||
|
md.decoded[md.context.add(k).String()] = true
|
||||||
|
md.context = append(md.context, k)
|
||||||
|
|
||||||
|
rvkey := indirect(reflect.New(rv.Type().Key()))
|
||||||
|
rvval := reflect.Indirect(reflect.New(rv.Type().Elem()))
|
||||||
|
if err := md.unify(v, rvval); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
md.context = md.context[0 : len(md.context)-1]
|
||||||
|
|
||||||
|
rvkey.SetString(k)
|
||||||
|
rv.SetMapIndex(rvkey, rvval)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error {
|
||||||
|
datav := reflect.ValueOf(data)
|
||||||
|
if datav.Kind() != reflect.Slice {
|
||||||
|
if !datav.IsValid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("slice", data)
|
||||||
|
}
|
||||||
|
sliceLen := datav.Len()
|
||||||
|
if sliceLen != rv.Len() {
|
||||||
|
return e("expected array length %d; got TOML array of length %d",
|
||||||
|
rv.Len(), sliceLen)
|
||||||
|
}
|
||||||
|
return md.unifySliceArray(datav, rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error {
|
||||||
|
datav := reflect.ValueOf(data)
|
||||||
|
if datav.Kind() != reflect.Slice {
|
||||||
|
if !datav.IsValid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("slice", data)
|
||||||
|
}
|
||||||
|
n := datav.Len()
|
||||||
|
if rv.IsNil() || rv.Cap() < n {
|
||||||
|
rv.Set(reflect.MakeSlice(rv.Type(), n, n))
|
||||||
|
}
|
||||||
|
rv.SetLen(n)
|
||||||
|
return md.unifySliceArray(datav, rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifySliceArray(data, rv reflect.Value) error {
|
||||||
|
sliceLen := data.Len()
|
||||||
|
for i := 0; i < sliceLen; i++ {
|
||||||
|
v := data.Index(i).Interface()
|
||||||
|
sliceval := indirect(rv.Index(i))
|
||||||
|
if err := md.unify(v, sliceval); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyDatetime(data interface{}, rv reflect.Value) error {
|
||||||
|
if _, ok := data.(time.Time); ok {
|
||||||
|
rv.Set(reflect.ValueOf(data))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("time.Time", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error {
|
||||||
|
if s, ok := data.(string); ok {
|
||||||
|
rv.SetString(s)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("string", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error {
|
||||||
|
if num, ok := data.(float64); ok {
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Float32:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Float64:
|
||||||
|
rv.SetFloat(num)
|
||||||
|
default:
|
||||||
|
panic("bug")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("float", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error {
|
||||||
|
if num, ok := data.(int64); ok {
|
||||||
|
if rv.Kind() >= reflect.Int && rv.Kind() <= reflect.Int64 {
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int64:
|
||||||
|
// No bounds checking necessary.
|
||||||
|
case reflect.Int8:
|
||||||
|
if num < math.MinInt8 || num > math.MaxInt8 {
|
||||||
|
return e("value %d is out of range for int8", num)
|
||||||
|
}
|
||||||
|
case reflect.Int16:
|
||||||
|
if num < math.MinInt16 || num > math.MaxInt16 {
|
||||||
|
return e("value %d is out of range for int16", num)
|
||||||
|
}
|
||||||
|
case reflect.Int32:
|
||||||
|
if num < math.MinInt32 || num > math.MaxInt32 {
|
||||||
|
return e("value %d is out of range for int32", num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv.SetInt(num)
|
||||||
|
} else if rv.Kind() >= reflect.Uint && rv.Kind() <= reflect.Uint64 {
|
||||||
|
unum := uint64(num)
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Uint, reflect.Uint64:
|
||||||
|
// No bounds checking necessary.
|
||||||
|
case reflect.Uint8:
|
||||||
|
if num < 0 || unum > math.MaxUint8 {
|
||||||
|
return e("value %d is out of range for uint8", num)
|
||||||
|
}
|
||||||
|
case reflect.Uint16:
|
||||||
|
if num < 0 || unum > math.MaxUint16 {
|
||||||
|
return e("value %d is out of range for uint16", num)
|
||||||
|
}
|
||||||
|
case reflect.Uint32:
|
||||||
|
if num < 0 || unum > math.MaxUint32 {
|
||||||
|
return e("value %d is out of range for uint32", num)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rv.SetUint(unum)
|
||||||
|
} else {
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("integer", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error {
|
||||||
|
if b, ok := data.(bool); ok {
|
||||||
|
rv.SetBool(b)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return badtype("boolean", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error {
|
||||||
|
rv.Set(reflect.ValueOf(data))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (md *MetaData) unifyText(data interface{}, v TextUnmarshaler) error {
|
||||||
|
var s string
|
||||||
|
switch sdata := data.(type) {
|
||||||
|
case TextMarshaler:
|
||||||
|
text, err := sdata.MarshalText()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s = string(text)
|
||||||
|
case fmt.Stringer:
|
||||||
|
s = sdata.String()
|
||||||
|
case string:
|
||||||
|
s = sdata
|
||||||
|
case bool:
|
||||||
|
s = fmt.Sprintf("%v", sdata)
|
||||||
|
case int64:
|
||||||
|
s = fmt.Sprintf("%d", sdata)
|
||||||
|
case float64:
|
||||||
|
s = fmt.Sprintf("%f", sdata)
|
||||||
|
default:
|
||||||
|
return badtype("primitive (string-like)", data)
|
||||||
|
}
|
||||||
|
if err := v.UnmarshalText([]byte(s)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// rvalue returns a reflect.Value of `v`. All pointers are resolved.
|
||||||
|
func rvalue(v interface{}) reflect.Value {
|
||||||
|
return indirect(reflect.ValueOf(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// indirect returns the value pointed to by a pointer.
|
||||||
|
// Pointers are followed until the value is not a pointer.
|
||||||
|
// New values are allocated for each nil pointer.
|
||||||
|
//
|
||||||
|
// An exception to this rule is if the value satisfies an interface of
|
||||||
|
// interest to us (like encoding.TextUnmarshaler).
|
||||||
|
func indirect(v reflect.Value) reflect.Value {
|
||||||
|
if v.Kind() != reflect.Ptr {
|
||||||
|
if v.CanSet() {
|
||||||
|
pv := v.Addr()
|
||||||
|
if _, ok := pv.Interface().(TextUnmarshaler); ok {
|
||||||
|
return pv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
if v.IsNil() {
|
||||||
|
v.Set(reflect.New(v.Type().Elem()))
|
||||||
|
}
|
||||||
|
return indirect(reflect.Indirect(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
func isUnifiable(rv reflect.Value) bool {
|
||||||
|
if rv.CanSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if _, ok := rv.Interface().(TextUnmarshaler); ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func badtype(expected string, data interface{}) error {
|
||||||
|
return e("cannot load TOML value of type %T into a Go %s", data, expected)
|
||||||
|
}
|
121
vendor/github.com/BurntSushi/toml/decode_meta.go
generated
vendored
Normal file
121
vendor/github.com/BurntSushi/toml/decode_meta.go
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package toml
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// MetaData allows access to meta information about TOML data that may not
|
||||||
|
// be inferrable via reflection. In particular, whether a key has been defined
|
||||||
|
// and the TOML type of a key.
|
||||||
|
type MetaData struct {
|
||||||
|
mapping map[string]interface{}
|
||||||
|
types map[string]tomlType
|
||||||
|
keys []Key
|
||||||
|
decoded map[string]bool
|
||||||
|
context Key // Used only during decoding.
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDefined returns true if the key given exists in the TOML data. The key
|
||||||
|
// should be specified hierarchially. e.g.,
|
||||||
|
//
|
||||||
|
// // access the TOML key 'a.b.c'
|
||||||
|
// IsDefined("a", "b", "c")
|
||||||
|
//
|
||||||
|
// IsDefined will return false if an empty key given. Keys are case sensitive.
|
||||||
|
func (md *MetaData) IsDefined(key ...string) bool {
|
||||||
|
if len(key) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash map[string]interface{}
|
||||||
|
var ok bool
|
||||||
|
var hashOrVal interface{} = md.mapping
|
||||||
|
for _, k := range key {
|
||||||
|
if hash, ok = hashOrVal.(map[string]interface{}); !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if hashOrVal, ok = hash[k]; !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type returns a string representation of the type of the key specified.
|
||||||
|
//
|
||||||
|
// Type will return the empty string if given an empty key or a key that
|
||||||
|
// does not exist. Keys are case sensitive.
|
||||||
|
func (md *MetaData) Type(key ...string) string {
|
||||||
|
fullkey := strings.Join(key, ".")
|
||||||
|
if typ, ok := md.types[fullkey]; ok {
|
||||||
|
return typ.typeString()
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key is the type of any TOML key, including key groups. Use (MetaData).Keys
|
||||||
|
// to get values of this type.
|
||||||
|
type Key []string
|
||||||
|
|
||||||
|
func (k Key) String() string {
|
||||||
|
return strings.Join(k, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Key) maybeQuotedAll() string {
|
||||||
|
var ss []string
|
||||||
|
for i := range k {
|
||||||
|
ss = append(ss, k.maybeQuoted(i))
|
||||||
|
}
|
||||||
|
return strings.Join(ss, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Key) maybeQuoted(i int) string {
|
||||||
|
quote := false
|
||||||
|
for _, c := range k[i] {
|
||||||
|
if !isBareKeyChar(c) {
|
||||||
|
quote = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if quote {
|
||||||
|
return "\"" + strings.Replace(k[i], "\"", "\\\"", -1) + "\""
|
||||||
|
}
|
||||||
|
return k[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Key) add(piece string) Key {
|
||||||
|
newKey := make(Key, len(k)+1)
|
||||||
|
copy(newKey, k)
|
||||||
|
newKey[len(k)] = piece
|
||||||
|
return newKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keys returns a slice of every key in the TOML data, including key groups.
|
||||||
|
// Each key is itself a slice, where the first element is the top of the
|
||||||
|
// hierarchy and the last is the most specific.
|
||||||
|
//
|
||||||
|
// The list will have the same order as the keys appeared in the TOML data.
|
||||||
|
//
|
||||||
|
// All keys returned are non-empty.
|
||||||
|
func (md *MetaData) Keys() []Key {
|
||||||
|
return md.keys
|
||||||
|
}
|
||||||
|
|
||||||
|
// Undecoded returns all keys that have not been decoded in the order in which
|
||||||
|
// they appear in the original TOML document.
|
||||||
|
//
|
||||||
|
// This includes keys that haven't been decoded because of a Primitive value.
|
||||||
|
// Once the Primitive value is decoded, the keys will be considered decoded.
|
||||||
|
//
|
||||||
|
// Also note that decoding into an empty interface will result in no decoding,
|
||||||
|
// and so no keys will be considered decoded.
|
||||||
|
//
|
||||||
|
// In this sense, the Undecoded keys correspond to keys in the TOML document
|
||||||
|
// that do not have a concrete type in your representation.
|
||||||
|
func (md *MetaData) Undecoded() []Key {
|
||||||
|
undecoded := make([]Key, 0, len(md.keys))
|
||||||
|
for _, key := range md.keys {
|
||||||
|
if !md.decoded[key.String()] {
|
||||||
|
undecoded = append(undecoded, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undecoded
|
||||||
|
}
|
27
vendor/github.com/BurntSushi/toml/doc.go
generated
vendored
Normal file
27
vendor/github.com/BurntSushi/toml/doc.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
Package toml provides facilities for decoding and encoding TOML configuration
|
||||||
|
files via reflection. There is also support for delaying decoding with
|
||||||
|
the Primitive type, and querying the set of keys in a TOML document with the
|
||||||
|
MetaData type.
|
||||||
|
|
||||||
|
The specification implemented: https://github.com/toml-lang/toml
|
||||||
|
|
||||||
|
The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify
|
||||||
|
whether a file is a valid TOML document. It can also be used to print the
|
||||||
|
type of each key in a TOML document.
|
||||||
|
|
||||||
|
Testing
|
||||||
|
|
||||||
|
There are two important types of tests used for this package. The first is
|
||||||
|
contained inside '*_test.go' files and uses the standard Go unit testing
|
||||||
|
framework. These tests are primarily devoted to holistically testing the
|
||||||
|
decoder and encoder.
|
||||||
|
|
||||||
|
The second type of testing is used to verify the implementation's adherence
|
||||||
|
to the TOML specification. These tests have been factored into their own
|
||||||
|
project: https://github.com/BurntSushi/toml-test
|
||||||
|
|
||||||
|
The reason the tests are in a separate project is so that they can be used by
|
||||||
|
any implementation of TOML. Namely, it is language agnostic.
|
||||||
|
*/
|
||||||
|
package toml
|
568
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
Normal file
568
vendor/github.com/BurntSushi/toml/encode.go
generated
vendored
Normal file
@ -0,0 +1,568 @@
|
|||||||
|
package toml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type tomlEncodeError struct{ error }
|
||||||
|
|
||||||
|
var (
|
||||||
|
errArrayMixedElementTypes = errors.New(
|
||||||
|
"toml: cannot encode array with mixed element types")
|
||||||
|
errArrayNilElement = errors.New(
|
||||||
|
"toml: cannot encode array with nil element")
|
||||||
|
errNonString = errors.New(
|
||||||
|
"toml: cannot encode a map with non-string key type")
|
||||||
|
errAnonNonStruct = errors.New(
|
||||||
|
"toml: cannot encode an anonymous field that is not a struct")
|
||||||
|
errArrayNoTable = errors.New(
|
||||||
|
"toml: TOML array element cannot contain a table")
|
||||||
|
errNoKey = errors.New(
|
||||||
|
"toml: top-level values must be Go maps or structs")
|
||||||
|
errAnything = errors.New("") // used in testing
|
||||||
|
)
|
||||||
|
|
||||||
|
var quotedReplacer = strings.NewReplacer(
|
||||||
|
"\t", "\\t",
|
||||||
|
"\n", "\\n",
|
||||||
|
"\r", "\\r",
|
||||||
|
"\"", "\\\"",
|
||||||
|
"\\", "\\\\",
|
||||||
|
)
|
||||||
|
|
||||||
|
// Encoder controls the encoding of Go values to a TOML document to some
|
||||||
|
// io.Writer.
|
||||||
|
//
|
||||||
|
// The indentation level can be controlled with the Indent field.
|
||||||
|
type Encoder struct {
|
||||||
|
// A single indentation level. By default it is two spaces.
|
||||||
|
Indent string
|
||||||
|
|
||||||
|
// hasWritten is whether we have written any output to w yet.
|
||||||
|
hasWritten bool
|
||||||
|
w *bufio.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEncoder returns a TOML encoder that encodes Go values to the io.Writer
|
||||||
|
// given. By default, a single indentation level is 2 spaces.
|
||||||
|
func NewEncoder(w io.Writer) *Encoder {
|
||||||
|
return &Encoder{
|
||||||
|
w: bufio.NewWriter(w),
|
||||||
|
Indent: " ",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode writes a TOML representation of the Go value to the underlying
|
||||||
|
// io.Writer. If the value given cannot be encoded to a valid TOML document,
|
||||||
|
// then an error is returned.
|
||||||
|
//
|
||||||
|
// The mapping between Go values and TOML values should be precisely the same
|
||||||
|
// as for the Decode* functions. Similarly, the TextMarshaler interface is
|
||||||
|
// supported by encoding the resulting bytes as strings. (If you want to write
|
||||||
|
// arbitrary binary data then you will need to use something like base64 since
|
||||||
|
// TOML does not have any binary types.)
|
||||||
|
//
|
||||||
|
// When encoding TOML hashes (i.e., Go maps or structs), keys without any
|
||||||
|
// sub-hashes are encoded first.
|
||||||
|
//
|
||||||
|
// If a Go map is encoded, then its keys are sorted alphabetically for
|
||||||
|
// deterministic output. More control over this behavior may be provided if
|
||||||
|
// there is demand for it.
|
||||||
|
//
|
||||||
|
// Encoding Go values without a corresponding TOML representation---like map
|
||||||
|
// types with non-string keys---will cause an error to be returned. Similarly
|
||||||
|
// for mixed arrays/slices, arrays/slices with nil elements, embedded
|
||||||
|
// non-struct types and nested slices containing maps or structs.
|
||||||
|
// (e.g., [][]map[string]string is not allowed but []map[string]string is OK
|
||||||
|
// and so is []map[string][]string.)
|
||||||
|
func (enc *Encoder) Encode(v interface{}) error {
|
||||||
|
rv := eindirect(reflect.ValueOf(v))
|
||||||
|
if err := enc.safeEncode(Key([]string{}), rv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return enc.w.Flush()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
if terr, ok := r.(tomlEncodeError); ok {
|
||||||
|
err = terr.error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
enc.encode(key, rv)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) encode(key Key, rv reflect.Value) {
|
||||||
|
// Special case. Time needs to be in ISO8601 format.
|
||||||
|
// Special case. If we can marshal the type to text, then we used that.
|
||||||
|
// Basically, this prevents the encoder for handling these types as
|
||||||
|
// generic structs (or whatever the underlying type of a TextMarshaler is).
|
||||||
|
switch rv.Interface().(type) {
|
||||||
|
case time.Time, TextMarshaler:
|
||||||
|
enc.keyEqElement(key, rv)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
k := rv.Kind()
|
||||||
|
switch k {
|
||||||
|
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, reflect.String, reflect.Bool:
|
||||||
|
enc.keyEqElement(key, rv)
|
||||||
|
case reflect.Array, reflect.Slice:
|
||||||
|
if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) {
|
||||||
|
enc.eArrayOfTables(key, rv)
|
||||||
|
} else {
|
||||||
|
enc.keyEqElement(key, rv)
|
||||||
|
}
|
||||||
|
case reflect.Interface:
|
||||||
|
if rv.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
enc.encode(key, rv.Elem())
|
||||||
|
case reflect.Map:
|
||||||
|
if rv.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
enc.eTable(key, rv)
|
||||||
|
case reflect.Ptr:
|
||||||
|
if rv.IsNil() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
enc.encode(key, rv.Elem())
|
||||||
|
case reflect.Struct:
|
||||||
|
enc.eTable(key, rv)
|
||||||
|
default:
|
||||||
|
panic(e("unsupported type for key '%s': %s", key, k))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eElement encodes any value that can be an array element (primitives and
|
||||||
|
// arrays).
|
||||||
|
func (enc *Encoder) eElement(rv reflect.Value) {
|
||||||
|
switch v := rv.Interface().(type) {
|
||||||
|
case time.Time:
|
||||||
|
// Special case time.Time as a primitive. Has to come before
|
||||||
|
// TextMarshaler below because time.Time implements
|
||||||
|
// encoding.TextMarshaler, but we need to always use UTC.
|
||||||
|
enc.wf(v.UTC().Format("2006-01-02T15:04:05Z"))
|
||||||
|
return
|
||||||
|
case TextMarshaler:
|
||||||
|
// Special case. Use text marshaler if it's available for this value.
|
||||||
|
if s, err := v.MarshalText(); err != nil {
|
||||||
|
encPanic(err)
|
||||||
|
} else {
|
||||||
|
enc.writeQuoted(string(s))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
enc.wf(strconv.FormatBool(rv.Bool()))
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
|
||||||
|
reflect.Int64:
|
||||||
|
enc.wf(strconv.FormatInt(rv.Int(), 10))
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16,
|
||||||
|
reflect.Uint32, reflect.Uint64:
|
||||||
|
enc.wf(strconv.FormatUint(rv.Uint(), 10))
|
||||||
|
case reflect.Float32:
|
||||||
|
enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 32)))
|
||||||
|
case reflect.Float64:
|
||||||
|
enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 64)))
|
||||||
|
case reflect.Array, reflect.Slice:
|
||||||
|
enc.eArrayOrSliceElement(rv)
|
||||||
|
case reflect.Interface:
|
||||||
|
enc.eElement(rv.Elem())
|
||||||
|
case reflect.String:
|
||||||
|
enc.writeQuoted(rv.String())
|
||||||
|
default:
|
||||||
|
panic(e("unexpected primitive type: %s", rv.Kind()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// By the TOML spec, all floats must have a decimal with at least one
|
||||||
|
// number on either side.
|
||||||
|
func floatAddDecimal(fstr string) string {
|
||||||
|
if !strings.Contains(fstr, ".") {
|
||||||
|
return fstr + ".0"
|
||||||
|
}
|
||||||
|
return fstr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) writeQuoted(s string) {
|
||||||
|
enc.wf("\"%s\"", quotedReplacer.Replace(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) {
|
||||||
|
length := rv.Len()
|
||||||
|
enc.wf("[")
|
||||||
|
for i := 0; i < length; i++ {
|
||||||
|
elem := rv.Index(i)
|
||||||
|
enc.eElement(elem)
|
||||||
|
if i != length-1 {
|
||||||
|
enc.wf(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enc.wf("]")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) {
|
||||||
|
if len(key) == 0 {
|
||||||
|
encPanic(errNoKey)
|
||||||
|
}
|
||||||
|
for i := 0; i < rv.Len(); i++ {
|
||||||
|
trv := rv.Index(i)
|
||||||
|
if isNil(trv) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
panicIfInvalidKey(key)
|
||||||
|
enc.newline()
|
||||||
|
enc.wf("%s[[%s]]", enc.indentStr(key), key.maybeQuotedAll())
|
||||||
|
enc.newline()
|
||||||
|
enc.eMapOrStruct(key, trv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) eTable(key Key, rv reflect.Value) {
|
||||||
|
panicIfInvalidKey(key)
|
||||||
|
if len(key) == 1 {
|
||||||
|
// Output an extra newline between top-level tables.
|
||||||
|
// (The newline isn't written if nothing else has been written though.)
|
||||||
|
enc.newline()
|
||||||
|
}
|
||||||
|
if len(key) > 0 {
|
||||||
|
enc.wf("%s[%s]", enc.indentStr(key), key.maybeQuotedAll())
|
||||||
|
enc.newline()
|
||||||
|
}
|
||||||
|
enc.eMapOrStruct(key, rv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value) {
|
||||||
|
switch rv := eindirect(rv); rv.Kind() {
|
||||||
|
case reflect.Map:
|
||||||
|
enc.eMap(key, rv)
|
||||||
|
case reflect.Struct:
|
||||||
|
enc.eStruct(key, rv)
|
||||||
|
default:
|
||||||
|
panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) eMap(key Key, rv reflect.Value) {
|
||||||
|
rt := rv.Type()
|
||||||
|
if rt.Key().Kind() != reflect.String {
|
||||||
|
encPanic(errNonString)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort keys so that we have deterministic output. And write keys directly
|
||||||
|
// underneath this key first, before writing sub-structs or sub-maps.
|
||||||
|
var mapKeysDirect, mapKeysSub []string
|
||||||
|
for _, mapKey := range rv.MapKeys() {
|
||||||
|
k := mapKey.String()
|
||||||
|
if typeIsHash(tomlTypeOfGo(rv.MapIndex(mapKey))) {
|
||||||
|
mapKeysSub = append(mapKeysSub, k)
|
||||||
|
} else {
|
||||||
|
mapKeysDirect = append(mapKeysDirect, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var writeMapKeys = func(mapKeys []string) {
|
||||||
|
sort.Strings(mapKeys)
|
||||||
|
for _, mapKey := range mapKeys {
|
||||||
|
mrv := rv.MapIndex(reflect.ValueOf(mapKey))
|
||||||
|
if isNil(mrv) {
|
||||||
|
// Don't write anything for nil fields.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
enc.encode(key.add(mapKey), mrv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeMapKeys(mapKeysDirect)
|
||||||
|
writeMapKeys(mapKeysSub)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) eStruct(key Key, rv reflect.Value) {
|
||||||
|
// Write keys for fields directly under this key first, because if we write
|
||||||
|
// a field that creates a new table, then all keys under it will be in that
|
||||||
|
// table (not the one we're writing here).
|
||||||
|
rt := rv.Type()
|
||||||
|
var fieldsDirect, fieldsSub [][]int
|
||||||
|
var addFields func(rt reflect.Type, rv reflect.Value, start []int)
|
||||||
|
addFields = func(rt reflect.Type, rv reflect.Value, start []int) {
|
||||||
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
|
f := rt.Field(i)
|
||||||
|
// skip unexported fields
|
||||||
|
if f.PkgPath != "" && !f.Anonymous {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
frv := rv.Field(i)
|
||||||
|
if f.Anonymous {
|
||||||
|
t := f.Type
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Struct:
|
||||||
|
// Treat anonymous struct fields with
|
||||||
|
// tag names as though they are not
|
||||||
|
// anonymous, like encoding/json does.
|
||||||
|
if getOptions(f.Tag).name == "" {
|
||||||
|
addFields(t, frv, f.Index)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
case reflect.Ptr:
|
||||||
|
if t.Elem().Kind() == reflect.Struct &&
|
||||||
|
getOptions(f.Tag).name == "" {
|
||||||
|
if !frv.IsNil() {
|
||||||
|
addFields(t.Elem(), frv.Elem(), f.Index)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Fall through to the normal field encoding logic below
|
||||||
|
// for non-struct anonymous fields.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if typeIsHash(tomlTypeOfGo(frv)) {
|
||||||
|
fieldsSub = append(fieldsSub, append(start, f.Index...))
|
||||||
|
} else {
|
||||||
|
fieldsDirect = append(fieldsDirect, append(start, f.Index...))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addFields(rt, rv, nil)
|
||||||
|
|
||||||
|
var writeFields = func(fields [][]int) {
|
||||||
|
for _, fieldIndex := range fields {
|
||||||
|
sft := rt.FieldByIndex(fieldIndex)
|
||||||
|
sf := rv.FieldByIndex(fieldIndex)
|
||||||
|
if isNil(sf) {
|
||||||
|
// Don't write anything for nil fields.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := getOptions(sft.Tag)
|
||||||
|
if opts.skip {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
keyName := sft.Name
|
||||||
|
if opts.name != "" {
|
||||||
|
keyName = opts.name
|
||||||
|
}
|
||||||
|
if opts.omitempty && isEmpty(sf) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if opts.omitzero && isZero(sf) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
enc.encode(key.add(keyName), sf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeFields(fieldsDirect)
|
||||||
|
writeFields(fieldsSub)
|
||||||
|
}
|
||||||
|
|
||||||
|
// tomlTypeName returns the TOML type name of the Go value's type. It is
|
||||||
|
// used to determine whether the types of array elements are mixed (which is
|
||||||
|
// forbidden). If the Go value is nil, then it is illegal for it to be an array
|
||||||
|
// element, and valueIsNil is returned as true.
|
||||||
|
|
||||||
|
// Returns the TOML type of a Go value. The type may be `nil`, which means
|
||||||
|
// no concrete TOML type could be found.
|
||||||
|
func tomlTypeOfGo(rv reflect.Value) tomlType {
|
||||||
|
if isNil(rv) || !rv.IsValid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return tomlBool
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
|
||||||
|
reflect.Int64,
|
||||||
|
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
|
||||||
|
reflect.Uint64:
|
||||||
|
return tomlInteger
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return tomlFloat
|
||||||
|
case reflect.Array, reflect.Slice:
|
||||||
|
if typeEqual(tomlHash, tomlArrayType(rv)) {
|
||||||
|
return tomlArrayHash
|
||||||
|
}
|
||||||
|
return tomlArray
|
||||||
|
case reflect.Ptr, reflect.Interface:
|
||||||
|
return tomlTypeOfGo(rv.Elem())
|
||||||
|
case reflect.String:
|
||||||
|
return tomlString
|
||||||
|
case reflect.Map:
|
||||||
|
return tomlHash
|
||||||
|
case reflect.Struct:
|
||||||
|
switch rv.Interface().(type) {
|
||||||
|
case time.Time:
|
||||||
|
return tomlDatetime
|
||||||
|
case TextMarshaler:
|
||||||
|
return tomlString
|
||||||
|
default:
|
||||||
|
return tomlHash
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("unexpected reflect.Kind: " + rv.Kind().String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tomlArrayType returns the element type of a TOML array. The type returned
|
||||||
|
// may be nil if it cannot be determined (e.g., a nil slice or a zero length
|
||||||
|
// slize). This function may also panic if it finds a type that cannot be
|
||||||
|
// expressed in TOML (such as nil elements, heterogeneous arrays or directly
|
||||||
|
// nested arrays of tables).
|
||||||
|
func tomlArrayType(rv reflect.Value) tomlType {
|
||||||
|
if isNil(rv) || !rv.IsValid() || rv.Len() == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
firstType := tomlTypeOfGo(rv.Index(0))
|
||||||
|
if firstType == nil {
|
||||||
|
encPanic(errArrayNilElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
rvlen := rv.Len()
|
||||||
|
for i := 1; i < rvlen; i++ {
|
||||||
|
elem := rv.Index(i)
|
||||||
|
switch elemType := tomlTypeOfGo(elem); {
|
||||||
|
case elemType == nil:
|
||||||
|
encPanic(errArrayNilElement)
|
||||||
|
case !typeEqual(firstType, elemType):
|
||||||
|
encPanic(errArrayMixedElementTypes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we have a nested array, then we must make sure that the nested
|
||||||
|
// array contains ONLY primitives.
|
||||||
|
// This checks arbitrarily nested arrays.
|
||||||
|
if typeEqual(firstType, tomlArray) || typeEqual(firstType, tomlArrayHash) {
|
||||||
|
nest := tomlArrayType(eindirect(rv.Index(0)))
|
||||||
|
if typeEqual(nest, tomlHash) || typeEqual(nest, tomlArrayHash) {
|
||||||
|
encPanic(errArrayNoTable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return firstType
|
||||||
|
}
|
||||||
|
|
||||||
|
type tagOptions struct {
|
||||||
|
skip bool // "-"
|
||||||
|
name string
|
||||||
|
omitempty bool
|
||||||
|
omitzero bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOptions(tag reflect.StructTag) tagOptions {
|
||||||
|
t := tag.Get("toml")
|
||||||
|
if t == "-" {
|
||||||
|
return tagOptions{skip: true}
|
||||||
|
}
|
||||||
|
var opts tagOptions
|
||||||
|
parts := strings.Split(t, ",")
|
||||||
|
opts.name = parts[0]
|
||||||
|
for _, s := range parts[1:] {
|
||||||
|
switch s {
|
||||||
|
case "omitempty":
|
||||||
|
opts.omitempty = true
|
||||||
|
case "omitzero":
|
||||||
|
opts.omitzero = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
||||||
|
func isZero(rv reflect.Value) bool {
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return rv.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return rv.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return rv.Float() == 0.0
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEmpty(rv reflect.Value) bool {
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
|
||||||
|
return rv.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !rv.Bool()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) newline() {
|
||||||
|
if enc.hasWritten {
|
||||||
|
enc.wf("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) keyEqElement(key Key, val reflect.Value) {
|
||||||
|
if len(key) == 0 {
|
||||||
|
encPanic(errNoKey)
|
||||||
|
}
|
||||||
|
panicIfInvalidKey(key)
|
||||||
|
enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1))
|
||||||
|
enc.eElement(val)
|
||||||
|
enc.newline()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) wf(format string, v ...interface{}) {
|
||||||
|
if _, err := fmt.Fprintf(enc.w, format, v...); err != nil {
|
||||||
|
encPanic(err)
|
||||||
|
}
|
||||||
|
enc.hasWritten = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (enc *Encoder) indentStr(key Key) string {
|
||||||
|
return strings.Repeat(enc.Indent, len(key)-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func encPanic(err error) {
|
||||||
|
panic(tomlEncodeError{err})
|
||||||
|
}
|
||||||
|
|
||||||
|
func eindirect(v reflect.Value) reflect.Value {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Ptr, reflect.Interface:
|
||||||
|
return eindirect(v.Elem())
|
||||||
|
default:
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNil(rv reflect.Value) bool {
|
||||||
|
switch rv.Kind() {
|
||||||
|
case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
|
||||||
|
return rv.IsNil()
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func panicIfInvalidKey(key Key) {
|
||||||
|
for _, k := range key {
|
||||||
|
if len(k) == 0 {
|
||||||
|
encPanic(e("Key '%s' is not a valid table name. Key names "+
|
||||||
|
"cannot be empty.", key.maybeQuotedAll()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isValidKeyName(s string) bool {
|
||||||
|
return len(s) != 0
|
||||||
|
}
|
19
vendor/github.com/BurntSushi/toml/encoding_types.go
generated
vendored
Normal file
19
vendor/github.com/BurntSushi/toml/encoding_types.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// +build go1.2
|
||||||
|
|
||||||
|
package toml
|
||||||
|
|
||||||
|
// In order to support Go 1.1, we define our own TextMarshaler and
|
||||||
|
// TextUnmarshaler types. For Go 1.2+, we just alias them with the
|
||||||
|
// standard library interfaces.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here
|
||||||
|
// so that Go 1.1 can be supported.
|
||||||
|
type TextMarshaler encoding.TextMarshaler
|
||||||
|
|
||||||
|
// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined
|
||||||
|
// here so that Go 1.1 can be supported.
|
||||||
|
type TextUnmarshaler encoding.TextUnmarshaler
|
18
vendor/github.com/BurntSushi/toml/encoding_types_1.1.go
generated
vendored
Normal file
18
vendor/github.com/BurntSushi/toml/encoding_types_1.1.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// +build !go1.2
|
||||||
|
|
||||||
|
package toml
|
||||||
|
|
||||||
|
// These interfaces were introduced in Go 1.2, so we add them manually when
|
||||||
|
// compiling for Go 1.1.
|
||||||
|
|
||||||
|
// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here
|
||||||
|
// so that Go 1.1 can be supported.
|
||||||
|
type TextMarshaler interface {
|
||||||
|
MarshalText() (text []byte, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined
|
||||||
|
// here so that Go 1.1 can be supported.
|
||||||
|
type TextUnmarshaler interface {
|
||||||
|
UnmarshalText(text []byte) error
|
||||||
|
}
|
953
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
Normal file
953
vendor/github.com/BurntSushi/toml/lex.go
generated
vendored
Normal file
@ -0,0 +1,953 @@
|
|||||||
|
package toml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
type itemType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
itemError itemType = iota
|
||||||
|
itemNIL // used in the parser to indicate no type
|
||||||
|
itemEOF
|
||||||
|
itemText
|
||||||
|
itemString
|
||||||
|
itemRawString
|
||||||
|
itemMultilineString
|
||||||
|
itemRawMultilineString
|
||||||
|
itemBool
|
||||||
|
itemInteger
|
||||||
|
itemFloat
|
||||||
|
itemDatetime
|
||||||
|
itemArray // the start of an array
|
||||||
|
itemArrayEnd
|
||||||
|
itemTableStart
|
||||||
|
itemTableEnd
|
||||||
|
itemArrayTableStart
|
||||||
|
itemArrayTableEnd
|
||||||
|
itemKeyStart
|
||||||
|
itemCommentStart
|
||||||
|
itemInlineTableStart
|
||||||
|
itemInlineTableEnd
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
eof = 0
|
||||||
|
comma = ','
|
||||||
|
tableStart = '['
|
||||||
|
tableEnd = ']'
|
||||||
|
arrayTableStart = '['
|
||||||
|
arrayTableEnd = ']'
|
||||||
|
tableSep = '.'
|
||||||
|
keySep = '='
|
||||||
|
arrayStart = '['
|
||||||
|
arrayEnd = ']'
|
||||||
|
commentStart = '#'
|
||||||
|
stringStart = '"'
|
||||||
|
stringEnd = '"'
|
||||||
|
rawStringStart = '\''
|
||||||
|
rawStringEnd = '\''
|
||||||
|
inlineTableStart = '{'
|
||||||
|
inlineTableEnd = '}'
|
||||||
|
)
|
||||||
|
|
||||||
|
type stateFn func(lx *lexer) stateFn
|
||||||
|
|
||||||
|
type lexer struct {
|
||||||
|
input string
|
||||||
|
start int
|
||||||
|
pos int
|
||||||
|
line int
|
||||||
|
state stateFn
|
||||||
|
items chan item
|
||||||
|
|
||||||
|
// Allow for backing up up to three runes.
|
||||||
|
// This is necessary because TOML contains 3-rune tokens (""" and ''').
|
||||||
|
prevWidths [3]int
|
||||||
|
nprev int // how many of prevWidths are in use
|
||||||
|
// If we emit an eof, we can still back up, but it is not OK to call
|
||||||
|
// next again.
|
||||||
|
atEOF bool
|
||||||
|
|
||||||
|
// A stack of state functions used to maintain context.
|
||||||
|
// The idea is to reuse parts of the state machine in various places.
|
||||||
|
// For example, values can appear at the top level or within arbitrarily
|
||||||
|
// nested arrays. The last state on the stack is used after a value has
|
||||||
|
// been lexed. Similarly for comments.
|
||||||
|
stack []stateFn
|
||||||
|
}
|
||||||
|
|
||||||
|
type item struct {
|
||||||
|
typ itemType
|
||||||
|
val string
|
||||||
|
line int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lx *lexer) nextItem() item {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case item := <-lx.items:
|
||||||
|
return item
|
||||||
|
default:
|
||||||
|
lx.state = lx.state(lx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func lex(input string) *lexer {
|
||||||
|
lx := &lexer{
|
||||||
|
input: input,
|
||||||
|
state: lexTop,
|
||||||
|
line: 1,
|
||||||
|
items: make(chan item, 10),
|
||||||
|
stack: make([]stateFn, 0, 10),
|
||||||
|
}
|
||||||
|
return lx
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lx *lexer) push(state stateFn) {
|
||||||
|
lx.stack = append(lx.stack, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lx *lexer) pop() stateFn {
|
||||||
|
if len(lx.stack) == 0 {
|
||||||
|
return lx.errorf("BUG in lexer: no states to pop")
|
||||||
|
}
|
||||||
|
last := lx.stack[len(lx.stack)-1]
|
||||||
|
lx.stack = lx.stack[0 : len(lx.stack)-1]
|
||||||
|
return last
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lx *lexer) current() string {
|
||||||
|
return lx.input[lx.start:lx.pos]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lx *lexer) emit(typ itemType) {
|
||||||
|
lx.items <- item{typ, lx.current(), lx.line}
|
||||||
|
lx.start = lx.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lx *lexer) emitTrim(typ itemType) {
|
||||||
|
lx.items <- item{typ, strings.TrimSpace(lx.current()), lx.line}
|
||||||
|
lx.start = lx.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lx *lexer) next() (r rune) {
|
||||||
|
if lx.atEOF {
|
||||||
|
panic("next called after EOF")
|
||||||
|
}
|
||||||
|
if lx.pos >= len(lx.input) {
|
||||||
|
lx.atEOF = true
|
||||||
|
return eof
|
||||||
|
}
|
||||||
|
|
||||||
|
if lx.input[lx.pos] == '\n' {
|
||||||
|
lx.line++
|
||||||
|
}
|
||||||
|
lx.prevWidths[2] = lx.prevWidths[1]
|
||||||
|
lx.prevWidths[1] = lx.prevWidths[0]
|
||||||
|
if lx.nprev < 3 {
|
||||||
|
lx.nprev++
|
||||||
|
}
|
||||||
|
r, w := utf8.DecodeRuneInString(lx.input[lx.pos:])
|
||||||
|
lx.prevWidths[0] = w
|
||||||
|
lx.pos += w
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore skips over the pending input before this point.
|
||||||
|
func (lx *lexer) ignore() {
|
||||||
|
lx.start = lx.pos
|
||||||
|
}
|
||||||
|
|
||||||
|
// backup steps back one rune. Can be called only twice between calls to next.
|
||||||
|
func (lx *lexer) backup() {
|
||||||
|
if lx.atEOF {
|
||||||
|
lx.atEOF = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if lx.nprev < 1 {
|
||||||
|
panic("backed up too far")
|
||||||
|
}
|
||||||
|
w := lx.prevWidths[0]
|
||||||
|
lx.prevWidths[0] = lx.prevWidths[1]
|
||||||
|
lx.prevWidths[1] = lx.prevWidths[2]
|
||||||
|
lx.nprev--
|
||||||
|
lx.pos -= w
|
||||||
|
if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' {
|
||||||
|
lx.line--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// accept consumes the next rune if it's equal to `valid`.
|
||||||
|
func (lx *lexer) accept(valid rune) bool {
|
||||||
|
if lx.next() == valid {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// peek returns but does not consume the next rune in the input.
|
||||||
|
func (lx *lexer) peek() rune {
|
||||||
|
r := lx.next()
|
||||||
|
lx.backup()
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip ignores all input that matches the given predicate.
|
||||||
|
func (lx *lexer) skip(pred func(rune) bool) {
|
||||||
|
for {
|
||||||
|
r := lx.next()
|
||||||
|
if pred(r) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
lx.ignore()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// errorf stops all lexing by emitting an error and returning `nil`.
|
||||||
|
// Note that any value that is a character is escaped if it's a special
|
||||||
|
// character (newlines, tabs, etc.).
|
||||||
|
func (lx *lexer) errorf(format string, values ...interface{}) stateFn {
|
||||||
|
lx.items <- item{
|
||||||
|
itemError,
|
||||||
|
fmt.Sprintf(format, values...),
|
||||||
|
lx.line,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexTop consumes elements at the top level of TOML data.
|
||||||
|
func lexTop(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
if isWhitespace(r) || isNL(r) {
|
||||||
|
return lexSkip(lx, lexTop)
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case commentStart:
|
||||||
|
lx.push(lexTop)
|
||||||
|
return lexCommentStart
|
||||||
|
case tableStart:
|
||||||
|
return lexTableStart
|
||||||
|
case eof:
|
||||||
|
if lx.pos > lx.start {
|
||||||
|
return lx.errorf("unexpected EOF")
|
||||||
|
}
|
||||||
|
lx.emit(itemEOF)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point, the only valid item can be a key, so we back up
|
||||||
|
// and let the key lexer do the rest.
|
||||||
|
lx.backup()
|
||||||
|
lx.push(lexTopEnd)
|
||||||
|
return lexKeyStart
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexTopEnd is entered whenever a top-level item has been consumed. (A value
|
||||||
|
// or a table.) It must see only whitespace, and will turn back to lexTop
|
||||||
|
// upon a newline. If it sees EOF, it will quit the lexer successfully.
|
||||||
|
func lexTopEnd(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case r == commentStart:
|
||||||
|
// a comment will read to a newline for us.
|
||||||
|
lx.push(lexTop)
|
||||||
|
return lexCommentStart
|
||||||
|
case isWhitespace(r):
|
||||||
|
return lexTopEnd
|
||||||
|
case isNL(r):
|
||||||
|
lx.ignore()
|
||||||
|
return lexTop
|
||||||
|
case r == eof:
|
||||||
|
lx.emit(itemEOF)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return lx.errorf("expected a top-level item to end with a newline, "+
|
||||||
|
"comment, or EOF, but got %q instead", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexTable lexes the beginning of a table. Namely, it makes sure that
|
||||||
|
// it starts with a character other than '.' and ']'.
|
||||||
|
// It assumes that '[' has already been consumed.
|
||||||
|
// It also handles the case that this is an item in an array of tables.
|
||||||
|
// e.g., '[[name]]'.
|
||||||
|
func lexTableStart(lx *lexer) stateFn {
|
||||||
|
if lx.peek() == arrayTableStart {
|
||||||
|
lx.next()
|
||||||
|
lx.emit(itemArrayTableStart)
|
||||||
|
lx.push(lexArrayTableEnd)
|
||||||
|
} else {
|
||||||
|
lx.emit(itemTableStart)
|
||||||
|
lx.push(lexTableEnd)
|
||||||
|
}
|
||||||
|
return lexTableNameStart
|
||||||
|
}
|
||||||
|
|
||||||
|
func lexTableEnd(lx *lexer) stateFn {
|
||||||
|
lx.emit(itemTableEnd)
|
||||||
|
return lexTopEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
func lexArrayTableEnd(lx *lexer) stateFn {
|
||||||
|
if r := lx.next(); r != arrayTableEnd {
|
||||||
|
return lx.errorf("expected end of table array name delimiter %q, "+
|
||||||
|
"but got %q instead", arrayTableEnd, r)
|
||||||
|
}
|
||||||
|
lx.emit(itemArrayTableEnd)
|
||||||
|
return lexTopEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
func lexTableNameStart(lx *lexer) stateFn {
|
||||||
|
lx.skip(isWhitespace)
|
||||||
|
switch r := lx.peek(); {
|
||||||
|
case r == tableEnd || r == eof:
|
||||||
|
return lx.errorf("unexpected end of table name " +
|
||||||
|
"(table names cannot be empty)")
|
||||||
|
case r == tableSep:
|
||||||
|
return lx.errorf("unexpected table separator " +
|
||||||
|
"(table names cannot be empty)")
|
||||||
|
case r == stringStart || r == rawStringStart:
|
||||||
|
lx.ignore()
|
||||||
|
lx.push(lexTableNameEnd)
|
||||||
|
return lexValue // reuse string lexing
|
||||||
|
default:
|
||||||
|
return lexBareTableName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexBareTableName lexes the name of a table. It assumes that at least one
|
||||||
|
// valid character for the table has already been read.
|
||||||
|
func lexBareTableName(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
if isBareKeyChar(r) {
|
||||||
|
return lexBareTableName
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemText)
|
||||||
|
return lexTableNameEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexTableNameEnd reads the end of a piece of a table name, optionally
|
||||||
|
// consuming whitespace.
|
||||||
|
func lexTableNameEnd(lx *lexer) stateFn {
|
||||||
|
lx.skip(isWhitespace)
|
||||||
|
switch r := lx.next(); {
|
||||||
|
case isWhitespace(r):
|
||||||
|
return lexTableNameEnd
|
||||||
|
case r == tableSep:
|
||||||
|
lx.ignore()
|
||||||
|
return lexTableNameStart
|
||||||
|
case r == tableEnd:
|
||||||
|
return lx.pop()
|
||||||
|
default:
|
||||||
|
return lx.errorf("expected '.' or ']' to end table name, "+
|
||||||
|
"but got %q instead", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexKeyStart consumes a key name up until the first non-whitespace character.
|
||||||
|
// lexKeyStart will ignore whitespace.
|
||||||
|
func lexKeyStart(lx *lexer) stateFn {
|
||||||
|
r := lx.peek()
|
||||||
|
switch {
|
||||||
|
case r == keySep:
|
||||||
|
return lx.errorf("unexpected key separator %q", keySep)
|
||||||
|
case isWhitespace(r) || isNL(r):
|
||||||
|
lx.next()
|
||||||
|
return lexSkip(lx, lexKeyStart)
|
||||||
|
case r == stringStart || r == rawStringStart:
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemKeyStart)
|
||||||
|
lx.push(lexKeyEnd)
|
||||||
|
return lexValue // reuse string lexing
|
||||||
|
default:
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemKeyStart)
|
||||||
|
return lexBareKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexBareKey consumes the text of a bare key. Assumes that the first character
|
||||||
|
// (which is not whitespace) has not yet been consumed.
|
||||||
|
func lexBareKey(lx *lexer) stateFn {
|
||||||
|
switch r := lx.next(); {
|
||||||
|
case isBareKeyChar(r):
|
||||||
|
return lexBareKey
|
||||||
|
case isWhitespace(r):
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemText)
|
||||||
|
return lexKeyEnd
|
||||||
|
case r == keySep:
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemText)
|
||||||
|
return lexKeyEnd
|
||||||
|
default:
|
||||||
|
return lx.errorf("bare keys cannot contain %q", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexKeyEnd consumes the end of a key and trims whitespace (up to the key
|
||||||
|
// separator).
|
||||||
|
func lexKeyEnd(lx *lexer) stateFn {
|
||||||
|
switch r := lx.next(); {
|
||||||
|
case r == keySep:
|
||||||
|
return lexSkip(lx, lexValue)
|
||||||
|
case isWhitespace(r):
|
||||||
|
return lexSkip(lx, lexKeyEnd)
|
||||||
|
default:
|
||||||
|
return lx.errorf("expected key separator %q, but got %q instead",
|
||||||
|
keySep, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexValue starts the consumption of a value anywhere a value is expected.
|
||||||
|
// lexValue will ignore whitespace.
|
||||||
|
// After a value is lexed, the last state on the next is popped and returned.
|
||||||
|
func lexValue(lx *lexer) stateFn {
|
||||||
|
// We allow whitespace to precede a value, but NOT newlines.
|
||||||
|
// In array syntax, the array states are responsible for ignoring newlines.
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case isWhitespace(r):
|
||||||
|
return lexSkip(lx, lexValue)
|
||||||
|
case isDigit(r):
|
||||||
|
lx.backup() // avoid an extra state and use the same as above
|
||||||
|
return lexNumberOrDateStart
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case arrayStart:
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemArray)
|
||||||
|
return lexArrayValue
|
||||||
|
case inlineTableStart:
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemInlineTableStart)
|
||||||
|
return lexInlineTableValue
|
||||||
|
case stringStart:
|
||||||
|
if lx.accept(stringStart) {
|
||||||
|
if lx.accept(stringStart) {
|
||||||
|
lx.ignore() // Ignore """
|
||||||
|
return lexMultilineString
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
}
|
||||||
|
lx.ignore() // ignore the '"'
|
||||||
|
return lexString
|
||||||
|
case rawStringStart:
|
||||||
|
if lx.accept(rawStringStart) {
|
||||||
|
if lx.accept(rawStringStart) {
|
||||||
|
lx.ignore() // Ignore """
|
||||||
|
return lexMultilineRawString
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
}
|
||||||
|
lx.ignore() // ignore the "'"
|
||||||
|
return lexRawString
|
||||||
|
case '+', '-':
|
||||||
|
return lexNumberStart
|
||||||
|
case '.': // special error case, be kind to users
|
||||||
|
return lx.errorf("floats must start with a digit, not '.'")
|
||||||
|
}
|
||||||
|
if unicode.IsLetter(r) {
|
||||||
|
// Be permissive here; lexBool will give a nice error if the
|
||||||
|
// user wrote something like
|
||||||
|
// x = foo
|
||||||
|
// (i.e. not 'true' or 'false' but is something else word-like.)
|
||||||
|
lx.backup()
|
||||||
|
return lexBool
|
||||||
|
}
|
||||||
|
return lx.errorf("expected value but found %q instead", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexArrayValue consumes one value in an array. It assumes that '[' or ','
|
||||||
|
// have already been consumed. All whitespace and newlines are ignored.
|
||||||
|
func lexArrayValue(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case isWhitespace(r) || isNL(r):
|
||||||
|
return lexSkip(lx, lexArrayValue)
|
||||||
|
case r == commentStart:
|
||||||
|
lx.push(lexArrayValue)
|
||||||
|
return lexCommentStart
|
||||||
|
case r == comma:
|
||||||
|
return lx.errorf("unexpected comma")
|
||||||
|
case r == arrayEnd:
|
||||||
|
// NOTE(caleb): The spec isn't clear about whether you can have
|
||||||
|
// a trailing comma or not, so we'll allow it.
|
||||||
|
return lexArrayEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
lx.backup()
|
||||||
|
lx.push(lexArrayValueEnd)
|
||||||
|
return lexValue
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexArrayValueEnd consumes everything between the end of an array value and
|
||||||
|
// the next value (or the end of the array): it ignores whitespace and newlines
|
||||||
|
// and expects either a ',' or a ']'.
|
||||||
|
func lexArrayValueEnd(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case isWhitespace(r) || isNL(r):
|
||||||
|
return lexSkip(lx, lexArrayValueEnd)
|
||||||
|
case r == commentStart:
|
||||||
|
lx.push(lexArrayValueEnd)
|
||||||
|
return lexCommentStart
|
||||||
|
case r == comma:
|
||||||
|
lx.ignore()
|
||||||
|
return lexArrayValue // move on to the next value
|
||||||
|
case r == arrayEnd:
|
||||||
|
return lexArrayEnd
|
||||||
|
}
|
||||||
|
return lx.errorf(
|
||||||
|
"expected a comma or array terminator %q, but got %q instead",
|
||||||
|
arrayEnd, r,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexArrayEnd finishes the lexing of an array.
|
||||||
|
// It assumes that a ']' has just been consumed.
|
||||||
|
func lexArrayEnd(lx *lexer) stateFn {
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemArrayEnd)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexInlineTableValue consumes one key/value pair in an inline table.
|
||||||
|
// It assumes that '{' or ',' have already been consumed. Whitespace is ignored.
|
||||||
|
func lexInlineTableValue(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case isWhitespace(r):
|
||||||
|
return lexSkip(lx, lexInlineTableValue)
|
||||||
|
case isNL(r):
|
||||||
|
return lx.errorf("newlines not allowed within inline tables")
|
||||||
|
case r == commentStart:
|
||||||
|
lx.push(lexInlineTableValue)
|
||||||
|
return lexCommentStart
|
||||||
|
case r == comma:
|
||||||
|
return lx.errorf("unexpected comma")
|
||||||
|
case r == inlineTableEnd:
|
||||||
|
return lexInlineTableEnd
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
lx.push(lexInlineTableValueEnd)
|
||||||
|
return lexKeyStart
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexInlineTableValueEnd consumes everything between the end of an inline table
|
||||||
|
// key/value pair and the next pair (or the end of the table):
|
||||||
|
// it ignores whitespace and expects either a ',' or a '}'.
|
||||||
|
func lexInlineTableValueEnd(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case isWhitespace(r):
|
||||||
|
return lexSkip(lx, lexInlineTableValueEnd)
|
||||||
|
case isNL(r):
|
||||||
|
return lx.errorf("newlines not allowed within inline tables")
|
||||||
|
case r == commentStart:
|
||||||
|
lx.push(lexInlineTableValueEnd)
|
||||||
|
return lexCommentStart
|
||||||
|
case r == comma:
|
||||||
|
lx.ignore()
|
||||||
|
return lexInlineTableValue
|
||||||
|
case r == inlineTableEnd:
|
||||||
|
return lexInlineTableEnd
|
||||||
|
}
|
||||||
|
return lx.errorf("expected a comma or an inline table terminator %q, "+
|
||||||
|
"but got %q instead", inlineTableEnd, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexInlineTableEnd finishes the lexing of an inline table.
|
||||||
|
// It assumes that a '}' has just been consumed.
|
||||||
|
func lexInlineTableEnd(lx *lexer) stateFn {
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemInlineTableEnd)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexString consumes the inner contents of a string. It assumes that the
|
||||||
|
// beginning '"' has already been consumed and ignored.
|
||||||
|
func lexString(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case r == eof:
|
||||||
|
return lx.errorf("unexpected EOF")
|
||||||
|
case isNL(r):
|
||||||
|
return lx.errorf("strings cannot contain newlines")
|
||||||
|
case r == '\\':
|
||||||
|
lx.push(lexString)
|
||||||
|
return lexStringEscape
|
||||||
|
case r == stringEnd:
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemString)
|
||||||
|
lx.next()
|
||||||
|
lx.ignore()
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
return lexString
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexMultilineString consumes the inner contents of a string. It assumes that
|
||||||
|
// the beginning '"""' has already been consumed and ignored.
|
||||||
|
func lexMultilineString(lx *lexer) stateFn {
|
||||||
|
switch lx.next() {
|
||||||
|
case eof:
|
||||||
|
return lx.errorf("unexpected EOF")
|
||||||
|
case '\\':
|
||||||
|
return lexMultilineStringEscape
|
||||||
|
case stringEnd:
|
||||||
|
if lx.accept(stringEnd) {
|
||||||
|
if lx.accept(stringEnd) {
|
||||||
|
lx.backup()
|
||||||
|
lx.backup()
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemMultilineString)
|
||||||
|
lx.next()
|
||||||
|
lx.next()
|
||||||
|
lx.next()
|
||||||
|
lx.ignore()
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lexMultilineString
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexRawString consumes a raw string. Nothing can be escaped in such a string.
|
||||||
|
// It assumes that the beginning "'" has already been consumed and ignored.
|
||||||
|
func lexRawString(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch {
|
||||||
|
case r == eof:
|
||||||
|
return lx.errorf("unexpected EOF")
|
||||||
|
case isNL(r):
|
||||||
|
return lx.errorf("strings cannot contain newlines")
|
||||||
|
case r == rawStringEnd:
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemRawString)
|
||||||
|
lx.next()
|
||||||
|
lx.ignore()
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
return lexRawString
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexMultilineRawString consumes a raw string. Nothing can be escaped in such
|
||||||
|
// a string. It assumes that the beginning "'''" has already been consumed and
|
||||||
|
// ignored.
|
||||||
|
func lexMultilineRawString(lx *lexer) stateFn {
|
||||||
|
switch lx.next() {
|
||||||
|
case eof:
|
||||||
|
return lx.errorf("unexpected EOF")
|
||||||
|
case rawStringEnd:
|
||||||
|
if lx.accept(rawStringEnd) {
|
||||||
|
if lx.accept(rawStringEnd) {
|
||||||
|
lx.backup()
|
||||||
|
lx.backup()
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemRawMultilineString)
|
||||||
|
lx.next()
|
||||||
|
lx.next()
|
||||||
|
lx.next()
|
||||||
|
lx.ignore()
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lexMultilineRawString
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexMultilineStringEscape consumes an escaped character. It assumes that the
|
||||||
|
// preceding '\\' has already been consumed.
|
||||||
|
func lexMultilineStringEscape(lx *lexer) stateFn {
|
||||||
|
// Handle the special case first:
|
||||||
|
if isNL(lx.next()) {
|
||||||
|
return lexMultilineString
|
||||||
|
}
|
||||||
|
lx.backup()
|
||||||
|
lx.push(lexMultilineString)
|
||||||
|
return lexStringEscape(lx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func lexStringEscape(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
switch r {
|
||||||
|
case 'b':
|
||||||
|
fallthrough
|
||||||
|
case 't':
|
||||||
|
fallthrough
|
||||||
|
case 'n':
|
||||||
|
fallthrough
|
||||||
|
case 'f':
|
||||||
|
fallthrough
|
||||||
|
case 'r':
|
||||||
|
fallthrough
|
||||||
|
case '"':
|
||||||
|
fallthrough
|
||||||
|
case '\\':
|
||||||
|
return lx.pop()
|
||||||
|
case 'u':
|
||||||
|
return lexShortUnicodeEscape
|
||||||
|
case 'U':
|
||||||
|
return lexLongUnicodeEscape
|
||||||
|
}
|
||||||
|
return lx.errorf("invalid escape character %q; only the following "+
|
||||||
|
"escape characters are allowed: "+
|
||||||
|
`\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func lexShortUnicodeEscape(lx *lexer) stateFn {
|
||||||
|
var r rune
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
r = lx.next()
|
||||||
|
if !isHexadecimal(r) {
|
||||||
|
return lx.errorf(`expected four hexadecimal digits after '\u', `+
|
||||||
|
"but got %q instead", lx.current())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
func lexLongUnicodeEscape(lx *lexer) stateFn {
|
||||||
|
var r rune
|
||||||
|
for i := 0; i < 8; i++ {
|
||||||
|
r = lx.next()
|
||||||
|
if !isHexadecimal(r) {
|
||||||
|
return lx.errorf(`expected eight hexadecimal digits after '\U', `+
|
||||||
|
"but got %q instead", lx.current())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexNumberOrDateStart consumes either an integer, a float, or datetime.
|
||||||
|
func lexNumberOrDateStart(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
if isDigit(r) {
|
||||||
|
return lexNumberOrDate
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case '_':
|
||||||
|
return lexNumber
|
||||||
|
case 'e', 'E':
|
||||||
|
return lexFloat
|
||||||
|
case '.':
|
||||||
|
return lx.errorf("floats must start with a digit, not '.'")
|
||||||
|
}
|
||||||
|
return lx.errorf("expected a digit but got %q", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexNumberOrDate consumes either an integer, float or datetime.
|
||||||
|
func lexNumberOrDate(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
if isDigit(r) {
|
||||||
|
return lexNumberOrDate
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case '-':
|
||||||
|
return lexDatetime
|
||||||
|
case '_':
|
||||||
|
return lexNumber
|
||||||
|
case '.', 'e', 'E':
|
||||||
|
return lexFloat
|
||||||
|
}
|
||||||
|
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemInteger)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexDatetime consumes a Datetime, to a first approximation.
|
||||||
|
// The parser validates that it matches one of the accepted formats.
|
||||||
|
func lexDatetime(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
if isDigit(r) {
|
||||||
|
return lexDatetime
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case '-', 'T', ':', '.', 'Z', '+':
|
||||||
|
return lexDatetime
|
||||||
|
}
|
||||||
|
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemDatetime)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexNumberStart consumes either an integer or a float. It assumes that a sign
|
||||||
|
// has already been read, but that *no* digits have been consumed.
|
||||||
|
// lexNumberStart will move to the appropriate integer or float states.
|
||||||
|
func lexNumberStart(lx *lexer) stateFn {
|
||||||
|
// We MUST see a digit. Even floats have to start with a digit.
|
||||||
|
r := lx.next()
|
||||||
|
if !isDigit(r) {
|
||||||
|
if r == '.' {
|
||||||
|
return lx.errorf("floats must start with a digit, not '.'")
|
||||||
|
}
|
||||||
|
return lx.errorf("expected a digit but got %q", r)
|
||||||
|
}
|
||||||
|
return lexNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexNumber consumes an integer or a float after seeing the first digit.
|
||||||
|
func lexNumber(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
if isDigit(r) {
|
||||||
|
return lexNumber
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case '_':
|
||||||
|
return lexNumber
|
||||||
|
case '.', 'e', 'E':
|
||||||
|
return lexFloat
|
||||||
|
}
|
||||||
|
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemInteger)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexFloat consumes the elements of a float. It allows any sequence of
|
||||||
|
// float-like characters, so floats emitted by the lexer are only a first
|
||||||
|
// approximation and must be validated by the parser.
|
||||||
|
func lexFloat(lx *lexer) stateFn {
|
||||||
|
r := lx.next()
|
||||||
|
if isDigit(r) {
|
||||||
|
return lexFloat
|
||||||
|
}
|
||||||
|
switch r {
|
||||||
|
case '_', '.', '-', '+', 'e', 'E':
|
||||||
|
return lexFloat
|
||||||
|
}
|
||||||
|
|
||||||
|
lx.backup()
|
||||||
|
lx.emit(itemFloat)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexBool consumes a bool string: 'true' or 'false.
|
||||||
|
func lexBool(lx *lexer) stateFn {
|
||||||
|
var rs []rune
|
||||||
|
for {
|
||||||
|
r := lx.next()
|
||||||
|
if !unicode.IsLetter(r) {
|
||||||
|
lx.backup()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
rs = append(rs, r)
|
||||||
|
}
|
||||||
|
s := string(rs)
|
||||||
|
switch s {
|
||||||
|
case "true", "false":
|
||||||
|
lx.emit(itemBool)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
return lx.errorf("expected value but found %q instead", s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexCommentStart begins the lexing of a comment. It will emit
|
||||||
|
// itemCommentStart and consume no characters, passing control to lexComment.
|
||||||
|
func lexCommentStart(lx *lexer) stateFn {
|
||||||
|
lx.ignore()
|
||||||
|
lx.emit(itemCommentStart)
|
||||||
|
return lexComment
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexComment lexes an entire comment. It assumes that '#' has been consumed.
|
||||||
|
// It will consume *up to* the first newline character, and pass control
|
||||||
|
// back to the last state on the stack.
|
||||||
|
func lexComment(lx *lexer) stateFn {
|
||||||
|
r := lx.peek()
|
||||||
|
if isNL(r) || r == eof {
|
||||||
|
lx.emit(itemText)
|
||||||
|
return lx.pop()
|
||||||
|
}
|
||||||
|
lx.next()
|
||||||
|
return lexComment
|
||||||
|
}
|
||||||
|
|
||||||
|
// lexSkip ignores all slurped input and moves on to the next state.
|
||||||
|
func lexSkip(lx *lexer, nextState stateFn) stateFn {
|
||||||
|
return func(lx *lexer) stateFn {
|
||||||
|
lx.ignore()
|
||||||
|
return nextState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// isWhitespace returns true if `r` is a whitespace character according
|
||||||
|
// to the spec.
|
||||||
|
func isWhitespace(r rune) bool {
|
||||||
|
return r == '\t' || r == ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNL(r rune) bool {
|
||||||
|
return r == '\n' || r == '\r'
|
||||||
|
}
|
||||||
|
|
||||||
|
func isDigit(r rune) bool {
|
||||||
|
return r >= '0' && r <= '9'
|
||||||
|
}
|
||||||
|
|
||||||
|
func isHexadecimal(r rune) bool {
|
||||||
|
return (r >= '0' && r <= '9') ||
|
||||||
|
(r >= 'a' && r <= 'f') ||
|
||||||
|
(r >= 'A' && r <= 'F')
|
||||||
|
}
|
||||||
|
|
||||||
|
func isBareKeyChar(r rune) bool {
|
||||||
|
return (r >= 'A' && r <= 'Z') ||
|
||||||
|
(r >= 'a' && r <= 'z') ||
|
||||||
|
(r >= '0' && r <= '9') ||
|
||||||
|
r == '_' ||
|
||||||
|
r == '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
func (itype itemType) String() string {
|
||||||
|
switch itype {
|
||||||
|
case itemError:
|
||||||
|
return "Error"
|
||||||
|
case itemNIL:
|
||||||
|
return "NIL"
|
||||||
|
case itemEOF:
|
||||||
|
return "EOF"
|
||||||
|
case itemText:
|
||||||
|
return "Text"
|
||||||
|
case itemString, itemRawString, itemMultilineString, itemRawMultilineString:
|
||||||
|
return "String"
|
||||||
|
case itemBool:
|
||||||
|
return "Bool"
|
||||||
|
case itemInteger:
|
||||||
|
return "Integer"
|
||||||
|
case itemFloat:
|
||||||
|
return "Float"
|
||||||
|
case itemDatetime:
|
||||||
|
return "DateTime"
|
||||||
|
case itemTableStart:
|
||||||
|
return "TableStart"
|
||||||
|
case itemTableEnd:
|
||||||
|
return "TableEnd"
|
||||||
|
case itemKeyStart:
|
||||||
|
return "KeyStart"
|
||||||
|
case itemArray:
|
||||||
|
return "Array"
|
||||||
|
case itemArrayEnd:
|
||||||
|
return "ArrayEnd"
|
||||||
|
case itemCommentStart:
|
||||||
|
return "CommentStart"
|
||||||
|
}
|
||||||
|
panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (item item) String() string {
|
||||||
|
return fmt.Sprintf("(%s, %s)", item.typ.String(), item.val)
|
||||||
|
}
|
592
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
Normal file
592
vendor/github.com/BurntSushi/toml/parse.go
generated
vendored
Normal file
@ -0,0 +1,592 @@
|
|||||||
|
package toml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"unicode"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
type parser struct {
|
||||||
|
mapping map[string]interface{}
|
||||||
|
types map[string]tomlType
|
||||||
|
lx *lexer
|
||||||
|
|
||||||
|
// A list of keys in the order that they appear in the TOML data.
|
||||||
|
ordered []Key
|
||||||
|
|
||||||
|
// the full key for the current hash in scope
|
||||||
|
context Key
|
||||||
|
|
||||||
|
// the base key name for everything except hashes
|
||||||
|
currentKey string
|
||||||
|
|
||||||
|
// rough approximation of line number
|
||||||
|
approxLine int
|
||||||
|
|
||||||
|
// A map of 'key.group.names' to whether they were created implicitly.
|
||||||
|
implicits map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type parseError string
|
||||||
|
|
||||||
|
func (pe parseError) Error() string {
|
||||||
|
return string(pe)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse(data string) (p *parser, err error) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
var ok bool
|
||||||
|
if err, ok = r.(parseError); ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
p = &parser{
|
||||||
|
mapping: make(map[string]interface{}),
|
||||||
|
types: make(map[string]tomlType),
|
||||||
|
lx: lex(data),
|
||||||
|
ordered: make([]Key, 0),
|
||||||
|
implicits: make(map[string]bool),
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
item := p.next()
|
||||||
|
if item.typ == itemEOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
p.topLevel(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) panicf(format string, v ...interface{}) {
|
||||||
|
msg := fmt.Sprintf("Near line %d (last key parsed '%s'): %s",
|
||||||
|
p.approxLine, p.current(), fmt.Sprintf(format, v...))
|
||||||
|
panic(parseError(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) next() item {
|
||||||
|
it := p.lx.nextItem()
|
||||||
|
if it.typ == itemError {
|
||||||
|
p.panicf("%s", it.val)
|
||||||
|
}
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) bug(format string, v ...interface{}) {
|
||||||
|
panic(fmt.Sprintf("BUG: "+format+"\n\n", v...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) expect(typ itemType) item {
|
||||||
|
it := p.next()
|
||||||
|
p.assertEqual(typ, it.typ)
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) assertEqual(expected, got itemType) {
|
||||||
|
if expected != got {
|
||||||
|
p.bug("Expected '%s' but got '%s'.", expected, got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) topLevel(item item) {
|
||||||
|
switch item.typ {
|
||||||
|
case itemCommentStart:
|
||||||
|
p.approxLine = item.line
|
||||||
|
p.expect(itemText)
|
||||||
|
case itemTableStart:
|
||||||
|
kg := p.next()
|
||||||
|
p.approxLine = kg.line
|
||||||
|
|
||||||
|
var key Key
|
||||||
|
for ; kg.typ != itemTableEnd && kg.typ != itemEOF; kg = p.next() {
|
||||||
|
key = append(key, p.keyString(kg))
|
||||||
|
}
|
||||||
|
p.assertEqual(itemTableEnd, kg.typ)
|
||||||
|
|
||||||
|
p.establishContext(key, false)
|
||||||
|
p.setType("", tomlHash)
|
||||||
|
p.ordered = append(p.ordered, key)
|
||||||
|
case itemArrayTableStart:
|
||||||
|
kg := p.next()
|
||||||
|
p.approxLine = kg.line
|
||||||
|
|
||||||
|
var key Key
|
||||||
|
for ; kg.typ != itemArrayTableEnd && kg.typ != itemEOF; kg = p.next() {
|
||||||
|
key = append(key, p.keyString(kg))
|
||||||
|
}
|
||||||
|
p.assertEqual(itemArrayTableEnd, kg.typ)
|
||||||
|
|
||||||
|
p.establishContext(key, true)
|
||||||
|
p.setType("", tomlArrayHash)
|
||||||
|
p.ordered = append(p.ordered, key)
|
||||||
|
case itemKeyStart:
|
||||||
|
kname := p.next()
|
||||||
|
p.approxLine = kname.line
|
||||||
|
p.currentKey = p.keyString(kname)
|
||||||
|
|
||||||
|
val, typ := p.value(p.next())
|
||||||
|
p.setValue(p.currentKey, val)
|
||||||
|
p.setType(p.currentKey, typ)
|
||||||
|
p.ordered = append(p.ordered, p.context.add(p.currentKey))
|
||||||
|
p.currentKey = ""
|
||||||
|
default:
|
||||||
|
p.bug("Unexpected type at top level: %s", item.typ)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a string for a key (or part of a key in a table name).
|
||||||
|
func (p *parser) keyString(it item) string {
|
||||||
|
switch it.typ {
|
||||||
|
case itemText:
|
||||||
|
return it.val
|
||||||
|
case itemString, itemMultilineString,
|
||||||
|
itemRawString, itemRawMultilineString:
|
||||||
|
s, _ := p.value(it)
|
||||||
|
return s.(string)
|
||||||
|
default:
|
||||||
|
p.bug("Unexpected key type: %s", it.typ)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// value translates an expected value from the lexer into a Go value wrapped
|
||||||
|
// as an empty interface.
|
||||||
|
func (p *parser) value(it item) (interface{}, tomlType) {
|
||||||
|
switch it.typ {
|
||||||
|
case itemString:
|
||||||
|
return p.replaceEscapes(it.val), p.typeOfPrimitive(it)
|
||||||
|
case itemMultilineString:
|
||||||
|
trimmed := stripFirstNewline(stripEscapedWhitespace(it.val))
|
||||||
|
return p.replaceEscapes(trimmed), p.typeOfPrimitive(it)
|
||||||
|
case itemRawString:
|
||||||
|
return it.val, p.typeOfPrimitive(it)
|
||||||
|
case itemRawMultilineString:
|
||||||
|
return stripFirstNewline(it.val), p.typeOfPrimitive(it)
|
||||||
|
case itemBool:
|
||||||
|
switch it.val {
|
||||||
|
case "true":
|
||||||
|
return true, p.typeOfPrimitive(it)
|
||||||
|
case "false":
|
||||||
|
return false, p.typeOfPrimitive(it)
|
||||||
|
}
|
||||||
|
p.bug("Expected boolean value, but got '%s'.", it.val)
|
||||||
|
case itemInteger:
|
||||||
|
if !numUnderscoresOK(it.val) {
|
||||||
|
p.panicf("Invalid integer %q: underscores must be surrounded by digits",
|
||||||
|
it.val)
|
||||||
|
}
|
||||||
|
val := strings.Replace(it.val, "_", "", -1)
|
||||||
|
num, err := strconv.ParseInt(val, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
// Distinguish integer values. Normally, it'd be a bug if the lexer
|
||||||
|
// provides an invalid integer, but it's possible that the number is
|
||||||
|
// out of range of valid values (which the lexer cannot determine).
|
||||||
|
// So mark the former as a bug but the latter as a legitimate user
|
||||||
|
// error.
|
||||||
|
if e, ok := err.(*strconv.NumError); ok &&
|
||||||
|
e.Err == strconv.ErrRange {
|
||||||
|
|
||||||
|
p.panicf("Integer '%s' is out of the range of 64-bit "+
|
||||||
|
"signed integers.", it.val)
|
||||||
|
} else {
|
||||||
|
p.bug("Expected integer value, but got '%s'.", it.val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num, p.typeOfPrimitive(it)
|
||||||
|
case itemFloat:
|
||||||
|
parts := strings.FieldsFunc(it.val, func(r rune) bool {
|
||||||
|
switch r {
|
||||||
|
case '.', 'e', 'E':
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
for _, part := range parts {
|
||||||
|
if !numUnderscoresOK(part) {
|
||||||
|
p.panicf("Invalid float %q: underscores must be "+
|
||||||
|
"surrounded by digits", it.val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !numPeriodsOK(it.val) {
|
||||||
|
// As a special case, numbers like '123.' or '1.e2',
|
||||||
|
// which are valid as far as Go/strconv are concerned,
|
||||||
|
// must be rejected because TOML says that a fractional
|
||||||
|
// part consists of '.' followed by 1+ digits.
|
||||||
|
p.panicf("Invalid float %q: '.' must be followed "+
|
||||||
|
"by one or more digits", it.val)
|
||||||
|
}
|
||||||
|
val := strings.Replace(it.val, "_", "", -1)
|
||||||
|
num, err := strconv.ParseFloat(val, 64)
|
||||||
|
if err != nil {
|
||||||
|
if e, ok := err.(*strconv.NumError); ok &&
|
||||||
|
e.Err == strconv.ErrRange {
|
||||||
|
|
||||||
|
p.panicf("Float '%s' is out of the range of 64-bit "+
|
||||||
|
"IEEE-754 floating-point numbers.", it.val)
|
||||||
|
} else {
|
||||||
|
p.panicf("Invalid float value: %q", it.val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num, p.typeOfPrimitive(it)
|
||||||
|
case itemDatetime:
|
||||||
|
var t time.Time
|
||||||
|
var ok bool
|
||||||
|
var err error
|
||||||
|
for _, format := range []string{
|
||||||
|
"2006-01-02T15:04:05Z07:00",
|
||||||
|
"2006-01-02T15:04:05",
|
||||||
|
"2006-01-02",
|
||||||
|
} {
|
||||||
|
t, err = time.ParseInLocation(format, it.val, time.Local)
|
||||||
|
if err == nil {
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
p.panicf("Invalid TOML Datetime: %q.", it.val)
|
||||||
|
}
|
||||||
|
return t, p.typeOfPrimitive(it)
|
||||||
|
case itemArray:
|
||||||
|
array := make([]interface{}, 0)
|
||||||
|
types := make([]tomlType, 0)
|
||||||
|
|
||||||
|
for it = p.next(); it.typ != itemArrayEnd; it = p.next() {
|
||||||
|
if it.typ == itemCommentStart {
|
||||||
|
p.expect(itemText)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val, typ := p.value(it)
|
||||||
|
array = append(array, val)
|
||||||
|
types = append(types, typ)
|
||||||
|
}
|
||||||
|
return array, p.typeOfArray(types)
|
||||||
|
case itemInlineTableStart:
|
||||||
|
var (
|
||||||
|
hash = make(map[string]interface{})
|
||||||
|
outerContext = p.context
|
||||||
|
outerKey = p.currentKey
|
||||||
|
)
|
||||||
|
|
||||||
|
p.context = append(p.context, p.currentKey)
|
||||||
|
p.currentKey = ""
|
||||||
|
for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() {
|
||||||
|
if it.typ != itemKeyStart {
|
||||||
|
p.bug("Expected key start but instead found %q, around line %d",
|
||||||
|
it.val, p.approxLine)
|
||||||
|
}
|
||||||
|
if it.typ == itemCommentStart {
|
||||||
|
p.expect(itemText)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve key
|
||||||
|
k := p.next()
|
||||||
|
p.approxLine = k.line
|
||||||
|
kname := p.keyString(k)
|
||||||
|
|
||||||
|
// retrieve value
|
||||||
|
p.currentKey = kname
|
||||||
|
val, typ := p.value(p.next())
|
||||||
|
// make sure we keep metadata up to date
|
||||||
|
p.setType(kname, typ)
|
||||||
|
p.ordered = append(p.ordered, p.context.add(p.currentKey))
|
||||||
|
hash[kname] = val
|
||||||
|
}
|
||||||
|
p.context = outerContext
|
||||||
|
p.currentKey = outerKey
|
||||||
|
return hash, tomlHash
|
||||||
|
}
|
||||||
|
p.bug("Unexpected value type: %s", it.typ)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// numUnderscoresOK checks whether each underscore in s is surrounded by
|
||||||
|
// characters that are not underscores.
|
||||||
|
func numUnderscoresOK(s string) bool {
|
||||||
|
accept := false
|
||||||
|
for _, r := range s {
|
||||||
|
if r == '_' {
|
||||||
|
if !accept {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
accept = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
accept = true
|
||||||
|
}
|
||||||
|
return accept
|
||||||
|
}
|
||||||
|
|
||||||
|
// numPeriodsOK checks whether every period in s is followed by a digit.
|
||||||
|
func numPeriodsOK(s string) bool {
|
||||||
|
period := false
|
||||||
|
for _, r := range s {
|
||||||
|
if period && !isDigit(r) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
period = r == '.'
|
||||||
|
}
|
||||||
|
return !period
|
||||||
|
}
|
||||||
|
|
||||||
|
// establishContext sets the current context of the parser,
|
||||||
|
// where the context is either a hash or an array of hashes. Which one is
|
||||||
|
// set depends on the value of the `array` parameter.
|
||||||
|
//
|
||||||
|
// Establishing the context also makes sure that the key isn't a duplicate, and
|
||||||
|
// will create implicit hashes automatically.
|
||||||
|
func (p *parser) establishContext(key Key, array bool) {
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
// Always start at the top level and drill down for our context.
|
||||||
|
hashContext := p.mapping
|
||||||
|
keyContext := make(Key, 0)
|
||||||
|
|
||||||
|
// We only need implicit hashes for key[0:-1]
|
||||||
|
for _, k := range key[0 : len(key)-1] {
|
||||||
|
_, ok = hashContext[k]
|
||||||
|
keyContext = append(keyContext, k)
|
||||||
|
|
||||||
|
// No key? Make an implicit hash and move on.
|
||||||
|
if !ok {
|
||||||
|
p.addImplicit(keyContext)
|
||||||
|
hashContext[k] = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the hash context is actually an array of tables, then set
|
||||||
|
// the hash context to the last element in that array.
|
||||||
|
//
|
||||||
|
// Otherwise, it better be a table, since this MUST be a key group (by
|
||||||
|
// virtue of it not being the last element in a key).
|
||||||
|
switch t := hashContext[k].(type) {
|
||||||
|
case []map[string]interface{}:
|
||||||
|
hashContext = t[len(t)-1]
|
||||||
|
case map[string]interface{}:
|
||||||
|
hashContext = t
|
||||||
|
default:
|
||||||
|
p.panicf("Key '%s' was already created as a hash.", keyContext)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p.context = keyContext
|
||||||
|
if array {
|
||||||
|
// If this is the first element for this array, then allocate a new
|
||||||
|
// list of tables for it.
|
||||||
|
k := key[len(key)-1]
|
||||||
|
if _, ok := hashContext[k]; !ok {
|
||||||
|
hashContext[k] = make([]map[string]interface{}, 0, 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a new table. But make sure the key hasn't already been used
|
||||||
|
// for something else.
|
||||||
|
if hash, ok := hashContext[k].([]map[string]interface{}); ok {
|
||||||
|
hashContext[k] = append(hash, make(map[string]interface{}))
|
||||||
|
} else {
|
||||||
|
p.panicf("Key '%s' was already created and cannot be used as "+
|
||||||
|
"an array.", keyContext)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.setValue(key[len(key)-1], make(map[string]interface{}))
|
||||||
|
}
|
||||||
|
p.context = append(p.context, key[len(key)-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// setValue sets the given key to the given value in the current context.
|
||||||
|
// It will make sure that the key hasn't already been defined, account for
|
||||||
|
// implicit key groups.
|
||||||
|
func (p *parser) setValue(key string, value interface{}) {
|
||||||
|
var tmpHash interface{}
|
||||||
|
var ok bool
|
||||||
|
|
||||||
|
hash := p.mapping
|
||||||
|
keyContext := make(Key, 0)
|
||||||
|
for _, k := range p.context {
|
||||||
|
keyContext = append(keyContext, k)
|
||||||
|
if tmpHash, ok = hash[k]; !ok {
|
||||||
|
p.bug("Context for key '%s' has not been established.", keyContext)
|
||||||
|
}
|
||||||
|
switch t := tmpHash.(type) {
|
||||||
|
case []map[string]interface{}:
|
||||||
|
// The context is a table of hashes. Pick the most recent table
|
||||||
|
// defined as the current hash.
|
||||||
|
hash = t[len(t)-1]
|
||||||
|
case map[string]interface{}:
|
||||||
|
hash = t
|
||||||
|
default:
|
||||||
|
p.bug("Expected hash to have type 'map[string]interface{}', but "+
|
||||||
|
"it has '%T' instead.", tmpHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyContext = append(keyContext, key)
|
||||||
|
|
||||||
|
if _, ok := hash[key]; ok {
|
||||||
|
// Typically, if the given key has already been set, then we have
|
||||||
|
// to raise an error since duplicate keys are disallowed. However,
|
||||||
|
// it's possible that a key was previously defined implicitly. In this
|
||||||
|
// case, it is allowed to be redefined concretely. (See the
|
||||||
|
// `tests/valid/implicit-and-explicit-after.toml` test in `toml-test`.)
|
||||||
|
//
|
||||||
|
// But we have to make sure to stop marking it as an implicit. (So that
|
||||||
|
// another redefinition provokes an error.)
|
||||||
|
//
|
||||||
|
// Note that since it has already been defined (as a hash), we don't
|
||||||
|
// want to overwrite it. So our business is done.
|
||||||
|
if p.isImplicit(keyContext) {
|
||||||
|
p.removeImplicit(keyContext)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we have a concrete key trying to override a previous
|
||||||
|
// key, which is *always* wrong.
|
||||||
|
p.panicf("Key '%s' has already been defined.", keyContext)
|
||||||
|
}
|
||||||
|
hash[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
// setType sets the type of a particular value at a given key.
|
||||||
|
// It should be called immediately AFTER setValue.
|
||||||
|
//
|
||||||
|
// Note that if `key` is empty, then the type given will be applied to the
|
||||||
|
// current context (which is either a table or an array of tables).
|
||||||
|
func (p *parser) setType(key string, typ tomlType) {
|
||||||
|
keyContext := make(Key, 0, len(p.context)+1)
|
||||||
|
for _, k := range p.context {
|
||||||
|
keyContext = append(keyContext, k)
|
||||||
|
}
|
||||||
|
if len(key) > 0 { // allow type setting for hashes
|
||||||
|
keyContext = append(keyContext, key)
|
||||||
|
}
|
||||||
|
p.types[keyContext.String()] = typ
|
||||||
|
}
|
||||||
|
|
||||||
|
// addImplicit sets the given Key as having been created implicitly.
|
||||||
|
func (p *parser) addImplicit(key Key) {
|
||||||
|
p.implicits[key.String()] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeImplicit stops tagging the given key as having been implicitly
|
||||||
|
// created.
|
||||||
|
func (p *parser) removeImplicit(key Key) {
|
||||||
|
p.implicits[key.String()] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isImplicit returns true if the key group pointed to by the key was created
|
||||||
|
// implicitly.
|
||||||
|
func (p *parser) isImplicit(key Key) bool {
|
||||||
|
return p.implicits[key.String()]
|
||||||
|
}
|
||||||
|
|
||||||
|
// current returns the full key name of the current context.
|
||||||
|
func (p *parser) current() string {
|
||||||
|
if len(p.currentKey) == 0 {
|
||||||
|
return p.context.String()
|
||||||
|
}
|
||||||
|
if len(p.context) == 0 {
|
||||||
|
return p.currentKey
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s.%s", p.context, p.currentKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stripFirstNewline(s string) string {
|
||||||
|
if len(s) == 0 || s[0] != '\n' {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return s[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func stripEscapedWhitespace(s string) string {
|
||||||
|
esc := strings.Split(s, "\\\n")
|
||||||
|
if len(esc) > 1 {
|
||||||
|
for i := 1; i < len(esc); i++ {
|
||||||
|
esc[i] = strings.TrimLeftFunc(esc[i], unicode.IsSpace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(esc, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) replaceEscapes(str string) string {
|
||||||
|
var replaced []rune
|
||||||
|
s := []byte(str)
|
||||||
|
r := 0
|
||||||
|
for r < len(s) {
|
||||||
|
if s[r] != '\\' {
|
||||||
|
c, size := utf8.DecodeRune(s[r:])
|
||||||
|
r += size
|
||||||
|
replaced = append(replaced, c)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r += 1
|
||||||
|
if r >= len(s) {
|
||||||
|
p.bug("Escape sequence at end of string.")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
switch s[r] {
|
||||||
|
default:
|
||||||
|
p.bug("Expected valid escape code after \\, but got %q.", s[r])
|
||||||
|
return ""
|
||||||
|
case 'b':
|
||||||
|
replaced = append(replaced, rune(0x0008))
|
||||||
|
r += 1
|
||||||
|
case 't':
|
||||||
|
replaced = append(replaced, rune(0x0009))
|
||||||
|
r += 1
|
||||||
|
case 'n':
|
||||||
|
replaced = append(replaced, rune(0x000A))
|
||||||
|
r += 1
|
||||||
|
case 'f':
|
||||||
|
replaced = append(replaced, rune(0x000C))
|
||||||
|
r += 1
|
||||||
|
case 'r':
|
||||||
|
replaced = append(replaced, rune(0x000D))
|
||||||
|
r += 1
|
||||||
|
case '"':
|
||||||
|
replaced = append(replaced, rune(0x0022))
|
||||||
|
r += 1
|
||||||
|
case '\\':
|
||||||
|
replaced = append(replaced, rune(0x005C))
|
||||||
|
r += 1
|
||||||
|
case 'u':
|
||||||
|
// At this point, we know we have a Unicode escape of the form
|
||||||
|
// `uXXXX` at [r, r+5). (Because the lexer guarantees this
|
||||||
|
// for us.)
|
||||||
|
escaped := p.asciiEscapeToUnicode(s[r+1 : r+5])
|
||||||
|
replaced = append(replaced, escaped)
|
||||||
|
r += 5
|
||||||
|
case 'U':
|
||||||
|
// At this point, we know we have a Unicode escape of the form
|
||||||
|
// `uXXXX` at [r, r+9). (Because the lexer guarantees this
|
||||||
|
// for us.)
|
||||||
|
escaped := p.asciiEscapeToUnicode(s[r+1 : r+9])
|
||||||
|
replaced = append(replaced, escaped)
|
||||||
|
r += 9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(replaced)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *parser) asciiEscapeToUnicode(bs []byte) rune {
|
||||||
|
s := string(bs)
|
||||||
|
hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
p.bug("Could not parse '%s' as a hexadecimal number, but the "+
|
||||||
|
"lexer claims it's OK: %s", s, err)
|
||||||
|
}
|
||||||
|
if !utf8.ValidRune(rune(hex)) {
|
||||||
|
p.panicf("Escaped character '\\u%s' is not valid UTF-8.", s)
|
||||||
|
}
|
||||||
|
return rune(hex)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isStringType(ty itemType) bool {
|
||||||
|
return ty == itemString || ty == itemMultilineString ||
|
||||||
|
ty == itemRawString || ty == itemRawMultilineString
|
||||||
|
}
|
1
vendor/github.com/BurntSushi/toml/session.vim
generated
vendored
Normal file
1
vendor/github.com/BurntSushi/toml/session.vim
generated
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
au BufWritePost *.go silent!make tags > /dev/null 2>&1
|
91
vendor/github.com/BurntSushi/toml/type_check.go
generated
vendored
Normal file
91
vendor/github.com/BurntSushi/toml/type_check.go
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package toml
|
||||||
|
|
||||||
|
// tomlType represents any Go type that corresponds to a TOML type.
|
||||||
|
// While the first draft of the TOML spec has a simplistic type system that
|
||||||
|
// probably doesn't need this level of sophistication, we seem to be militating
|
||||||
|
// toward adding real composite types.
|
||||||
|
type tomlType interface {
|
||||||
|
typeString() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// typeEqual accepts any two types and returns true if they are equal.
|
||||||
|
func typeEqual(t1, t2 tomlType) bool {
|
||||||
|
if t1 == nil || t2 == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return t1.typeString() == t2.typeString()
|
||||||
|
}
|
||||||
|
|
||||||
|
func typeIsHash(t tomlType) bool {
|
||||||
|
return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
type tomlBaseType string
|
||||||
|
|
||||||
|
func (btype tomlBaseType) typeString() string {
|
||||||
|
return string(btype)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (btype tomlBaseType) String() string {
|
||||||
|
return btype.typeString()
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
tomlInteger tomlBaseType = "Integer"
|
||||||
|
tomlFloat tomlBaseType = "Float"
|
||||||
|
tomlDatetime tomlBaseType = "Datetime"
|
||||||
|
tomlString tomlBaseType = "String"
|
||||||
|
tomlBool tomlBaseType = "Bool"
|
||||||
|
tomlArray tomlBaseType = "Array"
|
||||||
|
tomlHash tomlBaseType = "Hash"
|
||||||
|
tomlArrayHash tomlBaseType = "ArrayHash"
|
||||||
|
)
|
||||||
|
|
||||||
|
// typeOfPrimitive returns a tomlType of any primitive value in TOML.
|
||||||
|
// Primitive values are: Integer, Float, Datetime, String and Bool.
|
||||||
|
//
|
||||||
|
// Passing a lexer item other than the following will cause a BUG message
|
||||||
|
// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime.
|
||||||
|
func (p *parser) typeOfPrimitive(lexItem item) tomlType {
|
||||||
|
switch lexItem.typ {
|
||||||
|
case itemInteger:
|
||||||
|
return tomlInteger
|
||||||
|
case itemFloat:
|
||||||
|
return tomlFloat
|
||||||
|
case itemDatetime:
|
||||||
|
return tomlDatetime
|
||||||
|
case itemString:
|
||||||
|
return tomlString
|
||||||
|
case itemMultilineString:
|
||||||
|
return tomlString
|
||||||
|
case itemRawString:
|
||||||
|
return tomlString
|
||||||
|
case itemRawMultilineString:
|
||||||
|
return tomlString
|
||||||
|
case itemBool:
|
||||||
|
return tomlBool
|
||||||
|
}
|
||||||
|
p.bug("Cannot infer primitive type of lex item '%s'.", lexItem)
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
// typeOfArray returns a tomlType for an array given a list of types of its
|
||||||
|
// values.
|
||||||
|
//
|
||||||
|
// In the current spec, if an array is homogeneous, then its type is always
|
||||||
|
// "Array". If the array is not homogeneous, an error is generated.
|
||||||
|
func (p *parser) typeOfArray(types []tomlType) tomlType {
|
||||||
|
// Empty arrays are cool.
|
||||||
|
if len(types) == 0 {
|
||||||
|
return tomlArray
|
||||||
|
}
|
||||||
|
|
||||||
|
theType := types[0]
|
||||||
|
for _, t := range types[1:] {
|
||||||
|
if !typeEqual(theType, t) {
|
||||||
|
p.panicf("Array contains values of type '%s' and '%s', but "+
|
||||||
|
"arrays must be homogeneous.", theType, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tomlArray
|
||||||
|
}
|
242
vendor/github.com/BurntSushi/toml/type_fields.go
generated
vendored
Normal file
242
vendor/github.com/BurntSushi/toml/type_fields.go
generated
vendored
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
package toml
|
||||||
|
|
||||||
|
// Struct field handling is adapted from code in encoding/json:
|
||||||
|
//
|
||||||
|
// Copyright 2010 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the Go distribution.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A field represents a single field found in a struct.
|
||||||
|
type field struct {
|
||||||
|
name string // the name of the field (`toml` tag included)
|
||||||
|
tag bool // whether field has a `toml` tag
|
||||||
|
index []int // represents the depth of an anonymous field
|
||||||
|
typ reflect.Type // the type of the field
|
||||||
|
}
|
||||||
|
|
||||||
|
// byName sorts field by name, breaking ties with depth,
|
||||||
|
// then breaking ties with "name came from toml tag", then
|
||||||
|
// breaking ties with index sequence.
|
||||||
|
type byName []field
|
||||||
|
|
||||||
|
func (x byName) Len() int { return len(x) }
|
||||||
|
|
||||||
|
func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
func (x byName) Less(i, j int) bool {
|
||||||
|
if x[i].name != x[j].name {
|
||||||
|
return x[i].name < x[j].name
|
||||||
|
}
|
||||||
|
if len(x[i].index) != len(x[j].index) {
|
||||||
|
return len(x[i].index) < len(x[j].index)
|
||||||
|
}
|
||||||
|
if x[i].tag != x[j].tag {
|
||||||
|
return x[i].tag
|
||||||
|
}
|
||||||
|
return byIndex(x).Less(i, j)
|
||||||
|
}
|
||||||
|
|
||||||
|
// byIndex sorts field by index sequence.
|
||||||
|
type byIndex []field
|
||||||
|
|
||||||
|
func (x byIndex) Len() int { return len(x) }
|
||||||
|
|
||||||
|
func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
|
func (x byIndex) Less(i, j int) bool {
|
||||||
|
for k, xik := range x[i].index {
|
||||||
|
if k >= len(x[j].index) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if xik != x[j].index[k] {
|
||||||
|
return xik < x[j].index[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(x[i].index) < len(x[j].index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// typeFields returns a list of fields that TOML should recognize for the given
|
||||||
|
// type. The algorithm is breadth-first search over the set of structs to
|
||||||
|
// include - the top struct and then any reachable anonymous structs.
|
||||||
|
func typeFields(t reflect.Type) []field {
|
||||||
|
// Anonymous fields to explore at the current level and the next.
|
||||||
|
current := []field{}
|
||||||
|
next := []field{{typ: t}}
|
||||||
|
|
||||||
|
// Count of queued names for current level and the next.
|
||||||
|
count := map[reflect.Type]int{}
|
||||||
|
nextCount := map[reflect.Type]int{}
|
||||||
|
|
||||||
|
// Types already visited at an earlier level.
|
||||||
|
visited := map[reflect.Type]bool{}
|
||||||
|
|
||||||
|
// Fields found.
|
||||||
|
var fields []field
|
||||||
|
|
||||||
|
for len(next) > 0 {
|
||||||
|
current, next = next, current[:0]
|
||||||
|
count, nextCount = nextCount, map[reflect.Type]int{}
|
||||||
|
|
||||||
|
for _, f := range current {
|
||||||
|
if visited[f.typ] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
visited[f.typ] = true
|
||||||
|
|
||||||
|
// Scan f.typ for fields to include.
|
||||||
|
for i := 0; i < f.typ.NumField(); i++ {
|
||||||
|
sf := f.typ.Field(i)
|
||||||
|
if sf.PkgPath != "" && !sf.Anonymous { // unexported
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
opts := getOptions(sf.Tag)
|
||||||
|
if opts.skip {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
index := make([]int, len(f.index)+1)
|
||||||
|
copy(index, f.index)
|
||||||
|
index[len(f.index)] = i
|
||||||
|
|
||||||
|
ft := sf.Type
|
||||||
|
if ft.Name() == "" && ft.Kind() == reflect.Ptr {
|
||||||
|
// Follow pointer.
|
||||||
|
ft = ft.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record found field and index sequence.
|
||||||
|
if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
|
||||||
|
tagged := opts.name != ""
|
||||||
|
name := opts.name
|
||||||
|
if name == "" {
|
||||||
|
name = sf.Name
|
||||||
|
}
|
||||||
|
fields = append(fields, field{name, tagged, index, ft})
|
||||||
|
if count[f.typ] > 1 {
|
||||||
|
// If there were multiple instances, add a second,
|
||||||
|
// so that the annihilation code will see a duplicate.
|
||||||
|
// It only cares about the distinction between 1 or 2,
|
||||||
|
// so don't bother generating any more copies.
|
||||||
|
fields = append(fields, fields[len(fields)-1])
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record new anonymous struct to explore in next round.
|
||||||
|
nextCount[ft]++
|
||||||
|
if nextCount[ft] == 1 {
|
||||||
|
f := field{name: ft.Name(), index: index, typ: ft}
|
||||||
|
next = append(next, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(byName(fields))
|
||||||
|
|
||||||
|
// Delete all fields that are hidden by the Go rules for embedded fields,
|
||||||
|
// except that fields with TOML tags are promoted.
|
||||||
|
|
||||||
|
// The fields are sorted in primary order of name, secondary order
|
||||||
|
// of field index length. Loop over names; for each name, delete
|
||||||
|
// hidden fields by choosing the one dominant field that survives.
|
||||||
|
out := fields[:0]
|
||||||
|
for advance, i := 0, 0; i < len(fields); i += advance {
|
||||||
|
// One iteration per name.
|
||||||
|
// Find the sequence of fields with the name of this first field.
|
||||||
|
fi := fields[i]
|
||||||
|
name := fi.name
|
||||||
|
for advance = 1; i+advance < len(fields); advance++ {
|
||||||
|
fj := fields[i+advance]
|
||||||
|
if fj.name != name {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if advance == 1 { // Only one field with this name
|
||||||
|
out = append(out, fi)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dominant, ok := dominantField(fields[i : i+advance])
|
||||||
|
if ok {
|
||||||
|
out = append(out, dominant)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fields = out
|
||||||
|
sort.Sort(byIndex(fields))
|
||||||
|
|
||||||
|
return fields
|
||||||
|
}
|
||||||
|
|
||||||
|
// dominantField looks through the fields, all of which are known to
|
||||||
|
// have the same name, to find the single field that dominates the
|
||||||
|
// others using Go's embedding rules, modified by the presence of
|
||||||
|
// TOML tags. If there are multiple top-level fields, the boolean
|
||||||
|
// will be false: This condition is an error in Go and we skip all
|
||||||
|
// the fields.
|
||||||
|
func dominantField(fields []field) (field, bool) {
|
||||||
|
// The fields are sorted in increasing index-length order. The winner
|
||||||
|
// must therefore be one with the shortest index length. Drop all
|
||||||
|
// longer entries, which is easy: just truncate the slice.
|
||||||
|
length := len(fields[0].index)
|
||||||
|
tagged := -1 // Index of first tagged field.
|
||||||
|
for i, f := range fields {
|
||||||
|
if len(f.index) > length {
|
||||||
|
fields = fields[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if f.tag {
|
||||||
|
if tagged >= 0 {
|
||||||
|
// Multiple tagged fields at the same level: conflict.
|
||||||
|
// Return no field.
|
||||||
|
return field{}, false
|
||||||
|
}
|
||||||
|
tagged = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tagged >= 0 {
|
||||||
|
return fields[tagged], true
|
||||||
|
}
|
||||||
|
// All remaining fields have the same length. If there's more than one,
|
||||||
|
// we have a conflict (two fields named "X" at the same level) and we
|
||||||
|
// return no field.
|
||||||
|
if len(fields) > 1 {
|
||||||
|
return field{}, false
|
||||||
|
}
|
||||||
|
return fields[0], true
|
||||||
|
}
|
||||||
|
|
||||||
|
var fieldCache struct {
|
||||||
|
sync.RWMutex
|
||||||
|
m map[reflect.Type][]field
|
||||||
|
}
|
||||||
|
|
||||||
|
// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
|
||||||
|
func cachedTypeFields(t reflect.Type) []field {
|
||||||
|
fieldCache.RLock()
|
||||||
|
f := fieldCache.m[t]
|
||||||
|
fieldCache.RUnlock()
|
||||||
|
if f != nil {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute fields without lock.
|
||||||
|
// Might duplicate effort but won't hold other computations back.
|
||||||
|
f = typeFields(t)
|
||||||
|
if f == nil {
|
||||||
|
f = []field{}
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldCache.Lock()
|
||||||
|
if fieldCache.m == nil {
|
||||||
|
fieldCache.m = map[reflect.Type][]field{}
|
||||||
|
}
|
||||||
|
fieldCache.m[t] = f
|
||||||
|
fieldCache.Unlock()
|
||||||
|
return f
|
||||||
|
}
|
11
vendor/github.com/elastic/gosigar/CHANGELOG.md
generated
vendored
11
vendor/github.com/elastic/gosigar/CHANGELOG.md
generated
vendored
@ -12,6 +12,17 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
## [0.10.5]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fixed uptime calculation under Windows. #126
|
||||||
|
- Fixed compilation issue for darwin/386. #128
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Load DLLs only from Windows system directory. #132
|
||||||
|
|
||||||
## [0.10.4]
|
## [0.10.4]
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
1
vendor/github.com/elastic/gosigar/README.md
generated
vendored
1
vendor/github.com/elastic/gosigar/README.md
generated
vendored
@ -37,6 +37,7 @@ The features vary by operating system.
|
|||||||
| ProcMem | X | X | X | | X |
|
| ProcMem | X | X | X | | X |
|
||||||
| ProcState | X | X | X | | X |
|
| ProcState | X | X | X | | X |
|
||||||
| ProcTime | X | X | X | | X |
|
| ProcTime | X | X | X | | X |
|
||||||
|
| Rusage | X | | X | | |
|
||||||
| Swap | X | X | | X | X |
|
| Swap | X | X | | X | X |
|
||||||
| Uptime | X | X | | X | X |
|
| Uptime | X | X | | X | X |
|
||||||
|
|
||||||
|
12
vendor/github.com/elastic/gosigar/sigar_darwin.go
generated
vendored
12
vendor/github.com/elastic/gosigar/sigar_darwin.go
generated
vendored
@ -40,18 +40,6 @@ func (self *LoadAverage) Get() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Uptime) Get() error {
|
|
||||||
tv := syscall.Timeval32{}
|
|
||||||
|
|
||||||
if err := sysctlbyname("kern.boottime", &tv); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *Mem) Get() error {
|
func (self *Mem) Get() error {
|
||||||
var vmstat C.vm_statistics_data_t
|
var vmstat C.vm_statistics_data_t
|
||||||
|
|
||||||
|
18
vendor/github.com/elastic/gosigar/sigar_darwin_386.go
generated
vendored
Normal file
18
vendor/github.com/elastic/gosigar/sigar_darwin_386.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package gosigar
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (self *Uptime) Get() error {
|
||||||
|
tv := syscall.Timeval{}
|
||||||
|
|
||||||
|
if err := sysctlbyname("kern.boottime", &tv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
18
vendor/github.com/elastic/gosigar/sigar_darwin_amd64.go
generated
vendored
Normal file
18
vendor/github.com/elastic/gosigar/sigar_darwin_amd64.go
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package gosigar
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (self *Uptime) Get() error {
|
||||||
|
tv := syscall.Timeval32{}
|
||||||
|
|
||||||
|
if err := sysctlbyname("kern.boottime", &tv); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
42
vendor/github.com/elastic/gosigar/sigar_interface.go
generated
vendored
42
vendor/github.com/elastic/gosigar/sigar_interface.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ErrNotImplemented is returned when a particular statistic isn't implemented on the host OS.
|
||||||
type ErrNotImplemented struct {
|
type ErrNotImplemented struct {
|
||||||
OS string
|
OS string
|
||||||
}
|
}
|
||||||
@ -12,6 +13,7 @@ func (e ErrNotImplemented) Error() string {
|
|||||||
return "not implemented on " + e.OS
|
return "not implemented on " + e.OS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsNotImplemented returns true if the error is ErrNotImplemented
|
||||||
func IsNotImplemented(err error) bool {
|
func IsNotImplemented(err error) bool {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case ErrNotImplemented, *ErrNotImplemented:
|
case ErrNotImplemented, *ErrNotImplemented:
|
||||||
@ -21,6 +23,7 @@ func IsNotImplemented(err error) bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sigar is an interface for gathering system host stats
|
||||||
type Sigar interface {
|
type Sigar interface {
|
||||||
CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{})
|
CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{})
|
||||||
GetLoadAverage() (LoadAverage, error)
|
GetLoadAverage() (LoadAverage, error)
|
||||||
@ -32,6 +35,7 @@ type Sigar interface {
|
|||||||
GetRusage(who int) (Rusage, error)
|
GetRusage(who int) (Rusage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cpu contains CPU time stats
|
||||||
type Cpu struct {
|
type Cpu struct {
|
||||||
User uint64
|
User uint64
|
||||||
Nice uint64
|
Nice uint64
|
||||||
@ -43,11 +47,13 @@ type Cpu struct {
|
|||||||
Stolen uint64
|
Stolen uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Total returns total CPU time
|
||||||
func (cpu *Cpu) Total() uint64 {
|
func (cpu *Cpu) Total() uint64 {
|
||||||
return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle +
|
return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle +
|
||||||
cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen
|
cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delta returns the difference between two Cpu stat objects
|
||||||
func (cpu Cpu) Delta(other Cpu) Cpu {
|
func (cpu Cpu) Delta(other Cpu) Cpu {
|
||||||
return Cpu{
|
return Cpu{
|
||||||
User: cpu.User - other.User,
|
User: cpu.User - other.User,
|
||||||
@ -61,14 +67,17 @@ func (cpu Cpu) Delta(other Cpu) Cpu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadAverage reports standard load averages
|
||||||
type LoadAverage struct {
|
type LoadAverage struct {
|
||||||
One, Five, Fifteen float64
|
One, Five, Fifteen float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uptime reports system uptime
|
||||||
type Uptime struct {
|
type Uptime struct {
|
||||||
Length float64
|
Length float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mem contains host memory stats
|
||||||
type Mem struct {
|
type Mem struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Used uint64
|
Used uint64
|
||||||
@ -77,12 +86,14 @@ type Mem struct {
|
|||||||
ActualUsed uint64
|
ActualUsed uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Swap contains stats on swap space
|
||||||
type Swap struct {
|
type Swap struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Used uint64
|
Used uint64
|
||||||
Free uint64
|
Free uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HugeTLBPages contains HugePages stats
|
||||||
type HugeTLBPages struct {
|
type HugeTLBPages struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Free uint64
|
Free uint64
|
||||||
@ -92,16 +103,19 @@ type HugeTLBPages struct {
|
|||||||
TotalAllocatedSize uint64
|
TotalAllocatedSize uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CpuList contains a list of CPUs on the host system
|
||||||
type CpuList struct {
|
type CpuList struct {
|
||||||
List []Cpu
|
List []Cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FDUsage contains stats on filesystem usage
|
||||||
type FDUsage struct {
|
type FDUsage struct {
|
||||||
Open uint64
|
Open uint64
|
||||||
Unused uint64
|
Unused uint64
|
||||||
Max uint64
|
Max uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSystem contains basic information about a given mounted filesystem
|
||||||
type FileSystem struct {
|
type FileSystem struct {
|
||||||
DirName string
|
DirName string
|
||||||
DevName string
|
DevName string
|
||||||
@ -111,10 +125,12 @@ type FileSystem struct {
|
|||||||
Flags uint32
|
Flags uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSystemList gets a list of mounted filesystems
|
||||||
type FileSystemList struct {
|
type FileSystemList struct {
|
||||||
List []FileSystem
|
List []FileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileSystemUsage contains basic stats for the specified filesystem
|
||||||
type FileSystemUsage struct {
|
type FileSystemUsage struct {
|
||||||
Total uint64
|
Total uint64
|
||||||
Used uint64
|
Used uint64
|
||||||
@ -124,21 +140,30 @@ type FileSystemUsage struct {
|
|||||||
FreeFiles uint64
|
FreeFiles uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcList contains a list of processes found on the host system
|
||||||
type ProcList struct {
|
type ProcList struct {
|
||||||
List []int
|
List []int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunState is a byte-long code used to specify the current runtime state of a process
|
||||||
type RunState byte
|
type RunState byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RunStateSleep = 'S'
|
// RunStateSleep corresponds to a sleep state
|
||||||
RunStateRun = 'R'
|
RunStateSleep = 'S'
|
||||||
RunStateStop = 'T'
|
// RunStateRun corresponds to a running state
|
||||||
RunStateZombie = 'Z'
|
RunStateRun = 'R'
|
||||||
RunStateIdle = 'D'
|
// RunStateStop corresponds to a stopped state
|
||||||
|
RunStateStop = 'T'
|
||||||
|
// RunStateZombie marks a zombie process
|
||||||
|
RunStateZombie = 'Z'
|
||||||
|
// RunStateIdle corresponds to an idle state
|
||||||
|
RunStateIdle = 'D'
|
||||||
|
// RunStateUnknown corresponds to a process in an unknown state
|
||||||
RunStateUnknown = '?'
|
RunStateUnknown = '?'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ProcState contains basic metadata and process ownership info for the specified process
|
||||||
type ProcState struct {
|
type ProcState struct {
|
||||||
Name string
|
Name string
|
||||||
Username string
|
Username string
|
||||||
@ -151,6 +176,7 @@ type ProcState struct {
|
|||||||
Processor int
|
Processor int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcMem contains memory statistics for a specified process
|
||||||
type ProcMem struct {
|
type ProcMem struct {
|
||||||
Size uint64
|
Size uint64
|
||||||
Resident uint64
|
Resident uint64
|
||||||
@ -160,6 +186,7 @@ type ProcMem struct {
|
|||||||
PageFaults uint64
|
PageFaults uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcTime contains run time statistics for a specified process
|
||||||
type ProcTime struct {
|
type ProcTime struct {
|
||||||
StartTime uint64
|
StartTime uint64
|
||||||
User uint64
|
User uint64
|
||||||
@ -167,26 +194,31 @@ type ProcTime struct {
|
|||||||
Total uint64
|
Total uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcArgs contains a list of args for a specified process
|
||||||
type ProcArgs struct {
|
type ProcArgs struct {
|
||||||
List []string
|
List []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcEnv contains a map of environment variables for specified process
|
||||||
type ProcEnv struct {
|
type ProcEnv struct {
|
||||||
Vars map[string]string
|
Vars map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcExe contains basic data about a specified process
|
||||||
type ProcExe struct {
|
type ProcExe struct {
|
||||||
Name string
|
Name string
|
||||||
Cwd string
|
Cwd string
|
||||||
Root string
|
Root string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcFDUsage contains data on file limits and usage
|
||||||
type ProcFDUsage struct {
|
type ProcFDUsage struct {
|
||||||
Open uint64
|
Open uint64
|
||||||
SoftLimit uint64
|
SoftLimit uint64
|
||||||
HardLimit uint64
|
HardLimit uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rusage contains data on resource usage for a specified process
|
||||||
type Rusage struct {
|
type Rusage struct {
|
||||||
Utime time.Duration
|
Utime time.Duration
|
||||||
Stime time.Duration
|
Stime time.Duration
|
||||||
|
22
vendor/github.com/elastic/gosigar/sigar_windows.go
generated
vendored
22
vendor/github.com/elastic/gosigar/sigar_windows.go
generated
vendored
@ -8,7 +8,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -24,11 +23,6 @@ var (
|
|||||||
// 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer
|
// 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer
|
||||||
// OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION.
|
// OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION.
|
||||||
processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION
|
processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION
|
||||||
|
|
||||||
// bootTime is the time when the OS was last booted. This value may be nil
|
|
||||||
// on operating systems that do not support the WMI query used to obtain it.
|
|
||||||
bootTime *time.Time
|
|
||||||
bootTimeLock sync.Mutex
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -63,19 +57,11 @@ func (self *Uptime) Get() error {
|
|||||||
if !version.IsWindowsVistaOrGreater() {
|
if !version.IsWindowsVistaOrGreater() {
|
||||||
return ErrNotImplemented{runtime.GOOS}
|
return ErrNotImplemented{runtime.GOOS}
|
||||||
}
|
}
|
||||||
|
uptimeMs, err := windows.GetTickCount64()
|
||||||
bootTimeLock.Lock()
|
if err != nil {
|
||||||
defer bootTimeLock.Unlock()
|
return errors.Wrap(err, "failed to get boot time using GetTickCount64 api")
|
||||||
if bootTime == nil {
|
|
||||||
uptime, err := windows.GetTickCount64()
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "failed to get boot time using win32 api")
|
|
||||||
}
|
|
||||||
var boot = time.Unix(int64(uptime), 0)
|
|
||||||
bootTime = &boot
|
|
||||||
}
|
}
|
||||||
|
self.Length = float64(time.Duration(uptimeMs)*time.Millisecond) / float64(time.Second)
|
||||||
self.Length = time.Since(*bootTime).Seconds()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
vendor/github.com/elastic/gosigar/sys/windows/doc.go
generated
vendored
6
vendor/github.com/elastic/gosigar/sys/windows/doc.go
generated
vendored
@ -1,2 +1,8 @@
|
|||||||
// Package windows contains various Windows system call.
|
// Package windows contains various Windows system call.
|
||||||
package windows
|
package windows
|
||||||
|
|
||||||
|
// Use "go generate -v -x ." to generate the source.
|
||||||
|
|
||||||
|
// Add -trace to enable debug prints around syscalls.
|
||||||
|
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=true -output zsyscall_windows.go syscall_windows.go
|
||||||
|
//go:generate go run fix_generated.go -input zsyscall_windows.go
|
||||||
|
5
vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go
generated
vendored
5
vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go
generated
vendored
@ -580,11 +580,6 @@ func GetTickCount64() (uptime uint64, err error) {
|
|||||||
return uptime, nil
|
return uptime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use "GOOS=windows go generate -v -x ." to generate the source.
|
|
||||||
|
|
||||||
// Add -trace to enable debug prints around syscalls.
|
|
||||||
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=false -output zsyscall_windows.go syscall_windows.go
|
|
||||||
|
|
||||||
// Windows API calls
|
// Windows API calls
|
||||||
//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
|
//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
|
||||||
//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW
|
//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW
|
||||||
|
10
vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go
generated
vendored
10
vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go
generated
vendored
@ -5,6 +5,8 @@ package windows
|
|||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ unsafe.Pointer
|
var _ unsafe.Pointer
|
||||||
@ -35,10 +37,10 @@ func errnoErr(e syscall.Errno) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
|
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
modpsapi = syscall.NewLazyDLL("psapi.dll")
|
modpsapi = windows.NewLazySystemDLL("psapi.dll")
|
||||||
modntdll = syscall.NewLazyDLL("ntdll.dll")
|
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
|
|
||||||
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
|
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
|
||||||
procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
|
procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
|
||||||
|
11
vendor/github.com/ethereum/go-ethereum/eth/downloader/downloader.go
generated
vendored
11
vendor/github.com/ethereum/go-ethereum/eth/downloader/downloader.go
generated
vendored
@ -525,12 +525,19 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
|
|||||||
} else if d.mode == FullSync {
|
} else if d.mode == FullSync {
|
||||||
fetchers = append(fetchers, d.processFullSyncContent)
|
fetchers = append(fetchers, d.processFullSyncContent)
|
||||||
}
|
}
|
||||||
return d.spawnSync(fetchers)
|
return d.spawnSync(errCanceled, fetchers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// spawnSync runs d.process and all given fetcher functions to completion in
|
// spawnSync runs d.process and all given fetcher functions to completion in
|
||||||
// separate goroutines, returning the first error that appears.
|
// separate goroutines, returning the first error that appears.
|
||||||
func (d *Downloader) spawnSync(fetchers []func() error) error {
|
func (d *Downloader) spawnSync(errCancel error, fetchers []func() error) error {
|
||||||
|
d.cancelLock.Lock()
|
||||||
|
select {
|
||||||
|
case <-d.cancelCh:
|
||||||
|
d.cancelLock.Unlock()
|
||||||
|
return errCancel
|
||||||
|
default:
|
||||||
|
}
|
||||||
errc := make(chan error, len(fetchers))
|
errc := make(chan error, len(fetchers))
|
||||||
d.cancelWg.Add(len(fetchers))
|
d.cancelWg.Add(len(fetchers))
|
||||||
d.cancelLock.Unlock()
|
d.cancelLock.Unlock()
|
||||||
|
16
vendor/github.com/ethereum/go-ethereum/go.mod
generated
vendored
16
vendor/github.com/ethereum/go-ethereum/go.mod
generated
vendored
@ -9,7 +9,7 @@ require (
|
|||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6
|
||||||
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156
|
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156
|
||||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847
|
||||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6
|
github.com/btcsuite/btcd v0.20.0-beta
|
||||||
github.com/cespare/cp v0.1.0
|
github.com/cespare/cp v0.1.0
|
||||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd
|
||||||
github.com/davecgh/go-spew v1.1.0
|
github.com/davecgh/go-spew v1.1.0
|
||||||
@ -23,7 +23,7 @@ require (
|
|||||||
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091
|
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091
|
||||||
github.com/go-ole/go-ole v1.2.1
|
github.com/go-ole/go-ole v1.2.1
|
||||||
github.com/go-stack/stack v1.5.4
|
github.com/go-stack/stack v1.5.4
|
||||||
github.com/golang/protobuf v0.0.0-20170726212829-748d386b5c1e
|
github.com/golang/protobuf v1.2.0
|
||||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049
|
github.com/golang/snappy v0.0.0-20170215233205-553a64147049
|
||||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad
|
||||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3
|
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3
|
||||||
@ -54,12 +54,12 @@ require (
|
|||||||
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2
|
||||||
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6
|
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6
|
||||||
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7
|
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7
|
||||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf
|
||||||
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3
|
||||||
golang.org/x/sync v0.0.0-20170517211232-f52d1811a629
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
|
||||||
golang.org/x/sys v0.0.0-20190214214411-e77772198cdc
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d
|
||||||
golang.org/x/text v0.0.0-20171227012246-e19ae1496984
|
golang.org/x/text v0.3.2
|
||||||
golang.org/x/tools v0.0.0-20170215214335-be0fcc31ae23
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e
|
||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5
|
||||||
|
42
vendor/github.com/ethereum/go-ethereum/go.sum
generated
vendored
42
vendor/github.com/ethereum/go-ethereum/go.sum
generated
vendored
@ -2,30 +2,49 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxo
|
|||||||
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
|
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
|
||||||
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
|
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
|
||||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
|
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||||
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
||||||
|
github.com/btcsuite/btcd v0.20.0-beta h1:DnZGUjFbRkpytojHWwy6nfUSA7vFrzWXDLpFNzt74ZA=
|
||||||
|
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||||
|
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||||
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
|
||||||
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||||
|
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||||
|
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||||
|
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||||
|
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||||
|
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
|
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||||
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/ethereum/go-ethereum v1.9.5/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||||
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
||||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||||
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/golang/protobuf v0.0.0-20170726212829-748d386b5c1e/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v0.0.0-20170726212829-748d386b5c1e/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
||||||
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||||
github.com/julienschmidt/httprouter v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
|
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
|
||||||
|
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||||
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
|
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
|
||||||
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
@ -35,6 +54,9 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd
|
|||||||
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||||
github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||||
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
||||||
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||||
@ -45,18 +67,38 @@ github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRr
|
|||||||
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||||
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||||
|
github.com/status-im/extkeys v1.0.0 h1:2wmG5NG2FTbZzXSykaNPmdFCDBwxHoqF88CJX3MK92E=
|
||||||
|
github.com/status-im/extkeys v1.0.0/go.mod h1:wNx0pnvGTgyKz/S8hBNesAHKKKI9beF+BuVLIuBJuQI=
|
||||||
github.com/stretchr/testify v0.0.0-20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v0.0.0-20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||||
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||||
|
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf h1:fnPsqIDRbCSgumaMCRpoIoF2s4qxv0xSSS0BVZUE/ss=
|
||||||
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190214214411-e77772198cdc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190214214411-e77772198cdc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.0.0-20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20170215214335-be0fcc31ae23/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20170215214335-be0fcc31ae23/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
15
vendor/github.com/status-im/status-go/account/accounts.go
generated
vendored
15
vendor/github.com/status-im/status-go/account/accounts.go
generated
vendored
@ -13,13 +13,12 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
gethcommon "github.com/ethereum/go-ethereum/common"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/pborman/uuid"
|
"github.com/pborman/uuid"
|
||||||
|
|
||||||
"github.com/status-im/status-go/account/generator"
|
"github.com/status-im/status-go/account/generator"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/extkeys"
|
"github.com/status-im/status-go/extkeys"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// errors
|
// errors
|
||||||
@ -158,7 +157,7 @@ func (m *Manager) VerifyAccountPassword(keyStoreDir, address, password string) (
|
|||||||
var err error
|
var err error
|
||||||
var foundKeyFile []byte
|
var foundKeyFile []byte
|
||||||
|
|
||||||
addressObj := gethcommon.BytesToAddress(gethcommon.FromHex(address))
|
addressObj := common.BytesToAddress(common.FromHex(address))
|
||||||
checkAccountKey := func(path string, fileInfo os.FileInfo) error {
|
checkAccountKey := func(path string, fileInfo os.FileInfo) error {
|
||||||
if len(foundKeyFile) > 0 || fileInfo.IsDir() {
|
if len(foundKeyFile) > 0 || fileInfo.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
@ -176,7 +175,7 @@ func (m *Manager) VerifyAccountPassword(keyStoreDir, address, password string) (
|
|||||||
return fmt.Errorf("failed to read key file: %s", e)
|
return fmt.Errorf("failed to read key file: %s", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if gethcommon.HexToAddress("0x"+accountKey.Address).Hex() == addressObj.Hex() {
|
if common.HexToAddress("0x"+accountKey.Address).Hex() == addressObj.Hex() {
|
||||||
foundKeyFile = rawKeyFile
|
foundKeyFile = rawKeyFile
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +324,7 @@ func (m *Manager) ImportSingleExtendedKey(extKey *extkeys.ExtendedKey, password
|
|||||||
return address, "", err
|
return address, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
pubKey = statusproto.EncodeHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
|
pubKey = types.EncodeHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -349,17 +348,17 @@ func (m *Manager) importExtendedKey(keyPurpose extkeys.KeyPurpose, extKey *extke
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return address, "", err
|
return address, "", err
|
||||||
}
|
}
|
||||||
pubKey = statusproto.EncodeHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
|
pubKey = types.EncodeHex(crypto.FromECDSAPub(&key.PrivateKey.PublicKey))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accounts returns list of addresses for selected account, including
|
// Accounts returns list of addresses for selected account, including
|
||||||
// subaccounts.
|
// subaccounts.
|
||||||
func (m *Manager) Accounts() ([]gethcommon.Address, error) {
|
func (m *Manager) Accounts() ([]common.Address, error) {
|
||||||
m.mu.RLock()
|
m.mu.RLock()
|
||||||
defer m.mu.RUnlock()
|
defer m.mu.RUnlock()
|
||||||
addresses := make([]gethcommon.Address, 0)
|
addresses := make([]common.Address, 0)
|
||||||
if m.mainAccountAddress != zeroAddress {
|
if m.mainAccountAddress != zeroAddress {
|
||||||
addresses = append(addresses, m.mainAccountAddress)
|
addresses = append(addresses, m.mainAccountAddress)
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/status-im/status-go/account/address.go
generated
vendored
6
vendor/github.com/status-im/status-go/account/address.go
generated
vendored
@ -2,7 +2,7 @@ package account
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateAddress() (address, pubKey, privKey string, err error) {
|
func CreateAddress() (address, pubKey, privKey string, err error) {
|
||||||
@ -15,8 +15,8 @@ func CreateAddress() (address, pubKey, privKey string, err error) {
|
|||||||
pubKeyBytes := crypto.FromECDSAPub(&key.PublicKey)
|
pubKeyBytes := crypto.FromECDSAPub(&key.PublicKey)
|
||||||
addressBytes := crypto.PubkeyToAddress(key.PublicKey)
|
addressBytes := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
||||||
privKey = statusproto.EncodeHex(privKeyBytes)
|
privKey = types.EncodeHex(privKeyBytes)
|
||||||
pubKey = statusproto.EncodeHex(pubKeyBytes)
|
pubKey = types.EncodeHex(pubKeyBytes)
|
||||||
address = addressBytes.Hex()
|
address = addressBytes.Hex()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
14
vendor/github.com/status-im/status-go/account/generator/account.go
generated
vendored
14
vendor/github.com/status-im/status-go/account/generator/account.go
generated
vendored
@ -2,10 +2,11 @@ package generator
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"crypto/sha256"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/extkeys"
|
"github.com/status-im/status-go/extkeys"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type account struct {
|
type account struct {
|
||||||
@ -14,7 +15,7 @@ type account struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *account) toAccountInfo() AccountInfo {
|
func (a *account) toAccountInfo() AccountInfo {
|
||||||
publicKeyHex := statusproto.EncodeHex(crypto.FromECDSAPub(&a.privateKey.PublicKey))
|
publicKeyHex := types.EncodeHex(crypto.FromECDSAPub(&a.privateKey.PublicKey))
|
||||||
addressHex := crypto.PubkeyToAddress(a.privateKey.PublicKey).Hex()
|
addressHex := crypto.PubkeyToAddress(a.privateKey.PublicKey).Hex()
|
||||||
|
|
||||||
return AccountInfo{
|
return AccountInfo{
|
||||||
@ -25,9 +26,12 @@ func (a *account) toAccountInfo() AccountInfo {
|
|||||||
|
|
||||||
func (a *account) toIdentifiedAccountInfo(id string) IdentifiedAccountInfo {
|
func (a *account) toIdentifiedAccountInfo(id string) IdentifiedAccountInfo {
|
||||||
info := a.toAccountInfo()
|
info := a.toAccountInfo()
|
||||||
|
keyUID := sha256.Sum256(crypto.FromECDSAPub(&a.privateKey.PublicKey))
|
||||||
|
keyUIDHex := types.EncodeHex(keyUID[:])
|
||||||
return IdentifiedAccountInfo{
|
return IdentifiedAccountInfo{
|
||||||
AccountInfo: info,
|
AccountInfo: info,
|
||||||
ID: id,
|
ID: id,
|
||||||
|
KeyUID: keyUIDHex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +53,12 @@ type AccountInfo struct {
|
|||||||
type IdentifiedAccountInfo struct {
|
type IdentifiedAccountInfo struct {
|
||||||
AccountInfo
|
AccountInfo
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
// KeyUID is calculated as sha256 of the master public key and used for key
|
||||||
|
// identification. This is the only information available about the master
|
||||||
|
// key stored on a keycard before the card is paired.
|
||||||
|
// KeyUID name is chosen over KeyID in order to make it consistent with
|
||||||
|
// the name already used in Status and Keycard codebases.
|
||||||
|
KeyUID string `json:"keyUid"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeneratedAccountInfo contains IdentifiedAccountInfo and the mnemonic of an account.
|
// GeneratedAccountInfo contains IdentifiedAccountInfo and the mnemonic of an account.
|
||||||
|
4
vendor/github.com/status-im/status-go/account/onboarding.go
generated
vendored
4
vendor/github.com/status-im/status-go/account/onboarding.go
generated
vendored
@ -6,8 +6,8 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/pborman/uuid"
|
"github.com/pborman/uuid"
|
||||||
"github.com/status-im/status-go/account/generator"
|
"github.com/status-im/status-go/account/generator"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/extkeys"
|
"github.com/status-im/status-go/extkeys"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// OnboardingAccount is returned during onboarding and contains its ID and the mnemonic to re-generate the same account Info keys.
|
// OnboardingAccount is returned during onboarding and contains its ID and the mnemonic to re-generate the same account Info keys.
|
||||||
@ -107,7 +107,7 @@ func (o *Onboarding) deriveAccount(masterExtendedKey *extkeys.ExtendedKey, purpo
|
|||||||
|
|
||||||
privateKeyECDSA := extendedKey.ToECDSA()
|
privateKeyECDSA := extendedKey.ToECDSA()
|
||||||
address := crypto.PubkeyToAddress(privateKeyECDSA.PublicKey)
|
address := crypto.PubkeyToAddress(privateKeyECDSA.PublicKey)
|
||||||
publicKeyHex := statusproto.EncodeHex(crypto.FromECDSAPub(&privateKeyECDSA.PublicKey))
|
publicKeyHex := types.EncodeHex(crypto.FromECDSAPub(&privateKeyECDSA.PublicKey))
|
||||||
|
|
||||||
return address.Hex(), publicKeyHex, nil
|
return address.Hex(), publicKeyHex, nil
|
||||||
}
|
}
|
||||||
|
19
vendor/github.com/status-im/status-go/db/history.go
generated
vendored
19
vendor/github.com/status-im/status-go/db/history.go
generated
vendored
@ -6,8 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/util"
|
"github.com/syndtr/goleveldb/leveldb/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,7 +25,7 @@ type DB interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TopicHistoryKey defines bytes that are used as unique key for TopicHistory.
|
// TopicHistoryKey defines bytes that are used as unique key for TopicHistory.
|
||||||
// first 4 bytes are whispertypes.TopicType bytes
|
// first 4 bytes are types.TopicType bytes
|
||||||
// next 8 bytes are time.Duration encoded in big endian notation.
|
// next 8 bytes are time.Duration encoded in big endian notation.
|
||||||
type TopicHistoryKey [12]byte
|
type TopicHistoryKey [12]byte
|
||||||
|
|
||||||
@ -36,7 +35,7 @@ func LoadTopicHistoryFromKey(db DB, key TopicHistoryKey) (th TopicHistory, err e
|
|||||||
if (key == TopicHistoryKey{}) {
|
if (key == TopicHistoryKey{}) {
|
||||||
return th, ErrEmptyKey
|
return th, ErrEmptyKey
|
||||||
}
|
}
|
||||||
topic := whispertypes.TopicType{}
|
topic := types.TopicType{}
|
||||||
copy(topic[:], key[:4])
|
copy(topic[:], key[:4])
|
||||||
duration := binary.BigEndian.Uint64(key[4:])
|
duration := binary.BigEndian.Uint64(key[4:])
|
||||||
th = TopicHistory{db: db, Topic: topic, Duration: time.Duration(duration)}
|
th = TopicHistory{db: db, Topic: topic, Duration: time.Duration(duration)}
|
||||||
@ -47,7 +46,7 @@ func LoadTopicHistoryFromKey(db DB, key TopicHistoryKey) (th TopicHistory, err e
|
|||||||
type TopicHistory struct {
|
type TopicHistory struct {
|
||||||
db DB
|
db DB
|
||||||
// whisper topic
|
// whisper topic
|
||||||
Topic whispertypes.TopicType
|
Topic types.TopicType
|
||||||
|
|
||||||
Duration time.Duration
|
Duration time.Duration
|
||||||
// Timestamp that was used for the first request with this topic.
|
// Timestamp that was used for the first request with this topic.
|
||||||
@ -57,7 +56,7 @@ type TopicHistory struct {
|
|||||||
Current time.Time
|
Current time.Time
|
||||||
End time.Time
|
End time.Time
|
||||||
|
|
||||||
RequestID statusproto.Hash
|
RequestID types.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// Key returns unique identifier for this TopicHistory.
|
// Key returns unique identifier for this TopicHistory.
|
||||||
@ -115,7 +114,7 @@ func (t TopicHistory) SameRange(other TopicHistory) bool {
|
|||||||
|
|
||||||
// Pending returns true if this topic was requested from a mail server.
|
// Pending returns true if this topic was requested from a mail server.
|
||||||
func (t TopicHistory) Pending() bool {
|
func (t TopicHistory) Pending() bool {
|
||||||
return t.RequestID != statusproto.Hash{}
|
return t.RequestID != types.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HistoryRequest is kept in the database while request is in the progress.
|
// HistoryRequest is kept in the database while request is in the progress.
|
||||||
@ -127,7 +126,7 @@ type HistoryRequest struct {
|
|||||||
histories []TopicHistory
|
histories []TopicHistory
|
||||||
|
|
||||||
// Generated ID
|
// Generated ID
|
||||||
ID statusproto.Hash
|
ID types.Hash
|
||||||
// List of the topics
|
// List of the topics
|
||||||
TopicHistoryKeys []TopicHistoryKey
|
TopicHistoryKeys []TopicHistoryKey
|
||||||
}
|
}
|
||||||
@ -167,8 +166,8 @@ func (req HistoryRequest) Save() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replace saves request with new ID and all data attached to the old one.
|
// Replace saves request with new ID and all data attached to the old one.
|
||||||
func (req HistoryRequest) Replace(id statusproto.Hash) error {
|
func (req HistoryRequest) Replace(id types.Hash) error {
|
||||||
if (req.ID != statusproto.Hash{}) {
|
if (req.ID != types.Hash{}) {
|
||||||
if err := req.Delete(); err != nil {
|
if err := req.Delete(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
11
vendor/github.com/status-im/status-go/db/history_store.go
generated
vendored
11
vendor/github.com/status-im/status-go/db/history_store.go
generated
vendored
@ -3,8 +3,7 @@ package db
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,7 +23,7 @@ type HistoryStore struct {
|
|||||||
|
|
||||||
// GetHistory creates history instance and loads history from database.
|
// GetHistory creates history instance and loads history from database.
|
||||||
// Returns instance populated with topic and duration if history is not found in database.
|
// Returns instance populated with topic and duration if history is not found in database.
|
||||||
func (h HistoryStore) GetHistory(topic whispertypes.TopicType, duration time.Duration) (TopicHistory, error) {
|
func (h HistoryStore) GetHistory(topic types.TopicType, duration time.Duration) (TopicHistory, error) {
|
||||||
thist := h.NewHistory(topic, duration)
|
thist := h.NewHistory(topic, duration)
|
||||||
err := thist.Load()
|
err := thist.Load()
|
||||||
if err != nil && err != errors.ErrNotFound {
|
if err != nil && err != errors.ErrNotFound {
|
||||||
@ -39,12 +38,12 @@ func (h HistoryStore) NewRequest() HistoryRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewHistory creates TopicHistory object with required values.
|
// NewHistory creates TopicHistory object with required values.
|
||||||
func (h HistoryStore) NewHistory(topic whispertypes.TopicType, duration time.Duration) TopicHistory {
|
func (h HistoryStore) NewHistory(topic types.TopicType, duration time.Duration) TopicHistory {
|
||||||
return TopicHistory{db: h.topicDB, Duration: duration, Topic: topic}
|
return TopicHistory{db: h.topicDB, Duration: duration, Topic: topic}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRequest loads HistoryRequest from database.
|
// GetRequest loads HistoryRequest from database.
|
||||||
func (h HistoryStore) GetRequest(id statusproto.Hash) (HistoryRequest, error) {
|
func (h HistoryStore) GetRequest(id types.Hash) (HistoryRequest, error) {
|
||||||
req := HistoryRequest{requestDB: h.requestDB, topicDB: h.topicDB, ID: id}
|
req := HistoryRequest{requestDB: h.requestDB, topicDB: h.topicDB, ID: id}
|
||||||
err := req.Load()
|
err := req.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -74,7 +73,7 @@ func (h HistoryStore) GetAllRequests() ([]HistoryRequest, error) {
|
|||||||
// GetHistoriesByTopic returns all histories with a given topic.
|
// GetHistoriesByTopic returns all histories with a given topic.
|
||||||
// This is needed when we will have multiple range per single topic.
|
// This is needed when we will have multiple range per single topic.
|
||||||
// TODO explain
|
// TODO explain
|
||||||
func (h HistoryStore) GetHistoriesByTopic(topic whispertypes.TopicType) ([]TopicHistory, error) {
|
func (h HistoryStore) GetHistoriesByTopic(topic types.TopicType) ([]TopicHistory, error) {
|
||||||
rst := []TopicHistory{}
|
rst := []TopicHistory{}
|
||||||
iter := h.topicDB.NewIterator(h.topicDB.Range(topic[:], nil))
|
iter := h.topicDB.NewIterator(h.topicDB.Range(topic[:], nil))
|
||||||
for iter.Next() {
|
for iter.Next() {
|
||||||
|
@ -3,15 +3,16 @@ package ens
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
|
||||||
ens "github.com/wealdtech/go-ens/v3"
|
|
||||||
"go.uber.org/zap"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
|
enstypes "github.com/status-im/status-go/eth-node/types/ens"
|
||||||
|
ens "github.com/wealdtech/go-ens/v3"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -22,29 +23,16 @@ type ENSVerifier struct {
|
|||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
type ENSDetails struct {
|
// NewVerifier returns a ENSVerifier attached to the specified logger
|
||||||
Name string `json:"name"`
|
|
||||||
PublicKeyString string `json:"publicKey"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ENSResponse struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Verified bool `json:"verified"`
|
|
||||||
VerifiedAt int64 `json:"verifiedAt"`
|
|
||||||
Error error `json:"error"`
|
|
||||||
PublicKey *ecdsa.PublicKey `json:"-"`
|
|
||||||
PublicKeyString string `json:"publicKey"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewVerifier(logger *zap.Logger) *ENSVerifier {
|
func NewVerifier(logger *zap.Logger) *ENSVerifier {
|
||||||
return &ENSVerifier{logger: logger}
|
return &ENSVerifier{logger: logger}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ENSVerifier) verifyENSName(ensInfo ENSDetails, ethclient *ethclient.Client) ENSResponse {
|
func (m *ENSVerifier) verifyENSName(ensInfo enstypes.ENSDetails, ethclient *ethclient.Client) enstypes.ENSResponse {
|
||||||
publicKeyStr := ensInfo.PublicKeyString
|
publicKeyStr := ensInfo.PublicKeyString
|
||||||
ensName := ensInfo.Name
|
ensName := ensInfo.Name
|
||||||
m.logger.Info("Resolving ENS name", zap.String("name", ensName), zap.String("publicKey", publicKeyStr))
|
m.logger.Info("Resolving ENS name", zap.String("name", ensName), zap.String("publicKey", publicKeyStr))
|
||||||
response := ENSResponse{
|
response := enstypes.ENSResponse{
|
||||||
Name: ensName,
|
Name: ensName,
|
||||||
PublicKeyString: publicKeyStr,
|
PublicKeyString: publicKeyStr,
|
||||||
VerifiedAt: time.Now().Unix(),
|
VerifiedAt: time.Now().Unix(),
|
||||||
@ -85,12 +73,12 @@ func (m *ENSVerifier) verifyENSName(ensInfo ENSDetails, ethclient *ethclient.Cli
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CheckBatch verifies that a registered ENS name matches the expected public key
|
// CheckBatch verifies that a registered ENS name matches the expected public key
|
||||||
func (m *ENSVerifier) CheckBatch(ensDetails []ENSDetails, rpcEndpoint, contractAddress string) (map[string]ENSResponse, error) {
|
func (m *ENSVerifier) CheckBatch(ensDetails []enstypes.ENSDetails, rpcEndpoint, contractAddress string) (map[string]enstypes.ENSResponse, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), contractQueryTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), contractQueryTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
ch := make(chan ENSResponse)
|
ch := make(chan enstypes.ENSResponse)
|
||||||
response := make(map[string]ENSResponse)
|
response := make(map[string]enstypes.ENSResponse)
|
||||||
|
|
||||||
ethclient, err := ethclient.DialContext(ctx, rpcEndpoint)
|
ethclient, err := ethclient.DialContext(ctx, rpcEndpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -98,7 +86,7 @@ func (m *ENSVerifier) CheckBatch(ensDetails []ENSDetails, rpcEndpoint, contractA
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, ensInfo := range ensDetails {
|
for _, ensInfo := range ensDetails {
|
||||||
go func(info ENSDetails) { ch <- m.verifyENSName(info, ethclient) }(ensInfo)
|
go func(info enstypes.ENSDetails) { ch <- m.verifyENSName(info, ethclient) }(ensInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
for range ensDetails {
|
for range ensDetails {
|
@ -1,8 +1,7 @@
|
|||||||
package gethbridge
|
package gethbridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,20 +9,20 @@ type gethEnvelopeWrapper struct {
|
|||||||
envelope *whisper.Envelope
|
envelope *whisper.Envelope
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGethEnvelopeWrapper returns an object that wraps Geth's Envelope in a whispertypes interface
|
// NewGethEnvelopeWrapper returns an object that wraps Geth's Envelope in a types interface
|
||||||
func NewGethEnvelopeWrapper(e *whisper.Envelope) whispertypes.Envelope {
|
func NewGethEnvelopeWrapper(e *whisper.Envelope) types.Envelope {
|
||||||
return &gethEnvelopeWrapper{
|
return &gethEnvelopeWrapper{
|
||||||
envelope: e,
|
envelope: e,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGethEnvelopeFrom retrieves the underlying whisper Envelope struct from a wrapped Envelope interface
|
// GetGethEnvelopeFrom retrieves the underlying whisper Envelope struct from a wrapped Envelope interface
|
||||||
func GetGethEnvelopeFrom(f whispertypes.Envelope) *whisper.Envelope {
|
func GetGethEnvelopeFrom(f types.Envelope) *whisper.Envelope {
|
||||||
return f.(*gethEnvelopeWrapper).envelope
|
return f.(*gethEnvelopeWrapper).envelope
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethEnvelopeWrapper) Hash() statusproto.Hash {
|
func (w *gethEnvelopeWrapper) Hash() types.Hash {
|
||||||
return statusproto.Hash(w.envelope.Hash())
|
return types.Hash(w.envelope.Hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethEnvelopeWrapper) Bloom() []byte {
|
func (w *gethEnvelopeWrapper) Bloom() []byte {
|
29
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope_error.go
generated
vendored
Normal file
29
vendor/github.com/status-im/status-go/eth-node/bridge/geth/envelope_error.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package gethbridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGethEnvelopeErrorWrapper returns a types.EnvelopeError object that mimics Geth's EnvelopeError
|
||||||
|
func NewGethEnvelopeErrorWrapper(envelopeError *whisper.EnvelopeError) *types.EnvelopeError {
|
||||||
|
if envelopeError == nil {
|
||||||
|
panic("envelopeError should not be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.EnvelopeError{
|
||||||
|
Hash: types.Hash(envelopeError.Hash),
|
||||||
|
Code: mapGethErrorCode(envelopeError.Code),
|
||||||
|
Description: envelopeError.Description,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapGethErrorCode(code uint) uint {
|
||||||
|
switch code {
|
||||||
|
case whisper.EnvelopeTimeNotSynced:
|
||||||
|
return types.EnvelopeTimeNotSynced
|
||||||
|
case whisper.EnvelopeOtherError:
|
||||||
|
return types.EnvelopeOtherError
|
||||||
|
}
|
||||||
|
return types.EnvelopeOtherError
|
||||||
|
}
|
@ -1,13 +1,12 @@
|
|||||||
package gethbridge
|
package gethbridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewGethEnvelopeEventWrapper returns a whispertypes.EnvelopeEvent object that mimics Geth's EnvelopeEvent
|
// NewGethEnvelopeEventWrapper returns a types.EnvelopeEvent object that mimics Geth's EnvelopeEvent
|
||||||
func NewGethEnvelopeEventWrapper(envelopeEvent *whisper.EnvelopeEvent) *whispertypes.EnvelopeEvent {
|
func NewGethEnvelopeEventWrapper(envelopeEvent *whisper.EnvelopeEvent) *types.EnvelopeEvent {
|
||||||
if envelopeEvent == nil {
|
if envelopeEvent == nil {
|
||||||
panic("envelopeEvent should not be nil")
|
panic("envelopeEvent should not be nil")
|
||||||
}
|
}
|
||||||
@ -15,7 +14,7 @@ func NewGethEnvelopeEventWrapper(envelopeEvent *whisper.EnvelopeEvent) *whispert
|
|||||||
wrappedData := envelopeEvent.Data
|
wrappedData := envelopeEvent.Data
|
||||||
switch data := envelopeEvent.Data.(type) {
|
switch data := envelopeEvent.Data.(type) {
|
||||||
case []whisper.EnvelopeError:
|
case []whisper.EnvelopeError:
|
||||||
wrappedData := make([]whispertypes.EnvelopeError, len(data))
|
wrappedData := make([]types.EnvelopeError, len(data))
|
||||||
for index, envError := range data {
|
for index, envError := range data {
|
||||||
wrappedData[index] = *NewGethEnvelopeErrorWrapper(&envError)
|
wrappedData[index] = *NewGethEnvelopeErrorWrapper(&envError)
|
||||||
}
|
}
|
||||||
@ -24,11 +23,11 @@ func NewGethEnvelopeEventWrapper(envelopeEvent *whisper.EnvelopeEvent) *whispert
|
|||||||
case whisper.SyncEventResponse:
|
case whisper.SyncEventResponse:
|
||||||
wrappedData = NewGethSyncEventResponseWrapper(data)
|
wrappedData = NewGethSyncEventResponseWrapper(data)
|
||||||
}
|
}
|
||||||
return &whispertypes.EnvelopeEvent{
|
return &types.EnvelopeEvent{
|
||||||
Event: whispertypes.EventType(envelopeEvent.Event),
|
Event: types.EventType(envelopeEvent.Event),
|
||||||
Hash: statusproto.Hash(envelopeEvent.Hash),
|
Hash: types.Hash(envelopeEvent.Hash),
|
||||||
Batch: statusproto.Hash(envelopeEvent.Batch),
|
Batch: types.Hash(envelopeEvent.Batch),
|
||||||
Peer: whispertypes.EnodeID(envelopeEvent.Peer),
|
Peer: types.EnodeID(envelopeEvent.Peer),
|
||||||
Data: wrappedData,
|
Data: wrappedData,
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package gethbridge
|
package gethbridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -10,8 +10,8 @@ type gethFilterWrapper struct {
|
|||||||
id string
|
id string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGethFilterWrapper returns an object that wraps Geth's Filter in a whispertypes interface
|
// NewGethFilterWrapper returns an object that wraps Geth's Filter in a types interface
|
||||||
func NewGethFilterWrapper(f *whisper.Filter, id string) whispertypes.Filter {
|
func NewGethFilterWrapper(f *whisper.Filter, id string) types.Filter {
|
||||||
if f.Messages == nil {
|
if f.Messages == nil {
|
||||||
panic("Messages should not be nil")
|
panic("Messages should not be nil")
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ func NewGethFilterWrapper(f *whisper.Filter, id string) whispertypes.Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetGethFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
|
// GetGethFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
|
||||||
func GetGethFilterFrom(f whispertypes.Filter) *whisper.Filter {
|
func GetGethFilterFrom(f types.Filter) *whisper.Filter {
|
||||||
return f.(*gethFilterWrapper).filter
|
return f.(*gethFilterWrapper).filter
|
||||||
}
|
}
|
||||||
|
|
19
vendor/github.com/status-im/status-go/eth-node/bridge/geth/mailserver_response.go
generated
vendored
Normal file
19
vendor/github.com/status-im/status-go/eth-node/bridge/geth/mailserver_response.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package gethbridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGethMailServerResponseWrapper returns a types.MailServerResponse object that mimics Geth's MailServerResponse
|
||||||
|
func NewGethMailServerResponseWrapper(mailServerResponse *whisper.MailServerResponse) *types.MailServerResponse {
|
||||||
|
if mailServerResponse == nil {
|
||||||
|
panic("mailServerResponse should not be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.MailServerResponse{
|
||||||
|
LastEnvelopeHash: types.Hash(mailServerResponse.LastEnvelopeHash),
|
||||||
|
Cursor: mailServerResponse.Cursor,
|
||||||
|
Error: mailServerResponse.Error,
|
||||||
|
}
|
||||||
|
}
|
45
vendor/github.com/status-im/status-go/eth-node/bridge/geth/node.go
generated
vendored
Normal file
45
vendor/github.com/status-im/status-go/eth-node/bridge/geth/node.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package gethbridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/node"
|
||||||
|
gethens "github.com/status-im/status-go/eth-node/bridge/geth/ens"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
enstypes "github.com/status-im/status-go/eth-node/types/ens"
|
||||||
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type gethNodeWrapper struct {
|
||||||
|
stack *node.Node
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNodeBridge(stack *node.Node) types.Node {
|
||||||
|
return &gethNodeWrapper{stack: stack}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *gethNodeWrapper) NewENSVerifier(logger *zap.Logger) enstypes.ENSVerifier {
|
||||||
|
return gethens.NewVerifier(logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *gethNodeWrapper) GetWhisper(ctx interface{}) (types.Whisper, error) {
|
||||||
|
var nativeWhisper *whisper.Whisper
|
||||||
|
if ctx == nil || ctx == w {
|
||||||
|
err := w.stack.Service(&nativeWhisper)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch serviceProvider := ctx.(type) {
|
||||||
|
case *node.ServiceContext:
|
||||||
|
err := serviceProvider.Service(&nativeWhisper)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if nativeWhisper == nil {
|
||||||
|
panic("Whisper service is not available")
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewGethWhisperWrapper(nativeWhisper), nil
|
||||||
|
}
|
@ -4,8 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -13,8 +12,8 @@ type gethPublicWhisperAPIWrapper struct {
|
|||||||
publicWhisperAPI *whisper.PublicWhisperAPI
|
publicWhisperAPI *whisper.PublicWhisperAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGethPublicWhisperAPIWrapper returns an object that wraps Geth's PublicWhisperAPI in a whispertypes interface
|
// NewGethPublicWhisperAPIWrapper returns an object that wraps Geth's PublicWhisperAPI in a types interface
|
||||||
func NewGethPublicWhisperAPIWrapper(publicWhisperAPI *whisper.PublicWhisperAPI) whispertypes.PublicWhisperAPI {
|
func NewGethPublicWhisperAPIWrapper(publicWhisperAPI *whisper.PublicWhisperAPI) types.PublicWhisperAPI {
|
||||||
if publicWhisperAPI == nil {
|
if publicWhisperAPI == nil {
|
||||||
panic("publicWhisperAPI cannot be nil")
|
panic("publicWhisperAPI cannot be nil")
|
||||||
}
|
}
|
||||||
@ -25,7 +24,7 @@ func NewGethPublicWhisperAPIWrapper(publicWhisperAPI *whisper.PublicWhisperAPI)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddPrivateKey imports the given private key.
|
// AddPrivateKey imports the given private key.
|
||||||
func (w *gethPublicWhisperAPIWrapper) AddPrivateKey(ctx context.Context, privateKey statusproto.HexBytes) (string, error) {
|
func (w *gethPublicWhisperAPIWrapper) AddPrivateKey(ctx context.Context, privateKey types.HexBytes) (string, error) {
|
||||||
return w.publicWhisperAPI.AddPrivateKey(ctx, hexutil.Bytes(privateKey))
|
return w.publicWhisperAPI.AddPrivateKey(ctx, hexutil.Bytes(privateKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ func (w *gethPublicWhisperAPIWrapper) DeleteKeyPair(ctx context.Context, key str
|
|||||||
|
|
||||||
// NewMessageFilter creates a new filter that can be used to poll for
|
// NewMessageFilter creates a new filter that can be used to poll for
|
||||||
// (new) messages that satisfy the given criteria.
|
// (new) messages that satisfy the given criteria.
|
||||||
func (w *gethPublicWhisperAPIWrapper) NewMessageFilter(req whispertypes.Criteria) (string, error) {
|
func (w *gethPublicWhisperAPIWrapper) NewMessageFilter(req types.Criteria) (string, error) {
|
||||||
topics := make([]whisper.TopicType, len(req.Topics))
|
topics := make([]whisper.TopicType, len(req.Topics))
|
||||||
for index, tt := range req.Topics {
|
for index, tt := range req.Topics {
|
||||||
topics[index] = whisper.TopicType(tt)
|
topics[index] = whisper.TopicType(tt)
|
||||||
@ -60,19 +59,19 @@ func (w *gethPublicWhisperAPIWrapper) NewMessageFilter(req whispertypes.Criteria
|
|||||||
|
|
||||||
// GetFilterMessages returns the messages that match the filter criteria and
|
// GetFilterMessages returns the messages that match the filter criteria and
|
||||||
// are received between the last poll and now.
|
// are received between the last poll and now.
|
||||||
func (w *gethPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whispertypes.Message, error) {
|
func (w *gethPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*types.Message, error) {
|
||||||
msgs, err := w.publicWhisperAPI.GetFilterMessages(id)
|
msgs, err := w.publicWhisperAPI.GetFilterMessages(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappedMsgs := make([]*whispertypes.Message, len(msgs))
|
wrappedMsgs := make([]*types.Message, len(msgs))
|
||||||
for index, msg := range msgs {
|
for index, msg := range msgs {
|
||||||
wrappedMsgs[index] = &whispertypes.Message{
|
wrappedMsgs[index] = &types.Message{
|
||||||
Sig: msg.Sig,
|
Sig: msg.Sig,
|
||||||
TTL: msg.TTL,
|
TTL: msg.TTL,
|
||||||
Timestamp: msg.Timestamp,
|
Timestamp: msg.Timestamp,
|
||||||
Topic: whispertypes.TopicType(msg.Topic),
|
Topic: types.TopicType(msg.Topic),
|
||||||
Payload: msg.Payload,
|
Payload: msg.Payload,
|
||||||
Padding: msg.Padding,
|
Padding: msg.Padding,
|
||||||
PoW: msg.PoW,
|
PoW: msg.PoW,
|
||||||
@ -86,7 +85,7 @@ func (w *gethPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whisperty
|
|||||||
|
|
||||||
// Post posts a message on the Whisper network.
|
// Post posts a message on the Whisper network.
|
||||||
// returns the hash of the message in case of success.
|
// returns the hash of the message in case of success.
|
||||||
func (w *gethPublicWhisperAPIWrapper) Post(ctx context.Context, req whispertypes.NewMessage) ([]byte, error) {
|
func (w *gethPublicWhisperAPIWrapper) Post(ctx context.Context, req types.NewMessage) ([]byte, error) {
|
||||||
msg := whisper.NewMessage{
|
msg := whisper.NewMessage{
|
||||||
SymKeyID: req.SymKeyID,
|
SymKeyID: req.SymKeyID,
|
||||||
PublicKey: req.PublicKey,
|
PublicKey: req.PublicKey,
|
@ -2,15 +2,15 @@ package gethbridge
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type gethSubscriptionWrapper struct {
|
type gethSubscriptionWrapper struct {
|
||||||
subscription event.Subscription
|
subscription event.Subscription
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGethSubscriptionWrapper returns an object that wraps Geth's Subscription in a whispertypes interface
|
// NewGethSubscriptionWrapper returns an object that wraps Geth's Subscription in a types interface
|
||||||
func NewGethSubscriptionWrapper(subscription event.Subscription) whispertypes.Subscription {
|
func NewGethSubscriptionWrapper(subscription event.Subscription) types.Subscription {
|
||||||
if subscription == nil {
|
if subscription == nil {
|
||||||
panic("subscription cannot be nil")
|
panic("subscription cannot be nil")
|
||||||
}
|
}
|
14
vendor/github.com/status-im/status-go/eth-node/bridge/geth/syncevent_response.go
generated
vendored
Normal file
14
vendor/github.com/status-im/status-go/eth-node/bridge/geth/syncevent_response.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package gethbridge
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewGethSyncEventResponseWrapper returns a types.SyncEventResponse object that mimics Geth's SyncEventResponse
|
||||||
|
func NewGethSyncEventResponseWrapper(syncEventResponse whisper.SyncEventResponse) types.SyncEventResponse {
|
||||||
|
return types.SyncEventResponse{
|
||||||
|
Cursor: syncEventResponse.Cursor,
|
||||||
|
Error: syncEventResponse.Error,
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,12 @@
|
|||||||
package gethbridge
|
package gethbridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetGethSyncMailRequestFrom converts a whisper SyncMailRequest struct from a SyncMailRequest struct
|
// GetGethSyncMailRequestFrom converts a whisper SyncMailRequest struct from a SyncMailRequest struct
|
||||||
func GetGethSyncMailRequestFrom(r *whispertypes.SyncMailRequest) *whisper.SyncMailRequest {
|
func GetGethSyncMailRequestFrom(r *types.SyncMailRequest) *whisper.SyncMailRequest {
|
||||||
return &whisper.SyncMailRequest{
|
return &whisper.SyncMailRequest{
|
||||||
Lower: r.Lower,
|
Lower: r.Lower,
|
||||||
Upper: r.Upper,
|
Upper: r.Upper,
|
@ -4,7 +4,7 @@ import (
|
|||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -12,8 +12,8 @@ type gethWhisperWrapper struct {
|
|||||||
whisper *whisper.Whisper
|
whisper *whisper.Whisper
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGethWhisperWrapper returns an object that wraps Geth's Whisper in a whispertypes interface
|
// NewGethWhisperWrapper returns an object that wraps Geth's Whisper in a types interface
|
||||||
func NewGethWhisperWrapper(w *whisper.Whisper) whispertypes.Whisper {
|
func NewGethWhisperWrapper(w *whisper.Whisper) types.Whisper {
|
||||||
if w == nil {
|
if w == nil {
|
||||||
panic("w cannot be nil")
|
panic("w cannot be nil")
|
||||||
}
|
}
|
||||||
@ -24,11 +24,11 @@ func NewGethWhisperWrapper(w *whisper.Whisper) whispertypes.Whisper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetGethWhisperFrom retrieves the underlying whisper Whisper struct from a wrapped Whisper interface
|
// GetGethWhisperFrom retrieves the underlying whisper Whisper struct from a wrapped Whisper interface
|
||||||
func GetGethWhisperFrom(m whispertypes.Whisper) *whisper.Whisper {
|
func GetGethWhisperFrom(m types.Whisper) *whisper.Whisper {
|
||||||
return m.(*gethWhisperWrapper).whisper
|
return m.(*gethWhisperWrapper).whisper
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethWhisperWrapper) PublicWhisperAPI() whispertypes.PublicWhisperAPI {
|
func (w *gethWhisperWrapper) PublicWhisperAPI() types.PublicWhisperAPI {
|
||||||
return NewGethPublicWhisperAPIWrapper(whisper.NewPublicWhisperAPI(w.whisper))
|
return NewGethPublicWhisperAPIWrapper(whisper.NewPublicWhisperAPI(w.whisper))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ func (w *gethWhisperWrapper) SetTimeSource(timesource func() time.Time) {
|
|||||||
w.whisper.SetTimeSource(timesource)
|
w.whisper.SetTimeSource(timesource)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethWhisperWrapper) SubscribeEnvelopeEvents(eventsProxy chan<- whispertypes.EnvelopeEvent) whispertypes.Subscription {
|
func (w *gethWhisperWrapper) SubscribeEnvelopeEvents(eventsProxy chan<- types.EnvelopeEvent) types.Subscription {
|
||||||
events := make(chan whisper.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
events := make(chan whisper.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||||
go func() {
|
go func() {
|
||||||
for e := range events {
|
for e := range events {
|
||||||
@ -112,7 +112,7 @@ func (w *gethWhisperWrapper) GetSymKey(id string) ([]byte, error) {
|
|||||||
return w.whisper.GetSymKey(id)
|
return w.whisper.GetSymKey(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethWhisperWrapper) Subscribe(opts *whispertypes.SubscriptionOptions) (string, error) {
|
func (w *gethWhisperWrapper) Subscribe(opts *types.SubscriptionOptions) (string, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
keyAsym *ecdsa.PrivateKey
|
keyAsym *ecdsa.PrivateKey
|
||||||
@ -146,7 +146,7 @@ func (w *gethWhisperWrapper) Subscribe(opts *whispertypes.SubscriptionOptions) (
|
|||||||
return id, nil
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethWhisperWrapper) GetFilter(id string) whispertypes.Filter {
|
func (w *gethWhisperWrapper) GetFilter(id string) types.Filter {
|
||||||
return NewGethFilterWrapper(w.whisper.GetFilter(id), id)
|
return NewGethFilterWrapper(w.whisper.GetFilter(id), id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ func (w *gethWhisperWrapper) Unsubscribe(id string) error {
|
|||||||
return w.whisper.Unsubscribe(id)
|
return w.whisper.Unsubscribe(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethWhisperWrapper) createFilterWrapper(id string, keyAsym *ecdsa.PrivateKey, keySym []byte, pow float64, topics [][]byte) (whispertypes.Filter, error) {
|
func (w *gethWhisperWrapper) createFilterWrapper(id string, keyAsym *ecdsa.PrivateKey, keySym []byte, pow float64, topics [][]byte) (types.Filter, error) {
|
||||||
return NewGethFilterWrapper(&whisper.Filter{
|
return NewGethFilterWrapper(&whisper.Filter{
|
||||||
KeyAsym: keyAsym,
|
KeyAsym: keyAsym,
|
||||||
KeySym: keySym,
|
KeySym: keySym,
|
||||||
@ -165,7 +165,7 @@ func (w *gethWhisperWrapper) createFilterWrapper(id string, keyAsym *ecdsa.Priva
|
|||||||
}, id), nil
|
}, id), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *gethWhisperWrapper) SendMessagesRequest(peerID []byte, r whispertypes.MessagesRequest) error {
|
func (w *gethWhisperWrapper) SendMessagesRequest(peerID []byte, r types.MessagesRequest) error {
|
||||||
return w.whisper.SendMessagesRequest(peerID, whisper.MessagesRequest{
|
return w.whisper.SendMessagesRequest(peerID, whisper.MessagesRequest{
|
||||||
ID: r.ID,
|
ID: r.ID,
|
||||||
From: r.From,
|
From: r.From,
|
||||||
@ -181,11 +181,11 @@ func (w *gethWhisperWrapper) SendMessagesRequest(peerID []byte, r whispertypes.M
|
|||||||
// request and respond with a number of peer-to-peer messages (possibly expired),
|
// request and respond with a number of peer-to-peer messages (possibly expired),
|
||||||
// which are not supposed to be forwarded any further.
|
// which are not supposed to be forwarded any further.
|
||||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||||
func (w *gethWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope whispertypes.Envelope, timeout time.Duration) error {
|
func (w *gethWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
||||||
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, GetGethEnvelopeFrom(envelope), timeout)
|
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, GetGethEnvelopeFrom(envelope), timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
||||||
func (w *gethWhisperWrapper) SyncMessages(peerID []byte, req whispertypes.SyncMailRequest) error {
|
func (w *gethWhisperWrapper) SyncMessages(peerID []byte, req types.SyncMailRequest) error {
|
||||||
return w.whisper.SyncMessages(peerID, *GetGethSyncMailRequestFrom(&req))
|
return w.whisper.SyncMessages(peerID, *GetGethSyncMailRequestFrom(&req))
|
||||||
}
|
}
|
19
scripts/build-nimbus.sh → vendor/github.com/status-im/status-go/eth-node/bridge/nimbus/build-nimbus.sh
generated
vendored
Executable file → Normal file
19
scripts/build-nimbus.sh → vendor/github.com/status-im/status-go/eth-node/bridge/nimbus/build-nimbus.sh
generated
vendored
Executable file → Normal file
@ -9,11 +9,11 @@ GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
|
|||||||
# NOTE: To use a local Nimbus repository, uncomment and edit the following line
|
# NOTE: To use a local Nimbus repository, uncomment and edit the following line
|
||||||
#nimbus_dir=~/src/github.com/status-im/nimbus
|
#nimbus_dir=~/src/github.com/status-im/nimbus
|
||||||
|
|
||||||
protocol_dir="${GIT_ROOT}/vendor/github.com/status-im/status-protocol-go/bridge/nimbus"
|
target_dir="${GIT_ROOT}/vendor/github.com/status-im/status-go/eth-node/bridge/nimbus"
|
||||||
|
|
||||||
if [ -z "$nimbus_dir" ]; then
|
if [ -z "$nimbus_dir" ]; then
|
||||||
# The git ref of Nimbus to fetch and build. This should represent a commit SHA or a tag, for reproducible builds
|
# The git ref of Nimbus to fetch and build. This should represent a commit SHA or a tag, for reproducible builds
|
||||||
nimbus_ref='wrapper-go' # TODO: Use a real ref/tag once https://github.com/status-im/nimbus/pull/395 is merged
|
nimbus_ref='master' # TODO: Use a tag once
|
||||||
|
|
||||||
nimbus_src='https://github.com/status-im/nimbus/'
|
nimbus_src='https://github.com/status-im/nimbus/'
|
||||||
nimbus_dir="${GIT_ROOT}/vendor/github.com/status-im/nimbus"
|
nimbus_dir="${GIT_ROOT}/vendor/github.com/status-im/nimbus"
|
||||||
@ -22,7 +22,7 @@ if [ -z "$nimbus_dir" ]; then
|
|||||||
|
|
||||||
# Clone nimbus repo into vendor directory, if necessary
|
# Clone nimbus repo into vendor directory, if necessary
|
||||||
if [ -d "$nimbus_dir" ]; then
|
if [ -d "$nimbus_dir" ]; then
|
||||||
cd $nimbus_dir && git reset --hard; cd -
|
cd $nimbus_dir && git reset --hard $nimbus_ref; cd -
|
||||||
else
|
else
|
||||||
# List fetched from vendorDeps array in https://github.com/status-im/nimbus/blob/master/nix/nimbus-wrappers.nix#L9-L12
|
# List fetched from vendorDeps array in https://github.com/status-im/nimbus/blob/master/nix/nimbus-wrappers.nix#L9-L12
|
||||||
vendor_paths=( nim-chronicles nim-faststreams nim-json-serialization nim-chronos nim-eth nim-json nim-metrics nim-secp256k1 nim-serialization nim-stew nim-stint nimcrypto )
|
vendor_paths=( nim-chronicles nim-faststreams nim-json-serialization nim-chronos nim-eth nim-json nim-metrics nim-secp256k1 nim-serialization nim-stew nim-stint nimcrypto )
|
||||||
@ -31,13 +31,14 @@ if [ -z "$nimbus_dir" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build Nimbus wrappers and copy them into the Nimbus bridge in status-protocol-go
|
# Build Nimbus wrappers and copy them into the Nimbus bridge in status-eth-node
|
||||||
protocol_build_dir=$(cd $nimbus_dir && nix-build --pure --no-out-link -A wrappers)
|
build_dir=$(cd $nimbus_dir && nix-build --pure --no-out-link -A wrappers)
|
||||||
# Ideally we'd use the static version of the Nimbus library (.a),
|
# Ideally we'd use the static version of the Nimbus library (.a),
|
||||||
# however that causes link errors due to duplicate symbols:
|
# however that causes link errors due to duplicate symbols:
|
||||||
# ${protocol_dir}/libnimbus.a(secp256k1.c.o): In function `secp256k1_context_create':
|
# ${target_dir}/libnimbus.a(secp256k1.c.o): In function `secp256k1_context_create':
|
||||||
# (.text+0xca80): multiple definition of `secp256k1_context_create'
|
# (.text+0xca80): multiple definition of `secp256k1_context_create'
|
||||||
# /tmp/go-link-476687730/000014.o:${GIT_ROOT}/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/./libsecp256k1/src/secp256k1.c:56: first defined here
|
# /tmp/go-link-476687730/000014.o:${GIT_ROOT}/vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/./libsecp256k1/src/secp256k1.c:56: first defined here
|
||||||
rm -f ${protocol_dir}/libnimbus.*
|
rm -f ${target_dir}/libnimbus.*
|
||||||
cp -f ${protocol_build_dir}/include/* ${protocol_build_dir}/lib/libnimbus.so \
|
mkdir -p ${target_dir}
|
||||||
${protocol_dir}/
|
cp -f ${build_dir}/include/* ${build_dir}/lib/libnimbus.so \
|
||||||
|
${target_dir}/
|
@ -15,7 +15,7 @@ import "C"
|
|||||||
import (
|
import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nimbusFilterWrapper struct {
|
type nimbusFilterWrapper struct {
|
||||||
@ -24,8 +24,8 @@ type nimbusFilterWrapper struct {
|
|||||||
own bool
|
own bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNimbusFilterWrapper returns an object that wraps Nimbus's Filter in a whispertypes interface
|
// NewNimbusFilterWrapper returns an object that wraps Nimbus's Filter in a types interface
|
||||||
func NewNimbusFilterWrapper(f *C.filter_options, id string, own bool) whispertypes.Filter {
|
func NewNimbusFilterWrapper(f *C.filter_options, id string, own bool) types.Filter {
|
||||||
wrapper := &nimbusFilterWrapper{
|
wrapper := &nimbusFilterWrapper{
|
||||||
filter: f,
|
filter: f,
|
||||||
id: id,
|
id: id,
|
||||||
@ -35,7 +35,7 @@ func NewNimbusFilterWrapper(f *C.filter_options, id string, own bool) whispertyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetNimbusFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
|
// GetNimbusFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
|
||||||
func GetNimbusFilterFrom(f whispertypes.Filter) *C.filter_options {
|
func GetNimbusFilterFrom(f types.Filter) *C.filter_options {
|
||||||
return f.(*nimbusFilterWrapper).filter
|
return f.(*nimbusFilterWrapper).filter
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,10 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
enstypes "github.com/status-im/status-go/eth-node/types/ens"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
@ -42,3 +45,19 @@ func StartNimbus(privateKey *ecdsa.PrivateKey, listenAddr string, staging bool)
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type nimbusNodeWrapper struct {
|
||||||
|
w types.Whisper
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNodeBridge() types.Node {
|
||||||
|
return &nimbusNodeWrapper{w: NewNimbusWhisperWrapper()}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *nimbusNodeWrapper) NewENSVerifier(_ *zap.Logger) enstypes.ENSVerifier {
|
||||||
|
panic("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *nimbusNodeWrapper) GetWhisper(ctx interface{}) (types.Whisper, error) {
|
||||||
|
return w.w, nil
|
||||||
|
}
|
@ -20,8 +20,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type nimbusPublicWhisperAPIWrapper struct {
|
type nimbusPublicWhisperAPIWrapper struct {
|
||||||
@ -30,8 +29,8 @@ type nimbusPublicWhisperAPIWrapper struct {
|
|||||||
routineQueue *RoutineQueue
|
routineQueue *RoutineQueue
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNimbusPublicWhisperAPIWrapper returns an object that wraps Nimbus's PublicWhisperAPI in a whispertypes interface
|
// NewNimbusPublicWhisperAPIWrapper returns an object that wraps Nimbus's PublicWhisperAPI in a types interface
|
||||||
func NewNimbusPublicWhisperAPIWrapper(filterMessagesMu *sync.Mutex, filterMessages *map[string]*list.List, routineQueue *RoutineQueue) whispertypes.PublicWhisperAPI {
|
func NewNimbusPublicWhisperAPIWrapper(filterMessagesMu *sync.Mutex, filterMessages *map[string]*list.List, routineQueue *RoutineQueue) types.PublicWhisperAPI {
|
||||||
return &nimbusPublicWhisperAPIWrapper{
|
return &nimbusPublicWhisperAPIWrapper{
|
||||||
filterMessagesMu: filterMessagesMu,
|
filterMessagesMu: filterMessagesMu,
|
||||||
filterMessages: filterMessages,
|
filterMessages: filterMessages,
|
||||||
@ -40,7 +39,7 @@ func NewNimbusPublicWhisperAPIWrapper(filterMessagesMu *sync.Mutex, filterMessag
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddPrivateKey imports the given private key.
|
// AddPrivateKey imports the given private key.
|
||||||
func (w *nimbusPublicWhisperAPIWrapper) AddPrivateKey(ctx context.Context, privateKey statusproto.HexBytes) (string, error) {
|
func (w *nimbusPublicWhisperAPIWrapper) AddPrivateKey(ctx context.Context, privateKey types.HexBytes) (string, error) {
|
||||||
retVal := w.routineQueue.Send(func(c chan<- interface{}) {
|
retVal := w.routineQueue.Send(func(c chan<- interface{}) {
|
||||||
privKeyC := C.CBytes(privateKey)
|
privKeyC := C.CBytes(privateKey)
|
||||||
defer C.free(unsafe.Pointer(privKeyC))
|
defer C.free(unsafe.Pointer(privKeyC))
|
||||||
@ -48,7 +47,7 @@ func (w *nimbusPublicWhisperAPIWrapper) AddPrivateKey(ctx context.Context, priva
|
|||||||
idC := C.malloc(C.size_t(C.ID_LEN))
|
idC := C.malloc(C.size_t(C.ID_LEN))
|
||||||
defer C.free(idC)
|
defer C.free(idC)
|
||||||
if C.nimbus_add_keypair((*C.uchar)(privKeyC), (*C.uchar)(idC)) {
|
if C.nimbus_add_keypair((*C.uchar)(privKeyC), (*C.uchar)(idC)) {
|
||||||
c <- statusproto.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
c <- types.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
||||||
} else {
|
} else {
|
||||||
c <- errors.New("failed to add private key to Nimbus")
|
c <- errors.New("failed to add private key to Nimbus")
|
||||||
}
|
}
|
||||||
@ -69,7 +68,7 @@ func (w *nimbusPublicWhisperAPIWrapper) GenerateSymKeyFromPassword(ctx context.C
|
|||||||
idC := C.malloc(C.size_t(C.ID_LEN))
|
idC := C.malloc(C.size_t(C.ID_LEN))
|
||||||
defer C.free(idC)
|
defer C.free(idC)
|
||||||
if C.nimbus_add_symkey_from_password(passwordC, (*C.uchar)(idC)) {
|
if C.nimbus_add_symkey_from_password(passwordC, (*C.uchar)(idC)) {
|
||||||
c <- statusproto.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
c <- types.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
||||||
} else {
|
} else {
|
||||||
c <- errors.New("failed to add symkey to Nimbus")
|
c <- errors.New("failed to add symkey to Nimbus")
|
||||||
}
|
}
|
||||||
@ -102,7 +101,7 @@ func (w *nimbusPublicWhisperAPIWrapper) DeleteKeyPair(ctx context.Context, key s
|
|||||||
|
|
||||||
// NewMessageFilter creates a new filter that can be used to poll for
|
// NewMessageFilter creates a new filter that can be used to poll for
|
||||||
// (new) messages that satisfy the given criteria.
|
// (new) messages that satisfy the given criteria.
|
||||||
func (w *nimbusPublicWhisperAPIWrapper) NewMessageFilter(req whispertypes.Criteria) (string, error) {
|
func (w *nimbusPublicWhisperAPIWrapper) NewMessageFilter(req types.Criteria) (string, error) {
|
||||||
// topics := make([]whisper.TopicType, len(req.Topics))
|
// topics := make([]whisper.TopicType, len(req.Topics))
|
||||||
// for index, tt := range req.Topics {
|
// for index, tt := range req.Topics {
|
||||||
// topics[index] = whisper.TopicType(tt)
|
// topics[index] = whisper.TopicType(tt)
|
||||||
@ -123,7 +122,7 @@ func (w *nimbusPublicWhisperAPIWrapper) NewMessageFilter(req whispertypes.Criter
|
|||||||
|
|
||||||
// GetFilterMessages returns the messages that match the filter criteria and
|
// GetFilterMessages returns the messages that match the filter criteria and
|
||||||
// are received between the last poll and now.
|
// are received between the last poll and now.
|
||||||
func (w *nimbusPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whispertypes.Message, error) {
|
func (w *nimbusPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*types.Message, error) {
|
||||||
idC := C.CString(id)
|
idC := C.CString(id)
|
||||||
defer C.free(unsafe.Pointer(idC))
|
defer C.free(unsafe.Pointer(idC))
|
||||||
|
|
||||||
@ -137,7 +136,7 @@ func (w *nimbusPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whisper
|
|||||||
return nil, fmt.Errorf("no filter with ID %s", id)
|
return nil, fmt.Errorf("no filter with ID %s", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
retVal := make([]*whispertypes.Message, messageList.Len())
|
retVal := make([]*types.Message, messageList.Len())
|
||||||
if messageList.Len() == 0 {
|
if messageList.Len() == 0 {
|
||||||
return retVal, nil
|
return retVal, nil
|
||||||
}
|
}
|
||||||
@ -145,7 +144,7 @@ func (w *nimbusPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whisper
|
|||||||
elem := messageList.Front()
|
elem := messageList.Front()
|
||||||
index := 0
|
index := 0
|
||||||
for elem != nil {
|
for elem != nil {
|
||||||
retVal[index] = (elem.Value).(*whispertypes.Message)
|
retVal[index] = (elem.Value).(*types.Message)
|
||||||
index++
|
index++
|
||||||
next := elem.Next()
|
next := elem.Next()
|
||||||
messageList.Remove(elem)
|
messageList.Remove(elem)
|
||||||
@ -156,7 +155,7 @@ func (w *nimbusPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whisper
|
|||||||
|
|
||||||
// Post posts a message on the Whisper network.
|
// Post posts a message on the Whisper network.
|
||||||
// returns the hash of the message in case of success.
|
// returns the hash of the message in case of success.
|
||||||
func (w *nimbusPublicWhisperAPIWrapper) Post(ctx context.Context, req whispertypes.NewMessage) ([]byte, error) {
|
func (w *nimbusPublicWhisperAPIWrapper) Post(ctx context.Context, req types.NewMessage) ([]byte, error) {
|
||||||
retVal := w.routineQueue.Send(func(c chan<- interface{}) {
|
retVal := w.routineQueue.Send(func(c chan<- interface{}) {
|
||||||
msg := C.post_message{
|
msg := C.post_message{
|
||||||
ttl: C.uint32_t(req.TTL),
|
ttl: C.uint32_t(req.TTL),
|
@ -24,33 +24,32 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
gopointer "github.com/mattn/go-pointer"
|
gopointer "github.com/mattn/go-pointer"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type nimbusWhisperWrapper struct {
|
type nimbusWhisperWrapper struct {
|
||||||
timesource func() time.Time
|
timesource func() time.Time
|
||||||
filters map[string]whispertypes.Filter
|
filters map[string]types.Filter
|
||||||
filterMessagesMu sync.Mutex
|
filterMessagesMu sync.Mutex
|
||||||
filterMessages map[string]*list.List
|
filterMessages map[string]*list.List
|
||||||
routineQueue *RoutineQueue
|
routineQueue *RoutineQueue
|
||||||
tid int
|
tid int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNimbusWhisperWrapper returns an object that wraps Nimbus' Whisper in a whispertypes interface
|
// NewNimbusWhisperWrapper returns an object that wraps Nimbus' Whisper in a types interface
|
||||||
func NewNimbusWhisperWrapper() whispertypes.Whisper {
|
func NewNimbusWhisperWrapper() types.Whisper {
|
||||||
return &nimbusWhisperWrapper{
|
return &nimbusWhisperWrapper{
|
||||||
timesource: func() time.Time { return time.Now() },
|
timesource: func() time.Time { return time.Now() },
|
||||||
filters: map[string]whispertypes.Filter{},
|
filters: map[string]types.Filter{},
|
||||||
filterMessages: map[string]*list.List{},
|
filterMessages: map[string]*list.List{},
|
||||||
routineQueue: NewRoutineQueue(),
|
routineQueue: NewRoutineQueue(),
|
||||||
tid: syscall.Gettid(),
|
tid: syscall.Gettid(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *nimbusWhisperWrapper) PublicWhisperAPI() whispertypes.PublicWhisperAPI {
|
func (w *nimbusWhisperWrapper) PublicWhisperAPI() types.PublicWhisperAPI {
|
||||||
return NewNimbusPublicWhisperAPIWrapper(&w.filterMessagesMu, &w.filterMessages, w.routineQueue)
|
return NewNimbusPublicWhisperAPIWrapper(&w.filterMessagesMu, &w.filterMessages, w.routineQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +99,7 @@ func (w *nimbusWhisperWrapper) SetTimeSource(timesource func() time.Time) {
|
|||||||
w.timesource = timesource
|
w.timesource = timesource
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *nimbusWhisperWrapper) SubscribeEnvelopeEvents(eventsProxy chan<- whispertypes.EnvelopeEvent) whispertypes.Subscription {
|
func (w *nimbusWhisperWrapper) SubscribeEnvelopeEvents(eventsProxy chan<- types.EnvelopeEvent) types.Subscription {
|
||||||
// TODO: when mailserver support is implemented
|
// TODO: when mailserver support is implemented
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
@ -119,7 +118,7 @@ func (w *nimbusWhisperWrapper) GetPrivateKey(id string) (*ecdsa.PrivateKey, erro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer C.free(unsafe.Pointer(idC))
|
defer C.free(unsafe.Pointer(idC))
|
||||||
privKeyC := C.malloc(whispertypes.AesKeyLength)
|
privKeyC := C.malloc(types.AesKeyLength)
|
||||||
defer C.free(unsafe.Pointer(privKeyC))
|
defer C.free(unsafe.Pointer(privKeyC))
|
||||||
|
|
||||||
if ok := C.nimbus_get_private_key(idC, (*C.uchar)(unsafe.Pointer(privKeyC))); !ok {
|
if ok := C.nimbus_get_private_key(idC, (*C.uchar)(unsafe.Pointer(privKeyC))); !ok {
|
||||||
@ -156,7 +155,7 @@ func (w *nimbusWhisperWrapper) AddKeyPair(key *ecdsa.PrivateKey) (string, error)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c <- statusproto.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
c <- types.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
||||||
})
|
})
|
||||||
if err, ok := retVal.(error); ok {
|
if err, ok := retVal.(error); ok {
|
||||||
return "", err
|
return "", err
|
||||||
@ -197,7 +196,7 @@ func (w *nimbusWhisperWrapper) AddSymKeyDirect(key []byte) (string, error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c <- statusproto.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
c <- types.EncodeHex(C.GoBytes(idC, C.ID_LEN))
|
||||||
})
|
})
|
||||||
if err, ok := retVal.(error); ok {
|
if err, ok := retVal.(error); ok {
|
||||||
return "", err
|
return "", err
|
||||||
@ -215,7 +214,7 @@ func (w *nimbusWhisperWrapper) AddSymKeyFromPassword(password string) (string, e
|
|||||||
defer C.free(idC)
|
defer C.free(idC)
|
||||||
if C.nimbus_add_symkey_from_password(passwordC, (*C.uchar)(idC)) {
|
if C.nimbus_add_symkey_from_password(passwordC, (*C.uchar)(idC)) {
|
||||||
id := C.GoBytes(idC, C.ID_LEN)
|
id := C.GoBytes(idC, C.ID_LEN)
|
||||||
c <- statusproto.EncodeHex(id)
|
c <- types.EncodeHex(id)
|
||||||
} else {
|
} else {
|
||||||
c <- errors.New("failed to add symkey to Nimbus")
|
c <- errors.New("failed to add symkey to Nimbus")
|
||||||
}
|
}
|
||||||
@ -270,28 +269,28 @@ func (w *nimbusWhisperWrapper) GetSymKey(id string) ([]byte, error) {
|
|||||||
func onMessageHandler(msg *C.received_message, udata unsafe.Pointer) {
|
func onMessageHandler(msg *C.received_message, udata unsafe.Pointer) {
|
||||||
messageList := (gopointer.Restore(udata)).(*list.List)
|
messageList := (gopointer.Restore(udata)).(*list.List)
|
||||||
|
|
||||||
topic := whispertypes.TopicType{}
|
topic := types.TopicType{}
|
||||||
copy(topic[:], C.GoBytes(unsafe.Pointer(&msg.topic[0]), whispertypes.TopicLength)[:whispertypes.TopicLength])
|
copy(topic[:], C.GoBytes(unsafe.Pointer(&msg.topic[0]), types.TopicLength)[:types.TopicLength])
|
||||||
wrappedMsg := &whispertypes.Message{
|
wrappedMsg := &types.Message{
|
||||||
TTL: uint32(msg.ttl),
|
TTL: uint32(msg.ttl),
|
||||||
Timestamp: uint32(msg.timestamp),
|
Timestamp: uint32(msg.timestamp),
|
||||||
Topic: topic,
|
Topic: topic,
|
||||||
Payload: C.GoBytes(unsafe.Pointer(msg.decoded), C.int(msg.decodedLen)),
|
Payload: C.GoBytes(unsafe.Pointer(msg.decoded), C.int(msg.decodedLen)),
|
||||||
PoW: float64(msg.pow),
|
PoW: float64(msg.pow),
|
||||||
Hash: C.GoBytes(unsafe.Pointer(&msg.hash[0]), statusproto.HashLength),
|
Hash: C.GoBytes(unsafe.Pointer(&msg.hash[0]), types.HashLength),
|
||||||
P2P: true,
|
P2P: true,
|
||||||
}
|
}
|
||||||
if msg.source != nil {
|
if msg.source != nil {
|
||||||
wrappedMsg.Sig = append([]byte{0x04}, C.GoBytes(unsafe.Pointer(msg.source), whispertypes.PubKeyLength)...)
|
wrappedMsg.Sig = append([]byte{0x04}, C.GoBytes(unsafe.Pointer(msg.source), types.PubKeyLength)...)
|
||||||
}
|
}
|
||||||
if msg.recipientPublicKey != nil {
|
if msg.recipientPublicKey != nil {
|
||||||
wrappedMsg.Dst = append([]byte{0x04}, C.GoBytes(unsafe.Pointer(msg.recipientPublicKey), whispertypes.PubKeyLength)...)
|
wrappedMsg.Dst = append([]byte{0x04}, C.GoBytes(unsafe.Pointer(msg.recipientPublicKey), types.PubKeyLength)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
messageList.PushBack(wrappedMsg)
|
messageList.PushBack(wrappedMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *nimbusWhisperWrapper) Subscribe(opts *whispertypes.SubscriptionOptions) (string, error) {
|
func (w *nimbusWhisperWrapper) Subscribe(opts *types.SubscriptionOptions) (string, error) {
|
||||||
f, err := w.createFilterWrapper("", opts)
|
f, err := w.createFilterWrapper("", opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -326,7 +325,7 @@ func (w *nimbusWhisperWrapper) Subscribe(opts *whispertypes.SubscriptionOptions)
|
|||||||
return retVal.(string), nil
|
return retVal.(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *nimbusWhisperWrapper) GetFilter(id string) whispertypes.Filter {
|
func (w *nimbusWhisperWrapper) GetFilter(id string) types.Filter {
|
||||||
idC := C.CString(id)
|
idC := C.CString(id)
|
||||||
defer C.free(unsafe.Pointer(idC))
|
defer C.free(unsafe.Pointer(idC))
|
||||||
|
|
||||||
@ -366,7 +365,7 @@ func (w *nimbusWhisperWrapper) Unsubscribe(id string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func decodeHexID(id string) (*C.uint8_t, error) {
|
func decodeHexID(id string) (*C.uint8_t, error) {
|
||||||
idBytes, err := statusproto.DecodeHex(id)
|
idBytes, err := types.DecodeHex(id)
|
||||||
if err == nil && len(idBytes) != C.ID_LEN {
|
if err == nil && len(idBytes) != C.ID_LEN {
|
||||||
err = fmt.Errorf("ID length must be %v bytes, actual length is %v", C.ID_LEN, len(idBytes))
|
err = fmt.Errorf("ID length must be %v bytes, actual length is %v", C.ID_LEN, len(idBytes))
|
||||||
}
|
}
|
||||||
@ -379,17 +378,17 @@ func decodeHexID(id string) (*C.uint8_t, error) {
|
|||||||
|
|
||||||
// copyTopicToCBuffer copies a Go topic buffer to a C topic buffer without allocating new memory
|
// copyTopicToCBuffer copies a Go topic buffer to a C topic buffer without allocating new memory
|
||||||
func copyTopicToCBuffer(dst *C.uchar, topic []byte) {
|
func copyTopicToCBuffer(dst *C.uchar, topic []byte) {
|
||||||
if len(topic) != whispertypes.TopicLength {
|
if len(topic) != types.TopicLength {
|
||||||
panic("invalid Whisper topic buffer size")
|
panic("invalid Whisper topic buffer size")
|
||||||
}
|
}
|
||||||
|
|
||||||
p := (*[whispertypes.TopicLength]C.uchar)(unsafe.Pointer(dst))
|
p := (*[types.TopicLength]C.uchar)(unsafe.Pointer(dst))
|
||||||
for index, b := range topic {
|
for index, b := range topic {
|
||||||
p[index] = C.uchar(b)
|
p[index] = C.uchar(b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *nimbusWhisperWrapper) createFilterWrapper(id string, opts *whispertypes.SubscriptionOptions) (whispertypes.Filter, error) {
|
func (w *nimbusWhisperWrapper) createFilterWrapper(id string, opts *types.SubscriptionOptions) (types.Filter, error) {
|
||||||
if len(opts.Topics) != 1 {
|
if len(opts.Topics) != 1 {
|
||||||
return nil, errors.New("currently only 1 topic is supported by the Nimbus bridge")
|
return nil, errors.New("currently only 1 topic is supported by the Nimbus bridge")
|
||||||
}
|
}
|
||||||
@ -417,7 +416,7 @@ func (w *nimbusWhisperWrapper) createFilterWrapper(id string, opts *whispertypes
|
|||||||
return NewNimbusFilterWrapper(&filter, id, true), nil
|
return NewNimbusFilterWrapper(&filter, id, true), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *nimbusWhisperWrapper) SendMessagesRequest(peerID []byte, r whispertypes.MessagesRequest) error {
|
func (w *nimbusWhisperWrapper) SendMessagesRequest(peerID []byte, r types.MessagesRequest) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,11 +425,11 @@ func (w *nimbusWhisperWrapper) SendMessagesRequest(peerID []byte, r whispertypes
|
|||||||
// request and respond with a number of peer-to-peer messages (possibly expired),
|
// request and respond with a number of peer-to-peer messages (possibly expired),
|
||||||
// which are not supposed to be forwarded any further.
|
// which are not supposed to be forwarded any further.
|
||||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||||
func (w *nimbusWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope whispertypes.Envelope, timeout time.Duration) error {
|
func (w *nimbusWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
||||||
func (w *nimbusWhisperWrapper) SyncMessages(peerID []byte, req whispertypes.SyncMailRequest) error {
|
func (w *nimbusWhisperWrapper) SyncMessages(peerID []byte, req types.SyncMailRequest) error {
|
||||||
return errors.New("not implemented")
|
return errors.New("not implemented")
|
||||||
}
|
}
|
@ -9,19 +9,31 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
gethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
aesNonceLength = 12
|
aesNonceLength = 12
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignBytes signs the hash of arbitrary data.
|
// Sign calculates an ECDSA signature.
|
||||||
func SignBytes(data []byte, identity *ecdsa.PrivateKey) ([]byte, error) {
|
//
|
||||||
return crypto.Sign(crypto.Keccak256(data), identity)
|
// This function is susceptible to chosen plaintext attacks that can leak
|
||||||
|
// information about the private key that is used for signing. Callers must
|
||||||
|
// be aware that the given digest cannot be chosen by an adversery. Common
|
||||||
|
// solution is to hash any input before calculating the signature.
|
||||||
|
//
|
||||||
|
// The produced signature is in the [R || S || V] format where V is 0 or 1.
|
||||||
|
func Sign(digestHash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
|
||||||
|
return gethcrypto.Sign(digestHash, prv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignStringAsHex signs the Keccak256 hash of arbitrary data and returns its hex representation.
|
// SignBytes signs the hash of arbitrary data.
|
||||||
|
func SignBytes(data []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
|
||||||
|
return Sign(Keccak256(data), prv)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignBytesAsHex signs the Keccak256 hash of arbitrary data and returns its hex representation.
|
||||||
func SignBytesAsHex(data []byte, identity *ecdsa.PrivateKey) (string, error) {
|
func SignBytesAsHex(data []byte, identity *ecdsa.PrivateKey) (string, error) {
|
||||||
signature, err := SignBytes(data, identity)
|
signature, err := SignBytes(data, identity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -35,16 +47,10 @@ func SignStringAsHex(data string, identity *ecdsa.PrivateKey) (string, error) {
|
|||||||
return SignBytesAsHex([]byte(data), identity)
|
return SignBytesAsHex([]byte(data), identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign signs the hash of arbitrary data.
|
|
||||||
// DEPRECATED: use SignStringAsHex instead.
|
|
||||||
func Sign(data string, identity *ecdsa.PrivateKey) (string, error) {
|
|
||||||
return SignStringAsHex(data, identity)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifySignatures verifies tuples of signatures content/hash/public key
|
// VerifySignatures verifies tuples of signatures content/hash/public key
|
||||||
func VerifySignatures(signaturePairs [][3]string) error {
|
func VerifySignatures(signaturePairs [][3]string) error {
|
||||||
for _, signaturePair := range signaturePairs {
|
for _, signaturePair := range signaturePairs {
|
||||||
content := crypto.Keccak256([]byte(signaturePair[0]))
|
content := Keccak256([]byte(signaturePair[0]))
|
||||||
|
|
||||||
signature, err := hex.DecodeString(signaturePair[1])
|
signature, err := hex.DecodeString(signaturePair[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -56,12 +62,12 @@ func VerifySignatures(signaturePairs [][3]string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
publicKey, err := crypto.UnmarshalPubkey(publicKeyBytes)
|
publicKey, err := UnmarshalPubkey(publicKeyBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
recoveredKey, err := crypto.SigToPub(
|
recoveredKey, err := SigToPub(
|
||||||
content,
|
content,
|
||||||
signature,
|
signature,
|
||||||
)
|
)
|
||||||
@ -69,7 +75,7 @@ func VerifySignatures(signaturePairs [][3]string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if crypto.PubkeyToAddress(*recoveredKey) != crypto.PubkeyToAddress(*publicKey) {
|
if PubkeyToAddress(*recoveredKey) != PubkeyToAddress(*publicKey) {
|
||||||
return errors.New("identity key and signature mismatch")
|
return errors.New("identity key and signature mismatch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,14 +88,14 @@ func VerifySignatures(signaturePairs [][3]string) error {
|
|||||||
func ExtractSignatures(signaturePairs [][2]string) ([]string, error) {
|
func ExtractSignatures(signaturePairs [][2]string) ([]string, error) {
|
||||||
response := make([]string, len(signaturePairs))
|
response := make([]string, len(signaturePairs))
|
||||||
for i, signaturePair := range signaturePairs {
|
for i, signaturePair := range signaturePairs {
|
||||||
content := crypto.Keccak256([]byte(signaturePair[0]))
|
content := Keccak256([]byte(signaturePair[0]))
|
||||||
|
|
||||||
signature, err := hex.DecodeString(signaturePair[1])
|
signature, err := hex.DecodeString(signaturePair[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
recoveredKey, err := crypto.SigToPub(
|
recoveredKey, err := SigToPub(
|
||||||
content,
|
content,
|
||||||
signature,
|
signature,
|
||||||
)
|
)
|
||||||
@ -97,7 +103,7 @@ func ExtractSignatures(signaturePairs [][2]string) ([]string, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response[i] = fmt.Sprintf("%x", crypto.FromECDSAPub(recoveredKey))
|
response[i] = fmt.Sprintf("%x", FromECDSAPub(recoveredKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
@ -105,8 +111,8 @@ func ExtractSignatures(signaturePairs [][2]string) ([]string, error) {
|
|||||||
|
|
||||||
// ExtractSignature returns a public key for a given data and signature.
|
// ExtractSignature returns a public key for a given data and signature.
|
||||||
func ExtractSignature(data, signature []byte) (*ecdsa.PublicKey, error) {
|
func ExtractSignature(data, signature []byte) (*ecdsa.PublicKey, error) {
|
||||||
dataHash := crypto.Keccak256(data)
|
dataHash := Keccak256(data)
|
||||||
return crypto.SigToPub(dataHash, signature)
|
return SigToPub(dataHash, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
func EncryptSymmetric(key, plaintext []byte) ([]byte, error) {
|
func EncryptSymmetric(key, plaintext []byte) ([]byte, error) {
|
366
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/ecies.go
generated
vendored
Normal file
366
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/ecies.go
generated
vendored
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
// Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is>
|
||||||
|
// Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package ecies
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/subtle"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
"io"
|
||||||
|
"math/big"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrImport = fmt.Errorf("ecies: failed to import key")
|
||||||
|
ErrInvalidCurve = fmt.Errorf("ecies: invalid elliptic curve")
|
||||||
|
ErrInvalidParams = fmt.Errorf("ecies: invalid ECIES parameters")
|
||||||
|
ErrInvalidPublicKey = fmt.Errorf("ecies: invalid public key")
|
||||||
|
ErrSharedKeyIsPointAtInfinity = fmt.Errorf("ecies: shared key is point at infinity")
|
||||||
|
ErrSharedKeyTooBig = fmt.Errorf("ecies: shared key params are too big")
|
||||||
|
)
|
||||||
|
|
||||||
|
// PublicKey is a representation of an elliptic curve public key.
|
||||||
|
type PublicKey struct {
|
||||||
|
X *big.Int
|
||||||
|
Y *big.Int
|
||||||
|
elliptic.Curve
|
||||||
|
Params *ECIESParams
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export an ECIES public key as an ECDSA public key.
|
||||||
|
func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey {
|
||||||
|
return &ecdsa.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import an ECDSA public key as an ECIES public key.
|
||||||
|
func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey {
|
||||||
|
return &PublicKey{
|
||||||
|
X: pub.X,
|
||||||
|
Y: pub.Y,
|
||||||
|
Curve: pub.Curve,
|
||||||
|
Params: ParamsFromCurve(pub.Curve),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrivateKey is a representation of an elliptic curve private key.
|
||||||
|
type PrivateKey struct {
|
||||||
|
PublicKey
|
||||||
|
D *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export an ECIES private key as an ECDSA private key.
|
||||||
|
func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey {
|
||||||
|
pub := &prv.PublicKey
|
||||||
|
pubECDSA := pub.ExportECDSA()
|
||||||
|
return &ecdsa.PrivateKey{PublicKey: *pubECDSA, D: prv.D}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import an ECDSA private key as an ECIES private key.
|
||||||
|
func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey {
|
||||||
|
pub := ImportECDSAPublic(&prv.PublicKey)
|
||||||
|
return &PrivateKey{*pub, prv.D}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate an elliptic curve public / private keypair. If params is nil,
|
||||||
|
// the recommended default parameters for the key will be chosen.
|
||||||
|
func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) {
|
||||||
|
pb, x, y, err := elliptic.GenerateKey(curve, rand)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prv = new(PrivateKey)
|
||||||
|
prv.PublicKey.X = x
|
||||||
|
prv.PublicKey.Y = y
|
||||||
|
prv.PublicKey.Curve = curve
|
||||||
|
prv.D = new(big.Int).SetBytes(pb)
|
||||||
|
if params == nil {
|
||||||
|
params = ParamsFromCurve(curve)
|
||||||
|
}
|
||||||
|
prv.PublicKey.Params = params
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaxSharedKeyLength returns the maximum length of the shared key the
|
||||||
|
// public key can produce.
|
||||||
|
func MaxSharedKeyLength(pub *PublicKey) int {
|
||||||
|
return (pub.Curve.Params().BitSize + 7) / 8
|
||||||
|
}
|
||||||
|
|
||||||
|
// ECDH key agreement method used to establish secret keys for encryption.
|
||||||
|
func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) {
|
||||||
|
if prv.PublicKey.Curve != pub.Curve {
|
||||||
|
return nil, ErrInvalidCurve
|
||||||
|
}
|
||||||
|
if skLen+macLen > MaxSharedKeyLength(pub) {
|
||||||
|
return nil, ErrSharedKeyTooBig
|
||||||
|
}
|
||||||
|
|
||||||
|
x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, prv.D.Bytes())
|
||||||
|
if x == nil {
|
||||||
|
return nil, ErrSharedKeyIsPointAtInfinity
|
||||||
|
}
|
||||||
|
|
||||||
|
sk = make([]byte, skLen+macLen)
|
||||||
|
skBytes := x.Bytes()
|
||||||
|
copy(sk[len(sk)-len(skBytes):], skBytes)
|
||||||
|
return sk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data")
|
||||||
|
ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long")
|
||||||
|
ErrInvalidMessage = fmt.Errorf("ecies: invalid message")
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
big2To32 = new(big.Int).Exp(big.NewInt(2), big.NewInt(32), nil)
|
||||||
|
big2To32M1 = new(big.Int).Sub(big2To32, big.NewInt(1))
|
||||||
|
)
|
||||||
|
|
||||||
|
func incCounter(ctr []byte) {
|
||||||
|
if ctr[3]++; ctr[3] != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ctr[2]++; ctr[2] != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ctr[1]++; ctr[1] != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if ctr[0]++; ctr[0] != 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
|
||||||
|
func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) {
|
||||||
|
if s1 == nil {
|
||||||
|
s1 = make([]byte, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
reps := ((kdLen + 7) * 8) / (hash.BlockSize() * 8)
|
||||||
|
if big.NewInt(int64(reps)).Cmp(big2To32M1) > 0 {
|
||||||
|
fmt.Println(big2To32M1)
|
||||||
|
return nil, ErrKeyDataTooLong
|
||||||
|
}
|
||||||
|
|
||||||
|
counter := []byte{0, 0, 0, 1}
|
||||||
|
k = make([]byte, 0)
|
||||||
|
|
||||||
|
for i := 0; i <= reps; i++ {
|
||||||
|
hash.Write(counter)
|
||||||
|
hash.Write(z)
|
||||||
|
hash.Write(s1)
|
||||||
|
k = append(k, hash.Sum(nil)...)
|
||||||
|
hash.Reset()
|
||||||
|
incCounter(counter)
|
||||||
|
}
|
||||||
|
|
||||||
|
k = k[:kdLen]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// messageTag computes the MAC of a message (called the tag) as per
|
||||||
|
// SEC 1, 3.5.
|
||||||
|
func messageTag(hash func() hash.Hash, km, msg, shared []byte) []byte {
|
||||||
|
mac := hmac.New(hash, km)
|
||||||
|
mac.Write(msg)
|
||||||
|
mac.Write(shared)
|
||||||
|
tag := mac.Sum(nil)
|
||||||
|
return tag
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate an initialisation vector for CTR mode.
|
||||||
|
func generateIV(params *ECIESParams, rand io.Reader) (iv []byte, err error) {
|
||||||
|
iv = make([]byte, params.BlockSize)
|
||||||
|
_, err = io.ReadFull(rand, iv)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// symEncrypt carries out CTR encryption using the block cipher specified in the
|
||||||
|
// parameters.
|
||||||
|
func symEncrypt(rand io.Reader, params *ECIESParams, key, m []byte) (ct []byte, err error) {
|
||||||
|
c, err := params.Cipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
iv, err := generateIV(params, rand)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctr := cipher.NewCTR(c, iv)
|
||||||
|
|
||||||
|
ct = make([]byte, len(m)+params.BlockSize)
|
||||||
|
copy(ct, iv)
|
||||||
|
ctr.XORKeyStream(ct[params.BlockSize:], m)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// symDecrypt carries out CTR decryption using the block cipher specified in
|
||||||
|
// the parameters
|
||||||
|
func symDecrypt(params *ECIESParams, key, ct []byte) (m []byte, err error) {
|
||||||
|
c, err := params.Cipher(key)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr := cipher.NewCTR(c, ct[:params.BlockSize])
|
||||||
|
|
||||||
|
m = make([]byte, len(ct)-params.BlockSize)
|
||||||
|
ctr.XORKeyStream(m, ct[params.BlockSize:])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypt encrypts a message using ECIES as specified in SEC 1, 5.1.
|
||||||
|
//
|
||||||
|
// s1 and s2 contain shared information that is not part of the resulting
|
||||||
|
// ciphertext. s1 is fed into key derivation, s2 is fed into the MAC. If the
|
||||||
|
// shared information parameters aren't being used, they should be nil.
|
||||||
|
func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err error) {
|
||||||
|
params := pub.Params
|
||||||
|
if params == nil {
|
||||||
|
if params = ParamsFromCurve(pub.Curve); params == nil {
|
||||||
|
err = ErrUnsupportedECIESParameters
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
R, err := GenerateKey(rand, pub.Curve, params)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := params.Hash()
|
||||||
|
z, err := R.GenerateShared(pub, params.KeyLen, params.KeyLen)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Ke := K[:params.KeyLen]
|
||||||
|
Km := K[params.KeyLen:]
|
||||||
|
hash.Write(Km)
|
||||||
|
Km = hash.Sum(nil)
|
||||||
|
hash.Reset()
|
||||||
|
|
||||||
|
em, err := symEncrypt(rand, params, Ke, m)
|
||||||
|
if err != nil || len(em) <= params.BlockSize {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d := messageTag(params.Hash, Km, em, s2)
|
||||||
|
|
||||||
|
Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y)
|
||||||
|
ct = make([]byte, len(Rb)+len(em)+len(d))
|
||||||
|
copy(ct, Rb)
|
||||||
|
copy(ct[len(Rb):], em)
|
||||||
|
copy(ct[len(Rb)+len(em):], d)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt decrypts an ECIES ciphertext.
|
||||||
|
func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
|
||||||
|
if len(c) == 0 {
|
||||||
|
return nil, ErrInvalidMessage
|
||||||
|
}
|
||||||
|
params := prv.PublicKey.Params
|
||||||
|
if params == nil {
|
||||||
|
if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil {
|
||||||
|
err = ErrUnsupportedECIESParameters
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hash := params.Hash()
|
||||||
|
|
||||||
|
var (
|
||||||
|
rLen int
|
||||||
|
hLen int = hash.Size()
|
||||||
|
mStart int
|
||||||
|
mEnd int
|
||||||
|
)
|
||||||
|
|
||||||
|
switch c[0] {
|
||||||
|
case 2, 3, 4:
|
||||||
|
rLen = (prv.PublicKey.Curve.Params().BitSize + 7) / 4
|
||||||
|
if len(c) < (rLen + hLen + 1) {
|
||||||
|
err = ErrInvalidMessage
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
err = ErrInvalidPublicKey
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mStart = rLen
|
||||||
|
mEnd = len(c) - hLen
|
||||||
|
|
||||||
|
R := new(PublicKey)
|
||||||
|
R.Curve = prv.PublicKey.Curve
|
||||||
|
R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen])
|
||||||
|
if R.X == nil {
|
||||||
|
err = ErrInvalidPublicKey
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !R.Curve.IsOnCurve(R.X, R.Y) {
|
||||||
|
err = ErrInvalidCurve
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Ke := K[:params.KeyLen]
|
||||||
|
Km := K[params.KeyLen:]
|
||||||
|
hash.Write(Km)
|
||||||
|
Km = hash.Sum(nil)
|
||||||
|
hash.Reset()
|
||||||
|
|
||||||
|
d := messageTag(params.Hash, Km, c[mStart:mEnd], s2)
|
||||||
|
if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 {
|
||||||
|
err = ErrInvalidMessage
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err = symDecrypt(params, Ke, c[mStart:mEnd])
|
||||||
|
return
|
||||||
|
}
|
117
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/params.go
generated
vendored
Normal file
117
vendor/github.com/status-im/status-go/eth-node/crypto/ecies/params.go
generated
vendored
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
// Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is>
|
||||||
|
// Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package ecies
|
||||||
|
|
||||||
|
// This file contains parameters for ECIES encryption, specifying the
|
||||||
|
// symmetric encryption and HMAC parameters.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto"
|
||||||
|
"crypto/aes"
|
||||||
|
"crypto/cipher"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/sha512"
|
||||||
|
"fmt"
|
||||||
|
"hash"
|
||||||
|
|
||||||
|
gethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefaultCurve = gethcrypto.S256()
|
||||||
|
ErrUnsupportedECDHAlgorithm = fmt.Errorf("ecies: unsupported ECDH algorithm")
|
||||||
|
ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters")
|
||||||
|
)
|
||||||
|
|
||||||
|
type ECIESParams struct {
|
||||||
|
Hash func() hash.Hash // hash function
|
||||||
|
hashAlgo crypto.Hash
|
||||||
|
Cipher func([]byte) (cipher.Block, error) // symmetric cipher
|
||||||
|
BlockSize int // block size of symmetric cipher
|
||||||
|
KeyLen int // length of symmetric key
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard ECIES parameters:
|
||||||
|
// * ECIES using AES128 and HMAC-SHA-256-16
|
||||||
|
// * ECIES using AES256 and HMAC-SHA-256-32
|
||||||
|
// * ECIES using AES256 and HMAC-SHA-384-48
|
||||||
|
// * ECIES using AES256 and HMAC-SHA-512-64
|
||||||
|
|
||||||
|
var (
|
||||||
|
ECIES_AES128_SHA256 = &ECIESParams{
|
||||||
|
Hash: sha256.New,
|
||||||
|
hashAlgo: crypto.SHA256,
|
||||||
|
Cipher: aes.NewCipher,
|
||||||
|
BlockSize: aes.BlockSize,
|
||||||
|
KeyLen: 16,
|
||||||
|
}
|
||||||
|
|
||||||
|
ECIES_AES256_SHA256 = &ECIESParams{
|
||||||
|
Hash: sha256.New,
|
||||||
|
hashAlgo: crypto.SHA256,
|
||||||
|
Cipher: aes.NewCipher,
|
||||||
|
BlockSize: aes.BlockSize,
|
||||||
|
KeyLen: 32,
|
||||||
|
}
|
||||||
|
|
||||||
|
ECIES_AES256_SHA384 = &ECIESParams{
|
||||||
|
Hash: sha512.New384,
|
||||||
|
hashAlgo: crypto.SHA384,
|
||||||
|
Cipher: aes.NewCipher,
|
||||||
|
BlockSize: aes.BlockSize,
|
||||||
|
KeyLen: 32,
|
||||||
|
}
|
||||||
|
|
||||||
|
ECIES_AES256_SHA512 = &ECIESParams{
|
||||||
|
Hash: sha512.New,
|
||||||
|
hashAlgo: crypto.SHA512,
|
||||||
|
Cipher: aes.NewCipher,
|
||||||
|
BlockSize: aes.BlockSize,
|
||||||
|
KeyLen: 32,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
var paramsFromCurve = map[elliptic.Curve]*ECIESParams{
|
||||||
|
gethcrypto.S256(): ECIES_AES128_SHA256,
|
||||||
|
elliptic.P256(): ECIES_AES128_SHA256,
|
||||||
|
elliptic.P384(): ECIES_AES256_SHA384,
|
||||||
|
elliptic.P521(): ECIES_AES256_SHA512,
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddParamsForCurve(curve elliptic.Curve, params *ECIESParams) {
|
||||||
|
paramsFromCurve[curve] = params
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamsFromCurve selects parameters optimal for the selected elliptic curve.
|
||||||
|
// Only the curves P256, P384, and P512 are supported.
|
||||||
|
func ParamsFromCurve(curve elliptic.Curve) (params *ECIESParams) {
|
||||||
|
return paramsFromCurve[curve]
|
||||||
|
}
|
@ -9,9 +9,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/crypto/ecies"
|
|
||||||
dr "github.com/status-im/doubleratchet"
|
dr "github.com/status-im/doubleratchet"
|
||||||
|
"github.com/status-im/status-go/eth-node/crypto/ecies"
|
||||||
"golang.org/x/crypto/hkdf"
|
"golang.org/x/crypto/hkdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -22,14 +21,14 @@ type EthereumCrypto struct{}
|
|||||||
|
|
||||||
// See the Crypto interface.
|
// See the Crypto interface.
|
||||||
func (c EthereumCrypto) GenerateDH() (dr.DHPair, error) {
|
func (c EthereumCrypto) GenerateDH() (dr.DHPair, error) {
|
||||||
keys, err := crypto.GenerateKey()
|
keys, err := GenerateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return DHPair{
|
return DHPair{
|
||||||
PubKey: crypto.CompressPubkey(&keys.PublicKey),
|
PubKey: CompressPubkey(&keys.PublicKey),
|
||||||
PrvKey: crypto.FromECDSA(keys),
|
PrvKey: FromECDSA(keys),
|
||||||
}, nil
|
}, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -37,14 +36,14 @@ func (c EthereumCrypto) GenerateDH() (dr.DHPair, error) {
|
|||||||
// See the Crypto interface.
|
// See the Crypto interface.
|
||||||
func (c EthereumCrypto) DH(dhPair dr.DHPair, dhPub dr.Key) (dr.Key, error) {
|
func (c EthereumCrypto) DH(dhPair dr.DHPair, dhPub dr.Key) (dr.Key, error) {
|
||||||
tmpKey := dhPair.PrivateKey()
|
tmpKey := dhPair.PrivateKey()
|
||||||
privateKey, err := crypto.ToECDSA(tmpKey)
|
privateKey, err := ToECDSA(tmpKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
eciesPrivate := ecies.ImportECDSA(privateKey)
|
eciesPrivate := ecies.ImportECDSA(privateKey)
|
||||||
|
|
||||||
publicKey, err := crypto.DecompressPubkey(dhPub)
|
publicKey, err := DecompressPubkey(dhPub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
242
vendor/github.com/status-im/status-go/eth-node/crypto/gethcrypto.go
generated
vendored
Normal file
242
vendor/github.com/status-im/status-go/eth-node/crypto/gethcrypto.go
generated
vendored
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
// Copyright 2014 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package crypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
"crypto/elliptic"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"math/big"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
)
|
||||||
|
|
||||||
|
//SignatureLength indicates the byte length required to carry a signature with recovery id.
|
||||||
|
const SignatureLength = 64 + 1 // 64 bytes ECDSA signature + 1 byte recovery id
|
||||||
|
|
||||||
|
// RecoveryIDOffset points to the byte offset within the signature that contains the recovery id.
|
||||||
|
const RecoveryIDOffset = 64
|
||||||
|
|
||||||
|
// DigestLength sets the signature digest exact length
|
||||||
|
const DigestLength = 32
|
||||||
|
|
||||||
|
var (
|
||||||
|
secp256k1N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
|
||||||
|
secp256k1halfN = new(big.Int).Div(secp256k1N, big.NewInt(2))
|
||||||
|
)
|
||||||
|
|
||||||
|
var errInvalidPubkey = errors.New("invalid secp256k1 public key")
|
||||||
|
|
||||||
|
// Keccak256 calculates and returns the Keccak256 hash of the input data.
|
||||||
|
func Keccak256(data ...[]byte) []byte {
|
||||||
|
d := sha3.NewLegacyKeccak256()
|
||||||
|
for _, b := range data {
|
||||||
|
d.Write(b)
|
||||||
|
}
|
||||||
|
return d.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
|
||||||
|
// converting it to an internal Hash data structure.
|
||||||
|
func Keccak256Hash(data ...[]byte) (h types.Hash) {
|
||||||
|
d := sha3.NewLegacyKeccak256()
|
||||||
|
for _, b := range data {
|
||||||
|
d.Write(b)
|
||||||
|
}
|
||||||
|
d.Sum(h[:0])
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keccak512 calculates and returns the Keccak512 hash of the input data.
|
||||||
|
func Keccak512(data ...[]byte) []byte {
|
||||||
|
d := sha3.NewLegacyKeccak512()
|
||||||
|
for _, b := range data {
|
||||||
|
d.Write(b)
|
||||||
|
}
|
||||||
|
return d.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAddress creates an ethereum address given the bytes and the nonce
|
||||||
|
func CreateAddress(b types.Address, nonce uint64) types.Address {
|
||||||
|
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
|
||||||
|
return types.BytesToAddress(Keccak256(data)[12:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateAddress2 creates an ethereum address given the address bytes, initial
|
||||||
|
// contract code hash and a salt.
|
||||||
|
func CreateAddress2(b types.Address, salt [32]byte, inithash []byte) types.Address {
|
||||||
|
return types.BytesToAddress(Keccak256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToECDSA creates a private key with the given D value.
|
||||||
|
func ToECDSA(d []byte) (*ecdsa.PrivateKey, error) {
|
||||||
|
return toECDSA(d, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost
|
||||||
|
// never be used unless you are sure the input is valid and want to avoid hitting
|
||||||
|
// errors due to bad origin encoding (0 prefixes cut off).
|
||||||
|
func ToECDSAUnsafe(d []byte) *ecdsa.PrivateKey {
|
||||||
|
priv, _ := toECDSA(d, false)
|
||||||
|
return priv
|
||||||
|
}
|
||||||
|
|
||||||
|
// toECDSA creates a private key with the given D value. The strict parameter
|
||||||
|
// controls whether the key's length should be enforced at the curve size or
|
||||||
|
// it can also accept legacy encodings (0 prefixes).
|
||||||
|
func toECDSA(d []byte, strict bool) (*ecdsa.PrivateKey, error) {
|
||||||
|
priv := new(ecdsa.PrivateKey)
|
||||||
|
priv.PublicKey.Curve = S256()
|
||||||
|
if strict && 8*len(d) != priv.Params().BitSize {
|
||||||
|
return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
|
||||||
|
}
|
||||||
|
priv.D = new(big.Int).SetBytes(d)
|
||||||
|
|
||||||
|
// The priv.D must < N
|
||||||
|
if priv.D.Cmp(secp256k1N) >= 0 {
|
||||||
|
return nil, fmt.Errorf("invalid private key, >=N")
|
||||||
|
}
|
||||||
|
// The priv.D must not be zero or negative.
|
||||||
|
if priv.D.Sign() <= 0 {
|
||||||
|
return nil, fmt.Errorf("invalid private key, zero or negative")
|
||||||
|
}
|
||||||
|
|
||||||
|
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
|
||||||
|
if priv.PublicKey.X == nil {
|
||||||
|
return nil, errors.New("invalid private key")
|
||||||
|
}
|
||||||
|
return priv, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromECDSA exports a private key into a binary dump.
|
||||||
|
func FromECDSA(priv *ecdsa.PrivateKey) []byte {
|
||||||
|
if priv == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalPubkey converts bytes to a secp256k1 public key.
|
||||||
|
func UnmarshalPubkey(pub []byte) (*ecdsa.PublicKey, error) {
|
||||||
|
x, y := elliptic.Unmarshal(S256(), pub)
|
||||||
|
if x == nil {
|
||||||
|
return nil, errInvalidPubkey
|
||||||
|
}
|
||||||
|
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
|
||||||
|
if pub == nil || pub.X == nil || pub.Y == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return elliptic.Marshal(S256(), pub.X, pub.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HexToECDSA parses a secp256k1 private key.
|
||||||
|
func HexToECDSA(hexkey string) (*ecdsa.PrivateKey, error) {
|
||||||
|
b, err := hex.DecodeString(hexkey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("invalid hex string")
|
||||||
|
}
|
||||||
|
return ToECDSA(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadECDSA loads a secp256k1 private key from the given file.
|
||||||
|
func LoadECDSA(file string) (*ecdsa.PrivateKey, error) {
|
||||||
|
buf := make([]byte, 64)
|
||||||
|
fd, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
if _, err := io.ReadFull(fd, buf); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
key, err := hex.DecodeString(string(buf))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ToECDSA(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveECDSA saves a secp256k1 private key to the given file with
|
||||||
|
// restrictive permissions. The key data is saved hex-encoded.
|
||||||
|
func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
|
||||||
|
k := hex.EncodeToString(FromECDSA(key))
|
||||||
|
return ioutil.WriteFile(file, []byte(k), 0600)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenerateKey() (*ecdsa.PrivateKey, error) {
|
||||||
|
return ecdsa.GenerateKey(S256(), rand.Reader)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PubkeyToAddress(p ecdsa.PublicKey) types.Address {
|
||||||
|
pubBytes := FromECDSAPub(&p)
|
||||||
|
return types.BytesToAddress(Keccak256(pubBytes[1:])[12:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func zeroBytes(bytes []byte) {
|
||||||
|
for i := range bytes {
|
||||||
|
bytes[i] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ecrecover returns the uncompressed public key that created the given signature.
|
||||||
|
func Ecrecover(hash, sig []byte) ([]byte, error) {
|
||||||
|
return secp256k1.RecoverPubkey(hash, sig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SigToPub returns the public key that created the given signature.
|
||||||
|
func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
|
||||||
|
s, err := Ecrecover(hash, sig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
x, y := elliptic.Unmarshal(S256(), s)
|
||||||
|
return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecompressPubkey parses a public key in the 33-byte compressed format.
|
||||||
|
func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) {
|
||||||
|
x, y := secp256k1.DecompressPubkey(pubkey)
|
||||||
|
if x == nil {
|
||||||
|
return nil, fmt.Errorf("invalid public key")
|
||||||
|
}
|
||||||
|
return &ecdsa.PublicKey{X: x, Y: y, Curve: S256()}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompressPubkey encodes a public key to the 33-byte compressed format.
|
||||||
|
func CompressPubkey(pubkey *ecdsa.PublicKey) []byte {
|
||||||
|
return secp256k1.CompressPubkey(pubkey.X, pubkey.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
// S256 returns an instance of the secp256k1 curve.
|
||||||
|
func S256() elliptic.Curve {
|
||||||
|
return secp256k1.S256()
|
||||||
|
}
|
219
vendor/github.com/status-im/status-go/eth-node/types/address.go
generated
vendored
Normal file
219
vendor/github.com/status-im/status-go/eth-node/types/address.go
generated
vendored
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
)
|
||||||
|
|
||||||
|
/////////// Address
|
||||||
|
|
||||||
|
// AddressLength is the expected length of the address
|
||||||
|
const AddressLength = 20
|
||||||
|
|
||||||
|
var (
|
||||||
|
addressT = reflect.TypeOf(Address{})
|
||||||
|
)
|
||||||
|
|
||||||
|
// Address represents the 20 byte address of an Ethereum account.
|
||||||
|
type Address [AddressLength]byte
|
||||||
|
|
||||||
|
// BytesToAddress returns Address with value b.
|
||||||
|
// If b is larger than len(h), b will be cropped from the left.
|
||||||
|
func BytesToAddress(b []byte) Address {
|
||||||
|
var a Address
|
||||||
|
a.SetBytes(b)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// BigToAddress returns Address with byte values of b.
|
||||||
|
// If b is larger than len(h), b will be cropped from the left.
|
||||||
|
func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
|
||||||
|
|
||||||
|
// HexToAddress returns Address with byte values of s.
|
||||||
|
// If s is larger than len(h), s will be cropped from the left.
|
||||||
|
func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
|
||||||
|
|
||||||
|
// IsHexAddress verifies whether a string can represent a valid hex-encoded
|
||||||
|
// Ethereum address or not.
|
||||||
|
func IsHexAddress(s string) bool {
|
||||||
|
if has0xPrefix(s) {
|
||||||
|
s = s[2:]
|
||||||
|
}
|
||||||
|
return len(s) == 2*AddressLength && isHex(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes gets the string representation of the underlying address.
|
||||||
|
func (a Address) Bytes() []byte { return a[:] }
|
||||||
|
|
||||||
|
// Hash converts an address to a hash by left-padding it with zeros.
|
||||||
|
func (a Address) Hash() Hash { return BytesToHash(a[:]) }
|
||||||
|
|
||||||
|
// Hex returns an EIP55-compliant hex string representation of the address.
|
||||||
|
func (a Address) Hex() string {
|
||||||
|
unchecksummed := hex.EncodeToString(a[:])
|
||||||
|
sha := sha3.NewLegacyKeccak256()
|
||||||
|
sha.Write([]byte(unchecksummed))
|
||||||
|
hash := sha.Sum(nil)
|
||||||
|
|
||||||
|
result := []byte(unchecksummed)
|
||||||
|
for i := 0; i < len(result); i++ {
|
||||||
|
hashByte := hash[i/2]
|
||||||
|
if i%2 == 0 {
|
||||||
|
hashByte = hashByte >> 4
|
||||||
|
} else {
|
||||||
|
hashByte &= 0xf
|
||||||
|
}
|
||||||
|
if result[i] > '9' && hashByte > 7 {
|
||||||
|
result[i] -= 32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "0x" + string(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer.
|
||||||
|
func (a Address) String() string {
|
||||||
|
return a.Hex()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format implements fmt.Formatter, forcing the byte slice to be formatted as is,
|
||||||
|
// without going through the stringer interface used for logging.
|
||||||
|
func (a Address) Format(s fmt.State, c rune) {
|
||||||
|
fmt.Fprintf(s, "%"+string(c), a[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBytes sets the address to the value of b.
|
||||||
|
// If b is larger than len(a) it will panic.
|
||||||
|
func (a *Address) SetBytes(b []byte) {
|
||||||
|
if len(b) > len(a) {
|
||||||
|
b = b[len(b)-AddressLength:]
|
||||||
|
}
|
||||||
|
copy(a[AddressLength-len(b):], b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText returns the hex representation of a.
|
||||||
|
func (a Address) MarshalText() ([]byte, error) {
|
||||||
|
return HexBytes(a[:]).MarshalText()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalText parses a hash in hex syntax.
|
||||||
|
func (a *Address) UnmarshalText(input []byte) error {
|
||||||
|
return UnmarshalFixedText("Address", input, a[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON parses a hash in hex syntax.
|
||||||
|
func (a *Address) UnmarshalJSON(input []byte) error {
|
||||||
|
return UnmarshalFixedJSON(addressT, input, a[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan implements Scanner for database/sql.
|
||||||
|
func (a *Address) Scan(src interface{}) error {
|
||||||
|
srcB, ok := src.([]byte)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("can't scan %T into Address", src)
|
||||||
|
}
|
||||||
|
if len(srcB) != AddressLength {
|
||||||
|
return fmt.Errorf("can't scan []byte of len %d into Address, want %d", len(srcB), AddressLength)
|
||||||
|
}
|
||||||
|
copy(a[:], srcB)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value implements valuer for database/sql.
|
||||||
|
func (a Address) Value() (driver.Value, error) {
|
||||||
|
return a[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ImplementsGraphQLType returns true if Hash implements the specified GraphQL type.
|
||||||
|
func (a Address) ImplementsGraphQLType(name string) bool { return name == "Address" }
|
||||||
|
|
||||||
|
// UnmarshalGraphQL unmarshals the provided GraphQL query data.
|
||||||
|
func (a *Address) UnmarshalGraphQL(input interface{}) error {
|
||||||
|
var err error
|
||||||
|
switch input := input.(type) {
|
||||||
|
case string:
|
||||||
|
err = a.UnmarshalText([]byte(input))
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("Unexpected type for Address: %v", input)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnprefixedAddress allows marshaling an Address without 0x prefix.
|
||||||
|
type UnprefixedAddress Address
|
||||||
|
|
||||||
|
// UnmarshalText decodes the address from hex. The 0x prefix is optional.
|
||||||
|
func (a *UnprefixedAddress) UnmarshalText(input []byte) error {
|
||||||
|
return UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalText encodes the address as hex.
|
||||||
|
func (a UnprefixedAddress) MarshalText() ([]byte, error) {
|
||||||
|
return []byte(hex.EncodeToString(a[:])), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MixedcaseAddress retains the original string, which may or may not be
|
||||||
|
// correctly checksummed
|
||||||
|
type MixedcaseAddress struct {
|
||||||
|
addr Address
|
||||||
|
original string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMixedcaseAddress constructor (mainly for testing)
|
||||||
|
func NewMixedcaseAddress(addr Address) MixedcaseAddress {
|
||||||
|
return MixedcaseAddress{addr: addr, original: addr.Hex()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMixedcaseAddressFromString is mainly meant for unit-testing
|
||||||
|
func NewMixedcaseAddressFromString(hexaddr string) (*MixedcaseAddress, error) {
|
||||||
|
if !IsHexAddress(hexaddr) {
|
||||||
|
return nil, fmt.Errorf("Invalid address")
|
||||||
|
}
|
||||||
|
a := FromHex(hexaddr)
|
||||||
|
return &MixedcaseAddress{addr: BytesToAddress(a), original: hexaddr}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON parses MixedcaseAddress
|
||||||
|
func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error {
|
||||||
|
if err := UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return json.Unmarshal(input, &ma.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON marshals the original value
|
||||||
|
func (ma *MixedcaseAddress) MarshalJSON() ([]byte, error) {
|
||||||
|
if strings.HasPrefix(ma.original, "0x") || strings.HasPrefix(ma.original, "0X") {
|
||||||
|
return json.Marshal(fmt.Sprintf("0x%s", ma.original[2:]))
|
||||||
|
}
|
||||||
|
return json.Marshal(fmt.Sprintf("0x%s", ma.original))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Address returns the address
|
||||||
|
func (ma *MixedcaseAddress) Address() Address {
|
||||||
|
return ma.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (ma *MixedcaseAddress) String() string {
|
||||||
|
if ma.ValidChecksum() {
|
||||||
|
return fmt.Sprintf("%s [chksum ok]", ma.original)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s [chksum INVALID]", ma.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidChecksum returns true if the address has valid checksum
|
||||||
|
func (ma *MixedcaseAddress) ValidChecksum() bool {
|
||||||
|
return ma.original == ma.addr.Hex()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original returns the mixed-case input string
|
||||||
|
func (ma *MixedcaseAddress) Original() string {
|
||||||
|
return ma.original
|
||||||
|
}
|
37
vendor/github.com/status-im/status-go/eth-node/types/bytes.go
generated
vendored
Normal file
37
vendor/github.com/status-im/status-go/eth-node/types/bytes.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import "encoding/hex"
|
||||||
|
|
||||||
|
// has0xPrefix validates str begins with '0x' or '0X'.
|
||||||
|
func has0xPrefix(str string) bool {
|
||||||
|
return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
|
||||||
|
}
|
||||||
|
|
||||||
|
// isHexCharacter returns bool of c being a valid hexadecimal.
|
||||||
|
func isHexCharacter(c byte) bool {
|
||||||
|
return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')
|
||||||
|
}
|
||||||
|
|
||||||
|
// isHex validates whether each byte is valid hexadecimal string.
|
||||||
|
func isHex(str string) bool {
|
||||||
|
if len(str)%2 != 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, c := range []byte(str) {
|
||||||
|
if !isHexCharacter(c) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes2Hex returns the hexadecimal encoding of d.
|
||||||
|
func Bytes2Hex(d []byte) string {
|
||||||
|
return hex.EncodeToString(d)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hex2Bytes returns the bytes represented by the hexadecimal string str.
|
||||||
|
func Hex2Bytes(str string) []byte {
|
||||||
|
h, _ := hex.DecodeString(str)
|
||||||
|
return h
|
||||||
|
}
|
22
vendor/github.com/status-im/status-go/eth-node/types/ens/ens.go
generated
vendored
Normal file
22
vendor/github.com/status-im/status-go/eth-node/types/ens/ens.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package enstypes
|
||||||
|
|
||||||
|
import "crypto/ecdsa"
|
||||||
|
|
||||||
|
type ENSVerifier interface {
|
||||||
|
// CheckBatch verifies that a registered ENS name matches the expected public key
|
||||||
|
CheckBatch(ensDetails []ENSDetails, rpcEndpoint, contractAddress string) (map[string]ENSResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type ENSDetails struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
PublicKeyString string `json:"publicKey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ENSResponse struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
VerifiedAt int64 `json:"verifiedAt"`
|
||||||
|
Error error `json:"error"`
|
||||||
|
PublicKey *ecdsa.PublicKey `json:"-"`
|
||||||
|
PublicKeyString string `json:"publicKey"`
|
||||||
|
}
|
@ -1,11 +1,9 @@
|
|||||||
package whispertypes
|
package types
|
||||||
|
|
||||||
import statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
|
|
||||||
// Envelope represents a clear-text data packet to transmit through the Whisper
|
// Envelope represents a clear-text data packet to transmit through the Whisper
|
||||||
// network. Its contents may or may not be encrypted and signed.
|
// network. Its contents may or may not be encrypted and signed.
|
||||||
type Envelope interface {
|
type Envelope interface {
|
||||||
Hash() statusproto.Hash // Cached hash of the envelope to avoid rehashing every time.
|
Hash() Hash // Cached hash of the envelope to avoid rehashing every time.
|
||||||
Bloom() []byte
|
Bloom() []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,15 +48,15 @@ const (
|
|||||||
// EnvelopeEvent used for envelopes events.
|
// EnvelopeEvent used for envelopes events.
|
||||||
type EnvelopeEvent struct {
|
type EnvelopeEvent struct {
|
||||||
Event EventType
|
Event EventType
|
||||||
Hash statusproto.Hash
|
Hash Hash
|
||||||
Batch statusproto.Hash
|
Batch Hash
|
||||||
Peer EnodeID
|
Peer EnodeID
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnvelopeError code and optional description of the error.
|
// EnvelopeError code and optional description of the error.
|
||||||
type EnvelopeError struct {
|
type EnvelopeError struct {
|
||||||
Hash statusproto.Hash
|
Hash Hash
|
||||||
Code uint
|
Code uint
|
||||||
Description string
|
Description string
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package whispertypes
|
package types
|
||||||
|
|
||||||
// Filter represents a Whisper message filter
|
// Filter represents a Whisper message filter
|
||||||
type Filter interface {
|
type Filter interface {
|
@ -1,6 +1,6 @@
|
|||||||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/types.go
|
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/types.go
|
||||||
|
|
||||||
package statusproto
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@ -26,17 +26,6 @@ func encode(b []byte) string {
|
|||||||
return string(enc)
|
return string(enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// has0xPrefix validates str begins with '0x' or '0X'.
|
|
||||||
func has0xPrefix(str string) bool {
|
|
||||||
return len(str) >= 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hex2Bytes returns the bytes represented by the hexadecimal string str.
|
|
||||||
func Hex2Bytes(str string) []byte {
|
|
||||||
h, _ := hex.DecodeString(str)
|
|
||||||
return h
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromHex returns the bytes represented by the hexadecimal string s.
|
// FromHex returns the bytes represented by the hexadecimal string s.
|
||||||
// s may be prefixed with "0x".
|
// s may be prefixed with "0x".
|
||||||
func FromHex(s string) []byte {
|
func FromHex(s string) []byte {
|
@ -1,9 +1,10 @@
|
|||||||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/hexutil.go
|
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/hexutil.go
|
||||||
|
|
||||||
package statusproto
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,3 +31,24 @@ func (b *HexBytes) UnmarshalJSON(input []byte) error {
|
|||||||
}
|
}
|
||||||
return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT)
|
return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The
|
||||||
|
// length of out determines the required input length. This function is commonly used to
|
||||||
|
// implement the UnmarshalText method for fixed-size types.
|
||||||
|
func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error {
|
||||||
|
raw, err := checkText(input, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(raw)/2 != len(out) {
|
||||||
|
return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname)
|
||||||
|
}
|
||||||
|
// Pre-verify syntax before modifying out.
|
||||||
|
for _, b := range raw {
|
||||||
|
if decodeNibble(b) == badNibble {
|
||||||
|
return ErrSyntax
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hex.Decode(out, raw)
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/json.go
|
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/json.go
|
||||||
|
|
||||||
package statusproto
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
@ -1,9 +1,7 @@
|
|||||||
package whispertypes
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -49,7 +47,7 @@ func (r *MessagesRequest) SetDefaults(now time.Time) {
|
|||||||
|
|
||||||
// MailServerResponse is the response payload sent by the mailserver.
|
// MailServerResponse is the response payload sent by the mailserver.
|
||||||
type MailServerResponse struct {
|
type MailServerResponse struct {
|
||||||
LastEnvelopeHash statusproto.Hash
|
LastEnvelopeHash Hash
|
||||||
Cursor []byte
|
Cursor []byte
|
||||||
Error error
|
Error error
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package whispertypes
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
21
vendor/github.com/status-im/status-go/eth-node/types/node.go
generated
vendored
Normal file
21
vendor/github.com/status-im/status-go/eth-node/types/node.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
enstypes "github.com/status-im/status-go/eth-node/types/ens"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnodeID is a unique identifier for each node.
|
||||||
|
type EnodeID [32]byte
|
||||||
|
|
||||||
|
// ID prints as a long hexadecimal number.
|
||||||
|
func (n EnodeID) String() string {
|
||||||
|
return fmt.Sprintf("%x", n[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
type Node interface {
|
||||||
|
NewENSVerifier(logger *zap.Logger) enstypes.ENSVerifier
|
||||||
|
GetWhisper(ctx interface{}) (Whisper, error)
|
||||||
|
}
|
@ -1,9 +1,7 @@
|
|||||||
package whispertypes
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewMessage represents a new whisper message that is posted through the RPC.
|
// NewMessage represents a new whisper message that is posted through the RPC.
|
||||||
@ -48,7 +46,7 @@ type Criteria struct {
|
|||||||
// use publicly without security implications.
|
// use publicly without security implications.
|
||||||
type PublicWhisperAPI interface {
|
type PublicWhisperAPI interface {
|
||||||
// AddPrivateKey imports the given private key.
|
// AddPrivateKey imports the given private key.
|
||||||
AddPrivateKey(ctx context.Context, privateKey statusproto.HexBytes) (string, error)
|
AddPrivateKey(ctx context.Context, privateKey HexBytes) (string, error)
|
||||||
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
||||||
GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error)
|
GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error)
|
||||||
// DeleteKeyPair removes the key with the given key if it exists.
|
// DeleteKeyPair removes the key with the given key if it exists.
|
@ -1,9 +1,4 @@
|
|||||||
package whispertypes
|
package types
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// TopicLength is the expected length of the topic, in bytes
|
// TopicLength is the expected length of the topic, in bytes
|
||||||
@ -32,17 +27,17 @@ func BytesToTopic(b []byte) (t TopicType) {
|
|||||||
|
|
||||||
// String converts a topic byte array to a string representation.
|
// String converts a topic byte array to a string representation.
|
||||||
func (t *TopicType) String() string {
|
func (t *TopicType) String() string {
|
||||||
return statusproto.EncodeHex(t[:])
|
return EncodeHex(t[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalText returns the hex representation of t.
|
// MarshalText returns the hex representation of t.
|
||||||
func (t TopicType) MarshalText() ([]byte, error) {
|
func (t TopicType) MarshalText() ([]byte, error) {
|
||||||
return statusproto.HexBytes(t[:]).MarshalText()
|
return HexBytes(t[:]).MarshalText()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmarshalText parses a hex representation to a topic.
|
// UnmarshalText parses a hex representation to a topic.
|
||||||
func (t *TopicType) UnmarshalText(input []byte) error {
|
func (t *TopicType) UnmarshalText(input []byte) error {
|
||||||
return hexutil.UnmarshalFixedText("Topic", input, t[:])
|
return UnmarshalFixedText("Topic", input, t[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes)
|
// TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes)
|
@ -1,4 +1,4 @@
|
|||||||
package whispertypes
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
13
vendor/github.com/status-im/status-go/extkeys/go.mod
generated
vendored
Normal file
13
vendor/github.com/status-im/status-go/extkeys/go.mod
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module github.com/status-im/status-go/extkeys
|
||||||
|
|
||||||
|
go 1.13
|
||||||
|
|
||||||
|
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/btcsuite/btcd v0.20.1-beta
|
||||||
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
|
||||||
|
github.com/ethereum/go-ethereum v1.9.5
|
||||||
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba
|
||||||
|
golang.org/x/text v0.3.2
|
||||||
|
)
|
99
vendor/github.com/status-im/status-go/extkeys/go.sum
generated
vendored
Normal file
99
vendor/github.com/status-im/status-go/extkeys/go.sum
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
|
||||||
|
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
|
||||||
|
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
|
||||||
|
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
|
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||||
|
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||||
|
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||||
|
github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||||
|
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
|
||||||
|
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||||
|
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||||
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
|
||||||
|
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||||
|
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||||
|
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||||
|
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||||
|
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||||
|
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||||
|
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||||
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
|
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||||
|
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||||
|
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
|
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||||
|
github.com/ethereum/go-ethereum v1.9.7 h1:p4O+z0MGzB7xxngHbplcYNloxkFwGkeComhkzWnq0ig=
|
||||||
|
github.com/ethereum/go-ethereum v1.9.7/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||||
|
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
|
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
||||||
|
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||||
|
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
||||||
|
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||||
|
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
|
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||||
|
github.com/julienschmidt/httprouter v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
|
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
|
||||||
|
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||||
|
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
|
||||||
|
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
|
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
|
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||||
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
|
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||||
|
github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
|
||||||
|
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||||
|
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
|
||||||
|
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
|
||||||
|
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||||
|
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||||
|
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
|
||||||
|
github.com/status-im/extkeys v1.0.0/go.mod h1:wNx0pnvGTgyKz/S8hBNesAHKKKI9beF+BuVLIuBJuQI=
|
||||||
|
github.com/status-im/go-ethereum v1.9.5-status.5/go.mod h1:g2+E89NWtyA+55p6XEl5Sdt7Mtez3V0T3+Y7mJNb+tI=
|
||||||
|
github.com/stretchr/testify v0.0.0-20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||||
|
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||||
|
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||||
|
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
|
||||||
|
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||||
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||||
|
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
|
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
2
vendor/github.com/status-im/status-go/logutils/zap_adapter.go
generated
vendored
2
vendor/github.com/status-im/status-go/logutils/zap_adapter.go
generated
vendored
@ -9,7 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/status-im/status-protocol-go/zaputil"
|
"github.com/status-im/status-go/protocol/zaputil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type gethLoggerCore struct {
|
type gethLoggerCore struct {
|
||||||
|
19
vendor/github.com/status-im/status-go/mailserver/db_key.go
generated
vendored
19
vendor/github.com/status-im/status-go/mailserver/db_key.go
generated
vendored
@ -4,14 +4,13 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DBKeyLength is a size of the envelope key.
|
// DBKeyLength is a size of the envelope key.
|
||||||
DBKeyLength = statusproto.HashLength + timestampLength + whispertypes.TopicLength
|
DBKeyLength = types.HashLength + timestampLength + types.TopicLength
|
||||||
CursorLength = statusproto.HashLength + timestampLength
|
CursorLength = types.HashLength + timestampLength
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -30,12 +29,12 @@ func (k *DBKey) Bytes() []byte {
|
|||||||
return k.raw
|
return k.raw
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *DBKey) Topic() whispertypes.TopicType {
|
func (k *DBKey) Topic() types.TopicType {
|
||||||
return whispertypes.BytesToTopic(k.raw[timestampLength+statusproto.HashLength:])
|
return types.BytesToTopic(k.raw[timestampLength+types.HashLength:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *DBKey) EnvelopeHash() statusproto.Hash {
|
func (k *DBKey) EnvelopeHash() types.Hash {
|
||||||
return statusproto.BytesToHash(k.raw[timestampLength : statusproto.HashLength+timestampLength])
|
return types.BytesToHash(k.raw[timestampLength : types.HashLength+timestampLength])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *DBKey) Cursor() []byte {
|
func (k *DBKey) Cursor() []byte {
|
||||||
@ -44,11 +43,11 @@ func (k *DBKey) Cursor() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewDBKey creates a new DBKey with the given values.
|
// NewDBKey creates a new DBKey with the given values.
|
||||||
func NewDBKey(timestamp uint32, topic whispertypes.TopicType, h statusproto.Hash) *DBKey {
|
func NewDBKey(timestamp uint32, topic types.TopicType, h types.Hash) *DBKey {
|
||||||
var k DBKey
|
var k DBKey
|
||||||
k.raw = make([]byte, DBKeyLength)
|
k.raw = make([]byte, DBKeyLength)
|
||||||
binary.BigEndian.PutUint32(k.raw, timestamp)
|
binary.BigEndian.PutUint32(k.raw, timestamp)
|
||||||
copy(k.raw[timestampLength:], h[:])
|
copy(k.raw[timestampLength:], h[:])
|
||||||
copy(k.raw[timestampLength+statusproto.HashLength:], topic[:])
|
copy(k.raw[timestampLength+types.HashLength:], topic[:])
|
||||||
return &k
|
return &k
|
||||||
}
|
}
|
||||||
|
19
vendor/github.com/status-im/status-go/mailserver/mailserver.go
generated
vendored
19
vendor/github.com/status-im/status-go/mailserver/mailserver.go
generated
vendored
@ -29,9 +29,8 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
|
|
||||||
prom "github.com/prometheus/client_golang/prometheus"
|
prom "github.com/prometheus/client_golang/prometheus"
|
||||||
@ -199,7 +198,7 @@ func (s *WMailServer) DeliverMail(peer *whisper.Peer, request *whisper.Envelope)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
requestID := statusproto.Hash(request.Hash())
|
requestID := types.Hash(request.Hash())
|
||||||
peerID := peerIDString(peer)
|
peerID := peerIDString(peer)
|
||||||
|
|
||||||
log.Info("[mailserver:DeliverMail] delivering mail",
|
log.Info("[mailserver:DeliverMail] delivering mail",
|
||||||
@ -356,7 +355,7 @@ func (s *WMailServer) Deliver(peer *whisper.Peer, r whisper.MessagesRequest) {
|
|||||||
deliveryAttemptsCounter.Inc()
|
deliveryAttemptsCounter.Inc()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
requestIDHash = statusproto.BytesToHash(r.ID)
|
requestIDHash = types.BytesToHash(r.ID)
|
||||||
requestIDStr = requestIDHash.String()
|
requestIDStr = requestIDHash.String()
|
||||||
peerID = peerIDString(peer)
|
peerID = peerIDString(peer)
|
||||||
err error
|
err error
|
||||||
@ -592,8 +591,8 @@ func (s *WMailServer) exceedsPeerRequests(peer []byte) bool {
|
|||||||
|
|
||||||
func (s *WMailServer) createIterator(lower, upper uint32, cursor []byte, bloom []byte, limit uint32) (Iterator, error) {
|
func (s *WMailServer) createIterator(lower, upper uint32, cursor []byte, bloom []byte, limit uint32) (Iterator, error) {
|
||||||
var (
|
var (
|
||||||
emptyHash statusproto.Hash
|
emptyHash types.Hash
|
||||||
emptyTopic whispertypes.TopicType
|
emptyTopic types.TopicType
|
||||||
ku, kl *DBKey
|
ku, kl *DBKey
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -620,7 +619,7 @@ func (s *WMailServer) processRequestInBundles(
|
|||||||
requestID string,
|
requestID string,
|
||||||
output chan<- []rlp.RawValue,
|
output chan<- []rlp.RawValue,
|
||||||
cancel <-chan struct{},
|
cancel <-chan struct{},
|
||||||
) ([]byte, statusproto.Hash) {
|
) ([]byte, types.Hash) {
|
||||||
timer := prom.NewTimer(requestsInBundlesDuration)
|
timer := prom.NewTimer(requestsInBundlesDuration)
|
||||||
defer timer.ObserveDuration()
|
defer timer.ObserveDuration()
|
||||||
|
|
||||||
@ -631,7 +630,7 @@ func (s *WMailServer) processRequestInBundles(
|
|||||||
processedEnvelopes int
|
processedEnvelopes int
|
||||||
processedEnvelopesSize int64
|
processedEnvelopesSize int64
|
||||||
nextCursor []byte
|
nextCursor []byte
|
||||||
lastEnvelopeHash statusproto.Hash
|
lastEnvelopeHash types.Hash
|
||||||
)
|
)
|
||||||
|
|
||||||
log.Info("[mailserver:processRequestInBundles] processing request",
|
log.Info("[mailserver:processRequestInBundles] processing request",
|
||||||
@ -760,13 +759,13 @@ func (s *WMailServer) sendRawEnvelopes(peer *whisper.Peer, envelopes []rlp.RawVa
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *WMailServer) sendHistoricMessageResponse(peer *whisper.Peer, requestID, lastEnvelopeHash statusproto.Hash, cursor []byte) error {
|
func (s *WMailServer) sendHistoricMessageResponse(peer *whisper.Peer, requestID, lastEnvelopeHash types.Hash, cursor []byte) error {
|
||||||
payload := whisper.CreateMailServerRequestCompletedPayload(common.Hash(requestID), common.Hash(lastEnvelopeHash), cursor)
|
payload := whisper.CreateMailServerRequestCompletedPayload(common.Hash(requestID), common.Hash(lastEnvelopeHash), cursor)
|
||||||
return s.w.SendHistoricMessageResponse(peer, payload)
|
return s.w.SendHistoricMessageResponse(peer, payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method doesn't return an error because it is already in the error handling chain
|
// this method doesn't return an error because it is already in the error handling chain
|
||||||
func (s *WMailServer) trySendHistoricMessageErrorResponse(peer *whisper.Peer, requestID statusproto.Hash, errorToReport error) {
|
func (s *WMailServer) trySendHistoricMessageErrorResponse(peer *whisper.Peer, requestID types.Hash, errorToReport error) {
|
||||||
payload := whisper.CreateMailServerRequestFailedPayload(common.Hash(requestID), errorToReport)
|
payload := whisper.CreateMailServerRequestFailedPayload(common.Hash(requestID), errorToReport)
|
||||||
|
|
||||||
err := s.w.SendHistoricMessageResponse(peer, payload)
|
err := s.w.SendHistoricMessageResponse(peer, payload)
|
||||||
|
2
vendor/github.com/status-im/status-go/mailserver/mailserver_db.go
generated
vendored
2
vendor/github.com/status-im/status-go/mailserver/mailserver_db.go
generated
vendored
@ -10,7 +10,7 @@ import (
|
|||||||
type DB interface {
|
type DB interface {
|
||||||
Close() error
|
Close() error
|
||||||
// SaveEnvelope stores an envelope
|
// SaveEnvelope stores an envelope
|
||||||
SaveEnvelope(*whisper.Envelope) error // TODO: Migrate to whispertypes.Envelope
|
SaveEnvelope(*whisper.Envelope) error // TODO: Migrate to types.Envelope
|
||||||
// GetEnvelope returns an rlp encoded envelope from the datastore
|
// GetEnvelope returns an rlp encoded envelope from the datastore
|
||||||
GetEnvelope(*DBKey) ([]byte, error)
|
GetEnvelope(*DBKey) ([]byte, error)
|
||||||
// Prune removes envelopes older than time
|
// Prune removes envelopes older than time
|
||||||
|
13
vendor/github.com/status-im/status-go/mailserver/mailserver_db_leveldb.go
generated
vendored
13
vendor/github.com/status-im/status-go/mailserver/mailserver_db_leveldb.go
generated
vendored
@ -6,9 +6,8 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||||
@ -48,9 +47,9 @@ func (i *LevelDBIterator) GetEnvelope(bloom []byte) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
envelopeBloom = whispertypes.TopicToBloom(key.Topic())
|
envelopeBloom = types.TopicToBloom(key.Topic())
|
||||||
}
|
}
|
||||||
if !whispertypes.BloomFilterMatch(bloom, envelopeBloom) {
|
if !types.BloomFilterMatch(bloom, envelopeBloom) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
return rawValue, nil
|
return rawValue, nil
|
||||||
@ -90,8 +89,8 @@ func (db *LevelDB) GetEnvelope(key *DBKey) ([]byte, error) {
|
|||||||
func (db *LevelDB) Prune(t time.Time, batchSize int) (int, error) {
|
func (db *LevelDB) Prune(t time.Time, batchSize int) (int, error) {
|
||||||
defer recoverLevelDBPanics("Prune")
|
defer recoverLevelDBPanics("Prune")
|
||||||
|
|
||||||
var zero statusproto.Hash
|
var zero types.Hash
|
||||||
var emptyTopic whispertypes.TopicType
|
var emptyTopic types.TopicType
|
||||||
kl := NewDBKey(0, emptyTopic, zero)
|
kl := NewDBKey(0, emptyTopic, zero)
|
||||||
ku := NewDBKey(uint32(t.Unix()), emptyTopic, zero)
|
ku := NewDBKey(uint32(t.Unix()), emptyTopic, zero)
|
||||||
query := CursorQuery{
|
query := CursorQuery{
|
||||||
@ -140,7 +139,7 @@ func (db *LevelDB) Prune(t time.Time, batchSize int) (int, error) {
|
|||||||
func (db *LevelDB) SaveEnvelope(env *whisper.Envelope) error {
|
func (db *LevelDB) SaveEnvelope(env *whisper.Envelope) error {
|
||||||
defer recoverLevelDBPanics("SaveEnvelope")
|
defer recoverLevelDBPanics("SaveEnvelope")
|
||||||
|
|
||||||
key := NewDBKey(env.Expiry-env.TTL, whispertypes.TopicType(env.Topic), statusproto.Hash(env.Hash()))
|
key := NewDBKey(env.Expiry-env.TTL, types.TopicType(env.Topic), types.Hash(env.Hash()))
|
||||||
rawEnvelope, err := rlp.EncodeToBytes(env)
|
rawEnvelope, err := rlp.EncodeToBytes(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
||||||
|
13
vendor/github.com/status-im/status-go/mailserver/mailserver_db_postgres.go
generated
vendored
13
vendor/github.com/status-im/status-go/mailserver/mailserver_db_postgres.go
generated
vendored
@ -15,8 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
statusproto "github.com/status-im/status-protocol-go/types"
|
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -159,8 +158,8 @@ func (i *PostgresDB) GetEnvelope(key *DBKey) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *PostgresDB) Prune(t time.Time, batch int) (int, error) {
|
func (i *PostgresDB) Prune(t time.Time, batch int) (int, error) {
|
||||||
var zero statusproto.Hash
|
var zero types.Hash
|
||||||
var emptyTopic whispertypes.TopicType
|
var emptyTopic types.TopicType
|
||||||
kl := NewDBKey(0, emptyTopic, zero)
|
kl := NewDBKey(0, emptyTopic, zero)
|
||||||
ku := NewDBKey(uint32(t.Unix()), emptyTopic, zero)
|
ku := NewDBKey(uint32(t.Unix()), emptyTopic, zero)
|
||||||
statement := "DELETE FROM envelopes WHERE id BETWEEN $1 AND $2"
|
statement := "DELETE FROM envelopes WHERE id BETWEEN $1 AND $2"
|
||||||
@ -179,8 +178,8 @@ func (i *PostgresDB) Prune(t time.Time, batch int) (int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *PostgresDB) SaveEnvelope(env *whisper.Envelope) error {
|
func (i *PostgresDB) SaveEnvelope(env *whisper.Envelope) error {
|
||||||
topic := whispertypes.TopicType(env.Topic)
|
topic := types.TopicType(env.Topic)
|
||||||
key := NewDBKey(env.Expiry-env.TTL, topic, statusproto.Hash(env.Hash()))
|
key := NewDBKey(env.Expiry-env.TTL, topic, types.Hash(env.Hash()))
|
||||||
rawEnvelope, err := rlp.EncodeToBytes(env)
|
rawEnvelope, err := rlp.EncodeToBytes(env)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
log.Error(fmt.Sprintf("rlp.EncodeToBytes failed: %s", err))
|
||||||
@ -214,7 +213,7 @@ func (i *PostgresDB) SaveEnvelope(env *whisper.Envelope) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func topicToByte(t whispertypes.TopicType) []byte {
|
func topicToByte(t types.TopicType) []byte {
|
||||||
return []byte{t[0], t[1], t[2], t[3]}
|
return []byte{t[0], t[1], t[2], t[3]}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
vendor/github.com/status-im/status-go/node/node.go
generated
vendored
36
vendor/github.com/status-im/status-go/node/node.go
generated
vendored
@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
gethcommon "github.com/ethereum/go-ethereum/common"
|
gethcommon "github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/eth"
|
"github.com/ethereum/go-ethereum/eth"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
"github.com/ethereum/go-ethereum/ethclient"
|
"github.com/ethereum/go-ethereum/ethclient"
|
||||||
@ -23,17 +22,18 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/p2p/discv5"
|
"github.com/ethereum/go-ethereum/p2p/discv5"
|
||||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||||
"github.com/ethereum/go-ethereum/p2p/nat"
|
"github.com/ethereum/go-ethereum/p2p/nat"
|
||||||
|
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
|
||||||
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
"github.com/status-im/status-go/mailserver"
|
"github.com/status-im/status-go/mailserver"
|
||||||
"github.com/status-im/status-go/params"
|
"github.com/status-im/status-go/params"
|
||||||
"github.com/status-im/status-go/services/incentivisation"
|
"github.com/status-im/status-go/services/incentivisation"
|
||||||
|
"github.com/status-im/status-go/services/nodebridge"
|
||||||
"github.com/status-im/status-go/services/peer"
|
"github.com/status-im/status-go/services/peer"
|
||||||
"github.com/status-im/status-go/services/personal"
|
"github.com/status-im/status-go/services/personal"
|
||||||
"github.com/status-im/status-go/services/shhext"
|
"github.com/status-im/status-go/services/shhext"
|
||||||
"github.com/status-im/status-go/services/status"
|
"github.com/status-im/status-go/services/status"
|
||||||
"github.com/status-im/status-go/services/whisperbridge"
|
|
||||||
"github.com/status-im/status-go/static"
|
"github.com/status-im/status-go/static"
|
||||||
"github.com/status-im/status-go/timesource"
|
"github.com/status-im/status-go/timesource"
|
||||||
gethbridge "github.com/status-im/status-protocol-go/bridge/geth"
|
|
||||||
whisper "github.com/status-im/whisper/whisperv6"
|
whisper "github.com/status-im/whisper/whisperv6"
|
||||||
"github.com/syndtr/goleveldb/leveldb"
|
"github.com/syndtr/goleveldb/leveldb"
|
||||||
)
|
)
|
||||||
@ -272,7 +272,7 @@ func activateStatusService(stack *node.Node, config *params.NodeConfig) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
var service *whisperbridge.WhisperService
|
var service *nodebridge.WhisperService
|
||||||
if err := ctx.Service(&service); err != nil {
|
if err := ctx.Service(&service); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -316,13 +316,25 @@ func activateShhService(stack *node.Node, config *params.NodeConfig, db *leveldb
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register Whisper status-protocol-go bridge
|
// Register eth-node node bridge
|
||||||
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
var whisper *whisper.Whisper
|
return &nodebridge.NodeService{Node: gethbridge.NewNodeBridge(stack)}, nil
|
||||||
if err := ctx.Service(&whisper); err != nil {
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register Whisper eth-node bridge
|
||||||
|
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
|
var ethnode *nodebridge.NodeService
|
||||||
|
if err := ctx.Service(ðnode); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &whisperbridge.WhisperService{Whisper: gethbridge.NewGethWhisperWrapper(whisper)}, nil
|
w, err := ethnode.Node.GetWhisper(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &nodebridge.WhisperService{Whisper: w}, nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@ -330,11 +342,11 @@ func activateShhService(stack *node.Node, config *params.NodeConfig, db *leveldb
|
|||||||
|
|
||||||
// TODO(dshulyak) add a config option to enable it by default, but disable if app is started from statusd
|
// TODO(dshulyak) add a config option to enable it by default, but disable if app is started from statusd
|
||||||
return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
var service *whisperbridge.WhisperService
|
var ethnode *nodebridge.NodeService
|
||||||
if err := ctx.Service(&service); err != nil {
|
if err := ctx.Service(ðnode); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return shhext.New(service.Whisper, shhext.EnvelopeSignalHandler{}, db, config.ShhextConfig), nil
|
return shhext.New(ethnode.Node, ctx, shhext.EnvelopeSignalHandler{}, db, config.ShhextConfig), nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,7 +410,7 @@ func activateIncentivisationService(stack *node.Node, config *params.NodeConfig)
|
|||||||
logger.Info("activating incentivisation")
|
logger.Info("activating incentivisation")
|
||||||
// TODO(dshulyak) add a config option to enable it by default, but disable if app is started from statusd
|
// TODO(dshulyak) add a config option to enable it by default, but disable if app is started from statusd
|
||||||
return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
return stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
|
||||||
var w *whisperbridge.WhisperService
|
var w *nodebridge.WhisperService
|
||||||
if err := ctx.Service(&w); err != nil {
|
if err := ctx.Service(&w); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user