Update for status-protocol-go API changes (#1627)
This commit is contained in:
parent
e164cbe421
commit
a2f106e4c5
|
@ -12,7 +12,6 @@ import (
|
|||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
|
@ -22,9 +21,12 @@ import (
|
|||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/services/shhext"
|
||||
"github.com/status-im/status-go/t/helpers"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"golang.org/x/crypto/sha3"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -105,11 +107,12 @@ func verifyMailserverBehavior(mailserverNode *enode.Node) {
|
|||
defer func() { _ = clientBackend.StopNode() }()
|
||||
|
||||
clientNode := clientBackend.StatusNode()
|
||||
clientWhisperService, err := clientNode.WhisperService()
|
||||
clientGethWhisperService, err := clientNode.WhisperService()
|
||||
if err != nil {
|
||||
logger.Error("Could not retrieve Whisper service", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
clientWhisperService := gethbridge.NewGethWhisperWrapper(clientGethWhisperService)
|
||||
clientShhExtService, err := clientNode.ShhExtService()
|
||||
if err != nil {
|
||||
logger.Error("Could not retrieve shhext service", "error", err)
|
||||
|
@ -139,7 +142,7 @@ func verifyMailserverBehavior(mailserverNode *enode.Node) {
|
|||
}
|
||||
|
||||
mailboxPeer := mailserverNode.ID().Bytes()
|
||||
err = clientWhisperService.AllowP2PMessagesFromPeer(mailboxPeer)
|
||||
err = clientGethWhisperService.AllowP2PMessagesFromPeer(mailboxPeer)
|
||||
if err != nil {
|
||||
logger.Error("Failed to allow P2P messages from mailserver peer", "error", err, mailserverNode.String())
|
||||
os.Exit(1)
|
||||
|
@ -155,12 +158,12 @@ func verifyMailserverBehavior(mailserverNode *enode.Node) {
|
|||
}
|
||||
|
||||
// watch for envelopes to be available in filters in the client
|
||||
envelopeAvailableWatcher := make(chan whisper.EnvelopeEvent, 1024)
|
||||
envelopeAvailableWatcher := make(chan whispertypes.EnvelopeEvent, 1024)
|
||||
sub := clientWhisperService.SubscribeEnvelopeEvents(envelopeAvailableWatcher)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
// watch for mailserver responses in the client
|
||||
mailServerResponseWatcher := make(chan whisper.EnvelopeEvent, 1024)
|
||||
mailServerResponseWatcher := make(chan whispertypes.EnvelopeEvent, 1024)
|
||||
sub = clientWhisperService.SubscribeEnvelopeEvents(mailServerResponseWatcher)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
|
@ -179,7 +182,7 @@ func verifyMailserverBehavior(mailserverNode *enode.Node) {
|
|||
logger.Error("Error requesting historic messages from mailserver", "error", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
requestID := common.BytesToHash(requestIDBytes)
|
||||
requestID := statusproto.BytesToHash(requestIDBytes)
|
||||
|
||||
// wait for mailserver request sent event
|
||||
err = waitForMailServerRequestSent(mailServerResponseWatcher, requestID, time.Duration(*timeout)*time.Second)
|
||||
|
@ -196,7 +199,7 @@ func verifyMailserverBehavior(mailserverNode *enode.Node) {
|
|||
}
|
||||
|
||||
// wait for last envelope sent by the mailserver to be available for filters
|
||||
err = waitForEnvelopeEvents(envelopeAvailableWatcher, []string{resp.LastEnvelopeHash.String()}, whisper.EventEnvelopeAvailable)
|
||||
err = waitForEnvelopeEvents(envelopeAvailableWatcher, []string{resp.LastEnvelopeHash.String()}, whispertypes.EventEnvelopeAvailable)
|
||||
if err != nil {
|
||||
logger.Error("Error waiting for envelopes to be available to client filter", "error", err)
|
||||
os.Exit(4)
|
||||
|
@ -300,32 +303,32 @@ func startClientNode() (*api.StatusBackend, error) {
|
|||
return clientBackend, err
|
||||
}
|
||||
|
||||
func joinPublicChat(w *whisper.Whisper, rpcClient *rpc.Client, name string) (string, whisper.TopicType, string, error) {
|
||||
func joinPublicChat(w whispertypes.Whisper, rpcClient *rpc.Client, name string) (string, whispertypes.TopicType, string, error) {
|
||||
keyID, err := w.AddSymKeyFromPassword(name)
|
||||
if err != nil {
|
||||
return "", whisper.TopicType{}, "", err
|
||||
return "", whispertypes.TopicType{}, "", err
|
||||
}
|
||||
|
||||
h := sha3.NewLegacyKeccak256()
|
||||
_, err = h.Write([]byte(name))
|
||||
if err != nil {
|
||||
return "", whisper.TopicType{}, "", err
|
||||
return "", whispertypes.TopicType{}, "", err
|
||||
}
|
||||
fullTopic := h.Sum(nil)
|
||||
topic := whisper.BytesToTopic(fullTopic)
|
||||
topic := whispertypes.BytesToTopic(fullTopic)
|
||||
|
||||
whisperAPI := whisper.NewPublicWhisperAPI(w)
|
||||
filterID, err := whisperAPI.NewMessageFilter(whisper.Criteria{SymKeyID: keyID, Topics: []whisper.TopicType{topic}})
|
||||
whisperAPI := w.PublicWhisperAPI()
|
||||
filterID, err := whisperAPI.NewMessageFilter(whispertypes.Criteria{SymKeyID: keyID, Topics: []whispertypes.TopicType{topic}})
|
||||
|
||||
return keyID, topic, filterID, err
|
||||
}
|
||||
|
||||
func waitForMailServerRequestSent(events chan whisper.EnvelopeEvent, requestID common.Hash, timeout time.Duration) error {
|
||||
func waitForMailServerRequestSent(events chan whispertypes.EnvelopeEvent, requestID statusproto.Hash, timeout time.Duration) error {
|
||||
timeoutTimer := time.NewTimer(timeout)
|
||||
for {
|
||||
select {
|
||||
case event := <-events:
|
||||
if event.Hash == requestID && event.Event == whisper.EventMailServerRequestSent {
|
||||
if event.Hash == requestID && event.Event == whispertypes.EventMailServerRequestSent {
|
||||
timeoutTimer.Stop()
|
||||
return nil
|
||||
}
|
||||
|
@ -335,7 +338,7 @@ func waitForMailServerRequestSent(events chan whisper.EnvelopeEvent, requestID c
|
|||
}
|
||||
}
|
||||
|
||||
func waitForMailServerResponse(events chan whisper.EnvelopeEvent, requestID common.Hash, timeout time.Duration) (*whisper.MailServerResponse, error) {
|
||||
func waitForMailServerResponse(events chan whispertypes.EnvelopeEvent, requestID statusproto.Hash, timeout time.Duration) (*whispertypes.MailServerResponse, error) {
|
||||
timeoutTimer := time.NewTimer(timeout)
|
||||
for {
|
||||
select {
|
||||
|
@ -353,25 +356,25 @@ func waitForMailServerResponse(events chan whisper.EnvelopeEvent, requestID comm
|
|||
}
|
||||
}
|
||||
|
||||
func decodeMailServerResponse(event whisper.EnvelopeEvent) (*whisper.MailServerResponse, error) {
|
||||
func decodeMailServerResponse(event whispertypes.EnvelopeEvent) (*whispertypes.MailServerResponse, error) {
|
||||
switch event.Event {
|
||||
case whisper.EventMailServerRequestSent:
|
||||
case whispertypes.EventMailServerRequestSent:
|
||||
return nil, nil
|
||||
case whisper.EventMailServerRequestCompleted:
|
||||
resp, ok := event.Data.(*whisper.MailServerResponse)
|
||||
case whispertypes.EventMailServerRequestCompleted:
|
||||
resp, ok := event.Data.(*whispertypes.MailServerResponse)
|
||||
if !ok {
|
||||
return nil, errors.New("failed to convert event to a *MailServerResponse")
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
case whisper.EventMailServerRequestExpired:
|
||||
case whispertypes.EventMailServerRequestExpired:
|
||||
return nil, errors.New("no messages available from mailserver")
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected event type: %v", event.Event)
|
||||
}
|
||||
}
|
||||
|
||||
func waitForEnvelopeEvents(events chan whisper.EnvelopeEvent, hashes []string, event whisper.EventType) error {
|
||||
func waitForEnvelopeEvents(events chan whispertypes.EnvelopeEvent, hashes []string, event whispertypes.EventType) error {
|
||||
check := make(map[string]struct{})
|
||||
for _, hash := range hashes {
|
||||
check[hash] = struct{}{}
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
)
|
||||
|
||||
|
@ -26,7 +26,7 @@ type DB interface {
|
|||
}
|
||||
|
||||
// TopicHistoryKey defines bytes that are used as unique key for TopicHistory.
|
||||
// first 4 bytes are whisper.TopicType bytes
|
||||
// first 4 bytes are whispertypes.TopicType bytes
|
||||
// next 8 bytes are time.Duration encoded in big endian notation.
|
||||
type TopicHistoryKey [12]byte
|
||||
|
||||
|
@ -36,7 +36,7 @@ func LoadTopicHistoryFromKey(db DB, key TopicHistoryKey) (th TopicHistory, err e
|
|||
if (key == TopicHistoryKey{}) {
|
||||
return th, ErrEmptyKey
|
||||
}
|
||||
topic := whisper.TopicType{}
|
||||
topic := whispertypes.TopicType{}
|
||||
copy(topic[:], key[:4])
|
||||
duration := binary.BigEndian.Uint64(key[4:])
|
||||
th = TopicHistory{db: db, Topic: topic, Duration: time.Duration(duration)}
|
||||
|
@ -47,7 +47,7 @@ func LoadTopicHistoryFromKey(db DB, key TopicHistoryKey) (th TopicHistory, err e
|
|||
type TopicHistory struct {
|
||||
db DB
|
||||
// whisper topic
|
||||
Topic whisper.TopicType
|
||||
Topic whispertypes.TopicType
|
||||
|
||||
Duration time.Duration
|
||||
// Timestamp that was used for the first request with this topic.
|
||||
|
@ -57,7 +57,7 @@ type TopicHistory struct {
|
|||
Current time.Time
|
||||
End time.Time
|
||||
|
||||
RequestID common.Hash
|
||||
RequestID statusproto.Hash
|
||||
}
|
||||
|
||||
// Key returns unique identifier for this TopicHistory.
|
||||
|
@ -115,7 +115,7 @@ func (t TopicHistory) SameRange(other TopicHistory) bool {
|
|||
|
||||
// Pending returns true if this topic was requested from a mail server.
|
||||
func (t TopicHistory) Pending() bool {
|
||||
return t.RequestID != common.Hash{}
|
||||
return t.RequestID != statusproto.Hash{}
|
||||
}
|
||||
|
||||
// HistoryRequest is kept in the database while request is in the progress.
|
||||
|
@ -127,7 +127,7 @@ type HistoryRequest struct {
|
|||
histories []TopicHistory
|
||||
|
||||
// Generated ID
|
||||
ID common.Hash
|
||||
ID statusproto.Hash
|
||||
// List of the topics
|
||||
TopicHistoryKeys []TopicHistoryKey
|
||||
}
|
||||
|
@ -167,8 +167,8 @@ func (req HistoryRequest) Save() error {
|
|||
}
|
||||
|
||||
// Replace saves request with new ID and all data attached to the old one.
|
||||
func (req HistoryRequest) Replace(id common.Hash) error {
|
||||
if (req.ID != common.Hash{}) {
|
||||
func (req HistoryRequest) Replace(id statusproto.Hash) error {
|
||||
if (req.ID != statusproto.Hash{}) {
|
||||
if err := req.Delete(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ package db
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||
)
|
||||
|
||||
|
@ -24,7 +24,7 @@ type HistoryStore struct {
|
|||
|
||||
// GetHistory creates history instance and loads history from database.
|
||||
// Returns instance populated with topic and duration if history is not found in database.
|
||||
func (h HistoryStore) GetHistory(topic whisper.TopicType, duration time.Duration) (TopicHistory, error) {
|
||||
func (h HistoryStore) GetHistory(topic whispertypes.TopicType, duration time.Duration) (TopicHistory, error) {
|
||||
thist := h.NewHistory(topic, duration)
|
||||
err := thist.Load()
|
||||
if err != nil && err != errors.ErrNotFound {
|
||||
|
@ -39,12 +39,12 @@ func (h HistoryStore) NewRequest() HistoryRequest {
|
|||
}
|
||||
|
||||
// NewHistory creates TopicHistory object with required values.
|
||||
func (h HistoryStore) NewHistory(topic whisper.TopicType, duration time.Duration) TopicHistory {
|
||||
func (h HistoryStore) NewHistory(topic whispertypes.TopicType, duration time.Duration) TopicHistory {
|
||||
return TopicHistory{db: h.topicDB, Duration: duration, Topic: topic}
|
||||
}
|
||||
|
||||
// GetRequest loads HistoryRequest from database.
|
||||
func (h HistoryStore) GetRequest(id common.Hash) (HistoryRequest, error) {
|
||||
func (h HistoryStore) GetRequest(id statusproto.Hash) (HistoryRequest, error) {
|
||||
req := HistoryRequest{requestDB: h.requestDB, topicDB: h.topicDB, ID: id}
|
||||
err := req.Load()
|
||||
if err != nil {
|
||||
|
@ -74,7 +74,7 @@ func (h HistoryStore) GetAllRequests() ([]HistoryRequest, error) {
|
|||
// GetHistoriesByTopic returns all histories with a given topic.
|
||||
// This is needed when we will have multiple range per single topic.
|
||||
// TODO explain
|
||||
func (h HistoryStore) GetHistoriesByTopic(topic whisper.TopicType) ([]TopicHistory, error) {
|
||||
func (h HistoryStore) GetHistoriesByTopic(topic whispertypes.TopicType) ([]TopicHistory, error) {
|
||||
rst := []TopicHistory{}
|
||||
iter := h.topicDB.NewIterator(h.topicDB.Range(topic[:], nil))
|
||||
for iter.Next() {
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -16,7 +16,7 @@ func createInMemStore(t *testing.T) HistoryStore {
|
|||
}
|
||||
|
||||
func TestGetNewHistory(t *testing.T) {
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
duration := time.Hour
|
||||
store := createInMemStore(t)
|
||||
th, err := store.GetHistory(topic, duration)
|
||||
|
@ -26,7 +26,7 @@ func TestGetNewHistory(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetExistingHistory(t *testing.T) {
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
duration := time.Hour
|
||||
store := createInMemStore(t)
|
||||
th, err := store.GetHistory(topic, duration)
|
||||
|
@ -43,13 +43,13 @@ func TestGetExistingHistory(t *testing.T) {
|
|||
|
||||
func TestNewHistoryRequest(t *testing.T) {
|
||||
store := createInMemStore(t)
|
||||
id := common.Hash{1}
|
||||
id := statusproto.Hash{1}
|
||||
req, err := store.GetRequest(id)
|
||||
require.Error(t, err)
|
||||
req = store.NewRequest()
|
||||
req.ID = id
|
||||
|
||||
th, err := store.GetHistory(whisper.TopicType{1}, time.Hour)
|
||||
th, err := store.GetHistory(whispertypes.TopicType{1}, time.Hour)
|
||||
require.NoError(t, err)
|
||||
req.AddHistory(th)
|
||||
require.NoError(t, req.Save())
|
||||
|
@ -61,8 +61,8 @@ func TestNewHistoryRequest(t *testing.T) {
|
|||
|
||||
func TestGetAllRequests(t *testing.T) {
|
||||
store := createInMemStore(t)
|
||||
idOne := common.Hash{1}
|
||||
idTwo := common.Hash{2}
|
||||
idOne := statusproto.Hash{1}
|
||||
idTwo := statusproto.Hash{2}
|
||||
|
||||
req := store.NewRequest()
|
||||
req.ID = idOne
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -14,7 +14,7 @@ func TestTopicHistoryStoreLoadFromKey(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
th := TopicHistory{
|
||||
db: db,
|
||||
Topic: whisper.TopicType{1, 1, 1},
|
||||
Topic: whispertypes.TopicType{1, 1, 1},
|
||||
Duration: 10 * time.Hour,
|
||||
}
|
||||
require.NoError(t, th.Save())
|
||||
|
@ -71,7 +71,7 @@ func TestTopicHistorySameRange(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAddHistory(t *testing.T) {
|
||||
topic := whisper.TopicType{1, 1, 1}
|
||||
topic := whispertypes.TopicType{1, 1, 1}
|
||||
now := time.Now()
|
||||
|
||||
topicdb, err := NewMemoryDBNamespace(TopicHistoryBucket)
|
||||
|
@ -80,7 +80,7 @@ func TestAddHistory(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
th := TopicHistory{db: topicdb, Topic: topic, Current: now}
|
||||
id := common.Hash{1}
|
||||
id := statusproto.Hash{1}
|
||||
|
||||
req := HistoryRequest{requestDB: requestdb, topicDB: topicdb, ID: id}
|
||||
req.AddHistory(th)
|
||||
|
@ -94,8 +94,8 @@ func TestAddHistory(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRequestIncludesMethod(t *testing.T) {
|
||||
topicOne := whisper.TopicType{1}
|
||||
topicTwo := whisper.TopicType{2}
|
||||
topicOne := whispertypes.TopicType{1}
|
||||
topicTwo := whispertypes.TopicType{2}
|
||||
testCases := []struct {
|
||||
description string
|
||||
result bool
|
||||
|
|
6
go.mod
6
go.mod
|
@ -30,10 +30,8 @@ require (
|
|||
github.com/status-im/keycard-go v0.0.0-20190424133014-d95853db0f48 // indirect
|
||||
github.com/status-im/migrate/v4 v4.3.1-status.0.20190822050738-a9d340ec8fb7
|
||||
github.com/status-im/rendezvous v1.3.0
|
||||
github.com/status-im/status-protocol-go v0.2.3-0.20190926081215-cc44ddb7ce44
|
||||
github.com/status-im/whisper v1.4.14
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
|
||||
github.com/status-im/status-protocol-go v0.2.3-0.20191009073015-e7ecec99a52b
|
||||
github.com/status-im/whisper v1.5.1
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
|
||||
|
|
17
go.sum
17
go.sum
|
@ -27,8 +27,11 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
|||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156 h1:hh7BAWFHv41r0gce0KRYtDJpL4erKfmB1/mpgoSADeI=
|
||||
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/allegro/bigcache v1.1.0 h1:MLuIKTjdxDc+qsG2rhjsYjsHQC5LUGjIWzutg7M+W68=
|
||||
github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
github.com/aristanetworks/goarista v0.0.0-20190502180301-283422fc1708/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7 h1:fKnuvQ/O22ZpD7HaJjGQXn/GxOdDJOQFL8bpM8Xe3X8=
|
||||
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
|
@ -41,6 +44,7 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce
|
|||
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/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-20190213025234-306aecffea32/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-20190824003749-130ea5bddde3 h1:A/EVblehb75cUgXA5njHPn0kLAsykn6mJGz7rnmW5W0=
|
||||
|
@ -115,7 +119,6 @@ github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt
|
|||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa h1:o8OuEkracbk3qH6GvlI6XpEN1HTSxkzOG42xZpfDv/s=
|
||||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||
github.com/ethereum/go-ethereum v1.8.20/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
|
||||
github.com/ethereum/go-ethereum v1.8.27/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 h1:jtW8jbpkO4YirRSyepBOH8E+2HEw6/hKkBvFPwhUN8c=
|
||||
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
|
@ -459,9 +462,13 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
|||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
|
@ -549,10 +556,10 @@ github.com/status-im/migrate/v4 v4.3.1-status.0.20190822050738-a9d340ec8fb7 h1:g
|
|||
github.com/status-im/migrate/v4 v4.3.1-status.0.20190822050738-a9d340ec8fb7/go.mod h1:r8HggRBZ/k7TRwByq/Hp3P/ubFppIna0nvyavVK0pjA=
|
||||
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/status-protocol-go v0.2.3-0.20190926081215-cc44ddb7ce44 h1:/dyB9wnkkNURvznzewDov3ulnLbjl8h1OeEEr5NQmQM=
|
||||
github.com/status-im/status-protocol-go v0.2.3-0.20190926081215-cc44ddb7ce44/go.mod h1:g059a1CeUmHKzsokiKwdk5pCuhCPE1GeOh8vULbfn5w=
|
||||
github.com/status-im/whisper v1.4.14 h1:9VHqx4+PUYfhDnYYtDxHkg/3cfVvkHjPNciY4LO83yc=
|
||||
github.com/status-im/whisper v1.4.14/go.mod h1:WS6z39YJQ8WJa9s+DmTuEM/s2nVF6Iz3B1SZYw5cYf0=
|
||||
github.com/status-im/status-protocol-go v0.2.3-0.20191009073015-e7ecec99a52b h1:hCB3tnF1yJ/IN0v+zR+Omc5DKUyUPyrrhyYkJUupnSw=
|
||||
github.com/status-im/status-protocol-go v0.2.3-0.20191009073015-e7ecec99a52b/go.mod h1:z4P5yngpR7aB6N6uYtJnhOkHzDHAHlqxTbIbaSX72Jg=
|
||||
github.com/status-im/whisper v1.5.1 h1:87/XIg0Wjua7lXBGiEXgAfTOqlt2Q1dMDuxugTyZbbA=
|
||||
github.com/status-im/whisper v1.5.1/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
|
||||
|
|
|
@ -32,6 +32,8 @@ import (
|
|||
"github.com/status-im/status-go/services/status"
|
||||
"github.com/status-im/status-go/static"
|
||||
"github.com/status-im/status-go/timesource"
|
||||
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
@ -356,7 +358,7 @@ func activateShhService(stack *node.Node, config *params.NodeConfig, db *leveldb
|
|||
if err := ctx.Service(&whisper); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return shhext.New(whisper, shhext.EnvelopeSignalHandler{}, db, config.ShhextConfig), nil
|
||||
return shhext.New(gethbridge.NewGethWhisperWrapper(whisper), shhext.EnvelopeSignalHandler{}, db, config.ShhextConfig), nil
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -375,7 +377,7 @@ func activateIncentivisationService(stack *node.Node, config *params.NodeConfig)
|
|||
logger.Info("activating incentivisation")
|
||||
// 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) {
|
||||
var w *whisper.Whisper
|
||||
var w whispertypes.Whisper
|
||||
if err := ctx.Service(&w); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -399,7 +401,7 @@ func activateIncentivisationService(stack *node.Node, config *params.NodeConfig)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
return incentivisation.New(privateKey, whisper.NewPublicWhisperAPI(w), incentivisationConfig, contract), nil
|
||||
return incentivisation.New(privateKey, w.PublicWhisperAPI(), incentivisationConfig, contract), nil
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
|
||||
"github.com/status-im/status-go/params"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
|
|
@ -8,6 +8,10 @@ import (
|
|||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
gethcommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
@ -15,12 +19,11 @@ import (
|
|||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"math/big"
|
||||
"net"
|
||||
"sort"
|
||||
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"time"
|
||||
|
||||
statustransp "github.com/status-im/status-protocol-go/transport/whisper"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -51,15 +54,6 @@ func (n *Enode) PublicKeyString() string {
|
|||
return hex.EncodeToString(n.PublicKey)
|
||||
}
|
||||
|
||||
type Whisper interface {
|
||||
Post(ctx context.Context, req whisper.NewMessage) (hexutil.Bytes, error)
|
||||
NewMessageFilter(req whisper.Criteria) (string, error)
|
||||
AddPrivateKey(ctx context.Context, privateKey hexutil.Bytes) (string, error)
|
||||
DeleteKeyPair(ctx context.Context, key string) (bool, error)
|
||||
GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error)
|
||||
GetFilterMessages(id string) ([]*whisper.Message, error)
|
||||
}
|
||||
|
||||
type ServiceConfig struct {
|
||||
RPCEndpoint string
|
||||
ContractAddress string
|
||||
|
@ -68,7 +62,7 @@ type ServiceConfig struct {
|
|||
}
|
||||
|
||||
type Service struct {
|
||||
w Whisper
|
||||
w whispertypes.PublicWhisperAPI
|
||||
whisperKeyID string
|
||||
whisperSymKeyID string
|
||||
whisperFilterID string
|
||||
|
@ -87,7 +81,7 @@ type Service struct {
|
|||
}
|
||||
|
||||
// New returns a new incentivization Service
|
||||
func New(prv *ecdsa.PrivateKey, w Whisper, config *ServiceConfig, contract Contract) *Service {
|
||||
func New(prv *ecdsa.PrivateKey, w whispertypes.PublicWhisperAPI, config *ServiceConfig, contract Contract) *Service {
|
||||
logger := log.New("package", "status-go/incentivisation/service")
|
||||
return &Service{
|
||||
w: w,
|
||||
|
@ -307,9 +301,9 @@ func (s *Service) Start(server *p2p.Server) error {
|
|||
}
|
||||
s.whisperSymKeyID = whisperSymKeyID
|
||||
|
||||
criteria := whisper.Criteria{
|
||||
criteria := whispertypes.Criteria{
|
||||
SymKeyID: whisperSymKeyID,
|
||||
Topics: []whisper.TopicType{toWhisperTopic(defaultTopic)},
|
||||
Topics: []whispertypes.TopicType{toWhisperTopic(defaultTopic)},
|
||||
}
|
||||
filterID, err := s.w.NewMessageFilter(criteria)
|
||||
if err != nil {
|
||||
|
@ -437,7 +431,7 @@ func (s *Service) addressString() string {
|
|||
|
||||
// postPing publishes a whisper message
|
||||
func (s *Service) postPing() (hexutil.Bytes, error) {
|
||||
msg := defaultWhisperMessage()
|
||||
msg := statustransp.DefaultWhisperMessage()
|
||||
|
||||
msg.Topic = toWhisperTopic(defaultTopic)
|
||||
|
||||
|
@ -484,18 +478,8 @@ func ip2Long(ip string) (uint32, error) {
|
|||
return long, nil
|
||||
}
|
||||
|
||||
func toWhisperTopic(s string) whisper.TopicType {
|
||||
return whisper.BytesToTopic(crypto.Keccak256([]byte(s)))
|
||||
}
|
||||
|
||||
func defaultWhisperMessage() whisper.NewMessage {
|
||||
msg := whisper.NewMessage{}
|
||||
|
||||
msg.TTL = 10
|
||||
msg.PowTarget = 0.002
|
||||
msg.PowTime = 1
|
||||
|
||||
return msg
|
||||
func toWhisperTopic(s string) whispertypes.TopicType {
|
||||
return whispertypes.BytesToTopic(crypto.Keccak256([]byte(s)))
|
||||
}
|
||||
|
||||
func int2ip(nn uint32) net.IP {
|
||||
|
|
|
@ -9,10 +9,10 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
gethcommon "github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
|
@ -34,8 +34,8 @@ type Vote struct {
|
|||
}
|
||||
|
||||
type MockWhisper struct {
|
||||
sentMessages []whisper.NewMessage
|
||||
filterMessages []*whisper.Message
|
||||
sentMessages []whispertypes.NewMessage
|
||||
filterMessages []*whispertypes.Message
|
||||
}
|
||||
|
||||
func BuildMockContract() *MockContract {
|
||||
|
@ -99,14 +99,14 @@ func (c *MockContract) GetInactiveNode(opts *bind.CallOpts, index *big.Int) ([]b
|
|||
return c.inactiveNodes[index.Int64()], 0, 0, 0, 0, nil
|
||||
}
|
||||
|
||||
func (w *MockWhisper) Post(ctx context.Context, req whisper.NewMessage) (hexutil.Bytes, error) {
|
||||
func (w *MockWhisper) Post(ctx context.Context, req whispertypes.NewMessage) ([]byte, error) {
|
||||
w.sentMessages = append(w.sentMessages, req)
|
||||
return nil, nil
|
||||
}
|
||||
func (w *MockWhisper) NewMessageFilter(req whisper.Criteria) (string, error) {
|
||||
func (w *MockWhisper) NewMessageFilter(req whispertypes.Criteria) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
func (w *MockWhisper) AddPrivateKey(ctx context.Context, privateKey hexutil.Bytes) (string, error) {
|
||||
func (w *MockWhisper) AddPrivateKey(ctx context.Context, privateKey statusproto.HexBytes) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
func (w *MockWhisper) DeleteKeyPair(ctx context.Context, key string) (bool, error) {
|
||||
|
@ -115,7 +115,7 @@ func (w *MockWhisper) DeleteKeyPair(ctx context.Context, key string) (bool, erro
|
|||
func (w *MockWhisper) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
func (w *MockWhisper) GetFilterMessages(id string) ([]*whisper.Message, error) {
|
||||
func (w *MockWhisper) GetFilterMessages(id string) ([]*whispertypes.Message, error) {
|
||||
return w.filterMessages, nil
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ func (s *IncentivisationSuite) TestPerform() {
|
|||
|
||||
now := time.Now().Unix()
|
||||
// Add some envelopes
|
||||
s.mockWhisper.filterMessages = []*whisper.Message{
|
||||
s.mockWhisper.filterMessages = []*whispertypes.Message{
|
||||
{
|
||||
// We strip the first byte when processing
|
||||
Sig: append(nodeOne, nodeOne[0]),
|
||||
|
|
|
@ -9,8 +9,6 @@ import (
|
|||
"math/big"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
|
@ -25,6 +23,9 @@ import (
|
|||
statusproto "github.com/status-im/status-protocol-go"
|
||||
"github.com/status-im/status-protocol-go/encryption/multidevice"
|
||||
statustransp "github.com/status-im/status-protocol-go/transport/whisper"
|
||||
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto_types "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -73,10 +74,10 @@ type MessagesRequest struct {
|
|||
|
||||
// Topic is a regular Whisper topic.
|
||||
// DEPRECATED
|
||||
Topic whisper.TopicType `json:"topic"`
|
||||
Topic whispertypes.TopicType `json:"topic"`
|
||||
|
||||
// Topics is a list of Whisper topics.
|
||||
Topics []whisper.TopicType `json:"topics"`
|
||||
Topics []whispertypes.TopicType `json:"topics"`
|
||||
|
||||
// SymKeyID is an ID of a symmetric key to authenticate to MailServer.
|
||||
// It's derived from MailServer password.
|
||||
|
@ -146,7 +147,7 @@ type SyncMessagesRequest struct {
|
|||
|
||||
// Topics is a list of Whisper topics.
|
||||
// If empty, a full bloom filter will be used.
|
||||
Topics []whisper.TopicType `json:"topics"`
|
||||
Topics []whispertypes.TopicType `json:"topics"`
|
||||
}
|
||||
|
||||
// SyncMessagesResponse is a response from the mail server
|
||||
|
@ -177,7 +178,7 @@ type InitiateHistoryRequestParams struct {
|
|||
// PublicAPI extends whisper public API.
|
||||
type PublicAPI struct {
|
||||
service *Service
|
||||
publicAPI *whisper.PublicWhisperAPI
|
||||
publicAPI whispertypes.PublicWhisperAPI
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
|
@ -185,7 +186,7 @@ type PublicAPI struct {
|
|||
func NewPublicAPI(s *Service) *PublicAPI {
|
||||
return &PublicAPI{
|
||||
service: s,
|
||||
publicAPI: whisper.NewPublicWhisperAPI(s.w),
|
||||
publicAPI: s.w.PublicWhisperAPI(),
|
||||
log: log.New("package", "status-go/services/sshext.PublicAPI"),
|
||||
}
|
||||
}
|
||||
|
@ -210,9 +211,9 @@ func (api *PublicAPI) RequestMessagesSync(conf RetryConfig, r MessagesRequest) (
|
|||
var resp MessagesResponse
|
||||
|
||||
shh := api.service.w
|
||||
events := make(chan whisper.EnvelopeEvent, 10)
|
||||
events := make(chan whispertypes.EnvelopeEvent, 10)
|
||||
var (
|
||||
requestID hexutil.Bytes
|
||||
requestID statusproto_types.HexBytes
|
||||
err error
|
||||
retries int
|
||||
)
|
||||
|
@ -227,7 +228,7 @@ func (api *PublicAPI) RequestMessagesSync(conf RetryConfig, r MessagesRequest) (
|
|||
sub.Unsubscribe()
|
||||
return resp, err
|
||||
}
|
||||
mailServerResp, err := waitForExpiredOrCompleted(common.BytesToHash(requestID), events, timeout)
|
||||
mailServerResp, err := waitForExpiredOrCompleted(statusproto_types.BytesToHash(requestID), events, timeout)
|
||||
sub.Unsubscribe()
|
||||
if err == nil {
|
||||
resp.Cursor = hex.EncodeToString(mailServerResp.Cursor)
|
||||
|
@ -240,12 +241,12 @@ func (api *PublicAPI) RequestMessagesSync(conf RetryConfig, r MessagesRequest) (
|
|||
return resp, fmt.Errorf("failed to request messages after %d retries", retries)
|
||||
}
|
||||
|
||||
func waitForExpiredOrCompleted(requestID common.Hash, events chan whisper.EnvelopeEvent, timeout time.Duration) (*whisper.MailServerResponse, error) {
|
||||
func waitForExpiredOrCompleted(requestID statusproto_types.Hash, events chan whispertypes.EnvelopeEvent, timeout time.Duration) (*whispertypes.MailServerResponse, error) {
|
||||
expired := fmt.Errorf("request %x expired", requestID)
|
||||
after := time.NewTimer(timeout)
|
||||
defer after.Stop()
|
||||
for {
|
||||
var ev whisper.EnvelopeEvent
|
||||
var ev whispertypes.EnvelopeEvent
|
||||
select {
|
||||
case ev = <-events:
|
||||
case <-after.C:
|
||||
|
@ -255,20 +256,20 @@ func waitForExpiredOrCompleted(requestID common.Hash, events chan whisper.Envelo
|
|||
continue
|
||||
}
|
||||
switch ev.Event {
|
||||
case whisper.EventMailServerRequestCompleted:
|
||||
data, ok := ev.Data.(*whisper.MailServerResponse)
|
||||
case whispertypes.EventMailServerRequestCompleted:
|
||||
data, ok := ev.Data.(*whispertypes.MailServerResponse)
|
||||
if ok {
|
||||
return data, nil
|
||||
}
|
||||
return nil, errors.New("invalid event data type")
|
||||
case whisper.EventMailServerRequestExpired:
|
||||
case whispertypes.EventMailServerRequestExpired:
|
||||
return nil, expired
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RequestMessages sends a request for historic messages to a MailServer.
|
||||
func (api *PublicAPI) RequestMessages(_ context.Context, r MessagesRequest) (hexutil.Bytes, error) {
|
||||
func (api *PublicAPI) RequestMessages(_ context.Context, r MessagesRequest) (statusproto_types.HexBytes, error) {
|
||||
api.log.Info("RequestMessages", "request", r)
|
||||
shh := api.service.w
|
||||
now := api.service.w.GetCurrentTime()
|
||||
|
@ -334,20 +335,20 @@ func (api *PublicAPI) RequestMessages(_ context.Context, r MessagesRequest) (hex
|
|||
|
||||
// createSyncMailRequest creates SyncMailRequest. It uses a full bloom filter
|
||||
// if no topics are given.
|
||||
func createSyncMailRequest(r SyncMessagesRequest) (whisper.SyncMailRequest, error) {
|
||||
func createSyncMailRequest(r SyncMessagesRequest) (whispertypes.SyncMailRequest, error) {
|
||||
var bloom []byte
|
||||
if len(r.Topics) > 0 {
|
||||
bloom = topicsToBloom(r.Topics...)
|
||||
} else {
|
||||
bloom = whisper.MakeFullNodeBloom()
|
||||
bloom = whispertypes.MakeFullNodeBloom()
|
||||
}
|
||||
|
||||
cursor, err := hex.DecodeString(r.Cursor)
|
||||
if err != nil {
|
||||
return whisper.SyncMailRequest{}, err
|
||||
return whispertypes.SyncMailRequest{}, err
|
||||
}
|
||||
|
||||
return whisper.SyncMailRequest{
|
||||
return whispertypes.SyncMailRequest{
|
||||
Lower: r.From,
|
||||
Upper: r.To,
|
||||
Bloom: bloom,
|
||||
|
@ -356,7 +357,7 @@ func createSyncMailRequest(r SyncMessagesRequest) (whisper.SyncMailRequest, erro
|
|||
}, nil
|
||||
}
|
||||
|
||||
func createSyncMessagesResponse(r whisper.SyncEventResponse) SyncMessagesResponse {
|
||||
func createSyncMessagesResponse(r whispertypes.SyncEventResponse) SyncMessagesResponse {
|
||||
return SyncMessagesResponse{
|
||||
Cursor: hex.EncodeToString(r.Cursor),
|
||||
Error: r.Error,
|
||||
|
@ -423,7 +424,7 @@ func (api *PublicAPI) ConfirmMessagesProcessedByID(messageConfirmations []*dedup
|
|||
// in other words don't use PFS-enabled messages. Otherwise, SendDirectMessage is used.
|
||||
// It's important to call PublicAPI.afterSend() so that the client receives a signal
|
||||
// with confirmation that the message left the device.
|
||||
func (api *PublicAPI) Post(ctx context.Context, newMessage whisper.NewMessage) (hexutil.Bytes, error) {
|
||||
func (api *PublicAPI) Post(ctx context.Context, newMessage whispertypes.NewMessage) (statusproto_types.HexBytes, error) {
|
||||
return api.publicAPI.Post(ctx, newMessage)
|
||||
}
|
||||
|
||||
|
@ -431,7 +432,7 @@ func (api *PublicAPI) Post(ctx context.Context, newMessage whisper.NewMessage) (
|
|||
// Message's payload is a transit encoded message.
|
||||
// It's important to call PublicAPI.afterSend() so that the client receives a signal
|
||||
// with confirmation that the message left the device.
|
||||
func (api *PublicAPI) SendPublicMessage(ctx context.Context, msg SendPublicMessageRPC) (hexutil.Bytes, error) {
|
||||
func (api *PublicAPI) SendPublicMessage(ctx context.Context, msg SendPublicMessageRPC) (statusproto_types.HexBytes, error) {
|
||||
chat := statusproto.Chat{
|
||||
Name: msg.Chat,
|
||||
}
|
||||
|
@ -442,7 +443,7 @@ func (api *PublicAPI) SendPublicMessage(ctx context.Context, msg SendPublicMessa
|
|||
// Message's payload is a transit encoded message.
|
||||
// It's important to call PublicAPI.afterSend() so that the client receives a signal
|
||||
// with confirmation that the message left the device.
|
||||
func (api *PublicAPI) SendDirectMessage(ctx context.Context, msg SendDirectMessageRPC) (hexutil.Bytes, error) {
|
||||
func (api *PublicAPI) SendDirectMessage(ctx context.Context, msg SendDirectMessageRPC) (statusproto_types.HexBytes, error) {
|
||||
publicKey, err := crypto.UnmarshalPubkey(msg.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -454,7 +455,7 @@ func (api *PublicAPI) SendDirectMessage(ctx context.Context, msg SendDirectMessa
|
|||
return api.service.messenger.SendRaw(ctx, chat, msg.Payload)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) requestMessagesUsingPayload(request db.HistoryRequest, peer, symkeyID string, payload []byte, force bool, timeout time.Duration, topics []whisper.TopicType) (hash common.Hash, err error) {
|
||||
func (api *PublicAPI) requestMessagesUsingPayload(request db.HistoryRequest, peer, symkeyID string, payload []byte, force bool, timeout time.Duration, topics []whispertypes.TopicType) (hash statusproto_types.Hash, err error) {
|
||||
shh := api.service.w
|
||||
now := api.service.w.GetCurrentTime()
|
||||
|
||||
|
@ -518,7 +519,7 @@ func (api *PublicAPI) requestMessagesUsingPayload(request db.HistoryRequest, pee
|
|||
// - Topic
|
||||
// - Duration in nanoseconds. Will be used to determine starting time for history request.
|
||||
// After that status-go will guarantee that request for this topic and date will be performed.
|
||||
func (api *PublicAPI) InitiateHistoryRequests(parent context.Context, request InitiateHistoryRequestParams) (rst []hexutil.Bytes, err error) {
|
||||
func (api *PublicAPI) InitiateHistoryRequests(parent context.Context, request InitiateHistoryRequestParams) (rst []statusproto_types.HexBytes, err error) {
|
||||
tx := api.service.storage.NewTx()
|
||||
defer func() {
|
||||
if err == nil {
|
||||
|
@ -532,7 +533,7 @@ func (api *PublicAPI) InitiateHistoryRequests(parent context.Context, request In
|
|||
}
|
||||
var (
|
||||
payload []byte
|
||||
hash common.Hash
|
||||
hash statusproto_types.Hash
|
||||
)
|
||||
for i := range requests {
|
||||
req := requests[i]
|
||||
|
@ -555,7 +556,7 @@ func (api *PublicAPI) InitiateHistoryRequests(parent context.Context, request In
|
|||
func (api *PublicAPI) CompleteRequest(parent context.Context, hex string) (err error) {
|
||||
tx := api.service.storage.NewTx()
|
||||
ctx := NewContextFromService(parent, api.service, tx)
|
||||
err = api.service.historyUpdates.UpdateFinishedRequest(ctx, common.HexToHash(hex))
|
||||
err = api.service.historyUpdates.UpdateFinishedRequest(ctx, statusproto_types.HexToHash(hex))
|
||||
if err == nil {
|
||||
return tx.Commit()
|
||||
}
|
||||
|
@ -667,7 +668,7 @@ func makeEnvelop(
|
|||
nodeID *ecdsa.PrivateKey,
|
||||
pow float64,
|
||||
now time.Time,
|
||||
) (*whisper.Envelope, error) {
|
||||
) (whispertypes.Envelope, error) {
|
||||
params := whisper.MessageParams{
|
||||
PoW: pow,
|
||||
Payload: payload,
|
||||
|
@ -685,7 +686,11 @@ func makeEnvelop(
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return message.Wrap(¶ms, now)
|
||||
envelope, err := message.Wrap(¶ms, now)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return gethbridge.NewGethEnvelopeWrapper(envelope), nil
|
||||
}
|
||||
|
||||
// makeMessagesRequestPayload makes a specific payload for MailServer
|
||||
|
@ -719,13 +724,13 @@ func createBloomFilter(r MessagesRequest) []byte {
|
|||
return topicsToBloom(r.Topics...)
|
||||
}
|
||||
|
||||
return whisper.TopicToBloom(r.Topic)
|
||||
return whisper.TopicToBloom(whisper.TopicType(r.Topic))
|
||||
}
|
||||
|
||||
func topicsToBloom(topics ...whisper.TopicType) []byte {
|
||||
func topicsToBloom(topics ...whispertypes.TopicType) []byte {
|
||||
i := new(big.Int)
|
||||
for _, topic := range topics {
|
||||
bloom := whisper.TopicToBloom(topic)
|
||||
bloom := whispertypes.TopicToBloom(topic)
|
||||
i.Or(i, new(big.Int).SetBytes(bloom[:]))
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,13 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
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"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/mailserver"
|
||||
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -100,26 +103,26 @@ func TestMakeMessagesRequestPayload(t *testing.T) {
|
|||
|
||||
func TestTopicsToBloom(t *testing.T) {
|
||||
t1 := stringToTopic("t1")
|
||||
b1 := whisper.TopicToBloom(t1)
|
||||
b1 := whispertypes.TopicToBloom(t1)
|
||||
t2 := stringToTopic("t2")
|
||||
b2 := whisper.TopicToBloom(t2)
|
||||
b2 := whispertypes.TopicToBloom(t2)
|
||||
t3 := stringToTopic("t3")
|
||||
b3 := whisper.TopicToBloom(t3)
|
||||
b3 := whispertypes.TopicToBloom(t3)
|
||||
|
||||
reqBloom := topicsToBloom(t1)
|
||||
assert.True(t, whisper.BloomFilterMatch(reqBloom, b1))
|
||||
assert.False(t, whisper.BloomFilterMatch(reqBloom, b2))
|
||||
assert.False(t, whisper.BloomFilterMatch(reqBloom, b3))
|
||||
assert.True(t, whispertypes.BloomFilterMatch(reqBloom, b1))
|
||||
assert.False(t, whispertypes.BloomFilterMatch(reqBloom, b2))
|
||||
assert.False(t, whispertypes.BloomFilterMatch(reqBloom, b3))
|
||||
|
||||
reqBloom = topicsToBloom(t1, t2)
|
||||
assert.True(t, whisper.BloomFilterMatch(reqBloom, b1))
|
||||
assert.True(t, whisper.BloomFilterMatch(reqBloom, b2))
|
||||
assert.False(t, whisper.BloomFilterMatch(reqBloom, b3))
|
||||
assert.True(t, whispertypes.BloomFilterMatch(reqBloom, b1))
|
||||
assert.True(t, whispertypes.BloomFilterMatch(reqBloom, b2))
|
||||
assert.False(t, whispertypes.BloomFilterMatch(reqBloom, b3))
|
||||
|
||||
reqBloom = topicsToBloom(t1, t2, t3)
|
||||
assert.True(t, whisper.BloomFilterMatch(reqBloom, b1))
|
||||
assert.True(t, whisper.BloomFilterMatch(reqBloom, b2))
|
||||
assert.True(t, whisper.BloomFilterMatch(reqBloom, b3))
|
||||
assert.True(t, whispertypes.BloomFilterMatch(reqBloom, b1))
|
||||
assert.True(t, whispertypes.BloomFilterMatch(reqBloom, b2))
|
||||
assert.True(t, whispertypes.BloomFilterMatch(reqBloom, b3))
|
||||
}
|
||||
|
||||
func TestCreateBloomFilter(t *testing.T) {
|
||||
|
@ -130,36 +133,36 @@ func TestCreateBloomFilter(t *testing.T) {
|
|||
bloom := createBloomFilter(req)
|
||||
assert.Equal(t, topicsToBloom(t1), bloom)
|
||||
|
||||
req = MessagesRequest{Topics: []whisper.TopicType{t1, t2}}
|
||||
req = MessagesRequest{Topics: []whispertypes.TopicType{t1, t2}}
|
||||
bloom = createBloomFilter(req)
|
||||
assert.Equal(t, topicsToBloom(t1, t2), bloom)
|
||||
}
|
||||
|
||||
func stringToTopic(s string) whisper.TopicType {
|
||||
return whisper.BytesToTopic([]byte(s))
|
||||
func stringToTopic(s string) whispertypes.TopicType {
|
||||
return whispertypes.BytesToTopic([]byte(s))
|
||||
}
|
||||
|
||||
func TestCreateSyncMailRequest(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Req SyncMessagesRequest
|
||||
Verify func(*testing.T, whisper.SyncMailRequest)
|
||||
Verify func(*testing.T, whispertypes.SyncMailRequest)
|
||||
Error string
|
||||
}{
|
||||
{
|
||||
Name: "no topics",
|
||||
Req: SyncMessagesRequest{},
|
||||
Verify: func(t *testing.T, r whisper.SyncMailRequest) {
|
||||
require.Equal(t, whisper.MakeFullNodeBloom(), r.Bloom)
|
||||
Verify: func(t *testing.T, r whispertypes.SyncMailRequest) {
|
||||
require.Equal(t, whispertypes.MakeFullNodeBloom(), r.Bloom)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "some topics",
|
||||
Req: SyncMessagesRequest{
|
||||
Topics: []whisper.TopicType{{0x01, 0xff, 0xff, 0xff}},
|
||||
Topics: []whispertypes.TopicType{{0x01, 0xff, 0xff, 0xff}},
|
||||
},
|
||||
Verify: func(t *testing.T, r whisper.SyncMailRequest) {
|
||||
expectedBloom := whisper.TopicToBloom(whisper.TopicType{0x01, 0xff, 0xff, 0xff})
|
||||
Verify: func(t *testing.T, r whispertypes.SyncMailRequest) {
|
||||
expectedBloom := whispertypes.TopicToBloom(whispertypes.TopicType{0x01, 0xff, 0xff, 0xff})
|
||||
require.Equal(t, expectedBloom, r.Bloom)
|
||||
},
|
||||
},
|
||||
|
@ -168,7 +171,7 @@ func TestCreateSyncMailRequest(t *testing.T) {
|
|||
Req: SyncMessagesRequest{
|
||||
Cursor: hex.EncodeToString([]byte{0x01, 0x02, 0x03}),
|
||||
},
|
||||
Verify: func(t *testing.T, r whisper.SyncMailRequest) {
|
||||
Verify: func(t *testing.T, r whispertypes.SyncMailRequest) {
|
||||
require.Equal(t, []byte{0x01, 0x02, 0x03}, r.Cursor)
|
||||
},
|
||||
},
|
||||
|
@ -223,9 +226,9 @@ func TestSyncMessagesErrors(t *testing.T) {
|
|||
|
||||
func TestExpiredOrCompleted(t *testing.T) {
|
||||
timeout := time.Millisecond
|
||||
events := make(chan whisper.EnvelopeEvent)
|
||||
events := make(chan whispertypes.EnvelopeEvent)
|
||||
errors := make(chan error, 1)
|
||||
hash := common.Hash{1}
|
||||
hash := statusproto.Hash{1}
|
||||
go func() {
|
||||
_, err := waitForExpiredOrCompleted(hash, events, timeout)
|
||||
errors <- err
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/status-im/status-go/db"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
"golang.org/x/crypto/sha3"
|
||||
|
@ -21,7 +21,7 @@ func newCache(db *leveldb.DB) *cache {
|
|||
return &cache{db, time.Now}
|
||||
}
|
||||
|
||||
func (d *cache) Has(filterID string, message *whisper.Message) (bool, error) {
|
||||
func (d *cache) Has(filterID string, message *whispertypes.Message) (bool, error) {
|
||||
has, err := d.db.Has(d.KeyToday(filterID, message), nil)
|
||||
|
||||
if err != nil {
|
||||
|
@ -34,7 +34,7 @@ func (d *cache) Has(filterID string, message *whisper.Message) (bool, error) {
|
|||
return d.db.Has(d.keyYesterday(filterID, message), nil)
|
||||
}
|
||||
|
||||
func (d *cache) Put(filterID string, messages []*whisper.Message) error {
|
||||
func (d *cache) Put(filterID string, messages []*whispertypes.Message) error {
|
||||
batch := leveldb.Batch{}
|
||||
|
||||
for _, msg := range messages {
|
||||
|
@ -89,11 +89,11 @@ func (d *cache) cleanOldEntries() error {
|
|||
return d.db.Write(&batch, nil)
|
||||
}
|
||||
|
||||
func (d *cache) keyYesterday(filterID string, message *whisper.Message) []byte {
|
||||
func (d *cache) keyYesterday(filterID string, message *whispertypes.Message) []byte {
|
||||
return prefixedKey(d.yesterdayDateString(), filterID, message)
|
||||
}
|
||||
|
||||
func (d *cache) KeyToday(filterID string, message *whisper.Message) []byte {
|
||||
func (d *cache) KeyToday(filterID string, message *whispertypes.Message) []byte {
|
||||
return prefixedKey(d.todayDateString(), filterID, message)
|
||||
}
|
||||
|
||||
|
@ -112,11 +112,11 @@ func dateString(t time.Time) string {
|
|||
return t.Format("20060102")
|
||||
}
|
||||
|
||||
func prefixedKey(date, filterID string, message *whisper.Message) []byte {
|
||||
func prefixedKey(date, filterID string, message *whispertypes.Message) []byte {
|
||||
return db.Key(db.DeduplicatorCache, []byte(date), []byte(filterID), key(message))
|
||||
}
|
||||
|
||||
func key(message *whisper.Message) []byte {
|
||||
func key(message *whispertypes.Message) []byte {
|
||||
data := make([]byte, len(message.Payload)+len(message.Topic))
|
||||
copy(data[:], message.Payload)
|
||||
copy(data[len(message.Payload):], message.Topic[:])
|
||||
|
|
|
@ -3,8 +3,8 @@ package dedup
|
|||
import (
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
)
|
||||
|
||||
|
@ -21,21 +21,21 @@ type Deduplicator struct {
|
|||
}
|
||||
|
||||
type Author struct {
|
||||
PublicKey hexutil.Bytes `json:"publicKey"`
|
||||
Alias string `json:"alias"`
|
||||
Identicon string `json:"identicon"`
|
||||
PublicKey statusproto.HexBytes `json:"publicKey"`
|
||||
Alias string `json:"alias"`
|
||||
Identicon string `json:"identicon"`
|
||||
}
|
||||
|
||||
type Metadata struct {
|
||||
DedupID []byte `json:"dedupId"`
|
||||
EncryptionID hexutil.Bytes `json:"encryptionId"`
|
||||
MessageID hexutil.Bytes `json:"messageId"`
|
||||
Author Author `json:"author"`
|
||||
DedupID []byte `json:"dedupId"`
|
||||
EncryptionID statusproto.HexBytes `json:"encryptionId"`
|
||||
MessageID statusproto.HexBytes `json:"messageId"`
|
||||
Author Author `json:"author"`
|
||||
}
|
||||
|
||||
type DeduplicateMessage struct {
|
||||
Message *whisper.Message `json:"message"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
Message *whispertypes.Message `json:"message"`
|
||||
Metadata Metadata `json:"metadata"`
|
||||
}
|
||||
|
||||
// NewDeduplicator creates a new deduplicator
|
||||
|
|
|
@ -3,14 +3,14 @@ package dedup
|
|||
import (
|
||||
"crypto/rand"
|
||||
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
func generateMessages(count int) []*whisper.Message {
|
||||
result := []*whisper.Message{}
|
||||
func generateMessages(count int) []*whispertypes.Message {
|
||||
result := []*whispertypes.Message{}
|
||||
for ; count > 0; count-- {
|
||||
content := mustGenerateRandomBytes()
|
||||
result = append(result, &whisper.Message{Payload: content})
|
||||
result = append(result, &whispertypes.Message{Payload: content})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func generateDedupMessages(count int) []*DeduplicateMessage {
|
|||
content := mustGenerateRandomBytes()
|
||||
result = append(result, &DeduplicateMessage{
|
||||
Metadata: Metadata{},
|
||||
Message: &whisper.Message{Payload: content},
|
||||
Message: &whispertypes.Message{Payload: content},
|
||||
})
|
||||
}
|
||||
return result
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/status-im/status-go/db"
|
||||
"github.com/status-im/status-go/mailserver"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -36,7 +36,7 @@ type HistoryUpdateReactor struct {
|
|||
|
||||
// UpdateFinishedRequest removes successfully finished request and updates every topic
|
||||
// attached to the request.
|
||||
func (reactor *HistoryUpdateReactor) UpdateFinishedRequest(ctx Context, id common.Hash) error {
|
||||
func (reactor *HistoryUpdateReactor) UpdateFinishedRequest(ctx Context, id statusproto.Hash) error {
|
||||
reactor.mu.Lock()
|
||||
defer reactor.mu.Unlock()
|
||||
req, err := ctx.HistoryStore().GetRequest(id)
|
||||
|
@ -45,7 +45,7 @@ func (reactor *HistoryUpdateReactor) UpdateFinishedRequest(ctx Context, id commo
|
|||
}
|
||||
for i := range req.Histories() {
|
||||
th := &req.Histories()[i]
|
||||
th.RequestID = common.Hash{}
|
||||
th.RequestID = statusproto.Hash{}
|
||||
th.Current = th.End
|
||||
th.End = time.Time{}
|
||||
if err := th.Save(); err != nil {
|
||||
|
@ -56,7 +56,7 @@ func (reactor *HistoryUpdateReactor) UpdateFinishedRequest(ctx Context, id commo
|
|||
}
|
||||
|
||||
// UpdateTopicHistory updates Current timestamp for the TopicHistory with a given timestamp.
|
||||
func (reactor *HistoryUpdateReactor) UpdateTopicHistory(ctx Context, topic whisper.TopicType, timestamp time.Time) error {
|
||||
func (reactor *HistoryUpdateReactor) UpdateTopicHistory(ctx Context, topic whispertypes.TopicType, timestamp time.Time) error {
|
||||
reactor.mu.Lock()
|
||||
defer reactor.mu.Unlock()
|
||||
histories, err := ctx.HistoryStore().GetHistoriesByTopic(topic)
|
||||
|
@ -87,7 +87,7 @@ func (reactor *HistoryUpdateReactor) UpdateTopicHistory(ctx Context, topic whisp
|
|||
|
||||
// TopicRequest defines what user has to provide.
|
||||
type TopicRequest struct {
|
||||
Topic whisper.TopicType
|
||||
Topic whispertypes.TopicType
|
||||
Duration time.Duration
|
||||
}
|
||||
|
||||
|
@ -96,14 +96,14 @@ type TopicRequest struct {
|
|||
func (reactor *HistoryUpdateReactor) CreateRequests(ctx Context, topicRequests []TopicRequest) ([]db.HistoryRequest, error) {
|
||||
reactor.mu.Lock()
|
||||
defer reactor.mu.Unlock()
|
||||
seen := map[whisper.TopicType]struct{}{}
|
||||
seen := map[whispertypes.TopicType]struct{}{}
|
||||
for i := range topicRequests {
|
||||
if _, exist := seen[topicRequests[i].Topic]; exist {
|
||||
return nil, errors.New("only one duration per topic is allowed")
|
||||
}
|
||||
seen[topicRequests[i].Topic] = struct{}{}
|
||||
}
|
||||
histories := map[whisper.TopicType]db.TopicHistory{}
|
||||
histories := map[whispertypes.TopicType]db.TopicHistory{}
|
||||
for i := range topicRequests {
|
||||
th, err := ctx.HistoryStore().GetHistory(topicRequests[i].Topic, topicRequests[i].Duration)
|
||||
if err != nil {
|
||||
|
@ -250,7 +250,7 @@ func CreateTopicOptionsFromRequest(req db.HistoryRequest) TopicOptions {
|
|||
return rst
|
||||
}
|
||||
|
||||
func mapToList(topics map[whisper.TopicType]db.TopicHistory) []db.TopicHistory {
|
||||
func mapToList(topics map[whispertypes.TopicType]db.TopicHistory) []db.TopicHistory {
|
||||
rst := make([]db.TopicHistory, 0, len(topics))
|
||||
for key := range topics {
|
||||
rst = append(rst, topics[key])
|
||||
|
@ -289,7 +289,7 @@ type Range struct {
|
|||
|
||||
// TopicOption request for a single topic.
|
||||
type TopicOption struct {
|
||||
Topic whisper.TopicType
|
||||
Topic whispertypes.TopicType
|
||||
Range Range
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,7 @@ type TopicOptions []TopicOption
|
|||
|
||||
// ToBloomFilterOption creates bloom filter request from a list of topics.
|
||||
func (options TopicOptions) ToBloomFilterOption() BloomFilterOption {
|
||||
topics := make([]whisper.TopicType, len(options))
|
||||
topics := make([]whispertypes.TopicType, len(options))
|
||||
var start, end uint64
|
||||
for i := range options {
|
||||
opt := options[i]
|
||||
|
@ -318,8 +318,8 @@ func (options TopicOptions) ToBloomFilterOption() BloomFilterOption {
|
|||
}
|
||||
|
||||
// Topics returns list of whisper TopicType attached to each TopicOption.
|
||||
func (options TopicOptions) Topics() []whisper.TopicType {
|
||||
rst := make([]whisper.TopicType, len(options))
|
||||
func (options TopicOptions) Topics() []whispertypes.TopicType {
|
||||
rst := make([]whispertypes.TopicType, len(options))
|
||||
for i := range options {
|
||||
rst[i] = options[i].Topic
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/status-im/status-go/db"
|
||||
"github.com/status-im/status-go/mailserver"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -51,7 +51,7 @@ func TestRenewRequest(t *testing.T) {
|
|||
|
||||
func TestCreateTopicOptionsFromRequest(t *testing.T) {
|
||||
req := db.HistoryRequest{}
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
now := time.Now()
|
||||
req.AddHistory(db.TopicHistory{Topic: topic, Current: now, End: now})
|
||||
options := CreateTopicOptionsFromRequest(req)
|
||||
|
@ -65,8 +65,8 @@ func TestCreateTopicOptionsFromRequest(t *testing.T) {
|
|||
|
||||
func TestTopicOptionsToBloom(t *testing.T) {
|
||||
options := TopicOptions{
|
||||
{Topic: whisper.TopicType{1}, Range: Range{Start: 1, End: 10}},
|
||||
{Topic: whisper.TopicType{2}, Range: Range{Start: 3, End: 12}},
|
||||
{Topic: whispertypes.TopicType{1}, Range: Range{Start: 1, End: 10}},
|
||||
{Topic: whispertypes.TopicType{2}, Range: Range{Start: 3, End: 12}},
|
||||
}
|
||||
bloom := options.ToBloomFilterOption()
|
||||
require.Equal(t, uint64(3), bloom.Range.Start, "Start must be the latest Start across all options")
|
||||
|
@ -105,9 +105,9 @@ func TestCreateRequestsEmptyState(t *testing.T) {
|
|||
ctx := newTestContext(t)
|
||||
reactor := NewHistoryUpdateReactor()
|
||||
requests, err := reactor.CreateRequests(ctx, []TopicRequest{
|
||||
{Topic: whisper.TopicType{1}, Duration: time.Hour},
|
||||
{Topic: whisper.TopicType{2}, Duration: time.Hour},
|
||||
{Topic: whisper.TopicType{3}, Duration: 10 * time.Hour},
|
||||
{Topic: whispertypes.TopicType{1}, Duration: time.Hour},
|
||||
{Topic: whispertypes.TopicType{2}, Duration: time.Hour},
|
||||
{Topic: whispertypes.TopicType{3}, Duration: 10 * time.Hour},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, requests, 2)
|
||||
|
@ -128,15 +128,15 @@ func TestCreateRequestsWithExistingRequest(t *testing.T) {
|
|||
ctx := newTestContext(t)
|
||||
store := ctx.HistoryStore()
|
||||
req := store.NewRequest()
|
||||
req.ID = common.Hash{1}
|
||||
th := store.NewHistory(whisper.TopicType{1}, time.Hour)
|
||||
req.ID = statusproto.Hash{1}
|
||||
th := store.NewHistory(whispertypes.TopicType{1}, time.Hour)
|
||||
req.AddHistory(th)
|
||||
require.NoError(t, req.Save())
|
||||
reactor := NewHistoryUpdateReactor()
|
||||
requests, err := reactor.CreateRequests(ctx, []TopicRequest{
|
||||
{Topic: whisper.TopicType{1}, Duration: time.Hour},
|
||||
{Topic: whisper.TopicType{2}, Duration: time.Hour},
|
||||
{Topic: whisper.TopicType{3}, Duration: time.Hour},
|
||||
{Topic: whispertypes.TopicType{1}, Duration: time.Hour},
|
||||
{Topic: whispertypes.TopicType{2}, Duration: time.Hour},
|
||||
{Topic: whispertypes.TopicType{3}, Duration: time.Hour},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, requests, 2)
|
||||
|
@ -157,13 +157,13 @@ func TestCreateMultiRequestsWithSameTopic(t *testing.T) {
|
|||
ctx := newTestContext(t)
|
||||
store := ctx.HistoryStore()
|
||||
reactor := NewHistoryUpdateReactor()
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
requests, err := reactor.CreateRequests(ctx, []TopicRequest{
|
||||
{Topic: topic, Duration: time.Hour},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, requests, 1)
|
||||
requests[0].ID = common.Hash{1}
|
||||
requests[0].ID = statusproto.Hash{1}
|
||||
require.NoError(t, requests[0].Save())
|
||||
|
||||
// duration changed. request wasn't finished
|
||||
|
@ -175,7 +175,7 @@ func TestCreateMultiRequestsWithSameTopic(t *testing.T) {
|
|||
longest := 0
|
||||
for i := range requests {
|
||||
r := &requests[i]
|
||||
r.ID = common.Hash{byte(i)}
|
||||
r.ID = statusproto.Hash{byte(i)}
|
||||
require.NoError(t, r.Save())
|
||||
require.Len(t, r.Histories(), 1)
|
||||
if r.Histories()[0].Duration == 10*time.Hour {
|
||||
|
@ -203,11 +203,11 @@ func TestRequestFinishedUpdate(t *testing.T) {
|
|||
ctx := newTestContext(t)
|
||||
store := ctx.HistoryStore()
|
||||
req := store.NewRequest()
|
||||
req.ID = common.Hash{1}
|
||||
req.ID = statusproto.Hash{1}
|
||||
now := ctx.Time()
|
||||
thOne := store.NewHistory(whisper.TopicType{1}, time.Hour)
|
||||
thOne := store.NewHistory(whispertypes.TopicType{1}, time.Hour)
|
||||
thOne.End = now
|
||||
thTwo := store.NewHistory(whisper.TopicType{2}, time.Hour)
|
||||
thTwo := store.NewHistory(whispertypes.TopicType{2}, time.Hour)
|
||||
thTwo.End = now
|
||||
req.AddHistory(thOne)
|
||||
req.AddHistory(thTwo)
|
||||
|
@ -228,12 +228,12 @@ func TestRequestFinishedUpdate(t *testing.T) {
|
|||
func TestTopicHistoryUpdate(t *testing.T) {
|
||||
ctx := newTestContext(t)
|
||||
store := ctx.HistoryStore()
|
||||
reqID := common.Hash{1}
|
||||
reqID := statusproto.Hash{1}
|
||||
request := store.NewRequest()
|
||||
request.ID = reqID
|
||||
now := time.Now()
|
||||
require.NoError(t, request.Save())
|
||||
th := store.NewHistory(whisper.TopicType{1}, time.Hour)
|
||||
th := store.NewHistory(whispertypes.TopicType{1}, time.Hour)
|
||||
th.RequestID = request.ID
|
||||
th.End = now
|
||||
require.NoError(t, th.Save())
|
||||
|
@ -251,12 +251,12 @@ func TestTopicHistoryUpdate(t *testing.T) {
|
|||
|
||||
func TestGroupHistoriesByRequestTimestamp(t *testing.T) {
|
||||
requests := GroupHistoriesByRequestTimespan(createInMemStore(t), []db.TopicHistory{
|
||||
{Topic: whisper.TopicType{1}, Duration: time.Hour},
|
||||
{Topic: whisper.TopicType{2}, Duration: time.Hour},
|
||||
{Topic: whisper.TopicType{3}, Duration: 2 * time.Hour},
|
||||
{Topic: whisper.TopicType{4}, Duration: 2 * time.Hour},
|
||||
{Topic: whisper.TopicType{5}, Duration: 3 * time.Hour},
|
||||
{Topic: whisper.TopicType{6}, Duration: 3 * time.Hour},
|
||||
{Topic: whispertypes.TopicType{1}, Duration: time.Hour},
|
||||
{Topic: whispertypes.TopicType{2}, Duration: time.Hour},
|
||||
{Topic: whispertypes.TopicType{3}, Duration: 2 * time.Hour},
|
||||
{Topic: whispertypes.TopicType{4}, Duration: 2 * time.Hour},
|
||||
{Topic: whispertypes.TopicType{5}, Duration: 3 * time.Hour},
|
||||
{Topic: whispertypes.TopicType{6}, Duration: 3 * time.Hour},
|
||||
})
|
||||
require.Len(t, requests, 3)
|
||||
for _, req := range requests {
|
||||
|
@ -267,7 +267,7 @@ func TestGroupHistoriesByRequestTimestamp(t *testing.T) {
|
|||
// initial creation of the history index. no other histories in store
|
||||
func TestAdjustHistoryWithNoOtherHistories(t *testing.T) {
|
||||
store := createInMemStore(t)
|
||||
th := store.NewHistory(whisper.TopicType{1}, time.Hour)
|
||||
th := store.NewHistory(whispertypes.TopicType{1}, time.Hour)
|
||||
adjusted, err := adjustRequestedHistories(store, []db.TopicHistory{th})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, adjusted, 1)
|
||||
|
@ -281,7 +281,7 @@ func TestAdjustHistoryWithNoOtherHistories(t *testing.T) {
|
|||
// that covers all of them e.g. {Duration: 4h}
|
||||
func TestAdjustHistoryWithExistingLowerRanges(t *testing.T) {
|
||||
store := createInMemStore(t)
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
histories := make([]db.TopicHistory, 3)
|
||||
i := 0
|
||||
for i = range histories {
|
||||
|
@ -309,7 +309,7 @@ func TestAdjustHistoryWithExistingLowerRanges(t *testing.T) {
|
|||
// We see that there is no reason to keep all indexes and we can squash them.
|
||||
func TestAdjustHistoriesWithExistingCoveredLowerRanges(t *testing.T) {
|
||||
store := createInMemStore(t)
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
histories := make([]db.TopicHistory, 3)
|
||||
i := 0
|
||||
now := time.Now()
|
||||
|
@ -332,7 +332,7 @@ func TestAdjustHistoriesWithExistingCoveredLowerRanges(t *testing.T) {
|
|||
|
||||
func TestAdjustHistoryReplaceTopicWithHigherDuration(t *testing.T) {
|
||||
store := createInMemStore(t)
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
hour := store.NewHistory(topic, time.Hour)
|
||||
require.NoError(t, hour.Save())
|
||||
minute := store.NewHistory(topic, time.Minute)
|
||||
|
@ -346,9 +346,9 @@ func TestAdjustHistoryReplaceTopicWithHigherDuration(t *testing.T) {
|
|||
// it will be discarded and we will use existing index
|
||||
func TestAdjustHistoryRemoveTopicIfPendingWithHigherDuration(t *testing.T) {
|
||||
store := createInMemStore(t)
|
||||
topic := whisper.TopicType{1}
|
||||
topic := whispertypes.TopicType{1}
|
||||
hour := store.NewHistory(topic, time.Hour)
|
||||
hour.RequestID = common.Hash{1}
|
||||
hour.RequestID = statusproto.Hash{1}
|
||||
require.NoError(t, hour.Save())
|
||||
minute := store.NewHistory(topic, time.Minute)
|
||||
adjusted, err := adjustRequestedHistories(store, []db.TopicHistory{minute})
|
||||
|
|
|
@ -3,9 +3,9 @@ package shhext
|
|||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
// EnvelopeState in local tracker
|
||||
|
@ -24,11 +24,11 @@ const (
|
|||
|
||||
// MailRequestMonitor is responsible for monitoring history request to mailservers.
|
||||
type MailRequestMonitor struct {
|
||||
w *whisper.Whisper
|
||||
w whispertypes.Whisper
|
||||
handler EnvelopeEventsHandler
|
||||
|
||||
mu sync.Mutex
|
||||
cache map[common.Hash]EnvelopeState
|
||||
cache map[statusproto.Hash]EnvelopeState
|
||||
|
||||
requestsRegistry *RequestsRegistry
|
||||
|
||||
|
@ -52,7 +52,7 @@ func (m *MailRequestMonitor) Stop() {
|
|||
m.wg.Wait()
|
||||
}
|
||||
|
||||
func (m *MailRequestMonitor) GetState(hash common.Hash) EnvelopeState {
|
||||
func (m *MailRequestMonitor) GetState(hash statusproto.Hash) EnvelopeState {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
state, exist := m.cache[hash]
|
||||
|
@ -64,7 +64,7 @@ func (m *MailRequestMonitor) GetState(hash common.Hash) EnvelopeState {
|
|||
|
||||
// handleEnvelopeEvents processes whisper envelope events
|
||||
func (m *MailRequestMonitor) handleEnvelopeEvents() {
|
||||
events := make(chan whisper.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||
events := make(chan whispertypes.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||
sub := m.w.SubscribeEnvelopeEvents(events)
|
||||
defer sub.Unsubscribe()
|
||||
for {
|
||||
|
@ -79,11 +79,11 @@ func (m *MailRequestMonitor) handleEnvelopeEvents() {
|
|||
|
||||
// handleEvent based on type of the event either triggers
|
||||
// confirmation handler or removes hash from MailRequestMonitor
|
||||
func (m *MailRequestMonitor) handleEvent(event whisper.EnvelopeEvent) {
|
||||
handlers := map[whisper.EventType]func(whisper.EnvelopeEvent){
|
||||
whisper.EventMailServerRequestSent: m.handleRequestSent,
|
||||
whisper.EventMailServerRequestCompleted: m.handleEventMailServerRequestCompleted,
|
||||
whisper.EventMailServerRequestExpired: m.handleEventMailServerRequestExpired,
|
||||
func (m *MailRequestMonitor) handleEvent(event whispertypes.EnvelopeEvent) {
|
||||
handlers := map[whispertypes.EventType]func(whispertypes.EnvelopeEvent){
|
||||
whispertypes.EventMailServerRequestSent: m.handleRequestSent,
|
||||
whispertypes.EventMailServerRequestCompleted: m.handleEventMailServerRequestCompleted,
|
||||
whispertypes.EventMailServerRequestExpired: m.handleEventMailServerRequestExpired,
|
||||
}
|
||||
|
||||
if handler, ok := handlers[event.Event]; ok {
|
||||
|
@ -91,13 +91,13 @@ func (m *MailRequestMonitor) handleEvent(event whisper.EnvelopeEvent) {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *MailRequestMonitor) handleRequestSent(event whisper.EnvelopeEvent) {
|
||||
func (m *MailRequestMonitor) handleRequestSent(event whispertypes.EnvelopeEvent) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.cache[event.Hash] = MailServerRequestSent
|
||||
}
|
||||
|
||||
func (m *MailRequestMonitor) handleEventMailServerRequestCompleted(event whisper.EnvelopeEvent) {
|
||||
func (m *MailRequestMonitor) handleEventMailServerRequestCompleted(event whispertypes.EnvelopeEvent) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.requestsRegistry.Unregister(event.Hash)
|
||||
|
@ -108,13 +108,13 @@ func (m *MailRequestMonitor) handleEventMailServerRequestCompleted(event whisper
|
|||
log.Debug("mailserver response received", "hash", event.Hash)
|
||||
delete(m.cache, event.Hash)
|
||||
if m.handler != nil {
|
||||
if resp, ok := event.Data.(*whisper.MailServerResponse); ok {
|
||||
if resp, ok := event.Data.(*whispertypes.MailServerResponse); ok {
|
||||
m.handler.MailServerRequestCompleted(event.Hash, resp.LastEnvelopeHash, resp.Cursor, resp.Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MailRequestMonitor) handleEventMailServerRequestExpired(event whisper.EnvelopeEvent) {
|
||||
func (m *MailRequestMonitor) handleEventMailServerRequestExpired(event whispertypes.EnvelopeEvent) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.requestsRegistry.Unregister(event.Hash)
|
||||
|
|
|
@ -5,13 +5,13 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
var (
|
||||
testHash = common.Hash{0x01}
|
||||
testHash = statusproto.Hash{0x01}
|
||||
)
|
||||
|
||||
func TestMailRequestMonitorSuite(t *testing.T) {
|
||||
|
@ -26,7 +26,7 @@ type MailRequestMonitorSuite struct {
|
|||
|
||||
func (s *MailRequestMonitorSuite) SetupTest() {
|
||||
s.monitor = &MailRequestMonitor{
|
||||
cache: map[common.Hash]EnvelopeState{},
|
||||
cache: map[statusproto.Hash]EnvelopeState{},
|
||||
requestsRegistry: NewRequestsRegistry(0),
|
||||
}
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ func (s *MailRequestMonitorSuite) TestRequestCompleted() {
|
|||
mock := newHandlerMock(1)
|
||||
s.monitor.handler = mock
|
||||
s.monitor.cache[testHash] = MailServerRequestSent
|
||||
s.monitor.handleEvent(whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestCompleted,
|
||||
s.monitor.handleEvent(whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestCompleted,
|
||||
Hash: testHash,
|
||||
Data: &whisper.MailServerResponse{},
|
||||
Data: &whispertypes.MailServerResponse{},
|
||||
})
|
||||
select {
|
||||
case requestID := <-mock.requestsCompleted:
|
||||
|
@ -53,10 +53,10 @@ func (s *MailRequestMonitorSuite) TestRequestFailed() {
|
|||
mock := newHandlerMock(1)
|
||||
s.monitor.handler = mock
|
||||
s.monitor.cache[testHash] = MailServerRequestSent
|
||||
s.monitor.handleEvent(whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestCompleted,
|
||||
s.monitor.handleEvent(whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestCompleted,
|
||||
Hash: testHash,
|
||||
Data: &whisper.MailServerResponse{Error: errors.New("test error")},
|
||||
Data: &whispertypes.MailServerResponse{Error: errors.New("test error")},
|
||||
})
|
||||
select {
|
||||
case requestID := <-mock.requestsFailed:
|
||||
|
@ -71,8 +71,8 @@ func (s *MailRequestMonitorSuite) TestRequestExpiration() {
|
|||
mock := newHandlerMock(1)
|
||||
s.monitor.handler = mock
|
||||
s.monitor.cache[testHash] = MailServerRequestSent
|
||||
s.monitor.handleEvent(whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestExpired,
|
||||
s.monitor.handleEvent(whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestExpired,
|
||||
Hash: testHash,
|
||||
})
|
||||
select {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/status-im/status-go/db"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/iterator"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
|
@ -67,8 +68,8 @@ func (c *Cache) Replace(nodes []*enode.Node) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, exist := newNodes[record.ID()]; exist {
|
||||
delete(newNodes, record.ID())
|
||||
if _, exist := newNodes[whispertypes.EnodeID(record.ID())]; exist {
|
||||
delete(newNodes, whispertypes.EnodeID(record.ID()))
|
||||
} else {
|
||||
batch.Delete(iter.Key())
|
||||
}
|
||||
|
@ -124,10 +125,10 @@ func unmarshalKeyValue(key, value []byte) (record PeerRecord, err error) {
|
|||
return record, err
|
||||
}
|
||||
|
||||
func nodesToMap(nodes []*enode.Node) map[enode.ID]*enode.Node {
|
||||
rst := map[enode.ID]*enode.Node{}
|
||||
func nodesToMap(nodes []*enode.Node) map[whispertypes.EnodeID]*enode.Node {
|
||||
rst := map[whispertypes.EnodeID]*enode.Node{}
|
||||
for _, n := range nodes {
|
||||
rst[n.ID()] = n
|
||||
rst[whispertypes.EnodeID(n.ID())] = n
|
||||
}
|
||||
return rst
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -28,9 +28,9 @@ type PeerEventsSubscriber interface {
|
|||
SubscribeEvents(chan *p2p.PeerEvent) event.Subscription
|
||||
}
|
||||
|
||||
// EnvelopeEventSubscbriber interface to subscribe for whisper.EnvelopeEvent's.
|
||||
type EnvelopeEventSubscbriber interface {
|
||||
SubscribeEnvelopeEvents(chan<- whisper.EnvelopeEvent) event.Subscription
|
||||
// EnvelopeEventSubscriber interface to subscribe for whispertypes.EnvelopeEvent's.
|
||||
type EnvelopeEventSubscriber interface {
|
||||
SubscribeEnvelopeEvents(chan<- whispertypes.EnvelopeEvent) whispertypes.Subscription
|
||||
}
|
||||
|
||||
type p2pServer interface {
|
||||
|
@ -39,7 +39,7 @@ type p2pServer interface {
|
|||
}
|
||||
|
||||
// NewConnectionManager creates an instance of ConnectionManager.
|
||||
func NewConnectionManager(server p2pServer, whisper EnvelopeEventSubscbriber, target, maxFailures int, timeout time.Duration) *ConnectionManager {
|
||||
func NewConnectionManager(server p2pServer, whisper EnvelopeEventSubscriber, target, maxFailures int, timeout time.Duration) *ConnectionManager {
|
||||
return &ConnectionManager{
|
||||
server: server,
|
||||
whisper: whisper,
|
||||
|
@ -56,7 +56,7 @@ type ConnectionManager struct {
|
|||
quit chan struct{}
|
||||
|
||||
server p2pServer
|
||||
whisper EnvelopeEventSubscbriber
|
||||
whisper EnvelopeEventSubscriber
|
||||
|
||||
notifications chan []*enode.Node
|
||||
connectedTarget int
|
||||
|
@ -85,10 +85,10 @@ func (ps *ConnectionManager) Start() {
|
|||
state := newInternalState(ps.server, ps.connectedTarget, ps.timeoutWaitAdded)
|
||||
events := make(chan *p2p.PeerEvent, peerEventsBuffer)
|
||||
sub := ps.server.SubscribeEvents(events)
|
||||
whisperEvents := make(chan whisper.EnvelopeEvent, whisperEventsBuffer)
|
||||
whisperEvents := make(chan whispertypes.EnvelopeEvent, whisperEventsBuffer)
|
||||
whisperSub := ps.whisper.SubscribeEnvelopeEvents(whisperEvents)
|
||||
requests := map[common.Hash]struct{}{}
|
||||
failuresPerServer := map[enode.ID]int{}
|
||||
requests := map[statusproto.Hash]struct{}{}
|
||||
failuresPerServer := map[whispertypes.EnodeID]int{}
|
||||
|
||||
defer sub.Unsubscribe()
|
||||
defer whisperSub.Unsubscribe()
|
||||
|
@ -110,13 +110,13 @@ func (ps *ConnectionManager) Start() {
|
|||
case ev := <-whisperEvents:
|
||||
// TODO treat failed requests the same way as expired
|
||||
switch ev.Event {
|
||||
case whisper.EventMailServerRequestSent:
|
||||
case whispertypes.EventMailServerRequestSent:
|
||||
requests[ev.Hash] = struct{}{}
|
||||
case whisper.EventMailServerRequestCompleted:
|
||||
case whispertypes.EventMailServerRequestCompleted:
|
||||
// reset failures count on first success
|
||||
failuresPerServer[ev.Peer] = 0
|
||||
delete(requests, ev.Hash)
|
||||
case whisper.EventMailServerRequestExpired:
|
||||
case whispertypes.EventMailServerRequestExpired:
|
||||
_, exist := requests[ev.Hash]
|
||||
if !exist {
|
||||
continue
|
||||
|
@ -148,9 +148,9 @@ func (ps *ConnectionManager) Stop() {
|
|||
}
|
||||
|
||||
func (state *internalState) processReplacement(newNodes []*enode.Node, events <-chan *p2p.PeerEvent) {
|
||||
replacement := map[enode.ID]*enode.Node{}
|
||||
replacement := map[whispertypes.EnodeID]*enode.Node{}
|
||||
for _, n := range newNodes {
|
||||
replacement[n.ID()] = n
|
||||
replacement[whispertypes.EnodeID(n.ID())] = n
|
||||
}
|
||||
state.replaceNodes(replacement)
|
||||
if state.ReachedTarget() {
|
||||
|
@ -170,8 +170,8 @@ func newInternalState(srv PeerAdderRemover, target int, timeout time.Duration) *
|
|||
return &internalState{
|
||||
options: options{target: target, timeout: timeout},
|
||||
srv: srv,
|
||||
connected: map[enode.ID]struct{}{},
|
||||
currentNodes: map[enode.ID]*enode.Node{},
|
||||
connected: map[whispertypes.EnodeID]struct{}{},
|
||||
currentNodes: map[whispertypes.EnodeID]*enode.Node{},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,15 +184,15 @@ type internalState struct {
|
|||
options
|
||||
srv PeerAdderRemover
|
||||
|
||||
connected map[enode.ID]struct{}
|
||||
currentNodes map[enode.ID]*enode.Node
|
||||
connected map[whispertypes.EnodeID]struct{}
|
||||
currentNodes map[whispertypes.EnodeID]*enode.Node
|
||||
}
|
||||
|
||||
func (state *internalState) ReachedTarget() bool {
|
||||
return len(state.connected) >= state.target
|
||||
}
|
||||
|
||||
func (state *internalState) replaceNodes(new map[enode.ID]*enode.Node) {
|
||||
func (state *internalState) replaceNodes(new map[whispertypes.EnodeID]*enode.Node) {
|
||||
for nid, n := range state.currentNodes {
|
||||
if _, exist := new[nid]; !exist {
|
||||
delete(state.connected, nid)
|
||||
|
@ -207,7 +207,7 @@ func (state *internalState) replaceNodes(new map[enode.ID]*enode.Node) {
|
|||
state.currentNodes = new
|
||||
}
|
||||
|
||||
func (state *internalState) nodeAdded(peer enode.ID) {
|
||||
func (state *internalState) nodeAdded(peer whispertypes.EnodeID) {
|
||||
n, exist := state.currentNodes[peer]
|
||||
if !exist {
|
||||
return
|
||||
|
@ -215,11 +215,11 @@ func (state *internalState) nodeAdded(peer enode.ID) {
|
|||
if state.ReachedTarget() {
|
||||
state.srv.RemovePeer(n)
|
||||
} else {
|
||||
state.connected[n.ID()] = struct{}{}
|
||||
state.connected[whispertypes.EnodeID(n.ID())] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func (state *internalState) nodeDisconnected(peer enode.ID) {
|
||||
func (state *internalState) nodeDisconnected(peer whispertypes.EnodeID) {
|
||||
n, exist := state.currentNodes[peer] // unrelated event
|
||||
if !exist {
|
||||
return
|
||||
|
@ -248,10 +248,10 @@ func processPeerEvent(state *internalState, ev *p2p.PeerEvent) {
|
|||
switch ev.Type {
|
||||
case p2p.PeerEventTypeAdd:
|
||||
log.Debug("connected to a mailserver", "address", ev.Peer)
|
||||
state.nodeAdded(ev.Peer)
|
||||
state.nodeAdded(whispertypes.EnodeID(ev.Peer))
|
||||
case p2p.PeerEventTypeDrop:
|
||||
log.Debug("mailserver disconnected", "address", ev.Peer)
|
||||
state.nodeDisconnected(ev.Peer)
|
||||
state.nodeDisconnected(whispertypes.EnodeID(ev.Peer))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,25 +6,25 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/status-im/status-go/t/utils"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type fakePeerEvents struct {
|
||||
mu sync.Mutex
|
||||
nodes map[enode.ID]struct{}
|
||||
nodes map[whispertypes.EnodeID]struct{}
|
||||
input chan *p2p.PeerEvent
|
||||
}
|
||||
|
||||
func (f *fakePeerEvents) Nodes() []enode.ID {
|
||||
func (f *fakePeerEvents) Nodes() []whispertypes.EnodeID {
|
||||
f.mu.Lock()
|
||||
rst := make([]enode.ID, 0, len(f.nodes))
|
||||
rst := make([]whispertypes.EnodeID, 0, len(f.nodes))
|
||||
for n := range f.nodes {
|
||||
rst = append(rst, n)
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func (f *fakePeerEvents) Nodes() []enode.ID {
|
|||
|
||||
func (f *fakePeerEvents) AddPeer(node *enode.Node) {
|
||||
f.mu.Lock()
|
||||
f.nodes[node.ID()] = struct{}{}
|
||||
f.nodes[whispertypes.EnodeID(node.ID())] = struct{}{}
|
||||
f.mu.Unlock()
|
||||
if f.input == nil {
|
||||
return
|
||||
|
@ -47,7 +47,7 @@ func (f *fakePeerEvents) AddPeer(node *enode.Node) {
|
|||
|
||||
func (f *fakePeerEvents) RemovePeer(node *enode.Node) {
|
||||
f.mu.Lock()
|
||||
delete(f.nodes, node.ID())
|
||||
delete(f.nodes, whispertypes.EnodeID(node.ID()))
|
||||
f.mu.Unlock()
|
||||
if f.input == nil {
|
||||
return
|
||||
|
@ -59,7 +59,7 @@ func (f *fakePeerEvents) RemovePeer(node *enode.Node) {
|
|||
}
|
||||
|
||||
func newFakePeerAdderRemover() *fakePeerEvents {
|
||||
return &fakePeerEvents{nodes: map[enode.ID]struct{}{}}
|
||||
return &fakePeerEvents{nodes: map[whispertypes.EnodeID]struct{}{}}
|
||||
}
|
||||
|
||||
func (f *fakePeerEvents) SubscribeEvents(output chan *p2p.PeerEvent) event.Subscription {
|
||||
|
@ -83,10 +83,10 @@ func newFakeServer() *fakePeerEvents {
|
|||
}
|
||||
|
||||
type fakeEnvelopeEvents struct {
|
||||
input chan whisper.EnvelopeEvent
|
||||
input chan whispertypes.EnvelopeEvent
|
||||
}
|
||||
|
||||
func (f *fakeEnvelopeEvents) SubscribeEnvelopeEvents(output chan<- whisper.EnvelopeEvent) event.Subscription {
|
||||
func (f *fakeEnvelopeEvents) SubscribeEnvelopeEvents(output chan<- whispertypes.EnvelopeEvent) whispertypes.Subscription {
|
||||
return event.NewSubscription(func(quit <-chan struct{}) error {
|
||||
for {
|
||||
select {
|
||||
|
@ -102,7 +102,7 @@ func (f *fakeEnvelopeEvents) SubscribeEnvelopeEvents(output chan<- whisper.Envel
|
|||
|
||||
func newFakeEnvelopesEvents() *fakeEnvelopeEvents {
|
||||
return &fakeEnvelopeEvents{
|
||||
input: make(chan whisper.EnvelopeEvent),
|
||||
input: make(chan whispertypes.EnvelopeEvent),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,13 +114,13 @@ func fillWithRandomNodes(t *testing.T, nodes []*enode.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
func getMapWithRandomNodes(t *testing.T, n int) map[enode.ID]*enode.Node {
|
||||
func getMapWithRandomNodes(t *testing.T, n int) map[whispertypes.EnodeID]*enode.Node {
|
||||
nodes := make([]*enode.Node, n)
|
||||
fillWithRandomNodes(t, nodes)
|
||||
return nodesToMap(nodes)
|
||||
}
|
||||
|
||||
func mergeOldIntoNew(old, new map[enode.ID]*enode.Node) {
|
||||
func mergeOldIntoNew(old, new map[whispertypes.EnodeID]*enode.Node) {
|
||||
for n := range old {
|
||||
new[n] = old[n]
|
||||
}
|
||||
|
@ -129,8 +129,8 @@ func mergeOldIntoNew(old, new map[enode.ID]*enode.Node) {
|
|||
func TestReplaceNodes(t *testing.T) {
|
||||
type testCase struct {
|
||||
description string
|
||||
old map[enode.ID]*enode.Node
|
||||
new map[enode.ID]*enode.Node
|
||||
old map[whispertypes.EnodeID]*enode.Node
|
||||
new map[whispertypes.EnodeID]*enode.Node
|
||||
target int
|
||||
}
|
||||
for _, tc := range []testCase{
|
||||
|
@ -183,7 +183,7 @@ func TestPartialReplaceNodesAboveTarget(t *testing.T) {
|
|||
new := getMapWithRandomNodes(t, 2)
|
||||
state := newInternalState(peers, 1, 0)
|
||||
state.replaceNodes(old)
|
||||
state.nodeAdded(initial.ID())
|
||||
state.nodeAdded(whispertypes.EnodeID(initial.ID()))
|
||||
mergeOldIntoNew(old, new)
|
||||
state.replaceNodes(new)
|
||||
require.Len(t, peers.nodes, 1)
|
||||
|
@ -209,7 +209,7 @@ func TestConnectionManagerAddDrop(t *testing.T) {
|
|||
if len(nodes) != target {
|
||||
return fmt.Errorf("unexpected number of connected servers: %d", len(nodes))
|
||||
}
|
||||
initial = nodes[0]
|
||||
initial = enode.ID(nodes[0])
|
||||
return nil
|
||||
}, time.Second, 100*time.Millisecond))
|
||||
// Send an event that peer was dropped.
|
||||
|
@ -224,7 +224,7 @@ func TestConnectionManagerAddDrop(t *testing.T) {
|
|||
if len(nodes) != target {
|
||||
return fmt.Errorf("unexpected number of connected servers: %d", len(nodes))
|
||||
}
|
||||
if nodes[0] == initial {
|
||||
if enode.ID(nodes[0]) == initial {
|
||||
return fmt.Errorf("connected node wasn't changed from %s", initial)
|
||||
}
|
||||
return nil
|
||||
|
@ -250,7 +250,7 @@ func TestConnectionManagerReplace(t *testing.T) {
|
|||
if len(connected) != target {
|
||||
return fmt.Errorf("unexpected number of connected servers: %d", len(connected))
|
||||
}
|
||||
if nodes[0].ID() != connected[0] {
|
||||
if whispertypes.EnodeID(nodes[0].ID()) != connected[0] {
|
||||
return fmt.Errorf("connected with a wrong peer. expected %s, got %s", nodes[0].ID(), connected[0])
|
||||
}
|
||||
return nil
|
||||
|
@ -263,7 +263,7 @@ func TestConnectionManagerReplace(t *testing.T) {
|
|||
if len(connected) != target {
|
||||
return fmt.Errorf("unexpected number of connected servers: %d", len(connected))
|
||||
}
|
||||
switch connected[0] {
|
||||
switch enode.ID(connected[0]) {
|
||||
case nodes[1].ID():
|
||||
case nodes[2].ID():
|
||||
default:
|
||||
|
@ -273,7 +273,7 @@ func TestConnectionManagerReplace(t *testing.T) {
|
|||
}, time.Second, 100*time.Millisecond))
|
||||
}
|
||||
|
||||
func setupTestConnectionAfterExpiry(t *testing.T, server *fakePeerEvents, whisperMock *fakeEnvelopeEvents, target, maxFailures int, hash common.Hash) (*ConnectionManager, enode.ID) {
|
||||
func setupTestConnectionAfterExpiry(t *testing.T, server *fakePeerEvents, whisperMock *fakeEnvelopeEvents, target, maxFailures int, hash statusproto.Hash) (*ConnectionManager, whispertypes.EnodeID) {
|
||||
connmanager := NewConnectionManager(server, whisperMock, target, maxFailures, 0)
|
||||
connmanager.Start()
|
||||
nodes := []*enode.Node{}
|
||||
|
@ -282,7 +282,7 @@ func setupTestConnectionAfterExpiry(t *testing.T, server *fakePeerEvents, whispe
|
|||
}
|
||||
// Send two random nodes to connection manager.
|
||||
connmanager.Notify(nodes)
|
||||
var initial enode.ID
|
||||
var initial whispertypes.EnodeID
|
||||
// Wait until connection manager establishes connection with one node.
|
||||
require.NoError(t, utils.Eventually(func() error {
|
||||
nodes := server.Nodes()
|
||||
|
@ -294,8 +294,8 @@ func setupTestConnectionAfterExpiry(t *testing.T, server *fakePeerEvents, whispe
|
|||
}, time.Second, 100*time.Millisecond))
|
||||
// Send event that history request for connected peer was sent.
|
||||
select {
|
||||
case whisperMock.input <- whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestSent, Peer: initial, Hash: hash}:
|
||||
case whisperMock.input <- whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestSent, Peer: initial, Hash: hash}:
|
||||
case <-time.After(time.Second):
|
||||
require.FailNow(t, "can't send a 'sent' event")
|
||||
}
|
||||
|
@ -307,14 +307,14 @@ func TestConnectionChangedAfterExpiry(t *testing.T) {
|
|||
whisperMock := newFakeEnvelopesEvents()
|
||||
target := 1
|
||||
maxFailures := 1
|
||||
hash := common.Hash{1}
|
||||
hash := statusproto.Hash{1}
|
||||
connmanager, initial := setupTestConnectionAfterExpiry(t, server, whisperMock, target, maxFailures, hash)
|
||||
defer connmanager.Stop()
|
||||
|
||||
// And eventually expired.
|
||||
select {
|
||||
case whisperMock.input <- whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestExpired, Peer: initial, Hash: hash}:
|
||||
case whisperMock.input <- whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestExpired, Peer: initial, Hash: hash}:
|
||||
case <-time.After(time.Second):
|
||||
require.FailNow(t, "can't send an 'expiry' event")
|
||||
}
|
||||
|
@ -335,14 +335,14 @@ func TestConnectionChangedAfterSecondExpiry(t *testing.T) {
|
|||
whisperMock := newFakeEnvelopesEvents()
|
||||
target := 1
|
||||
maxFailures := 2
|
||||
hash := common.Hash{1}
|
||||
hash := statusproto.Hash{1}
|
||||
connmanager, initial := setupTestConnectionAfterExpiry(t, server, whisperMock, target, maxFailures, hash)
|
||||
defer connmanager.Stop()
|
||||
|
||||
// First expired is sent. Nothing should happen.
|
||||
select {
|
||||
case whisperMock.input <- whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestExpired, Peer: initial, Hash: hash}:
|
||||
case whisperMock.input <- whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestExpired, Peer: initial, Hash: hash}:
|
||||
case <-time.After(time.Second):
|
||||
require.FailNow(t, "can't send an 'expiry' event")
|
||||
}
|
||||
|
@ -361,8 +361,8 @@ func TestConnectionChangedAfterSecondExpiry(t *testing.T) {
|
|||
|
||||
// second expiry event
|
||||
select {
|
||||
case whisperMock.input <- whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestExpired, Peer: initial, Hash: hash}:
|
||||
case whisperMock.input <- whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestExpired, Peer: initial, Hash: hash}:
|
||||
case <-time.After(time.Second):
|
||||
require.FailNow(t, "can't send an 'expiry' event")
|
||||
}
|
||||
|
|
|
@ -5,12 +5,11 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
// NewLastUsedConnectionMonitor returns pointer to the instance of LastUsedConnectionMonitor.
|
||||
func NewLastUsedConnectionMonitor(ps *PeerStore, cache *Cache, whisper EnvelopeEventSubscbriber) *LastUsedConnectionMonitor {
|
||||
func NewLastUsedConnectionMonitor(ps *PeerStore, cache *Cache, whisper EnvelopeEventSubscriber) *LastUsedConnectionMonitor {
|
||||
return &LastUsedConnectionMonitor{
|
||||
ps: ps,
|
||||
cache: cache,
|
||||
|
@ -23,7 +22,7 @@ type LastUsedConnectionMonitor struct {
|
|||
ps *PeerStore
|
||||
cache *Cache
|
||||
|
||||
whisper EnvelopeEventSubscbriber
|
||||
whisper EnvelopeEventSubscriber
|
||||
|
||||
quit chan struct{}
|
||||
wg sync.WaitGroup
|
||||
|
@ -34,7 +33,7 @@ func (mon *LastUsedConnectionMonitor) Start() {
|
|||
mon.quit = make(chan struct{})
|
||||
mon.wg.Add(1)
|
||||
go func() {
|
||||
events := make(chan whisper.EnvelopeEvent, whisperEventsBuffer)
|
||||
events := make(chan whispertypes.EnvelopeEvent, whisperEventsBuffer)
|
||||
sub := mon.whisper.SubscribeEnvelopeEvents(events)
|
||||
defer sub.Unsubscribe()
|
||||
defer mon.wg.Done()
|
||||
|
@ -50,7 +49,7 @@ func (mon *LastUsedConnectionMonitor) Start() {
|
|||
if node == nil {
|
||||
continue
|
||||
}
|
||||
if ev.Event == whisper.EventMailServerRequestCompleted {
|
||||
if ev.Event == whispertypes.EventMailServerRequestCompleted {
|
||||
err := mon.updateRecord(ev.Peer)
|
||||
if err != nil {
|
||||
log.Error("unable to update storage", "peer", ev.Peer, "error", err)
|
||||
|
@ -61,7 +60,7 @@ func (mon *LastUsedConnectionMonitor) Start() {
|
|||
}()
|
||||
}
|
||||
|
||||
func (mon *LastUsedConnectionMonitor) updateRecord(nodeID enode.ID) error {
|
||||
func (mon *LastUsedConnectionMonitor) updateRecord(nodeID whispertypes.EnodeID) error {
|
||||
node := mon.ps.Get(nodeID)
|
||||
if node == nil {
|
||||
return nil
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
"github.com/status-im/status-go/t/utils"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -25,8 +25,8 @@ func TestUsedConnectionPersisted(t *testing.T) {
|
|||
|
||||
// Send a confirmation that we received history from one of the peers.
|
||||
select {
|
||||
case whisperMock.input <- whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestCompleted, Peer: nodes[0].ID()}:
|
||||
case whisperMock.input <- whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestCompleted, Peer: whispertypes.EnodeID(nodes[0].ID())}:
|
||||
case <-time.After(time.Second):
|
||||
require.FailNow(t, "can't send a 'completed' event")
|
||||
}
|
||||
|
@ -47,15 +47,15 @@ func TestUsedConnectionPersisted(t *testing.T) {
|
|||
}
|
||||
}
|
||||
if !used {
|
||||
return fmt.Errorf("record %s is not marked as used", nodes[0].ID())
|
||||
return fmt.Errorf("record %s is not marked as used", whispertypes.EnodeID(nodes[0].ID()))
|
||||
}
|
||||
return nil
|
||||
}, time.Second, 100*time.Millisecond))
|
||||
|
||||
// Use different peer, first will be marked as unused.
|
||||
select {
|
||||
case whisperMock.input <- whisper.EnvelopeEvent{
|
||||
Event: whisper.EventMailServerRequestCompleted, Peer: nodes[1].ID()}:
|
||||
case whisperMock.input <- whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventMailServerRequestCompleted, Peer: whispertypes.EnodeID(nodes[1].ID())}:
|
||||
case <-time.After(time.Second):
|
||||
require.FailNow(t, "can't send a 'completed' event")
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -21,7 +22,7 @@ type PeersProvider interface {
|
|||
// NewPeerStore returns an instance of PeerStore.
|
||||
func NewPeerStore(cache *Cache) *PeerStore {
|
||||
return &PeerStore{
|
||||
nodes: map[enode.ID]*enode.Node{},
|
||||
nodes: map[whispertypes.EnodeID]*enode.Node{},
|
||||
cache: cache,
|
||||
}
|
||||
}
|
||||
|
@ -29,13 +30,13 @@ func NewPeerStore(cache *Cache) *PeerStore {
|
|||
// PeerStore stores list of selected mail servers and keeps N of them connected.
|
||||
type PeerStore struct {
|
||||
mu sync.RWMutex
|
||||
nodes map[enode.ID]*enode.Node
|
||||
nodes map[whispertypes.EnodeID]*enode.Node
|
||||
|
||||
cache *Cache
|
||||
}
|
||||
|
||||
// Exist confirms that peers was added to a store.
|
||||
func (ps *PeerStore) Exist(nodeID enode.ID) bool {
|
||||
func (ps *PeerStore) Exist(nodeID whispertypes.EnodeID) bool {
|
||||
ps.mu.RLock()
|
||||
defer ps.mu.RUnlock()
|
||||
_, exist := ps.nodes[nodeID]
|
||||
|
@ -43,7 +44,7 @@ func (ps *PeerStore) Exist(nodeID enode.ID) bool {
|
|||
}
|
||||
|
||||
// Get returns instance of the node with requested ID or nil if ID is not found.
|
||||
func (ps *PeerStore) Get(nodeID enode.ID) *enode.Node {
|
||||
func (ps *PeerStore) Get(nodeID whispertypes.EnodeID) *enode.Node {
|
||||
ps.mu.RLock()
|
||||
defer ps.mu.RUnlock()
|
||||
return ps.nodes[nodeID]
|
||||
|
@ -52,9 +53,9 @@ func (ps *PeerStore) Get(nodeID enode.ID) *enode.Node {
|
|||
// Update updates peers locally.
|
||||
func (ps *PeerStore) Update(nodes []*enode.Node) error {
|
||||
ps.mu.Lock()
|
||||
ps.nodes = map[enode.ID]*enode.Node{}
|
||||
ps.nodes = map[whispertypes.EnodeID]*enode.Node{}
|
||||
for _, n := range nodes {
|
||||
ps.nodes[n.ID()] = n
|
||||
ps.nodes[whispertypes.EnodeID(n.ID())] = n
|
||||
}
|
||||
ps.mu.Unlock()
|
||||
return ps.cache.Replace(nodes)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -24,11 +25,11 @@ func TestUpdateResetsInternalStorage(t *testing.T) {
|
|||
r2, err := RandomNode()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, store.Update([]*enode.Node{r1, r2}))
|
||||
require.True(t, store.Exist(r1.ID()))
|
||||
require.True(t, store.Exist(r2.ID()))
|
||||
require.True(t, store.Exist(whispertypes.EnodeID(r1.ID())))
|
||||
require.True(t, store.Exist(whispertypes.EnodeID(r2.ID())))
|
||||
require.NoError(t, store.Update([]*enode.Node{r2}))
|
||||
require.False(t, store.Exist(r1.ID()))
|
||||
require.True(t, store.Exist(r2.ID()))
|
||||
require.False(t, store.Exist(whispertypes.EnodeID(r1.ID())))
|
||||
require.True(t, store.Exist(whispertypes.EnodeID(r2.ID())))
|
||||
}
|
||||
|
||||
func TestGetNodeByID(t *testing.T) {
|
||||
|
@ -36,8 +37,8 @@ func TestGetNodeByID(t *testing.T) {
|
|||
r1, err := RandomNode()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, store.Update([]*enode.Node{r1}))
|
||||
require.Equal(t, r1, store.Get(r1.ID()))
|
||||
require.Nil(t, store.Get(enode.ID{1}))
|
||||
require.Equal(t, r1, store.Get(whispertypes.EnodeID(r1.ID())))
|
||||
require.Nil(t, store.Get(whispertypes.EnodeID{1}))
|
||||
}
|
||||
|
||||
type fakePeerProvider struct {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
// GetFirstConnected returns first connected peer that is also added to a peer store.
|
||||
|
@ -11,7 +12,7 @@ import (
|
|||
func GetFirstConnected(provider PeersProvider, store *PeerStore) (*enode.Node, error) {
|
||||
peers := provider.Peers()
|
||||
for _, p := range peers {
|
||||
if store.Exist(p.ID()) {
|
||||
if store.Exist(whispertypes.EnodeID(p.ID())) {
|
||||
return p.Node(), nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
|
@ -27,7 +28,7 @@ func TestGetFirstConnected(t *testing.T) {
|
|||
require.NoError(t, store.Update(nodes))
|
||||
node, err := GetFirstConnected(provider, store)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, nodesMap, node.ID())
|
||||
require.Contains(t, nodesMap, whispertypes.EnodeID(node.ID()))
|
||||
}
|
||||
|
||||
type trackingNodeNotifee struct {
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -17,7 +17,7 @@ const (
|
|||
|
||||
type requestMeta struct {
|
||||
timestamp time.Time
|
||||
lastUID common.Hash
|
||||
lastUID statusproto.Hash
|
||||
}
|
||||
|
||||
// NewRequestsRegistry creates instance of the RequestsRegistry and returns pointer to it.
|
||||
|
@ -33,13 +33,13 @@ func NewRequestsRegistry(delay time.Duration) *RequestsRegistry {
|
|||
type RequestsRegistry struct {
|
||||
mu sync.Mutex
|
||||
delay time.Duration
|
||||
uidToTopics map[common.Hash]common.Hash
|
||||
byTopicsHash map[common.Hash]requestMeta
|
||||
uidToTopics map[statusproto.Hash]statusproto.Hash
|
||||
byTopicsHash map[statusproto.Hash]requestMeta
|
||||
}
|
||||
|
||||
// Register request with given topics. If request with same topics was made in less then configured delay then error
|
||||
// will be returned.
|
||||
func (r *RequestsRegistry) Register(uid common.Hash, topics []whisper.TopicType) error {
|
||||
func (r *RequestsRegistry) Register(uid statusproto.Hash, topics []whispertypes.TopicType) error {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
topicsHash := topicsToHash(topics)
|
||||
|
@ -58,7 +58,7 @@ func (r *RequestsRegistry) Register(uid common.Hash, topics []whisper.TopicType)
|
|||
}
|
||||
|
||||
// Has returns true if given uid is stored in registry.
|
||||
func (r *RequestsRegistry) Has(uid common.Hash) bool {
|
||||
func (r *RequestsRegistry) Has(uid statusproto.Hash) bool {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
_, exist := r.uidToTopics[uid]
|
||||
|
@ -66,7 +66,7 @@ func (r *RequestsRegistry) Has(uid common.Hash) bool {
|
|||
}
|
||||
|
||||
// Unregister removes request with given UID from registry.
|
||||
func (r *RequestsRegistry) Unregister(uid common.Hash) {
|
||||
func (r *RequestsRegistry) Unregister(uid statusproto.Hash) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
topicsHash, exist := r.uidToTopics[uid]
|
||||
|
@ -85,15 +85,15 @@ func (r *RequestsRegistry) Unregister(uid common.Hash) {
|
|||
func (r *RequestsRegistry) Clear() {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
r.uidToTopics = map[common.Hash]common.Hash{}
|
||||
r.byTopicsHash = map[common.Hash]requestMeta{}
|
||||
r.uidToTopics = map[statusproto.Hash]statusproto.Hash{}
|
||||
r.byTopicsHash = map[statusproto.Hash]requestMeta{}
|
||||
}
|
||||
|
||||
// topicsToHash returns non-cryptographic hash of the topics.
|
||||
func topicsToHash(topics []whisper.TopicType) common.Hash {
|
||||
func topicsToHash(topics []whispertypes.TopicType) statusproto.Hash {
|
||||
hash := fnv.New32()
|
||||
for i := range topics {
|
||||
_, _ = hash.Write(topics[i][:]) // never returns error per documentation
|
||||
}
|
||||
return common.BytesToHash(hash.Sum(nil))
|
||||
return statusproto.BytesToHash(hash.Sum(nil))
|
||||
}
|
||||
|
|
|
@ -4,39 +4,39 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRegisterSameRequests(t *testing.T) {
|
||||
registry := NewRequestsRegistry(10 * time.Second)
|
||||
topics := []whisper.TopicType{{1}}
|
||||
require.NoError(t, registry.Register(common.Hash{1}, topics))
|
||||
require.Error(t, registry.Register(common.Hash{2}, topics))
|
||||
topics := []whispertypes.TopicType{{1}}
|
||||
require.NoError(t, registry.Register(statusproto.Hash{1}, topics))
|
||||
require.Error(t, registry.Register(statusproto.Hash{2}, topics))
|
||||
}
|
||||
|
||||
func TestRegisterSameRequestsWithoutDelay(t *testing.T) {
|
||||
registry := NewRequestsRegistry(0)
|
||||
topics := []whisper.TopicType{{1}}
|
||||
require.NoError(t, registry.Register(common.Hash{1}, topics))
|
||||
require.NoError(t, registry.Register(common.Hash{2}, topics))
|
||||
topics := []whispertypes.TopicType{{1}}
|
||||
require.NoError(t, registry.Register(statusproto.Hash{1}, topics))
|
||||
require.NoError(t, registry.Register(statusproto.Hash{2}, topics))
|
||||
}
|
||||
|
||||
func TestRegisterDifferentRequests(t *testing.T) {
|
||||
registry := NewRequestsRegistry(10 * time.Second)
|
||||
require.NoError(t, registry.Register(common.Hash{1}, []whisper.TopicType{{1}}))
|
||||
require.NoError(t, registry.Register(common.Hash{2}, []whisper.TopicType{{2}}))
|
||||
require.NoError(t, registry.Register(statusproto.Hash{1}, []whispertypes.TopicType{{1}}))
|
||||
require.NoError(t, registry.Register(statusproto.Hash{2}, []whispertypes.TopicType{{2}}))
|
||||
}
|
||||
|
||||
func TestUnregisterReplacedRequest(t *testing.T) {
|
||||
registry := NewRequestsRegistry(0)
|
||||
unreg := common.Hash{1}
|
||||
topics := []whisper.TopicType{{1}}
|
||||
unreg := statusproto.Hash{1}
|
||||
topics := []whispertypes.TopicType{{1}}
|
||||
require.NoError(t, registry.Register(unreg, topics))
|
||||
replacement := common.Hash{2}
|
||||
replacement := statusproto.Hash{2}
|
||||
require.NoError(t, registry.Register(replacement, topics))
|
||||
// record should be replaced with common.Hash{2}, so when we will remove unreg it will not affect topics map
|
||||
// record should be replaced with statusproto.Hash{2}, so when we will remove unreg it will not affect topics map
|
||||
registry.Unregister(unreg)
|
||||
record, exist := registry.uidToTopics[replacement]
|
||||
require.True(t, exist, "replaced record should exist")
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"database/sql"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/status-im/status-go/logutils"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/logutils"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
|
@ -27,7 +27,8 @@ import (
|
|||
|
||||
protocol "github.com/status-im/status-protocol-go"
|
||||
protocolwhisper "github.com/status-im/status-protocol-go/transport/whisper"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -43,8 +44,8 @@ const (
|
|||
type EnvelopeEventsHandler interface {
|
||||
EnvelopeSent([][]byte)
|
||||
EnvelopeExpired([][]byte, error)
|
||||
MailServerRequestCompleted(common.Hash, common.Hash, []byte, error)
|
||||
MailServerRequestExpired(common.Hash)
|
||||
MailServerRequestCompleted(statusproto.Hash, statusproto.Hash, []byte, error)
|
||||
MailServerRequestExpired(statusproto.Hash)
|
||||
}
|
||||
|
||||
// Service is a service that provides some additional Whisper API.
|
||||
|
@ -53,7 +54,7 @@ type Service struct {
|
|||
cancelMessenger chan struct{}
|
||||
|
||||
storage db.TransactionalStorage
|
||||
w *whisper.Whisper
|
||||
w whispertypes.Whisper
|
||||
config params.ShhextConfig
|
||||
mailMonitor *MailRequestMonitor
|
||||
requestsRegistry *RequestsRegistry
|
||||
|
@ -71,7 +72,7 @@ type Service struct {
|
|||
var _ node.Service = (*Service)(nil)
|
||||
|
||||
// New returns a new Service.
|
||||
func New(w *whisper.Whisper, handler EnvelopeEventsHandler, ldb *leveldb.DB, config params.ShhextConfig) *Service {
|
||||
func New(w whispertypes.Whisper, handler EnvelopeEventsHandler, ldb *leveldb.DB, config params.ShhextConfig) *Service {
|
||||
cache := mailservers.NewCache(ldb)
|
||||
ps := mailservers.NewPeerStore(cache)
|
||||
delay := defaultRequestsDelay
|
||||
|
@ -83,7 +84,7 @@ func New(w *whisper.Whisper, handler EnvelopeEventsHandler, ldb *leveldb.DB, con
|
|||
mailMonitor := &MailRequestMonitor{
|
||||
w: w,
|
||||
handler: handler,
|
||||
cache: map[common.Hash]EnvelopeState{},
|
||||
cache: map[statusproto.Hash]EnvelopeState{},
|
||||
requestsRegistry: requestsRegistry,
|
||||
}
|
||||
return &Service{
|
||||
|
@ -119,7 +120,7 @@ func (s *Service) InitProtocol(db *sql.DB) error { // nolint: gocyclo
|
|||
envelopesMonitorConfig := &protocolwhisper.EnvelopesMonitorConfig{
|
||||
MaxAttempts: s.config.MaxMessageDeliveryAttempts,
|
||||
MailserverConfirmationsEnabled: s.config.MailServerConfirmations,
|
||||
IsMailserver: func(peer enode.ID) bool {
|
||||
IsMailserver: func(peer whispertypes.EnodeID) bool {
|
||||
return s.peerStore.Exist(peer)
|
||||
},
|
||||
EnvelopeEventsHandler: EnvelopeSignalHandler{},
|
||||
|
@ -343,7 +344,7 @@ func (s *Service) Stop() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Service) syncMessages(ctx context.Context, mailServerID []byte, r whisper.SyncMailRequest) (resp whisper.SyncEventResponse, err error) {
|
||||
func (s *Service) syncMessages(ctx context.Context, mailServerID []byte, r whispertypes.SyncMailRequest) (resp whispertypes.SyncEventResponse, err error) {
|
||||
err = s.w.SyncMessages(mailServerID, r)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -351,7 +352,7 @@ func (s *Service) syncMessages(ctx context.Context, mailServerID []byte, r whisp
|
|||
|
||||
// Wait for the response which is received asynchronously as a p2p packet.
|
||||
// This packet handler will send an event which contains the response payload.
|
||||
events := make(chan whisper.EnvelopeEvent, 1024)
|
||||
events := make(chan whispertypes.EnvelopeEvent, 1024)
|
||||
sub := s.w.SubscribeEnvelopeEvents(events)
|
||||
defer sub.Unsubscribe()
|
||||
|
||||
|
@ -365,7 +366,7 @@ func (s *Service) syncMessages(ctx context.Context, mailServerID []byte, r whisp
|
|||
for {
|
||||
select {
|
||||
case event := <-events:
|
||||
if event.Event != whisper.EventMailServerSyncFinished {
|
||||
if event.Event != whispertypes.EventMailServerSyncFinished {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -373,7 +374,7 @@ func (s *Service) syncMessages(ctx context.Context, mailServerID []byte, r whisp
|
|||
|
||||
var ok bool
|
||||
|
||||
resp, ok = event.Data.(whisper.SyncEventResponse)
|
||||
resp, ok = event.Data.(whispertypes.SyncEventResponse)
|
||||
if !ok {
|
||||
err = fmt.Errorf("did not understand the response event data")
|
||||
return
|
||||
|
|
|
@ -23,6 +23,9 @@ import (
|
|||
"github.com/status-im/status-go/sqlite"
|
||||
"github.com/status-im/status-go/t/helpers"
|
||||
"github.com/status-im/status-go/t/utils"
|
||||
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
|
||||
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"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
|
@ -44,18 +47,18 @@ func newHandlerMock(buf int) handlerMock {
|
|||
return handlerMock{
|
||||
confirmations: make(chan [][]byte, buf),
|
||||
expirations: make(chan failureMessage, buf),
|
||||
requestsCompleted: make(chan common.Hash, buf),
|
||||
requestsExpired: make(chan common.Hash, buf),
|
||||
requestsFailed: make(chan common.Hash, buf),
|
||||
requestsCompleted: make(chan statusproto.Hash, buf),
|
||||
requestsExpired: make(chan statusproto.Hash, buf),
|
||||
requestsFailed: make(chan statusproto.Hash, buf),
|
||||
}
|
||||
}
|
||||
|
||||
type handlerMock struct {
|
||||
confirmations chan [][]byte
|
||||
expirations chan failureMessage
|
||||
requestsCompleted chan common.Hash
|
||||
requestsExpired chan common.Hash
|
||||
requestsFailed chan common.Hash
|
||||
requestsCompleted chan statusproto.Hash
|
||||
requestsExpired chan statusproto.Hash
|
||||
requestsFailed chan statusproto.Hash
|
||||
}
|
||||
|
||||
func (t handlerMock) EnvelopeSent(ids [][]byte) {
|
||||
|
@ -66,7 +69,7 @@ func (t handlerMock) EnvelopeExpired(ids [][]byte, err error) {
|
|||
t.expirations <- failureMessage{IDs: ids, Error: err}
|
||||
}
|
||||
|
||||
func (t handlerMock) MailServerRequestCompleted(requestID common.Hash, lastEnvelopeHash common.Hash, cursor []byte, err error) {
|
||||
func (t handlerMock) MailServerRequestCompleted(requestID statusproto.Hash, lastEnvelopeHash statusproto.Hash, cursor []byte, err error) {
|
||||
if err == nil {
|
||||
t.requestsCompleted <- requestID
|
||||
} else {
|
||||
|
@ -74,7 +77,7 @@ func (t handlerMock) MailServerRequestCompleted(requestID common.Hash, lastEnvel
|
|||
}
|
||||
}
|
||||
|
||||
func (t handlerMock) MailServerRequestExpired(hash common.Hash) {
|
||||
func (t handlerMock) MailServerRequestExpired(hash statusproto.Hash) {
|
||||
t.requestsExpired <- hash
|
||||
}
|
||||
|
||||
|
@ -87,13 +90,13 @@ type ShhExtSuite struct {
|
|||
|
||||
nodes []*node.Node
|
||||
services []*Service
|
||||
whisper []*whisper.Whisper
|
||||
whisper []whispertypes.Whisper
|
||||
}
|
||||
|
||||
func (s *ShhExtSuite) SetupTest() {
|
||||
s.nodes = make([]*node.Node, 2)
|
||||
s.services = make([]*Service, 2)
|
||||
s.whisper = make([]*whisper.Whisper, 2)
|
||||
s.whisper = make([]whispertypes.Whisper, 2)
|
||||
|
||||
directory, err := ioutil.TempDir("", "status-go-testing")
|
||||
s.Require().NoError(err)
|
||||
|
@ -111,7 +114,7 @@ func (s *ShhExtSuite) SetupTest() {
|
|||
}
|
||||
stack, err := node.New(cfg)
|
||||
s.NoError(err)
|
||||
s.whisper[i] = whisper.New(nil)
|
||||
s.whisper[i] = gethbridge.NewGethWhisperWrapper(whisper.New(nil))
|
||||
|
||||
privateKey, err := crypto.GenerateKey()
|
||||
s.NoError(err)
|
||||
|
@ -119,7 +122,7 @@ func (s *ShhExtSuite) SetupTest() {
|
|||
s.NoError(err)
|
||||
|
||||
s.NoError(stack.Register(func(n *node.ServiceContext) (node.Service, error) {
|
||||
return s.whisper[i], nil
|
||||
return gethbridge.GetGethWhisperFrom(s.whisper[i]), nil
|
||||
}))
|
||||
|
||||
config := params.ShhextConfig{
|
||||
|
@ -162,7 +165,7 @@ func (s *ShhExtSuite) TestInitProtocol() {
|
|||
db, err := leveldb.Open(storage.NewMemStorage(), nil)
|
||||
s.Require().NoError(err)
|
||||
|
||||
shh := whisper.New(nil)
|
||||
shh := gethbridge.NewGethWhisperWrapper(whisper.New(nil))
|
||||
privateKey, err := crypto.GenerateKey()
|
||||
s.Require().NoError(err)
|
||||
err = shh.SelectKeyPair(privateKey)
|
||||
|
@ -183,7 +186,7 @@ func (s *ShhExtSuite) TestInitProtocol() {
|
|||
func (s *ShhExtSuite) TestRequestMessagesErrors() {
|
||||
var err error
|
||||
|
||||
shh := whisper.New(nil)
|
||||
shh := gethbridge.NewGethWhisperWrapper(whisper.New(nil))
|
||||
aNode, err := node.New(&node.Config{
|
||||
P2P: p2p.Config{
|
||||
MaxPeers: math.MaxInt32,
|
||||
|
@ -193,7 +196,7 @@ func (s *ShhExtSuite) TestRequestMessagesErrors() {
|
|||
}) // in-memory node as no data dir
|
||||
s.NoError(err)
|
||||
err = aNode.Register(func(*node.ServiceContext) (node.Service, error) {
|
||||
return shh, nil
|
||||
return gethbridge.GetGethWhisperFrom(shh), nil
|
||||
})
|
||||
s.NoError(err)
|
||||
|
||||
|
@ -256,15 +259,15 @@ func (s *ShhExtSuite) TestMultipleRequestMessagesWithoutForce() {
|
|||
s.NoError(err)
|
||||
s.NoError(client.Call(nil, "shhext_requestMessages", MessagesRequest{
|
||||
MailServerPeer: s.nodes[1].Server().Self().URLv4(),
|
||||
Topics: []whisper.TopicType{{1}},
|
||||
Topics: []whispertypes.TopicType{{1}},
|
||||
}))
|
||||
s.EqualError(client.Call(nil, "shhext_requestMessages", MessagesRequest{
|
||||
MailServerPeer: s.nodes[1].Server().Self().URLv4(),
|
||||
Topics: []whisper.TopicType{{1}},
|
||||
Topics: []whispertypes.TopicType{{1}},
|
||||
}), "another request with the same topics was sent less than 3s ago. Please wait for a bit longer, or set `force` to true in request parameters")
|
||||
s.NoError(client.Call(nil, "shhext_requestMessages", MessagesRequest{
|
||||
MailServerPeer: s.nodes[1].Server().Self().URLv4(),
|
||||
Topics: []whisper.TopicType{{2}},
|
||||
Topics: []whispertypes.TopicType{{2}},
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -273,7 +276,7 @@ func (s *ShhExtSuite) TestFailedRequestUnregistered() {
|
|||
s.nodes[0].Server().AddPeer(s.nodes[1].Server().Self())
|
||||
s.Require().NoError(<-waitErr)
|
||||
client, err := s.nodes[0].Attach()
|
||||
topics := []whisper.TopicType{{1}}
|
||||
topics := []whispertypes.TopicType{{1}}
|
||||
s.NoError(err)
|
||||
s.EqualError(client.Call(nil, "shhext_requestMessages", MessagesRequest{
|
||||
MailServerPeer: "enode://19872f94b1e776da3a13e25afa71b47dfa99e658afd6427ea8d6e03c22a99f13590205a8826443e95a37eee1d815fc433af7a8ca9a8d0df7943d1f55684045b7@0.0.0.0:30305",
|
||||
|
@ -288,7 +291,7 @@ func (s *ShhExtSuite) TestFailedRequestUnregistered() {
|
|||
func (s *ShhExtSuite) TestRequestMessagesSuccess() {
|
||||
var err error
|
||||
|
||||
shh := whisper.New(nil)
|
||||
shh := gethbridge.NewGethWhisperWrapper(whisper.New(nil))
|
||||
privateKey, err := crypto.GenerateKey()
|
||||
s.Require().NoError(err)
|
||||
err = shh.SelectKeyPair(privateKey)
|
||||
|
@ -301,7 +304,7 @@ func (s *ShhExtSuite) TestRequestMessagesSuccess() {
|
|||
NoUSB: true,
|
||||
}) // in-memory node as no data dir
|
||||
s.Require().NoError(err)
|
||||
err = aNode.Register(func(*node.ServiceContext) (node.Service, error) { return shh, nil })
|
||||
err = aNode.Register(func(*node.ServiceContext) (node.Service, error) { return gethbridge.GetGethWhisperFrom(shh), nil })
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = aNode.Start()
|
||||
|
@ -408,10 +411,11 @@ func (s *WhisperNodeMockSuite) SetupTest() {
|
|||
err := w.HandlePeer(peer, rw2)
|
||||
errorc <- err
|
||||
}()
|
||||
s.Require().NoError(p2p.ExpectMsg(rw1, statusCode, []interface{}{whisper.ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), false, true}))
|
||||
s.Require().NoError(p2p.SendItems(rw1, statusCode, whisper.ProtocolVersion, whisper.ProtocolVersion, math.Float64bits(w.MinPow()), w.BloomFilter(), true, true))
|
||||
whisperWrapper := gethbridge.NewGethWhisperWrapper(w)
|
||||
s.Require().NoError(p2p.ExpectMsg(rw1, statusCode, []interface{}{whisper.ProtocolVersion, math.Float64bits(whisperWrapper.MinPow()), whisperWrapper.BloomFilter(), false, true}))
|
||||
s.Require().NoError(p2p.SendItems(rw1, statusCode, whisper.ProtocolVersion, whisper.ProtocolVersion, math.Float64bits(whisperWrapper.MinPow()), whisperWrapper.BloomFilter(), true, true))
|
||||
|
||||
s.localService = New(w, nil, db, params.ShhextConfig{MailServerConfirmations: true, MaxMessageDeliveryAttempts: 3})
|
||||
s.localService = New(whisperWrapper, nil, db, params.ShhextConfig{MailServerConfirmations: true, MaxMessageDeliveryAttempts: 3})
|
||||
s.Require().NoError(s.localService.UpdateMailservers([]*enode.Node{node}))
|
||||
|
||||
s.localWhisperAPI = whisper.NewPublicWhisperAPI(w)
|
||||
|
@ -514,7 +518,7 @@ type RequestWithTrackingHistorySuite struct {
|
|||
envelopeSymkey string
|
||||
envelopeSymkeyID string
|
||||
|
||||
localWhisperAPI *whisper.PublicWhisperAPI
|
||||
localWhisperAPI whispertypes.PublicWhisperAPI
|
||||
localAPI *PublicAPI
|
||||
localService *Service
|
||||
localContext Context
|
||||
|
@ -532,10 +536,11 @@ func (s *RequestWithTrackingHistorySuite) SetupTest() {
|
|||
MinimumAcceptedPOW: 0,
|
||||
MaxMessageSize: 100 << 10,
|
||||
}
|
||||
local := whisper.New(conf)
|
||||
s.Require().NoError(local.Start(nil))
|
||||
localSHH := whisper.New(conf)
|
||||
local := gethbridge.NewGethWhisperWrapper(localSHH)
|
||||
s.Require().NoError(localSHH.Start(nil))
|
||||
|
||||
s.localWhisperAPI = whisper.NewPublicWhisperAPI(local)
|
||||
s.localWhisperAPI = local.PublicWhisperAPI()
|
||||
s.localService = New(local, nil, db, params.ShhextConfig{})
|
||||
s.localContext = NewContextFromService(context.Background(), s.localService, s.localService.storage)
|
||||
localPkey, err := crypto.GenerateKey()
|
||||
|
@ -551,15 +556,15 @@ func (s *RequestWithTrackingHistorySuite) SetupTest() {
|
|||
s.Require().NoError(s.localService.Start(&p2p.Server{Config: p2p.Config{PrivateKey: localPkey}}))
|
||||
s.localAPI = NewPublicAPI(s.localService)
|
||||
|
||||
remote := whisper.New(conf)
|
||||
s.remoteWhisper = remote
|
||||
s.Require().NoError(remote.Start(nil))
|
||||
remoteSHH := whisper.New(conf)
|
||||
s.remoteWhisper = remoteSHH
|
||||
s.Require().NoError(remoteSHH.Start(nil))
|
||||
s.remoteMailserver = &mailserver.WMailServer{}
|
||||
remote.RegisterServer(s.remoteMailserver)
|
||||
remoteSHH.RegisterServer(s.remoteMailserver)
|
||||
password := "test"
|
||||
tmpdir, err = ioutil.TempDir("", "tracking-history-tests-")
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(s.remoteMailserver.Init(remote, ¶ms.WhisperConfig{
|
||||
s.Require().NoError(s.remoteMailserver.Init(remoteSHH, ¶ms.WhisperConfig{
|
||||
DataDir: tmpdir,
|
||||
MailServerPassword: password,
|
||||
}))
|
||||
|
@ -573,11 +578,11 @@ func (s *RequestWithTrackingHistorySuite) SetupTest() {
|
|||
// FIXME close this in tear down
|
||||
rw1, rw2 := p2p.MsgPipe()
|
||||
go func() {
|
||||
err := local.HandlePeer(remotePeer, rw1)
|
||||
err := localSHH.HandlePeer(remotePeer, rw1)
|
||||
s.Require().NoError(err)
|
||||
}()
|
||||
go func() {
|
||||
err := remote.HandlePeer(localPeer, rw2)
|
||||
err := remoteSHH.HandlePeer(localPeer, rw2)
|
||||
s.Require().NoError(err)
|
||||
}()
|
||||
s.mailSymKey, err = s.localWhisperAPI.GenerateSymKeyFromPassword(context.Background(), password)
|
||||
|
@ -588,13 +593,13 @@ func (s *RequestWithTrackingHistorySuite) SetupTest() {
|
|||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *RequestWithTrackingHistorySuite) postEnvelopes(topics ...whisper.TopicType) []hexutil.Bytes {
|
||||
func (s *RequestWithTrackingHistorySuite) postEnvelopes(topics ...whispertypes.TopicType) []hexutil.Bytes {
|
||||
var (
|
||||
rst = make([]hexutil.Bytes, len(topics))
|
||||
err error
|
||||
)
|
||||
for i, t := range topics {
|
||||
rst[i], err = s.localWhisperAPI.Post(context.Background(), whisper.NewMessage{
|
||||
rst[i], err = s.localWhisperAPI.Post(context.Background(), whispertypes.NewMessage{
|
||||
SymKeyID: s.envelopeSymkeyID,
|
||||
TTL: 10,
|
||||
Topic: t,
|
||||
|
@ -612,8 +617,8 @@ func (s *RequestWithTrackingHistorySuite) waitForArchival(hexes []hexutil.Bytes)
|
|||
s.Require().NoError(waitForArchival(events, 2*time.Second, hexes...))
|
||||
}
|
||||
|
||||
func (s *RequestWithTrackingHistorySuite) createEmptyFilter(topics ...whisper.TopicType) string {
|
||||
filterid, err := s.localWhisperAPI.NewMessageFilter(whisper.Criteria{
|
||||
func (s *RequestWithTrackingHistorySuite) createEmptyFilter(topics ...whispertypes.TopicType) string {
|
||||
filterid, err := s.localWhisperAPI.NewMessageFilter(whispertypes.Criteria{
|
||||
SymKeyID: s.envelopeSymkeyID,
|
||||
Topics: topics,
|
||||
AllowP2P: true,
|
||||
|
@ -627,7 +632,7 @@ func (s *RequestWithTrackingHistorySuite) createEmptyFilter(topics ...whisper.To
|
|||
return filterid
|
||||
}
|
||||
|
||||
func (s *RequestWithTrackingHistorySuite) initiateHistoryRequest(topics ...TopicRequest) []hexutil.Bytes {
|
||||
func (s *RequestWithTrackingHistorySuite) initiateHistoryRequest(topics ...TopicRequest) []statusproto.HexBytes {
|
||||
requests, err := s.localAPI.InitiateHistoryRequests(context.Background(), InitiateHistoryRequestParams{
|
||||
Peer: s.remoteNode.String(),
|
||||
SymKeyID: s.mailSymKey,
|
||||
|
@ -651,7 +656,6 @@ func (s *RequestWithTrackingHistorySuite) waitMessagesDelivered(filterid string,
|
|||
}
|
||||
return nil
|
||||
}, 2*time.Second, 200*time.Millisecond))
|
||||
|
||||
}
|
||||
|
||||
func (s *RequestWithTrackingHistorySuite) waitNoRequests() {
|
||||
|
@ -669,9 +673,9 @@ func (s *RequestWithTrackingHistorySuite) waitNoRequests() {
|
|||
}
|
||||
|
||||
func (s *RequestWithTrackingHistorySuite) TestMultipleMergeIntoOne() {
|
||||
topic1 := whisper.TopicType{1, 1, 1, 1}
|
||||
topic2 := whisper.TopicType{2, 2, 2, 2}
|
||||
topic3 := whisper.TopicType{3, 3, 3, 3}
|
||||
topic1 := whispertypes.TopicType{1, 1, 1, 1}
|
||||
topic2 := whispertypes.TopicType{2, 2, 2, 2}
|
||||
topic3 := whispertypes.TopicType{3, 3, 3, 3}
|
||||
hexes := s.postEnvelopes(topic1, topic2, topic3)
|
||||
s.waitForArchival(hexes)
|
||||
|
||||
|
@ -683,6 +687,7 @@ func (s *RequestWithTrackingHistorySuite) TestMultipleMergeIntoOne() {
|
|||
)
|
||||
// since we are using different duration for 3rd topic there will be 2 requests
|
||||
s.Require().Len(requests, 2)
|
||||
s.Require().NotEqual(requests[0], requests[1])
|
||||
s.waitMessagesDelivered(filterid, hexes...)
|
||||
|
||||
s.Require().NoError(s.localService.historyUpdates.UpdateTopicHistory(s.localContext, topic1, time.Now()))
|
||||
|
@ -702,8 +707,8 @@ func (s *RequestWithTrackingHistorySuite) TestMultipleMergeIntoOne() {
|
|||
}
|
||||
|
||||
func (s *RequestWithTrackingHistorySuite) TestSingleRequest() {
|
||||
topic1 := whisper.TopicType{1, 1, 1, 1}
|
||||
topic2 := whisper.TopicType{255, 255, 255, 255}
|
||||
topic1 := whispertypes.TopicType{1, 1, 1, 1}
|
||||
topic2 := whispertypes.TopicType{255, 255, 255, 255}
|
||||
hexes := s.postEnvelopes(topic1, topic2)
|
||||
s.waitForArchival(hexes)
|
||||
|
||||
|
@ -717,8 +722,8 @@ func (s *RequestWithTrackingHistorySuite) TestSingleRequest() {
|
|||
}
|
||||
|
||||
func (s *RequestWithTrackingHistorySuite) TestPreviousRequestReplaced() {
|
||||
topic1 := whisper.TopicType{1, 1, 1, 1}
|
||||
topic2 := whisper.TopicType{255, 255, 255, 255}
|
||||
topic1 := whispertypes.TopicType{1, 1, 1, 1}
|
||||
topic2 := whispertypes.TopicType{255, 255, 255, 255}
|
||||
|
||||
requests := s.initiateHistoryRequest(
|
||||
TopicRequest{Topic: topic1, Duration: time.Hour},
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package shhext
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/signal"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
// EnvelopeSignalHandler sends signals when envelope is sent or expired.
|
||||
|
@ -19,12 +19,12 @@ func (h EnvelopeSignalHandler) EnvelopeExpired(identifiers [][]byte, err error)
|
|||
}
|
||||
|
||||
// MailServerRequestCompleted triggered when the mailserver sends a message to notify that the request has been completed
|
||||
func (h EnvelopeSignalHandler) MailServerRequestCompleted(requestID common.Hash, lastEnvelopeHash common.Hash, cursor []byte, err error) {
|
||||
func (h EnvelopeSignalHandler) MailServerRequestCompleted(requestID statusproto.Hash, lastEnvelopeHash statusproto.Hash, cursor []byte, err error) {
|
||||
signal.SendMailServerRequestCompleted(requestID, lastEnvelopeHash, cursor, err)
|
||||
}
|
||||
|
||||
// MailServerRequestExpired triggered when the mailserver request expires
|
||||
func (h EnvelopeSignalHandler) MailServerRequestExpired(hash common.Hash) {
|
||||
func (h EnvelopeSignalHandler) MailServerRequestExpired(hash statusproto.Hash) {
|
||||
signal.SendMailServerRequestExpired(hash)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,13 +11,3 @@ var DiscoveryTopicBytes = ToTopic(discoveryTopic)
|
|||
func ToTopic(s string) whisper.TopicType {
|
||||
return whisper.BytesToTopic(crypto.Keccak256([]byte(s)))
|
||||
}
|
||||
|
||||
func DefaultWhisperMessage() whisper.NewMessage {
|
||||
msg := whisper.NewMessage{}
|
||||
|
||||
msg.TTL = 10
|
||||
msg.PowTarget = 0.002
|
||||
msg.PowTime = 1
|
||||
|
||||
return msg
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@ package signal
|
|||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/status-im/status-go/services/shhext/dedup"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
|
||||
statustransp "github.com/status-im/status-protocol-go/transport/whisper"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -46,17 +46,17 @@ const (
|
|||
|
||||
// EnvelopeSignal includes hash of the envelope.
|
||||
type EnvelopeSignal struct {
|
||||
IDs []hexutil.Bytes `json:"ids"`
|
||||
Hash common.Hash `json:"hash"`
|
||||
Message string `json:"message"`
|
||||
IDs []hexutil.Bytes `json:"ids"`
|
||||
Hash statusproto.Hash `json:"hash"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// MailServerResponseSignal holds the data received in the response from the mailserver.
|
||||
type MailServerResponseSignal struct {
|
||||
RequestID common.Hash `json:"requestID"`
|
||||
LastEnvelopeHash common.Hash `json:"lastEnvelopeHash"`
|
||||
Cursor string `json:"cursor"`
|
||||
ErrorMsg string `json:"errorMessage"`
|
||||
RequestID statusproto.Hash `json:"requestID"`
|
||||
LastEnvelopeHash statusproto.Hash `json:"lastEnvelopeHash"`
|
||||
Cursor string `json:"cursor"`
|
||||
ErrorMsg string `json:"errorMessage"`
|
||||
}
|
||||
|
||||
// DecryptMessageFailedSignal holds the sender of the message that could not be decrypted
|
||||
|
@ -82,7 +82,7 @@ type Filter struct {
|
|||
// Identity is the public key of the other recipient for non-public chats
|
||||
Identity string `json:"identity"`
|
||||
// Topic is the whisper topic
|
||||
Topic whisper.TopicType `json:"topic"`
|
||||
Topic whispertypes.TopicType `json:"topic"`
|
||||
}
|
||||
|
||||
type WhisperFilterAddedSignal struct {
|
||||
|
@ -121,7 +121,7 @@ func SendEnvelopeExpired(identifiers [][]byte, err error) {
|
|||
}
|
||||
|
||||
// SendMailServerRequestCompleted triggered when mail server response has been received
|
||||
func SendMailServerRequestCompleted(requestID common.Hash, lastEnvelopeHash common.Hash, cursor []byte, err error) {
|
||||
func SendMailServerRequestCompleted(requestID statusproto.Hash, lastEnvelopeHash statusproto.Hash, cursor []byte, err error) {
|
||||
errorMsg := ""
|
||||
if err != nil {
|
||||
errorMsg = err.Error()
|
||||
|
@ -136,7 +136,7 @@ func SendMailServerRequestCompleted(requestID common.Hash, lastEnvelopeHash comm
|
|||
}
|
||||
|
||||
// SendMailServerRequestExpired triggered when mail server request expires
|
||||
func SendMailServerRequestExpired(hash common.Hash) {
|
||||
func SendMailServerRequestExpired(hash statusproto.Hash) {
|
||||
send(EventMailServerRequestExpired, EnvelopeSignal{Hash: hash})
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/services/shhext"
|
||||
"github.com/status-im/status-protocol-go/transport/whisper/gethbridge"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
@ -41,7 +43,7 @@ func testMailserverPeer(t *testing.T) {
|
|||
BackupDisabledDataDir: os.TempDir(),
|
||||
InstallationID: "1",
|
||||
}
|
||||
mailService := shhext.New(shhService, nil, nil, config)
|
||||
mailService := shhext.New(gethbridge.NewGethWhisperWrapper(shhService), nil, nil, config)
|
||||
shhextAPI := shhext.NewPublicAPI(mailService)
|
||||
|
||||
// create node with services
|
||||
|
@ -88,7 +90,7 @@ func testMailserverPeer(t *testing.T) {
|
|||
requestID, err := shhextAPI.RequestMessages(context.TODO(), shhext.MessagesRequest{
|
||||
MailServerPeer: *peerURL,
|
||||
SymKeyID: symKeyID,
|
||||
Topic: topic,
|
||||
Topic: whispertypes.TopicType(topic),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, requestID)
|
||||
|
|
|
@ -2,9 +2,4 @@
|
|||
.DS_Store
|
||||
/server/server.exe
|
||||
/server/server
|
||||
/server/server_dar*
|
||||
/server/server_fre*
|
||||
/server/server_win*
|
||||
/server/server_net*
|
||||
/server/server_ope*
|
||||
CHANGELOG.md
|
||||
|
|
|
@ -14,7 +14,7 @@ before_install:
|
|||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get golang.org/x/tools/cmd/goimports
|
||||
- go get golang.org/x/lint/golint
|
||||
- go get github.com/golang/lint/golint
|
||||
- go get github.com/stretchr/testify/assert
|
||||
- go get github.com/gordonklaus/ineffassign
|
||||
|
||||
|
|
|
@ -46,15 +46,10 @@ config := bigcache.Config {
|
|||
// if value is reached then the oldest entries can be overridden for the new ones
|
||||
// 0 value means no size limit
|
||||
HardMaxCacheSize: 8192,
|
||||
// callback fired when the oldest entry is removed because of its expiration time or no space left
|
||||
// for the new entry, or because delete was called. A bitmask representing the reason will be returned.
|
||||
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
|
||||
// callback fired when the oldest entry is removed because of its
|
||||
// expiration time or no space left for the new entry. Default value is nil which
|
||||
// means no callback and it prevents from unwrapping the oldest entry.
|
||||
OnRemove: nil,
|
||||
// OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
|
||||
// for the new entry, or because delete was called. A constant representing the reason will be passed through.
|
||||
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
|
||||
// Ignored if OnRemove is specified.
|
||||
OnRemoveWithReason: nil,
|
||||
}
|
||||
|
||||
cache, initErr := bigcache.NewBigCache(config)
|
||||
|
@ -79,20 +74,20 @@ Benchmark tests were made using an i7-6700K with 32GB of RAM on Windows 10.
|
|||
```bash
|
||||
cd caches_bench; go test -bench=. -benchtime=10s ./... -timeout 30m
|
||||
|
||||
BenchmarkMapSet-8 3000000 569 ns/op 202 B/op 3 allocs/op
|
||||
BenchmarkConcurrentMapSet-8 1000000 1592 ns/op 347 B/op 8 allocs/op
|
||||
BenchmarkFreeCacheSet-8 3000000 775 ns/op 355 B/op 2 allocs/op
|
||||
BenchmarkBigCacheSet-8 3000000 640 ns/op 303 B/op 2 allocs/op
|
||||
BenchmarkMapGet-8 5000000 407 ns/op 24 B/op 1 allocs/op
|
||||
BenchmarkConcurrentMapGet-8 3000000 558 ns/op 24 B/op 2 allocs/op
|
||||
BenchmarkFreeCacheGet-8 2000000 682 ns/op 136 B/op 2 allocs/op
|
||||
BenchmarkBigCacheGet-8 3000000 512 ns/op 152 B/op 4 allocs/op
|
||||
BenchmarkBigCacheSetParallel-8 10000000 225 ns/op 313 B/op 3 allocs/op
|
||||
BenchmarkFreeCacheSetParallel-8 10000000 218 ns/op 341 B/op 3 allocs/op
|
||||
BenchmarkConcurrentMapSetParallel-8 5000000 318 ns/op 200 B/op 6 allocs/op
|
||||
BenchmarkBigCacheGetParallel-8 20000000 178 ns/op 152 B/op 4 allocs/op
|
||||
BenchmarkFreeCacheGetParallel-8 20000000 295 ns/op 136 B/op 3 allocs/op
|
||||
BenchmarkConcurrentMapGetParallel-8 10000000 237 ns/op 24 B/op 2 allocs/op
|
||||
BenchmarkMapSet-8 2000000 716 ns/op 336 B/op 3 allocs/op
|
||||
BenchmarkConcurrentMapSet-8 1000000 1292 ns/op 347 B/op 8 allocs/op
|
||||
BenchmarkFreeCacheSet-8 3000000 501 ns/op 371 B/op 3 allocs/op
|
||||
BenchmarkBigCacheSet-8 3000000 482 ns/op 303 B/op 2 allocs/op
|
||||
BenchmarkMapGet-8 5000000 309 ns/op 24 B/op 1 allocs/op
|
||||
BenchmarkConcurrentMapGet-8 2000000 659 ns/op 24 B/op 2 allocs/op
|
||||
BenchmarkFreeCacheGet-8 3000000 541 ns/op 152 B/op 3 allocs/op
|
||||
BenchmarkBigCacheGet-8 3000000 420 ns/op 152 B/op 3 allocs/op
|
||||
BenchmarkBigCacheSetParallel-8 10000000 184 ns/op 313 B/op 3 allocs/op
|
||||
BenchmarkFreeCacheSetParallel-8 10000000 195 ns/op 357 B/op 4 allocs/op
|
||||
BenchmarkConcurrentMapSetParallel-8 5000000 242 ns/op 200 B/op 6 allocs/op
|
||||
BenchmarkBigCacheGetParallel-8 20000000 100 ns/op 152 B/op 4 allocs/op
|
||||
BenchmarkFreeCacheGetParallel-8 10000000 133 ns/op 152 B/op 4 allocs/op
|
||||
BenchmarkConcurrentMapGetParallel-8 10000000 202 ns/op 24 B/op 2 allocs/op
|
||||
```
|
||||
|
||||
Writes and reads in bigcache are faster than in freecache.
|
||||
|
|
|
@ -10,7 +10,7 @@ const (
|
|||
)
|
||||
|
||||
// BigCache is fast, concurrent, evicting cache created to keep big number of entries without impact on performance.
|
||||
// It keeps entries on heap but omits GC for them. To achieve that, operations take place on byte arrays,
|
||||
// It keeps entries on heap but omits GC for them. To achieve that operations on bytes arrays take place,
|
||||
// therefore entries (de)serialization in front of the cache will be needed in most use cases.
|
||||
type BigCache struct {
|
||||
shards []*cacheShard
|
||||
|
@ -20,22 +20,8 @@ type BigCache struct {
|
|||
config Config
|
||||
shardMask uint64
|
||||
maxShardSize uint32
|
||||
close chan struct{}
|
||||
}
|
||||
|
||||
// RemoveReason is a value used to signal to the user why a particular key was removed in the OnRemove callback.
|
||||
type RemoveReason uint32
|
||||
|
||||
const (
|
||||
// Expired means the key is past its LifeWindow.
|
||||
Expired RemoveReason = iota
|
||||
// NoSpace means the key is the oldest and the cache size was at its maximum when Set was called, or the
|
||||
// entry exceeded the maximum shard size.
|
||||
NoSpace
|
||||
// Deleted means Delete was called and this key was removed as a result.
|
||||
Deleted
|
||||
)
|
||||
|
||||
// NewBigCache initialize new instance of BigCache
|
||||
func NewBigCache(config Config) (*BigCache, error) {
|
||||
return newBigCache(config, &systemClock{})
|
||||
|
@ -59,16 +45,13 @@ func newBigCache(config Config, clock clock) (*BigCache, error) {
|
|||
config: config,
|
||||
shardMask: uint64(config.Shards - 1),
|
||||
maxShardSize: uint32(config.maximumShardSize()),
|
||||
close: make(chan struct{}),
|
||||
}
|
||||
|
||||
var onRemove func(wrappedEntry []byte, reason RemoveReason)
|
||||
if config.OnRemove != nil {
|
||||
onRemove = cache.providedOnRemove
|
||||
} else if config.OnRemoveWithReason != nil {
|
||||
onRemove = cache.providedOnRemoveWithReason
|
||||
} else {
|
||||
var onRemove func(wrappedEntry []byte)
|
||||
if config.OnRemove == nil {
|
||||
onRemove = cache.notProvidedOnRemove
|
||||
} else {
|
||||
onRemove = cache.providedOnRemove
|
||||
}
|
||||
|
||||
for i := 0; i < config.Shards; i++ {
|
||||
|
@ -77,15 +60,8 @@ func newBigCache(config Config, clock clock) (*BigCache, error) {
|
|||
|
||||
if config.CleanWindow > 0 {
|
||||
go func() {
|
||||
ticker := time.NewTicker(config.CleanWindow)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case t := <-ticker.C:
|
||||
cache.cleanUp(uint64(t.Unix()))
|
||||
case <-cache.close:
|
||||
return
|
||||
}
|
||||
for t := range time.Tick(config.CleanWindow) {
|
||||
cache.cleanUp(uint64(t.Unix()))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
@ -93,16 +69,8 @@ func newBigCache(config Config, clock clock) (*BigCache, error) {
|
|||
return cache, nil
|
||||
}
|
||||
|
||||
// Close is used to signal a shutdown of the cache when you are done with it.
|
||||
// This allows the cleaning goroutines to exit and ensures references are not
|
||||
// kept to the cache preventing GC of the entire cache.
|
||||
func (c *BigCache) Close() error {
|
||||
close(c.close)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get reads entry for the key.
|
||||
// It returns an ErrEntryNotFound when
|
||||
// It returns an EntryNotFoundError when
|
||||
// no entry exists for the given key.
|
||||
func (c *BigCache) Get(key string) ([]byte, error) {
|
||||
hashedKey := c.hash.Sum64(key)
|
||||
|
@ -141,15 +109,6 @@ func (c *BigCache) Len() int {
|
|||
return len
|
||||
}
|
||||
|
||||
// Capacity returns amount of bytes store in the cache.
|
||||
func (c *BigCache) Capacity() int {
|
||||
var len int
|
||||
for _, shard := range c.shards {
|
||||
len += shard.capacity()
|
||||
}
|
||||
return len
|
||||
}
|
||||
|
||||
// Stats returns cache's statistics
|
||||
func (c *BigCache) Stats() Stats {
|
||||
var s Stats
|
||||
|
@ -169,10 +128,10 @@ func (c *BigCache) Iterator() *EntryInfoIterator {
|
|||
return newIterator(c)
|
||||
}
|
||||
|
||||
func (c *BigCache) onEvict(oldestEntry []byte, currentTimestamp uint64, evict func(reason RemoveReason) error) bool {
|
||||
func (c *BigCache) onEvict(oldestEntry []byte, currentTimestamp uint64, evict func() error) bool {
|
||||
oldestTimestamp := readTimestampFromEntry(oldestEntry)
|
||||
if currentTimestamp-oldestTimestamp > c.lifeWindow {
|
||||
evict(Expired)
|
||||
evict()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -188,15 +147,9 @@ func (c *BigCache) getShard(hashedKey uint64) (shard *cacheShard) {
|
|||
return c.shards[hashedKey&c.shardMask]
|
||||
}
|
||||
|
||||
func (c *BigCache) providedOnRemove(wrappedEntry []byte, reason RemoveReason) {
|
||||
func (c *BigCache) providedOnRemove(wrappedEntry []byte) {
|
||||
c.config.OnRemove(readKeyFromEntry(wrappedEntry), readEntry(wrappedEntry))
|
||||
}
|
||||
|
||||
func (c *BigCache) providedOnRemoveWithReason(wrappedEntry []byte, reason RemoveReason) {
|
||||
if c.config.onRemoveFilter == 0 || (1<<uint(reason))&c.config.onRemoveFilter > 0 {
|
||||
c.config.OnRemoveWithReason(readKeyFromEntry(wrappedEntry), readEntry(wrappedEntry), reason)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *BigCache) notProvidedOnRemove(wrappedEntry []byte, reason RemoveReason) {
|
||||
func (c *BigCache) notProvidedOnRemove(wrappedEntry []byte) {
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
// +build !appengine
|
||||
|
||||
package bigcache
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func bytesToString(b []byte) string {
|
||||
bytesHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
strHeader := reflect.StringHeader{Data: bytesHeader.Data, Len: bytesHeader.Len}
|
||||
return *(*string)(unsafe.Pointer(&strHeader))
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
// +build appengine
|
||||
|
||||
package bigcache
|
||||
|
||||
func bytesToString(b []byte) string {
|
||||
return string(b)
|
||||
}
|
|
@ -26,16 +26,8 @@ type Config struct {
|
|||
// the oldest entries are overridden for the new ones.
|
||||
HardMaxCacheSize int
|
||||
// OnRemove is a callback fired when the oldest entry is removed because of its expiration time or no space left
|
||||
// for the new entry, or because delete was called.
|
||||
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
|
||||
// for the new entry. Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
|
||||
OnRemove func(key string, entry []byte)
|
||||
// OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
|
||||
// for the new entry, or because delete was called. A constant representing the reason will be passed through.
|
||||
// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
|
||||
// Ignored if OnRemove is specified.
|
||||
OnRemoveWithReason func(key string, entry []byte, reason RemoveReason)
|
||||
|
||||
onRemoveFilter int
|
||||
|
||||
// Logger is a logging interface and used in combination with `Verbose`
|
||||
// Defaults to `DefaultLogger()`
|
||||
|
@ -73,14 +65,3 @@ func (c Config) maximumShardSize() int {
|
|||
|
||||
return maxShardSize
|
||||
}
|
||||
|
||||
// OnRemoveFilterSet sets which remove reasons will trigger a call to OnRemoveWithReason.
|
||||
// Filtering out reasons prevents bigcache from unwrapping them, which saves cpu.
|
||||
func (c Config) OnRemoveFilterSet(reasons ...RemoveReason) Config {
|
||||
c.onRemoveFilter = 0
|
||||
for i := range reasons {
|
||||
c.onRemoveFilter |= 1 << uint(reasons[i])
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package bigcache
|
|||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -53,6 +55,12 @@ func readKeyFromEntry(data []byte) string {
|
|||
return bytesToString(dst)
|
||||
}
|
||||
|
||||
func bytesToString(b []byte) string {
|
||||
bytesHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||
strHeader := reflect.StringHeader{Data: bytesHeader.Data, Len: bytesHeader.Len}
|
||||
return *(*string)(unsafe.Pointer(&strHeader))
|
||||
}
|
||||
|
||||
func readHashFromEntry(data []byte) uint64 {
|
||||
return binary.LittleEndian.Uint64(data[timestampSizeInBytes:])
|
||||
}
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
package bigcache
|
||||
|
||||
import "errors"
|
||||
import "fmt"
|
||||
|
||||
// ErrEntryNotFound is an error type struct which is returned when entry was not found for provided key
|
||||
var ErrEntryNotFound = errors.New("Entry not found")
|
||||
// EntryNotFoundError is an error type struct which is returned when entry was not found for provided key
|
||||
type EntryNotFoundError struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func notFound(key string) error {
|
||||
return &EntryNotFoundError{fmt.Sprintf("Entry %q not found", key)}
|
||||
}
|
||||
|
||||
// Error returned when entry does not exist.
|
||||
func (e EntryNotFoundError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
|
|
@ -16,12 +16,6 @@ const (
|
|||
minimumEmptyBlobSize = 32 + headerEntrySize
|
||||
)
|
||||
|
||||
var (
|
||||
errEmptyQueue = &queueError{"Empty queue"}
|
||||
errInvalidIndex = &queueError{"Index must be greater than zero. Invalid index."}
|
||||
errIndexOutOfBounds = &queueError{"Index out of range"}
|
||||
)
|
||||
|
||||
// BytesQueue is a non-thread safe queue type of fifo based on bytes array.
|
||||
// For every push operation index of entry is returned. It can be used to read the entry later
|
||||
type BytesQueue struct {
|
||||
|
@ -168,11 +162,6 @@ func (q *BytesQueue) Get(index int) ([]byte, error) {
|
|||
return data, err
|
||||
}
|
||||
|
||||
// CheckGet checks if an entry can be read from index
|
||||
func (q *BytesQueue) CheckGet(index int) error {
|
||||
return q.peekCheckErr(index)
|
||||
}
|
||||
|
||||
// Capacity returns number of allocated bytes for queue
|
||||
func (q *BytesQueue) Capacity() int {
|
||||
return q.capacity
|
||||
|
@ -188,35 +177,18 @@ func (e *queueError) Error() string {
|
|||
return e.message
|
||||
}
|
||||
|
||||
// peekCheckErr is identical to peek, but does not actually return any data
|
||||
func (q *BytesQueue) peekCheckErr(index int) error {
|
||||
|
||||
if q.count == 0 {
|
||||
return errEmptyQueue
|
||||
}
|
||||
|
||||
if index <= 0 {
|
||||
return errInvalidIndex
|
||||
}
|
||||
|
||||
if index+headerEntrySize >= len(q.array) {
|
||||
return errIndexOutOfBounds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *BytesQueue) peek(index int) ([]byte, int, error) {
|
||||
|
||||
if q.count == 0 {
|
||||
return nil, 0, errEmptyQueue
|
||||
return nil, 0, &queueError{"Empty queue"}
|
||||
}
|
||||
|
||||
if index <= 0 {
|
||||
return nil, 0, errInvalidIndex
|
||||
return nil, 0, &queueError{"Index must be grater than zero. Invalid index."}
|
||||
}
|
||||
|
||||
if index+headerEntrySize >= len(q.array) {
|
||||
return nil, 0, errIndexOutOfBounds
|
||||
return nil, 0, &queueError{"Index out of range"}
|
||||
}
|
||||
|
||||
blockSize := int(binary.LittleEndian.Uint32(q.array[index : index+headerEntrySize]))
|
||||
|
|
|
@ -8,14 +8,12 @@ import (
|
|||
"github.com/allegro/bigcache/queue"
|
||||
)
|
||||
|
||||
type onRemoveCallback func(wrappedEntry []byte, reason RemoveReason)
|
||||
|
||||
type cacheShard struct {
|
||||
hashmap map[uint64]uint32
|
||||
entries queue.BytesQueue
|
||||
lock sync.RWMutex
|
||||
entryBuffer []byte
|
||||
onRemove onRemoveCallback
|
||||
onRemove func(wrappedEntry []byte)
|
||||
|
||||
isVerbose bool
|
||||
logger Logger
|
||||
|
@ -25,6 +23,8 @@ type cacheShard struct {
|
|||
stats Stats
|
||||
}
|
||||
|
||||
type onRemoveCallback func(wrappedEntry []byte)
|
||||
|
||||
func (s *cacheShard) get(key string, hashedKey uint64) ([]byte, error) {
|
||||
s.lock.RLock()
|
||||
itemIndex := s.hashmap[hashedKey]
|
||||
|
@ -32,7 +32,7 @@ func (s *cacheShard) get(key string, hashedKey uint64) ([]byte, error) {
|
|||
if itemIndex == 0 {
|
||||
s.lock.RUnlock()
|
||||
s.miss()
|
||||
return nil, ErrEntryNotFound
|
||||
return nil, notFound(key)
|
||||
}
|
||||
|
||||
wrappedEntry, err := s.entries.Get(int(itemIndex))
|
||||
|
@ -47,12 +47,11 @@ func (s *cacheShard) get(key string, hashedKey uint64) ([]byte, error) {
|
|||
}
|
||||
s.lock.RUnlock()
|
||||
s.collision()
|
||||
return nil, ErrEntryNotFound
|
||||
return nil, notFound(key)
|
||||
}
|
||||
entry := readEntry(wrappedEntry)
|
||||
s.lock.RUnlock()
|
||||
s.hit()
|
||||
return entry, nil
|
||||
return readEntry(wrappedEntry), nil
|
||||
}
|
||||
|
||||
func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error {
|
||||
|
@ -78,7 +77,7 @@ func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error {
|
|||
s.lock.Unlock()
|
||||
return nil
|
||||
}
|
||||
if s.removeOldestEntry(NoSpace) != nil {
|
||||
if s.removeOldestEntry() != nil {
|
||||
s.lock.Unlock()
|
||||
return fmt.Errorf("entry is bigger than max shard size")
|
||||
}
|
||||
|
@ -86,17 +85,17 @@ func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error {
|
|||
}
|
||||
|
||||
func (s *cacheShard) del(key string, hashedKey uint64) error {
|
||||
// Optimistic pre-check using only readlock
|
||||
s.lock.RLock()
|
||||
itemIndex := s.hashmap[hashedKey]
|
||||
|
||||
if itemIndex == 0 {
|
||||
s.lock.RUnlock()
|
||||
s.delmiss()
|
||||
return ErrEntryNotFound
|
||||
return notFound(key)
|
||||
}
|
||||
|
||||
if err := s.entries.CheckGet(int(itemIndex)); err != nil {
|
||||
wrappedEntry, err := s.entries.Get(int(itemIndex))
|
||||
if err != nil {
|
||||
s.lock.RUnlock()
|
||||
s.delmiss()
|
||||
return err
|
||||
|
@ -105,25 +104,8 @@ func (s *cacheShard) del(key string, hashedKey uint64) error {
|
|||
|
||||
s.lock.Lock()
|
||||
{
|
||||
// After obtaining the writelock, we need to read the same again,
|
||||
// since the data delivered earlier may be stale now
|
||||
itemIndex = s.hashmap[hashedKey]
|
||||
|
||||
if itemIndex == 0 {
|
||||
s.lock.Unlock()
|
||||
s.delmiss()
|
||||
return ErrEntryNotFound
|
||||
}
|
||||
|
||||
wrappedEntry, err := s.entries.Get(int(itemIndex))
|
||||
if err != nil {
|
||||
s.lock.Unlock()
|
||||
s.delmiss()
|
||||
return err
|
||||
}
|
||||
|
||||
delete(s.hashmap, hashedKey)
|
||||
s.onRemove(wrappedEntry, Deleted)
|
||||
s.onRemove(wrappedEntry)
|
||||
resetKeyFromEntry(wrappedEntry)
|
||||
}
|
||||
s.lock.Unlock()
|
||||
|
@ -132,10 +114,10 @@ func (s *cacheShard) del(key string, hashedKey uint64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *cacheShard) onEvict(oldestEntry []byte, currentTimestamp uint64, evict func(reason RemoveReason) error) bool {
|
||||
func (s *cacheShard) onEvict(oldestEntry []byte, currentTimestamp uint64, evict func() error) bool {
|
||||
oldestTimestamp := readTimestampFromEntry(oldestEntry)
|
||||
if currentTimestamp-oldestTimestamp > s.lifeWindow {
|
||||
evict(Expired)
|
||||
evict()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -154,23 +136,18 @@ func (s *cacheShard) cleanUp(currentTimestamp uint64) {
|
|||
}
|
||||
|
||||
func (s *cacheShard) getOldestEntry() ([]byte, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
return s.entries.Peek()
|
||||
}
|
||||
|
||||
func (s *cacheShard) getEntry(index int) ([]byte, error) {
|
||||
s.lock.RLock()
|
||||
entry, err := s.entries.Get(index)
|
||||
s.lock.RUnlock()
|
||||
|
||||
return entry, err
|
||||
return s.entries.Get(index)
|
||||
}
|
||||
|
||||
func (s *cacheShard) copyKeys() (keys []uint32, next int) {
|
||||
s.lock.RLock()
|
||||
keys = make([]uint32, len(s.hashmap))
|
||||
|
||||
s.lock.RLock()
|
||||
|
||||
for _, index := range s.hashmap {
|
||||
keys[next] = index
|
||||
next++
|
||||
|
@ -180,12 +157,12 @@ func (s *cacheShard) copyKeys() (keys []uint32, next int) {
|
|||
return keys, next
|
||||
}
|
||||
|
||||
func (s *cacheShard) removeOldestEntry(reason RemoveReason) error {
|
||||
func (s *cacheShard) removeOldestEntry() error {
|
||||
oldest, err := s.entries.Pop()
|
||||
if err == nil {
|
||||
hash := readHashFromEntry(oldest)
|
||||
delete(s.hashmap, hash)
|
||||
s.onRemove(oldest, reason)
|
||||
s.onRemove(oldest)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
|
@ -206,13 +183,6 @@ func (s *cacheShard) len() int {
|
|||
return res
|
||||
}
|
||||
|
||||
func (s *cacheShard) capacity() int {
|
||||
s.lock.RLock()
|
||||
res := s.entries.Capacity()
|
||||
s.lock.RUnlock()
|
||||
return res
|
||||
}
|
||||
|
||||
func (s *cacheShard) getStats() Stats {
|
||||
var stats = Stats{
|
||||
Hits: atomic.LoadInt64(&s.stats.Hits),
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
// Copyright 2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is ignored during the regular build due to the following build tag.
|
||||
// It is called by go generate and used to automatically generate pre-computed
|
||||
// tables used to accelerate operations.
|
||||
// +build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fi, err := os.Create("secp256k1.go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer fi.Close()
|
||||
|
||||
// Compress the serialized byte points.
|
||||
serialized := btcec.S256().SerializedBytePoints()
|
||||
var compressed bytes.Buffer
|
||||
w := zlib.NewWriter(&compressed)
|
||||
if _, err := w.Write(serialized); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
w.Close()
|
||||
|
||||
// Encode the compressed byte points with base64.
|
||||
encoded := make([]byte, base64.StdEncoding.EncodedLen(compressed.Len()))
|
||||
base64.StdEncoding.Encode(encoded, compressed.Bytes())
|
||||
|
||||
fmt.Fprintln(fi, "// Copyright (c) 2015 The btcsuite developers")
|
||||
fmt.Fprintln(fi, "// Use of this source code is governed by an ISC")
|
||||
fmt.Fprintln(fi, "// license that can be found in the LICENSE file.")
|
||||
fmt.Fprintln(fi)
|
||||
fmt.Fprintln(fi, "package btcec")
|
||||
fmt.Fprintln(fi)
|
||||
fmt.Fprintln(fi, "// Auto-generated file (see genprecomps.go)")
|
||||
fmt.Fprintln(fi, "// DO NOT EDIT")
|
||||
fmt.Fprintln(fi)
|
||||
fmt.Fprintf(fi, "var secp256k1BytePoints = %q\n", string(encoded))
|
||||
|
||||
a1, b1, a2, b2 := btcec.S256().EndomorphismVectors()
|
||||
fmt.Println("The following values are the computed linearly " +
|
||||
"independent vectors needed to make use of the secp256k1 " +
|
||||
"endomorphism:")
|
||||
fmt.Printf("a1: %x\n", a1)
|
||||
fmt.Printf("b1: %x\n", b1)
|
||||
fmt.Printf("a2: %x\n", a2)
|
||||
fmt.Printf("b2: %x\n", b2)
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
// Copyright (c) 2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//+build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var (
|
||||
start = []byte(`// Copyright (c) 2015 The btcsuite developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// AUTOGENERATED by genalphabet.go; do not edit.
|
||||
|
||||
package base58
|
||||
|
||||
const (
|
||||
// alphabet is the modified base58 alphabet used by Bitcoin.
|
||||
alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
|
||||
alphabetIdx0 = '1'
|
||||
)
|
||||
|
||||
var b58 = [256]byte{`)
|
||||
|
||||
end = []byte(`}`)
|
||||
|
||||
alphabet = []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
|
||||
tab = []byte("\t")
|
||||
invalid = []byte("255")
|
||||
comma = []byte(",")
|
||||
space = []byte(" ")
|
||||
nl = []byte("\n")
|
||||
)
|
||||
|
||||
func write(w io.Writer, b []byte) {
|
||||
_, err := w.Write(b)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fi, err := os.Create("alphabet.go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer fi.Close()
|
||||
|
||||
write(fi, start)
|
||||
write(fi, nl)
|
||||
for i := byte(0); i < 32; i++ {
|
||||
write(fi, tab)
|
||||
for j := byte(0); j < 8; j++ {
|
||||
idx := bytes.IndexByte(alphabet, i*8+j)
|
||||
if idx == -1 {
|
||||
write(fi, invalid)
|
||||
} else {
|
||||
write(fi, strconv.AppendInt(nil, int64(idx), 10))
|
||||
}
|
||||
write(fi, comma)
|
||||
if j != 7 {
|
||||
write(fi, space)
|
||||
}
|
||||
}
|
||||
write(fi, nl)
|
||||
}
|
||||
write(fi, end)
|
||||
write(fi, nl)
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
// +build ignore
|
||||
|
||||
// Generate the table of OID values
|
||||
// Run with 'go run gen.go'.
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
// OID represent a postgres Object Identifier Type.
|
||||
type OID struct {
|
||||
ID int
|
||||
Type string
|
||||
}
|
||||
|
||||
// Name returns an upper case version of the oid type.
|
||||
func (o OID) Name() string {
|
||||
return strings.ToUpper(o.Type)
|
||||
}
|
||||
|
||||
func main() {
|
||||
datname := os.Getenv("PGDATABASE")
|
||||
sslmode := os.Getenv("PGSSLMODE")
|
||||
|
||||
if datname == "" {
|
||||
os.Setenv("PGDATABASE", "pqgotest")
|
||||
}
|
||||
|
||||
if sslmode == "" {
|
||||
os.Setenv("PGSSLMODE", "disable")
|
||||
}
|
||||
|
||||
db, err := sql.Open("postgres", "")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
rows, err := db.Query(`
|
||||
SELECT typname, oid
|
||||
FROM pg_type WHERE oid < 10000
|
||||
ORDER BY oid;
|
||||
`)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
oids := make([]*OID, 0)
|
||||
for rows.Next() {
|
||||
var oid OID
|
||||
if err = rows.Scan(&oid.Type, &oid.ID); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
oids = append(oids, &oid)
|
||||
}
|
||||
if err = rows.Err(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd := exec.Command("gofmt")
|
||||
cmd.Stderr = os.Stderr
|
||||
w, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
f, err := os.Create("types.go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd.Stdout = f
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Fprintln(w, "// Code generated by gen.go. DO NOT EDIT.")
|
||||
fmt.Fprintln(w, "\npackage oid")
|
||||
fmt.Fprintln(w, "const (")
|
||||
for _, oid := range oids {
|
||||
fmt.Fprintf(w, "T_%s Oid = %d\n", oid.Type, oid.ID)
|
||||
}
|
||||
fmt.Fprintln(w, ")")
|
||||
fmt.Fprintln(w, "var TypeName = map[Oid]string{")
|
||||
for _, oid := range oids {
|
||||
fmt.Fprintf(w, "T_%s: \"%s\",\n", oid.Type, oid.Name())
|
||||
}
|
||||
fmt.Fprintln(w, "}")
|
||||
w.Close()
|
||||
cmd.Wait()
|
||||
}
|
|
@ -4,17 +4,13 @@ notifications:
|
|||
language: go
|
||||
go:
|
||||
- "1.12.x"
|
||||
- "1.13beta1"
|
||||
- "1.13.x"
|
||||
|
||||
install: true
|
||||
|
||||
env:
|
||||
- GO111MODULE=on GOFLAGS=-mod=vendor
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: "1.13beta1"
|
||||
|
||||
before_script:
|
||||
- make install-linter
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ vendor:
|
|||
|
||||
install-linter:
|
||||
# install linter
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.17.1
|
||||
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(shell go env GOPATH)/bin v1.19.0
|
||||
.PHONY: install-linter
|
||||
|
||||
install-dev:
|
||||
|
|
|
@ -3,19 +3,15 @@ package statusproto
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/google/uuid"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
type ChatPagination struct {
|
||||
From uint
|
||||
To uint
|
||||
}
|
||||
|
||||
type ChatType int
|
||||
|
||||
const (
|
||||
ChatTypeOneToOne = iota + 1
|
||||
ChatTypeOneToOne ChatType = iota + 1
|
||||
ChatTypePublic
|
||||
ChatTypePrivateGroupChat
|
||||
)
|
||||
|
@ -87,7 +83,7 @@ type ChatMember struct {
|
|||
}
|
||||
|
||||
func (c ChatMember) PublicKey() (*ecdsa.PublicKey, error) {
|
||||
b, err := hexutil.Decode(c.ID)
|
||||
b, err := statusproto.DecodeHex(c.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -95,7 +91,7 @@ func (c ChatMember) PublicKey() (*ecdsa.PublicKey, error) {
|
|||
}
|
||||
|
||||
func oneToOneChatID(publicKey *ecdsa.PublicKey) string {
|
||||
return hexutil.Encode(crypto.FromECDSAPub(publicKey))
|
||||
return statusproto.EncodeHex(crypto.FromECDSAPub(publicKey))
|
||||
}
|
||||
|
||||
func CreateOneToOneChat(name string, publicKey *ecdsa.PublicKey) Chat {
|
||||
|
@ -117,6 +113,19 @@ func CreatePublicChat(name string) Chat {
|
|||
}
|
||||
}
|
||||
|
||||
func groupChatID(creator *ecdsa.PublicKey) string {
|
||||
return uuid.New().String() + statusproto.EncodeHex(crypto.FromECDSAPub(creator))
|
||||
}
|
||||
|
||||
func CreateGroupChat(name string, creator *ecdsa.PublicKey) Chat {
|
||||
return Chat{
|
||||
ID: groupChatID(creator),
|
||||
Name: name,
|
||||
Active: true,
|
||||
ChatType: ChatTypePrivateGroupChat,
|
||||
}
|
||||
}
|
||||
|
||||
func findChatByID(chatID string, chats []*Chat) *Chat {
|
||||
for _, c := range chats {
|
||||
if c.ID == chatID {
|
||||
|
|
|
@ -3,8 +3,8 @@ package statusproto
|
|||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -50,7 +50,7 @@ type Contact struct {
|
|||
}
|
||||
|
||||
func (c Contact) PublicKey() (*ecdsa.PublicKey, error) {
|
||||
b, err := hexutil.Decode(c.ID)
|
||||
b, err := statusproto.DecodeHex(c.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -16,17 +16,32 @@ const (
|
|||
aesNonceLength = 12
|
||||
)
|
||||
|
||||
// Sign signs the hash of an arbitrary string
|
||||
func Sign(content string, identity *ecdsa.PrivateKey) (string, error) {
|
||||
signature, err := crypto.Sign(crypto.Keccak256([]byte(content)), identity)
|
||||
// SignBytes signs the hash of arbitrary data.
|
||||
func SignBytes(data []byte, identity *ecdsa.PrivateKey) ([]byte, error) {
|
||||
return crypto.Sign(crypto.Keccak256(data), identity)
|
||||
}
|
||||
|
||||
// SignStringAsHex signs the Keccak256 hash of arbitrary data and returns its hex representation.
|
||||
func SignBytesAsHex(data []byte, identity *ecdsa.PrivateKey) (string, error) {
|
||||
signature, err := SignBytes(data, identity)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return hex.EncodeToString(signature), nil
|
||||
}
|
||||
|
||||
// VerifySignatures verifys tuples of signatures content/hash/public key
|
||||
// SignStringAsHex signs the Keccak256 hash of arbitrary string and returns its hex representation.
|
||||
func SignStringAsHex(data string, identity *ecdsa.PrivateKey) (string, error) {
|
||||
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
|
||||
func VerifySignatures(signaturePairs [][3]string) error {
|
||||
for _, signaturePair := range signaturePairs {
|
||||
content := crypto.Keccak256([]byte(signaturePair[0]))
|
||||
|
|
|
@ -5,22 +5,19 @@ go 1.12
|
|||
require (
|
||||
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7 // indirect
|
||||
github.com/cenkalti/backoff/v3 v3.0.0
|
||||
github.com/deckarep/golang-set v1.7.1 // indirect
|
||||
github.com/ethereum/go-ethereum v1.8.27
|
||||
github.com/ethereum/go-ethereum v1.9.5
|
||||
github.com/golang/protobuf v1.3.2
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8
|
||||
github.com/lucasb-eyer/go-colorful v1.0.2
|
||||
github.com/mutecomm/go-sqlcipher v0.0.0-20190227152316-55dbde17881f
|
||||
github.com/onsi/ginkgo v1.8.0 // indirect
|
||||
github.com/onsi/gomega v1.5.0 // indirect
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/rs/cors v1.6.0 // indirect
|
||||
github.com/russolsen/ohyeah v0.0.0-20160324131710-f4938c005315 // indirect
|
||||
github.com/russolsen/same v0.0.0-20160222130632-f089df61f51d // indirect
|
||||
github.com/russolsen/transit v0.0.0-20180705123435-0794b4c4505a
|
||||
github.com/status-im/doubleratchet v2.0.0+incompatible
|
||||
github.com/status-im/migrate/v4 v4.0.0-20190821140204-a9d340ec8fb76af4afda06acf01740d45d2661ed
|
||||
github.com/status-im/whisper v1.4.14
|
||||
github.com/status-im/whisper v1.5.1
|
||||
github.com/stretchr/testify v1.3.1-0.20190712000136-221dbe5ed467
|
||||
github.com/vacp2p/mvds v0.0.21
|
||||
go.uber.org/zap v1.10.0
|
||||
|
@ -29,4 +26,4 @@ require (
|
|||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3 // indirect
|
||||
)
|
||||
|
||||
replace github.com/ethereum/go-ethereum v1.8.27 => github.com/status-im/go-ethereum v1.8.27-status.4
|
||||
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.4
|
||||
|
|
|
@ -16,13 +16,16 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV
|
|||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8=
|
||||
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156 h1:hh7BAWFHv41r0gce0KRYtDJpL4erKfmB1/mpgoSADeI=
|
||||
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/allegro/bigcache v1.1.0/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
github.com/aristanetworks/goarista v0.0.0-20181002214814-33151c4543a7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7 h1:fKnuvQ/O22ZpD7HaJjGQXn/GxOdDJOQFL8bpM8Xe3X8=
|
||||
github.com/aristanetworks/goarista v0.0.0-20190704150520-f44d68189fd7/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
|
||||
github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
|
@ -32,6 +35,8 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCS
|
|||
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 h1:Eey/GGQ/E5Xp1P2Lyx1qj007hLZfbi0+CoVeJruGCtI=
|
||||
github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
||||
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac h1:/zx+Hglw2JN/pwVam1Z8cTCTl4pWyrbvOn2oooqCQSs=
|
||||
github.com/btcsuite/btcd v0.0.0-20181013004428-67e573d211ac/go.mod h1:Dmm/EzmjnCiweXmzRIAiUWCInVmPgjkzgv5k4tVyXiQ=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
|
@ -74,6 +79,7 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
|
|||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa h1:o8OuEkracbk3qH6GvlI6XpEN1HTSxkzOG42xZpfDv/s=
|
||||
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||
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=
|
||||
|
@ -83,6 +89,7 @@ github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7R
|
|||
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
|
@ -117,11 +124,15 @@ github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+u
|
|||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
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/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU=
|
||||
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
|
@ -134,11 +145,16 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
|||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3 h1:DqD8eigqlUm0+znmx7zhL0xvTW3+e1jCekJMfBUADWI=
|
||||
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
|
||||
github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=
|
||||
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||
github.com/jackc/pgx v3.2.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458 h1:LPECOO5LcZx5tvkxraIptrg6AiAUf+28rFV9+noSZFA=
|
||||
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jackpal/go-nat-pmp v1.0.1 h1:i0LektDkO1QlrTm/cSuP+PyBCDnYvjPLGl4LdWEMiaA=
|
||||
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8 h1:mGIXW/lubQ4B+3bXTLxcTMTjUNDqoF6T/HUW9LbFx9s=
|
||||
github.com/jinzhu/copier v0.0.0-20190625015134-976e0346caa8/go.mod h1:yL958EeXv8Ylng6IfnvG4oflryUi3vgA3xPs9hmII1s=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
|
@ -183,11 +199,11 @@ github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE
|
|||
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/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
|
||||
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
|
||||
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
|
@ -237,12 +253,14 @@ github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k
|
|||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/status-im/doubleratchet v2.0.0+incompatible h1:s77lF1lDubK0RKftxN2vH8G9gwtVVp13ggWfyY4O1q4=
|
||||
github.com/status-im/doubleratchet v2.0.0+incompatible/go.mod h1:1sqR0+yhiM/bd+wrdX79AOt2csZuJOni0nUDzKNuqOU=
|
||||
github.com/status-im/go-ethereum v1.8.27-status.4 h1:8jTQsYDLtKd/XCa++ZkexTPHfANIDh084JbO2SBAwp4=
|
||||
github.com/status-im/go-ethereum v1.8.27-status.4/go.mod h1:Ulij8LMpMvXnbnPcmDqrpI+iXoXSjxItuY/wmbasTZU=
|
||||
github.com/status-im/go-ethereum v1.9.5-status.4 h1:F5VrxH9LmTxWl4qwQjs0TI5TgG9dVuZKqGmdwHJ0cWk=
|
||||
github.com/status-im/go-ethereum v1.9.5-status.4/go.mod h1:Ulij8LMpMvXnbnPcmDqrpI+iXoXSjxItuY/wmbasTZU=
|
||||
github.com/status-im/migrate/v4 v4.0.0-20190821140204-a9d340ec8fb76af4afda06acf01740d45d2661ed h1:K2iga8l8OQIHnk2bBq2QsZTO2Q38YWy04xIspdITCdM=
|
||||
github.com/status-im/migrate/v4 v4.0.0-20190821140204-a9d340ec8fb76af4afda06acf01740d45d2661ed/go.mod h1:r8HggRBZ/k7TRwByq/Hp3P/ubFppIna0nvyavVK0pjA=
|
||||
github.com/status-im/whisper v1.4.14 h1:9VHqx4+PUYfhDnYYtDxHkg/3cfVvkHjPNciY4LO83yc=
|
||||
github.com/status-im/whisper v1.4.14/go.mod h1:WS6z39YJQ8WJa9s+DmTuEM/s2nVF6Iz3B1SZYw5cYf0=
|
||||
github.com/status-im/whisper v1.5.1 h1:87/XIg0Wjua7lXBGiEXgAfTOqlt2Q1dMDuxugTyZbbA=
|
||||
github.com/status-im/whisper v1.5.1/go.mod h1:emrOxzJme0k66QtbbQ2bdd3P8RCdLZ8sTD7SkwH1s2s=
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
|
@ -288,6 +306,7 @@ golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
|
|
@ -31,7 +31,7 @@ func renderBase64(id Identicon) (string, error) {
|
|||
}
|
||||
|
||||
func setBackgroundWhite(img *image.RGBA) {
|
||||
draw.Draw(img, img.Bounds(), &image.Uniform{color.White}, image.ZP, draw.Src)
|
||||
draw.Draw(img, img.Bounds(), &image.Uniform{C: color.White}, image.Point{}, draw.Src)
|
||||
}
|
||||
|
||||
func drawRect(rgba *image.RGBA, i int, c color.Color) {
|
||||
|
@ -45,7 +45,7 @@ func drawRect(rgba *image.RGBA, i int, c color.Color) {
|
|||
10+(i/maxRow)*sizeSquare+sizeSquare,
|
||||
)
|
||||
|
||||
draw.Draw(rgba, r, &image.Uniform{c}, image.ZP, draw.Src)
|
||||
draw.Draw(rgba, r, &image.Uniform{C: c}, image.Point{}, draw.Src)
|
||||
}
|
||||
|
||||
// GenerateBase64 generates an identicon in base64 png format given a string
|
||||
|
|
|
@ -3,18 +3,18 @@ package statusproto
|
|||
import (
|
||||
"database/sql/driver"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/pkg/errors"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
type hexutilSQL hexutil.Bytes
|
||||
type hexutilSQL statusproto.HexBytes
|
||||
|
||||
func (h hexutilSQL) Value() (driver.Value, error) {
|
||||
return []byte(h), nil
|
||||
}
|
||||
|
||||
func (h hexutilSQL) String() string {
|
||||
return hexutil.Encode(h)
|
||||
return statusproto.EncodeHex(h)
|
||||
}
|
||||
|
||||
func (h *hexutilSQL) Scan(value interface{}) error {
|
||||
|
|
|
@ -14,8 +14,8 @@ import (
|
|||
"github.com/status-im/status-protocol-go/encryption"
|
||||
"github.com/status-im/status-protocol-go/encryption/multidevice"
|
||||
transport "github.com/status-im/status-protocol-go/transport/whisper"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
protocol "github.com/status-im/status-protocol-go/v1"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
datasyncnode "github.com/vacp2p/mvds/node"
|
||||
datasyncproto "github.com/vacp2p/mvds/protobuf"
|
||||
"go.uber.org/zap"
|
||||
|
@ -155,7 +155,7 @@ func (p *messageProcessor) sendPrivate(
|
|||
return nil, errors.Wrap(err, "failed to send a message spec")
|
||||
}
|
||||
|
||||
p.transport.Track([][]byte{messageID}, hash, *newMessage)
|
||||
p.transport.Track([][]byte{messageID}, hash, newMessage)
|
||||
}
|
||||
|
||||
return messageID, nil
|
||||
|
@ -187,7 +187,7 @@ func (p *messageProcessor) SendPublic(ctx context.Context, chatID string, data [
|
|||
return nil, err
|
||||
}
|
||||
|
||||
hash, err := p.transport.SendPublic(ctx, &newMessage, chatID)
|
||||
hash, err := p.transport.SendPublic(ctx, newMessage, chatID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -201,21 +201,21 @@ func (p *messageProcessor) SendPublic(ctx context.Context, chatID string, data [
|
|||
|
||||
// SendPublicRaw takes encoded data, encrypts it and sends through the wire.
|
||||
func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, data []byte) ([]byte, error) {
|
||||
var newMessage whisper.NewMessage
|
||||
var newMessage *whispertypes.NewMessage
|
||||
|
||||
wrappedMessage, err := p.tryWrapMessageV1(data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to wrap message")
|
||||
}
|
||||
|
||||
newMessage = whisper.NewMessage{
|
||||
newMessage = &whispertypes.NewMessage{
|
||||
TTL: whisperTTL,
|
||||
Payload: wrappedMessage,
|
||||
PowTarget: whisperPoW,
|
||||
PowTime: whisperPoWTime,
|
||||
}
|
||||
|
||||
hash, err := p.transport.SendPublic(ctx, &newMessage, chatName)
|
||||
hash, err := p.transport.SendPublic(ctx, newMessage, chatName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -230,13 +230,11 @@ func (p *messageProcessor) SendPublicRaw(ctx context.Context, chatName string, d
|
|||
// Process processes received Whisper messages through all the layers
|
||||
// and returns decoded user messages.
|
||||
// It also handled all non-user messages like PairMessage.
|
||||
func (p *messageProcessor) Process(message *whisper.ReceivedMessage) ([]*protocol.Message, error) {
|
||||
func (p *messageProcessor) Process(shhMessage *whispertypes.Message) ([]*protocol.Message, error) {
|
||||
logger := p.logger.With(zap.String("site", "Process"))
|
||||
|
||||
var decodedMessages []*protocol.Message
|
||||
|
||||
shhMessage := whisper.ToWhisperMessage(message)
|
||||
|
||||
hlogger := logger.With(zap.Binary("hash", shhMessage.Hash))
|
||||
hlogger.Debug("handling a received message")
|
||||
|
||||
|
@ -283,7 +281,7 @@ func (p *messageProcessor) processPairMessage(m protocol.PairMessage) error {
|
|||
// layer message, or in case of Raw methods, the processing stops at the layer
|
||||
// before.
|
||||
// It returns an error only if the processing of required steps failed.
|
||||
func (p *messageProcessor) handleMessages(shhMessage *whisper.Message, applicationLayer bool) ([]*protocol.StatusMessage, error) {
|
||||
func (p *messageProcessor) handleMessages(shhMessage *whispertypes.Message, applicationLayer bool) ([]*protocol.StatusMessage, error) {
|
||||
logger := p.logger.With(zap.String("site", "handleMessages"))
|
||||
hlogger := logger.With(zap.Binary("hash", shhMessage.Hash))
|
||||
var statusMessage protocol.StatusMessage
|
||||
|
@ -423,13 +421,13 @@ func (p *messageProcessor) sendDataSync(ctx context.Context, publicKey *ecdsa.Pu
|
|||
return err
|
||||
}
|
||||
|
||||
p.transport.Track(messageIDs, hash, *newMessage)
|
||||
p.transport.Track(messageIDs, hash, newMessage)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// sendMessageSpec analyses the spec properties and selects a proper transport method.
|
||||
func (p *messageProcessor) sendMessageSpec(ctx context.Context, publicKey *ecdsa.PublicKey, messageSpec *encryption.ProtocolMessageSpec) ([]byte, *whisper.NewMessage, error) {
|
||||
func (p *messageProcessor) sendMessageSpec(ctx context.Context, publicKey *ecdsa.PublicKey, messageSpec *encryption.ProtocolMessageSpec) ([]byte, *whispertypes.NewMessage, error) {
|
||||
newMessage, err := messageSpecToWhisper(messageSpec)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
@ -442,33 +440,33 @@ func (p *messageProcessor) sendMessageSpec(ctx context.Context, publicKey *ecdsa
|
|||
switch {
|
||||
case messageSpec.SharedSecret != nil:
|
||||
logger.Debug("sending using shared secret")
|
||||
hash, err = p.transport.SendPrivateWithSharedSecret(ctx, &newMessage, publicKey, messageSpec.SharedSecret)
|
||||
hash, err = p.transport.SendPrivateWithSharedSecret(ctx, newMessage, publicKey, messageSpec.SharedSecret)
|
||||
case messageSpec.PartitionedTopicMode() == encryption.PartitionTopicV1:
|
||||
logger.Debug("sending partitioned topic")
|
||||
hash, err = p.transport.SendPrivateWithPartitioned(ctx, &newMessage, publicKey)
|
||||
hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
|
||||
case !p.featureFlags.genericDiscoveryTopicEnabled:
|
||||
logger.Debug("sending partitioned topic (generic discovery topic disabled)")
|
||||
hash, err = p.transport.SendPrivateWithPartitioned(ctx, &newMessage, publicKey)
|
||||
hash, err = p.transport.SendPrivateWithPartitioned(ctx, newMessage, publicKey)
|
||||
default:
|
||||
logger.Debug("sending using discovery topic")
|
||||
hash, err = p.transport.SendPrivateOnDiscovery(ctx, &newMessage, publicKey)
|
||||
hash, err = p.transport.SendPrivateOnDiscovery(ctx, newMessage, publicKey)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return hash, &newMessage, nil
|
||||
return hash, newMessage, nil
|
||||
}
|
||||
|
||||
func messageSpecToWhisper(spec *encryption.ProtocolMessageSpec) (whisper.NewMessage, error) {
|
||||
var newMessage whisper.NewMessage
|
||||
func messageSpecToWhisper(spec *encryption.ProtocolMessageSpec) (*whispertypes.NewMessage, error) {
|
||||
var newMessage *whispertypes.NewMessage
|
||||
|
||||
payload, err := proto.Marshal(spec.Message)
|
||||
if err != nil {
|
||||
return newMessage, err
|
||||
}
|
||||
|
||||
newMessage = whisper.NewMessage{
|
||||
newMessage = &whispertypes.NewMessage{
|
||||
TTL: whisperTTL,
|
||||
Payload: payload,
|
||||
PowTarget: whisperPoW,
|
||||
|
|
|
@ -9,10 +9,8 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/pkg/errors"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/status-im/status-protocol-go/encryption"
|
||||
|
@ -22,6 +20,8 @@ import (
|
|||
"github.com/status-im/status-protocol-go/identity/identicon"
|
||||
"github.com/status-im/status-protocol-go/sqlite"
|
||||
transport "github.com/status-im/status-protocol-go/transport/whisper"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
protocol "github.com/status-im/status-protocol-go/v1"
|
||||
)
|
||||
|
||||
|
@ -169,7 +169,7 @@ func WithEnvelopesMonitorConfig(emc *transport.EnvelopesMonitorConfig) Option {
|
|||
|
||||
func NewMessenger(
|
||||
identity *ecdsa.PrivateKey,
|
||||
shh *whisper.Whisper,
|
||||
shh whispertypes.Whisper,
|
||||
installationID string,
|
||||
opts ...Option,
|
||||
) (*Messenger, error) {
|
||||
|
@ -228,7 +228,7 @@ func NewMessenger(
|
|||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
chatName := transport.ContactCodeTopic(&messenger.identity.PublicKey)
|
||||
_, err = messenger.transport.SendPublic(ctx, &newMessage, chatName)
|
||||
_, err = messenger.transport.SendPublic(ctx, newMessage, chatName)
|
||||
if err != nil {
|
||||
slogger.Warn("failed to send a contact code", zap.Error(err))
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ func (m *Messenger) handleSharedSecrets(secrets []*sharedsecret.Secret) ([]*tran
|
|||
var result []*transport.Filter
|
||||
for _, secret := range secrets {
|
||||
logger.Debug("received shared secret", zap.Binary("identity", crypto.FromECDSAPub(secret.Identity)))
|
||||
fSecret := transport.NegotiatedSecret{
|
||||
fSecret := whispertypes.NegotiatedSecret{
|
||||
PublicKey: secret.Identity,
|
||||
Key: secret.Key,
|
||||
}
|
||||
|
@ -627,7 +627,7 @@ func (m *Messenger) retrieveLatest(ctx context.Context) ([]*protocol.Message, er
|
|||
return nil, errors.Wrap(err, "failed to retrieve messages")
|
||||
}
|
||||
|
||||
logger := m.logger.With(zap.String("site", "RetrieveAll"))
|
||||
logger := m.logger.With(zap.String("site", "retrieveLatest"))
|
||||
logger.Debug("retrieved messages", zap.Int("count", len(latest)))
|
||||
|
||||
var result []*protocol.Message
|
||||
|
@ -670,8 +670,7 @@ func (m *Messenger) RetrieveRawAll() (map[transport.Filter][]*protocol.StatusMes
|
|||
result := make(map[transport.Filter][]*protocol.StatusMessage)
|
||||
|
||||
for chat, messages := range chatWithMessages {
|
||||
for _, message := range messages {
|
||||
shhMessage := whisper.ToWhisperMessage(message)
|
||||
for _, shhMessage := range messages {
|
||||
// TODO: fix this to use an exported method.
|
||||
statusMessages, err := m.processor.handleMessages(shhMessage, false)
|
||||
if err != nil {
|
||||
|
@ -889,7 +888,7 @@ func (p *postProcessor) matchMessage(message *protocol.Message, chats []*Chat) (
|
|||
case message.MessageT == protocol.MessageTypePrivate:
|
||||
// It's an incoming private message. ChatID is calculated from the signature.
|
||||
// If a chat does not exist, a new one is created and saved.
|
||||
chatID := hexutil.Encode(crypto.FromECDSAPub(message.SigPubKey))
|
||||
chatID := statusproto.EncodeHex(crypto.FromECDSAPub(message.SigPubKey))
|
||||
chat := findChatByID(chatID, chats)
|
||||
if chat == nil {
|
||||
// TODO: this should be a three-word name used in the mobile client
|
||||
|
@ -905,7 +904,7 @@ func (p *postProcessor) matchMessage(message *protocol.Message, chats []*Chat) (
|
|||
// It needs to be verified if the signature public key belongs to the chat.
|
||||
chatID := message.Content.ChatID
|
||||
chat := findChatByID(chatID, chats)
|
||||
sigPubKeyHex := hexutil.Encode(crypto.FromECDSAPub(message.SigPubKey))
|
||||
sigPubKeyHex := statusproto.EncodeHex(crypto.FromECDSAPub(message.SigPubKey))
|
||||
for _, member := range chat.Members {
|
||||
if member.ID == sigPubKeyHex {
|
||||
return chat, nil
|
||||
|
|
|
@ -5,9 +5,8 @@ import (
|
|||
"errors"
|
||||
"sync"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -27,7 +26,7 @@ type EnvelopesMonitorConfig struct {
|
|||
EnvelopeEventsHandler EnvelopeEventsHandler
|
||||
MaxAttempts int
|
||||
MailserverConfirmationsEnabled bool
|
||||
IsMailserver func(enode.ID) bool
|
||||
IsMailserver func(whispertypes.EnodeID) bool
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
|
@ -35,21 +34,26 @@ type EnvelopesMonitorConfig struct {
|
|||
type EnvelopeEventsHandler interface {
|
||||
EnvelopeSent([][]byte)
|
||||
EnvelopeExpired([][]byte, error)
|
||||
MailServerRequestCompleted(common.Hash, common.Hash, []byte, error)
|
||||
MailServerRequestExpired(common.Hash)
|
||||
MailServerRequestCompleted(statusproto.Hash, statusproto.Hash, []byte, error)
|
||||
MailServerRequestExpired(statusproto.Hash)
|
||||
}
|
||||
|
||||
// NewEnvelopesMonitor returns a pointer to an instance of the EnvelopesMonitor.
|
||||
func NewEnvelopesMonitor(w *whisper.Whisper, config *EnvelopesMonitorConfig) *EnvelopesMonitor {
|
||||
func NewEnvelopesMonitor(w whispertypes.Whisper, config EnvelopesMonitorConfig) *EnvelopesMonitor {
|
||||
logger := config.Logger
|
||||
|
||||
if logger == nil {
|
||||
logger = zap.NewNop()
|
||||
}
|
||||
|
||||
var whisperAPI whispertypes.PublicWhisperAPI
|
||||
if w != nil {
|
||||
whisperAPI = w.PublicWhisperAPI()
|
||||
}
|
||||
|
||||
return &EnvelopesMonitor{
|
||||
w: w,
|
||||
whisperAPI: whisper.NewPublicWhisperAPI(w),
|
||||
whisperAPI: whisperAPI,
|
||||
handler: config.EnvelopeEventsHandler,
|
||||
mailServerConfirmation: config.MailserverConfirmationsEnabled,
|
||||
maxAttempts: config.MaxAttempts,
|
||||
|
@ -57,35 +61,35 @@ func NewEnvelopesMonitor(w *whisper.Whisper, config *EnvelopesMonitorConfig) *En
|
|||
logger: logger.With(zap.Namespace("EnvelopesMonitor")),
|
||||
|
||||
// key is envelope hash (event.Hash)
|
||||
envelopes: map[common.Hash]EnvelopeState{},
|
||||
messages: map[common.Hash]whisper.NewMessage{},
|
||||
attempts: map[common.Hash]int{},
|
||||
identifiers: make(map[common.Hash][][]byte),
|
||||
envelopes: map[statusproto.Hash]EnvelopeState{},
|
||||
messages: map[statusproto.Hash]*whispertypes.NewMessage{},
|
||||
attempts: map[statusproto.Hash]int{},
|
||||
identifiers: make(map[statusproto.Hash][][]byte),
|
||||
|
||||
// key is hash of the batch (event.Batch)
|
||||
batches: map[common.Hash]map[common.Hash]struct{}{},
|
||||
batches: map[statusproto.Hash]map[statusproto.Hash]struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
// EnvelopesMonitor is responsible for monitoring whisper envelopes state.
|
||||
type EnvelopesMonitor struct {
|
||||
w *whisper.Whisper
|
||||
whisperAPI *whisper.PublicWhisperAPI
|
||||
w whispertypes.Whisper
|
||||
whisperAPI whispertypes.PublicWhisperAPI
|
||||
handler EnvelopeEventsHandler
|
||||
mailServerConfirmation bool
|
||||
maxAttempts int
|
||||
|
||||
mu sync.Mutex
|
||||
envelopes map[common.Hash]EnvelopeState
|
||||
batches map[common.Hash]map[common.Hash]struct{}
|
||||
envelopes map[statusproto.Hash]EnvelopeState
|
||||
batches map[statusproto.Hash]map[statusproto.Hash]struct{}
|
||||
|
||||
messages map[common.Hash]whisper.NewMessage
|
||||
attempts map[common.Hash]int
|
||||
identifiers map[common.Hash][][]byte
|
||||
messages map[statusproto.Hash]*whispertypes.NewMessage
|
||||
attempts map[statusproto.Hash]int
|
||||
identifiers map[statusproto.Hash][][]byte
|
||||
|
||||
wg sync.WaitGroup
|
||||
quit chan struct{}
|
||||
isMailserver func(peer enode.ID) bool
|
||||
isMailserver func(peer whispertypes.EnodeID) bool
|
||||
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
@ -107,16 +111,16 @@ func (m *EnvelopesMonitor) Stop() {
|
|||
}
|
||||
|
||||
// Add hash to a tracker.
|
||||
func (m *EnvelopesMonitor) Add(identifiers [][]byte, envelopeHash common.Hash, message whisper.NewMessage) {
|
||||
func (m *EnvelopesMonitor) Add(identifiers [][]byte, envelopeHash statusproto.Hash, message whispertypes.NewMessage) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.envelopes[envelopeHash] = EnvelopePosted
|
||||
m.identifiers[envelopeHash] = identifiers
|
||||
m.messages[envelopeHash] = message
|
||||
m.messages[envelopeHash] = &message
|
||||
m.attempts[envelopeHash] = 1
|
||||
}
|
||||
|
||||
func (m *EnvelopesMonitor) GetState(hash common.Hash) EnvelopeState {
|
||||
func (m *EnvelopesMonitor) GetState(hash statusproto.Hash) EnvelopeState {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
state, exist := m.envelopes[hash]
|
||||
|
@ -128,13 +132,18 @@ func (m *EnvelopesMonitor) GetState(hash common.Hash) EnvelopeState {
|
|||
|
||||
// handleEnvelopeEvents processes whisper envelope events
|
||||
func (m *EnvelopesMonitor) handleEnvelopeEvents() {
|
||||
events := make(chan whisper.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||
events := make(chan whispertypes.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||
sub := m.w.SubscribeEnvelopeEvents(events)
|
||||
defer sub.Unsubscribe()
|
||||
defer func() {
|
||||
close(events)
|
||||
sub.Unsubscribe()
|
||||
}()
|
||||
for {
|
||||
select {
|
||||
case <-m.quit:
|
||||
return
|
||||
case <-sub.Err():
|
||||
return
|
||||
case event := <-events:
|
||||
m.handleEvent(event)
|
||||
}
|
||||
|
@ -143,19 +152,19 @@ func (m *EnvelopesMonitor) handleEnvelopeEvents() {
|
|||
|
||||
// handleEvent based on type of the event either triggers
|
||||
// confirmation handler or removes hash from tracker
|
||||
func (m *EnvelopesMonitor) handleEvent(event whisper.EnvelopeEvent) {
|
||||
handlers := map[whisper.EventType]func(whisper.EnvelopeEvent){
|
||||
whisper.EventEnvelopeSent: m.handleEventEnvelopeSent,
|
||||
whisper.EventEnvelopeExpired: m.handleEventEnvelopeExpired,
|
||||
whisper.EventBatchAcknowledged: m.handleAcknowledgedBatch,
|
||||
whisper.EventEnvelopeReceived: m.handleEventEnvelopeReceived,
|
||||
func (m *EnvelopesMonitor) handleEvent(event whispertypes.EnvelopeEvent) {
|
||||
handlers := map[whispertypes.EventType]func(whispertypes.EnvelopeEvent){
|
||||
whispertypes.EventEnvelopeSent: m.handleEventEnvelopeSent,
|
||||
whispertypes.EventEnvelopeExpired: m.handleEventEnvelopeExpired,
|
||||
whispertypes.EventBatchAcknowledged: m.handleAcknowledgedBatch,
|
||||
whispertypes.EventEnvelopeReceived: m.handleEventEnvelopeReceived,
|
||||
}
|
||||
if handler, ok := handlers[event.Event]; ok {
|
||||
handler(event)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *EnvelopesMonitor) handleEventEnvelopeSent(event whisper.EnvelopeEvent) {
|
||||
func (m *EnvelopesMonitor) handleEventEnvelopeSent(event whispertypes.EnvelopeEvent) {
|
||||
if m.mailServerConfirmation {
|
||||
if !m.isMailserver(event.Peer) {
|
||||
return
|
||||
|
@ -172,9 +181,9 @@ func (m *EnvelopesMonitor) handleEventEnvelopeSent(event whisper.EnvelopeEvent)
|
|||
return
|
||||
}
|
||||
m.logger.Debug("envelope is sent", zap.String("hash", event.Hash.String()), zap.String("peer", event.Peer.String()))
|
||||
if event.Batch != (common.Hash{}) {
|
||||
if event.Batch != (statusproto.Hash{}) {
|
||||
if _, ok := m.batches[event.Batch]; !ok {
|
||||
m.batches[event.Batch] = map[common.Hash]struct{}{}
|
||||
m.batches[event.Batch] = map[statusproto.Hash]struct{}{}
|
||||
}
|
||||
m.batches[event.Batch][event.Hash] = struct{}{}
|
||||
m.logger.Debug("waiting for a confirmation", zap.String("batch", event.Batch.String()))
|
||||
|
@ -186,7 +195,7 @@ func (m *EnvelopesMonitor) handleEventEnvelopeSent(event whisper.EnvelopeEvent)
|
|||
}
|
||||
}
|
||||
|
||||
func (m *EnvelopesMonitor) handleAcknowledgedBatch(event whisper.EnvelopeEvent) {
|
||||
func (m *EnvelopesMonitor) handleAcknowledgedBatch(event whispertypes.EnvelopeEvent) {
|
||||
if m.mailServerConfirmation {
|
||||
if !m.isMailserver(event.Peer) {
|
||||
return
|
||||
|
@ -201,11 +210,11 @@ func (m *EnvelopesMonitor) handleAcknowledgedBatch(event whisper.EnvelopeEvent)
|
|||
m.logger.Debug("batch is not found", zap.String("batch", event.Batch.String()))
|
||||
}
|
||||
m.logger.Debug("received a confirmation", zap.String("batch", event.Batch.String()), zap.String("peer", event.Peer.String()))
|
||||
envelopeErrors, ok := event.Data.([]whisper.EnvelopeError)
|
||||
envelopeErrors, ok := event.Data.([]whispertypes.EnvelopeError)
|
||||
if event.Data != nil && !ok {
|
||||
m.logger.Error("received unexpected data in the the confirmation event", zap.String("batch", event.Batch.String()))
|
||||
}
|
||||
failedEnvelopes := map[common.Hash]struct{}{}
|
||||
failedEnvelopes := map[statusproto.Hash]struct{}{}
|
||||
for i := range envelopeErrors {
|
||||
envelopeError := envelopeErrors[i]
|
||||
_, exist := m.envelopes[envelopeError.Hash]
|
||||
|
@ -213,7 +222,7 @@ func (m *EnvelopesMonitor) handleAcknowledgedBatch(event whisper.EnvelopeEvent)
|
|||
m.logger.Warn("envelope that was posted by us is discarded", zap.String("hash", envelopeError.Hash.String()), zap.String("peer", event.Peer.String()), zap.String("error", envelopeError.Description))
|
||||
var err error
|
||||
switch envelopeError.Code {
|
||||
case whisper.EnvelopeTimeNotSynced:
|
||||
case whispertypes.EnvelopeTimeNotSynced:
|
||||
err = errors.New("envelope wasn't delivered due to time sync issues")
|
||||
}
|
||||
m.handleEnvelopeFailure(envelopeError.Hash, err)
|
||||
|
@ -237,7 +246,7 @@ func (m *EnvelopesMonitor) handleAcknowledgedBatch(event whisper.EnvelopeEvent)
|
|||
delete(m.batches, event.Batch)
|
||||
}
|
||||
|
||||
func (m *EnvelopesMonitor) handleEventEnvelopeExpired(event whisper.EnvelopeEvent) {
|
||||
func (m *EnvelopesMonitor) handleEventEnvelopeExpired(event whispertypes.EnvelopeEvent) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.handleEnvelopeFailure(event.Hash, errors.New("envelope expired due to connectivity issues"))
|
||||
|
@ -245,7 +254,7 @@ func (m *EnvelopesMonitor) handleEventEnvelopeExpired(event whisper.EnvelopeEven
|
|||
|
||||
// handleEnvelopeFailure is a common code path for processing envelopes failures. not thread safe, lock
|
||||
// must be used on a higher level.
|
||||
func (m *EnvelopesMonitor) handleEnvelopeFailure(hash common.Hash, err error) {
|
||||
func (m *EnvelopesMonitor) handleEnvelopeFailure(hash statusproto.Hash, err error) {
|
||||
if state, ok := m.envelopes[hash]; ok {
|
||||
message, exist := m.messages[hash]
|
||||
if !exist {
|
||||
|
@ -259,7 +268,7 @@ func (m *EnvelopesMonitor) handleEnvelopeFailure(hash common.Hash, err error) {
|
|||
}
|
||||
if attempt < m.maxAttempts {
|
||||
m.logger.Debug("retrying to send a message", zap.String("hash", hash.String()), zap.Int("attempt", attempt+1))
|
||||
hex, err := m.whisperAPI.Post(context.TODO(), message)
|
||||
hex, err := m.whisperAPI.Post(context.TODO(), *message)
|
||||
if err != nil {
|
||||
m.logger.Error("failed to retry sending message", zap.String("hash", hash.String()), zap.Int("attempt", attempt+1), zap.Error(err))
|
||||
if m.handler != nil {
|
||||
|
@ -267,7 +276,7 @@ func (m *EnvelopesMonitor) handleEnvelopeFailure(hash common.Hash, err error) {
|
|||
}
|
||||
|
||||
}
|
||||
envelopeID := common.BytesToHash(hex)
|
||||
envelopeID := statusproto.BytesToHash(hex)
|
||||
m.envelopes[envelopeID] = EnvelopePosted
|
||||
m.messages[envelopeID] = message
|
||||
m.attempts[envelopeID] = attempt + 1
|
||||
|
@ -281,7 +290,7 @@ func (m *EnvelopesMonitor) handleEnvelopeFailure(hash common.Hash, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (m *EnvelopesMonitor) handleEventEnvelopeReceived(event whisper.EnvelopeEvent) {
|
||||
func (m *EnvelopesMonitor) handleEventEnvelopeReceived(event whispertypes.EnvelopeEvent) {
|
||||
if m.mailServerConfirmation {
|
||||
if !m.isMailserver(event.Peer) {
|
||||
return
|
||||
|
@ -302,7 +311,7 @@ func (m *EnvelopesMonitor) handleEventEnvelopeReceived(event whisper.EnvelopeEve
|
|||
|
||||
// clearMessageState removes all message and envelope state.
|
||||
// not thread-safe, should be protected on a higher level.
|
||||
func (m *EnvelopesMonitor) clearMessageState(envelopeID common.Hash) {
|
||||
func (m *EnvelopesMonitor) clearMessageState(envelopeID statusproto.Hash) {
|
||||
delete(m.envelopes, envelopeID)
|
||||
delete(m.messages, envelopeID)
|
||||
delete(m.attempts, envelopeID)
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/pkg/errors"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
|
@ -26,15 +26,10 @@ var (
|
|||
|
||||
type whisperFilter struct {
|
||||
FilterID string
|
||||
Topic whisper.TopicType
|
||||
Topic whispertypes.TopicType
|
||||
SymKeyID string
|
||||
}
|
||||
|
||||
type NegotiatedSecret struct {
|
||||
PublicKey *ecdsa.PublicKey
|
||||
Key []byte
|
||||
}
|
||||
|
||||
// TODO: revise fields encoding/decoding. Some are encoded using hexutil and some using encoding/hex.
|
||||
type Filter struct {
|
||||
// ChatID is the identifier of the chat
|
||||
|
@ -49,7 +44,7 @@ type Filter struct {
|
|||
// It's encoded using encoding/hex.
|
||||
Identity string `json:"identity"`
|
||||
// Topic is the whisper topic
|
||||
Topic whisper.TopicType `json:"topic"`
|
||||
Topic whispertypes.TopicType `json:"topic"`
|
||||
// Discovery is whether this is a discovery topic
|
||||
Discovery bool `json:"discovery"`
|
||||
// Negotiated tells us whether is a negotiated topic
|
||||
|
@ -63,7 +58,7 @@ func (c *Filter) IsPublic() bool {
|
|||
}
|
||||
|
||||
type filtersManager struct {
|
||||
whisper *whisper.Whisper
|
||||
whisper whispertypes.Whisper
|
||||
persistence *sqlitePersistence
|
||||
privateKey *ecdsa.PrivateKey
|
||||
keys map[string][]byte // a cache of symmetric manager derived from passwords
|
||||
|
@ -76,7 +71,7 @@ type filtersManager struct {
|
|||
}
|
||||
|
||||
// newFiltersManager returns a new filtersManager.
|
||||
func newFiltersManager(db *sql.DB, w *whisper.Whisper, privateKey *ecdsa.PrivateKey, logger *zap.Logger) (*filtersManager, error) {
|
||||
func newFiltersManager(db *sql.DB, w whispertypes.Whisper, privateKey *ecdsa.PrivateKey, logger *zap.Logger) (*filtersManager, error) {
|
||||
if logger == nil {
|
||||
logger = zap.NewNop()
|
||||
}
|
||||
|
@ -288,7 +283,7 @@ func (s *filtersManager) loadPartitioned(publicKey *ecdsa.PublicKey, listen bool
|
|||
}
|
||||
|
||||
// LoadNegotiated loads a negotiated secret as a filter.
|
||||
func (s *filtersManager) LoadNegotiated(secret NegotiatedSecret) (*Filter, error) {
|
||||
func (s *filtersManager) LoadNegotiated(secret whispertypes.NegotiatedSecret) (*Filter, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
|
@ -483,13 +478,11 @@ func (s *filtersManager) addSymmetric(chatID string) (*whisperFilter, error) {
|
|||
}
|
||||
}
|
||||
|
||||
f := &whisper.Filter{
|
||||
KeySym: symKey,
|
||||
PoW: minPow,
|
||||
AllowP2P: true,
|
||||
Topics: topics,
|
||||
Messages: s.whisper.NewMessageStore(),
|
||||
}
|
||||
f := s.whisper.CreateFilterWrapper(
|
||||
nil, symKey,
|
||||
minPow,
|
||||
topics,
|
||||
s.whisper.NewMessageStore())
|
||||
|
||||
id, err := s.whisper.Subscribe(f)
|
||||
if err != nil {
|
||||
|
@ -499,7 +492,7 @@ func (s *filtersManager) addSymmetric(chatID string) (*whisperFilter, error) {
|
|||
return &whisperFilter{
|
||||
FilterID: id,
|
||||
SymKeyID: symKeyID,
|
||||
Topic: whisper.BytesToTopic(topic),
|
||||
Topic: whispertypes.BytesToTopic(topic),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -518,19 +511,17 @@ func (s *filtersManager) addAsymmetric(chatID string, listen bool) (*whisperFilt
|
|||
topic := toTopic(chatID)
|
||||
topics := [][]byte{topic}
|
||||
|
||||
f := &whisper.Filter{
|
||||
KeyAsym: s.privateKey,
|
||||
PoW: pow,
|
||||
AllowP2P: true,
|
||||
Topics: topics,
|
||||
Messages: s.whisper.NewMessageStore(),
|
||||
}
|
||||
f := s.whisper.CreateFilterWrapper(
|
||||
s.privateKey, nil,
|
||||
pow,
|
||||
topics,
|
||||
s.whisper.NewMessageStore())
|
||||
|
||||
id, err := s.whisper.Subscribe(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &whisperFilter{FilterID: id, Topic: whisper.BytesToTopic(topic)}, nil
|
||||
return &whisperFilter{FilterID: id, Topic: whispertypes.BytesToTopic(topic)}, nil
|
||||
}
|
||||
|
||||
// GetNegotiated returns a negotiated chat given an identity
|
||||
|
@ -542,7 +533,7 @@ func (s *filtersManager) GetNegotiated(identity *ecdsa.PublicKey) *Filter {
|
|||
}
|
||||
|
||||
func toTopic(s string) []byte {
|
||||
return crypto.Keccak256([]byte(s))[:whisper.TopicLength]
|
||||
return crypto.Keccak256([]byte(s))[:whispertypes.TopicLength]
|
||||
}
|
||||
|
||||
// ToTopic converts a string to a whisper topic.
|
||||
|
|
31
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/envelope.go
generated
vendored
Normal file
31
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/envelope.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
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"
|
||||
)
|
||||
|
||||
type gethEnvelopeWrapper struct {
|
||||
envelope *whisper.Envelope
|
||||
}
|
||||
|
||||
// NewGethEnvelopeWrapper returns an object that wraps Geth's Envelope in a whispertypes interface
|
||||
func NewGethEnvelopeWrapper(e *whisper.Envelope) whispertypes.Envelope {
|
||||
return &gethEnvelopeWrapper{
|
||||
envelope: e,
|
||||
}
|
||||
}
|
||||
|
||||
// GetGethEnvelopeFrom retrieves the underlying whisper Envelope struct from a wrapped Envelope interface
|
||||
func GetGethEnvelopeFrom(f whispertypes.Envelope) *whisper.Envelope {
|
||||
return f.(*gethEnvelopeWrapper).envelope
|
||||
}
|
||||
|
||||
func (w *gethEnvelopeWrapper) Hash() statusproto.Hash {
|
||||
return statusproto.Hash(w.envelope.Hash())
|
||||
}
|
||||
|
||||
func (w *gethEnvelopeWrapper) Bloom() []byte {
|
||||
return w.envelope.Bloom()
|
||||
}
|
30
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/envelope_error.go
generated
vendored
Normal file
30
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/envelope_error.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
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"
|
||||
)
|
||||
|
||||
// NewGethEnvelopeErrorWrapper returns a whispertypes.EnvelopeError object that mimics Geth's EnvelopeError
|
||||
func NewGethEnvelopeErrorWrapper(envelopeError *whisper.EnvelopeError) *whispertypes.EnvelopeError {
|
||||
if envelopeError == nil {
|
||||
panic("envelopeError should not be nil")
|
||||
}
|
||||
|
||||
return &whispertypes.EnvelopeError{
|
||||
Hash: statusproto.Hash(envelopeError.Hash),
|
||||
Code: mapGethErrorCode(envelopeError.Code),
|
||||
Description: envelopeError.Description,
|
||||
}
|
||||
}
|
||||
|
||||
func mapGethErrorCode(code uint) uint {
|
||||
switch code {
|
||||
case whisper.EnvelopeTimeNotSynced:
|
||||
return whispertypes.EnvelopeTimeNotSynced
|
||||
case whisper.EnvelopeOtherError:
|
||||
return whispertypes.EnvelopeOtherError
|
||||
}
|
||||
return whispertypes.EnvelopeOtherError
|
||||
}
|
34
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/envelope_event.go
generated
vendored
Normal file
34
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/envelope_event.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
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"
|
||||
)
|
||||
|
||||
// NewGethEnvelopeEventWrapper returns a whispertypes.EnvelopeEvent object that mimics Geth's EnvelopeEvent
|
||||
func NewGethEnvelopeEventWrapper(envelopeEvent *whisper.EnvelopeEvent) *whispertypes.EnvelopeEvent {
|
||||
if envelopeEvent == nil {
|
||||
panic("envelopeEvent should not be nil")
|
||||
}
|
||||
|
||||
wrappedData := envelopeEvent.Data
|
||||
switch data := envelopeEvent.Data.(type) {
|
||||
case []whisper.EnvelopeError:
|
||||
wrappedData := make([]whispertypes.EnvelopeError, len(data))
|
||||
for index, envError := range data {
|
||||
wrappedData[index] = *NewGethEnvelopeErrorWrapper(&envError)
|
||||
}
|
||||
case *whisper.MailServerResponse:
|
||||
wrappedData = NewGethMailServerResponseWrapper(data)
|
||||
case whisper.SyncEventResponse:
|
||||
wrappedData = NewGethSyncEventResponseWrapper(data)
|
||||
}
|
||||
return &whispertypes.EnvelopeEvent{
|
||||
Event: whispertypes.EventType(envelopeEvent.Event),
|
||||
Hash: statusproto.Hash(envelopeEvent.Hash),
|
||||
Batch: statusproto.Hash(envelopeEvent.Batch),
|
||||
Peer: whispertypes.EnodeID(envelopeEvent.Peer),
|
||||
Data: wrappedData,
|
||||
}
|
||||
}
|
38
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/filter.go
generated
vendored
Normal file
38
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/filter.go
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
)
|
||||
|
||||
type gethFilterWrapper struct {
|
||||
filter *whisper.Filter
|
||||
}
|
||||
|
||||
// NewGethFilterWrapper returns an object that wraps Geth's Filter in a whispertypes interface
|
||||
func NewGethFilterWrapper(f *whisper.Filter) whispertypes.Filter {
|
||||
if f.Messages == nil {
|
||||
panic("Messages should not be nil")
|
||||
}
|
||||
|
||||
return &gethFilterWrapper{
|
||||
filter: f,
|
||||
}
|
||||
}
|
||||
|
||||
// GetGethFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
|
||||
func GetGethFilterFrom(f whispertypes.Filter) *whisper.Filter {
|
||||
return f.(*gethFilterWrapper).filter
|
||||
}
|
||||
|
||||
// KeyAsym returns the private Key of recipient
|
||||
func (w *gethFilterWrapper) KeyAsym() *ecdsa.PrivateKey {
|
||||
return w.filter.KeyAsym
|
||||
}
|
||||
|
||||
// KeySym returns the key associated with the Topic
|
||||
func (w *gethFilterWrapper) KeySym() []byte {
|
||||
return w.filter.KeySym
|
||||
}
|
20
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/mailserver_response.go
generated
vendored
Normal file
20
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/mailserver_response.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
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"
|
||||
)
|
||||
|
||||
// NewGethMailServerResponseWrapper returns a whispertypes.MailServerResponse object that mimics Geth's MailServerResponse
|
||||
func NewGethMailServerResponseWrapper(mailServerResponse *whisper.MailServerResponse) *whispertypes.MailServerResponse {
|
||||
if mailServerResponse == nil {
|
||||
panic("mailServerResponse should not be nil")
|
||||
}
|
||||
|
||||
return &whispertypes.MailServerResponse{
|
||||
LastEnvelopeHash: statusproto.Hash(mailServerResponse.LastEnvelopeHash),
|
||||
Cursor: mailServerResponse.Cursor,
|
||||
Error: mailServerResponse.Error,
|
||||
}
|
||||
}
|
43
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/message_store.go
generated
vendored
Normal file
43
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/message_store.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
)
|
||||
|
||||
type gethMessageStoreWrapper struct {
|
||||
messageStore whisper.MessageStore
|
||||
}
|
||||
|
||||
// NewGethMessageStoreWrapper returns an object that wraps Geth's MessageStore in a whispertypes interface
|
||||
func NewGethMessageStoreWrapper(messageStore whisper.MessageStore) whispertypes.MessageStore {
|
||||
if messageStore == nil {
|
||||
panic("messageStore cannot be nil")
|
||||
}
|
||||
|
||||
return &gethMessageStoreWrapper{
|
||||
messageStore: messageStore,
|
||||
}
|
||||
}
|
||||
|
||||
// GetGethMessageStoreFrom retrieves the underlying whisper MessageStore interface from a wrapped MessageStore interface
|
||||
func GetGethMessageStoreFrom(m whispertypes.MessageStore) whisper.MessageStore {
|
||||
return m.(*gethMessageStoreWrapper).messageStore
|
||||
}
|
||||
|
||||
func (w *gethMessageStoreWrapper) Add(m whispertypes.ReceivedMessage) error {
|
||||
return w.messageStore.Add(GetGethReceivedMessageFrom(m))
|
||||
}
|
||||
|
||||
func (w *gethMessageStoreWrapper) Pop() ([]whispertypes.ReceivedMessage, error) {
|
||||
msgs, err := w.messageStore.Pop()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wrappedMsgs := make([]whispertypes.ReceivedMessage, len(msgs))
|
||||
for index, m := range msgs {
|
||||
wrappedMsgs[index] = NewGethReceivedMessageWrapper(m)
|
||||
}
|
||||
return wrappedMsgs, err
|
||||
}
|
103
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/public_whisper_api.go
generated
vendored
Normal file
103
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/public_whisper_api.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
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"
|
||||
)
|
||||
|
||||
type gethPublicWhisperAPIWrapper struct {
|
||||
publicWhisperAPI *whisper.PublicWhisperAPI
|
||||
}
|
||||
|
||||
// NewGethPublicWhisperAPIWrapper returns an object that wraps Geth's PublicWhisperAPI in a whispertypes interface
|
||||
func NewGethPublicWhisperAPIWrapper(publicWhisperAPI *whisper.PublicWhisperAPI) whispertypes.PublicWhisperAPI {
|
||||
if publicWhisperAPI == nil {
|
||||
panic("publicWhisperAPI cannot be nil")
|
||||
}
|
||||
|
||||
return &gethPublicWhisperAPIWrapper{
|
||||
publicWhisperAPI: publicWhisperAPI,
|
||||
}
|
||||
}
|
||||
|
||||
// AddPrivateKey imports the given private key.
|
||||
func (w *gethPublicWhisperAPIWrapper) AddPrivateKey(ctx context.Context, privateKey statusproto.HexBytes) (string, error) {
|
||||
return w.publicWhisperAPI.AddPrivateKey(ctx, hexutil.Bytes(privateKey))
|
||||
}
|
||||
|
||||
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
||||
func (w *gethPublicWhisperAPIWrapper) GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error) {
|
||||
return w.publicWhisperAPI.GenerateSymKeyFromPassword(ctx, passwd)
|
||||
}
|
||||
|
||||
// DeleteKeyPair removes the key with the given key if it exists.
|
||||
func (w *gethPublicWhisperAPIWrapper) DeleteKeyPair(ctx context.Context, key string) (bool, error) {
|
||||
return w.publicWhisperAPI.DeleteKeyPair(ctx, key)
|
||||
}
|
||||
|
||||
// NewMessageFilter creates a new filter that can be used to poll for
|
||||
// (new) messages that satisfy the given criteria.
|
||||
func (w *gethPublicWhisperAPIWrapper) NewMessageFilter(req whispertypes.Criteria) (string, error) {
|
||||
topics := make([]whisper.TopicType, len(req.Topics))
|
||||
for index, tt := range req.Topics {
|
||||
topics[index] = whisper.TopicType(tt)
|
||||
}
|
||||
|
||||
criteria := whisper.Criteria{
|
||||
SymKeyID: req.SymKeyID,
|
||||
PrivateKeyID: req.PrivateKeyID,
|
||||
Sig: req.Sig,
|
||||
MinPow: req.MinPow,
|
||||
Topics: topics,
|
||||
AllowP2P: req.AllowP2P,
|
||||
}
|
||||
return w.publicWhisperAPI.NewMessageFilter(criteria)
|
||||
}
|
||||
|
||||
// GetFilterMessages returns the messages that match the filter criteria and
|
||||
// are received between the last poll and now.
|
||||
func (w *gethPublicWhisperAPIWrapper) GetFilterMessages(id string) ([]*whispertypes.Message, error) {
|
||||
msgs, err := w.publicWhisperAPI.GetFilterMessages(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wrappedMsgs := make([]*whispertypes.Message, len(msgs))
|
||||
for index, msg := range msgs {
|
||||
wrappedMsgs[index] = &whispertypes.Message{
|
||||
Sig: msg.Sig,
|
||||
TTL: msg.TTL,
|
||||
Timestamp: msg.Timestamp,
|
||||
Topic: whispertypes.TopicType(msg.Topic),
|
||||
Payload: msg.Payload,
|
||||
Padding: msg.Padding,
|
||||
PoW: msg.PoW,
|
||||
Hash: msg.Hash,
|
||||
Dst: msg.Dst,
|
||||
P2P: msg.P2P,
|
||||
}
|
||||
}
|
||||
return wrappedMsgs, nil
|
||||
}
|
||||
|
||||
// Post posts a message on the Whisper network.
|
||||
// returns the hash of the message in case of success.
|
||||
func (w *gethPublicWhisperAPIWrapper) Post(ctx context.Context, req whispertypes.NewMessage) ([]byte, error) {
|
||||
msg := whisper.NewMessage{
|
||||
SymKeyID: req.SymKeyID,
|
||||
PublicKey: req.PublicKey,
|
||||
Sig: req.Sig,
|
||||
TTL: req.TTL,
|
||||
Topic: whisper.TopicType(req.Topic),
|
||||
Payload: req.Payload,
|
||||
Padding: req.Padding,
|
||||
PowTime: req.PowTime,
|
||||
PowTarget: req.PowTarget,
|
||||
TargetPeer: req.TargetPeer,
|
||||
}
|
||||
return w.publicWhisperAPI.Post(ctx, msg)
|
||||
}
|
26
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/received_message.go
generated
vendored
Normal file
26
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/received_message.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
)
|
||||
|
||||
type gethReceivedMessageWrapper struct {
|
||||
receivedMessage *whisper.ReceivedMessage
|
||||
}
|
||||
|
||||
// NewGethReceivedMessageWrapper returns an object that wraps Geth's ReceivedMessage in a whispertypes interface
|
||||
func NewGethReceivedMessageWrapper(receivedMessage *whisper.ReceivedMessage) whispertypes.ReceivedMessage {
|
||||
if receivedMessage == nil {
|
||||
panic("receivedMessage cannot be nil")
|
||||
}
|
||||
|
||||
return &gethReceivedMessageWrapper{
|
||||
receivedMessage: receivedMessage,
|
||||
}
|
||||
}
|
||||
|
||||
// GetGethReceivedMessageFrom retrieves the underlying whisper ReceivedMessage struct from a wrapped ReceivedMessage interface
|
||||
func GetGethReceivedMessageFrom(m whispertypes.ReceivedMessage) *whisper.ReceivedMessage {
|
||||
return m.(*gethReceivedMessageWrapper).receivedMessage
|
||||
}
|
29
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/subscription.go
generated
vendored
Normal file
29
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/subscription.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
type gethSubscriptionWrapper struct {
|
||||
subscription event.Subscription
|
||||
}
|
||||
|
||||
// NewGethSubscriptionWrapper returns an object that wraps Geth's Subscription in a whispertypes interface
|
||||
func NewGethSubscriptionWrapper(subscription event.Subscription) whispertypes.Subscription {
|
||||
if subscription == nil {
|
||||
panic("subscription cannot be nil")
|
||||
}
|
||||
|
||||
return &gethSubscriptionWrapper{
|
||||
subscription: subscription,
|
||||
}
|
||||
}
|
||||
|
||||
func (w *gethSubscriptionWrapper) Err() <-chan error {
|
||||
return w.subscription.Err()
|
||||
}
|
||||
|
||||
func (w *gethSubscriptionWrapper) Unsubscribe() {
|
||||
w.subscription.Unsubscribe()
|
||||
}
|
14
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/syncevent_response.go
generated
vendored
Normal file
14
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/syncevent_response.go
generated
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
)
|
||||
|
||||
// NewGethSyncEventResponseWrapper returns a whispertypes.SyncEventResponse object that mimics Geth's SyncEventResponse
|
||||
func NewGethSyncEventResponseWrapper(syncEventResponse whisper.SyncEventResponse) whispertypes.SyncEventResponse {
|
||||
return whispertypes.SyncEventResponse{
|
||||
Cursor: syncEventResponse.Cursor,
|
||||
Error: syncEventResponse.Error,
|
||||
}
|
||||
}
|
17
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/syncmailrequest.go
generated
vendored
Normal file
17
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/syncmailrequest.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
)
|
||||
|
||||
// GetGethSyncMailRequestFrom converts a whisper SyncMailRequest struct from a SyncMailRequest struct
|
||||
func GetGethSyncMailRequestFrom(r *whispertypes.SyncMailRequest) *whisper.SyncMailRequest {
|
||||
return &whisper.SyncMailRequest{
|
||||
Lower: r.Lower,
|
||||
Upper: r.Upper,
|
||||
Bloom: r.Bloom,
|
||||
Limit: r.Limit,
|
||||
Cursor: r.Cursor,
|
||||
}
|
||||
}
|
150
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/whisper.go
generated
vendored
Normal file
150
vendor/github.com/status-im/status-protocol-go/transport/whisper/gethbridge/whisper.go
generated
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
package gethbridge
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"time"
|
||||
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
)
|
||||
|
||||
type gethWhisperWrapper struct {
|
||||
whisper *whisper.Whisper
|
||||
}
|
||||
|
||||
// NewGethWhisperWrapper returns an object that wraps Geth's Whisper in a whispertypes interface
|
||||
func NewGethWhisperWrapper(w *whisper.Whisper) whispertypes.Whisper {
|
||||
if w == nil {
|
||||
panic("w cannot be nil")
|
||||
}
|
||||
|
||||
return &gethWhisperWrapper{
|
||||
whisper: w,
|
||||
}
|
||||
}
|
||||
|
||||
// GetGethWhisperFrom retrieves the underlying whisper Whisper struct from a wrapped Whisper interface
|
||||
func GetGethWhisperFrom(m whispertypes.Whisper) *whisper.Whisper {
|
||||
return m.(*gethWhisperWrapper).whisper
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) PublicWhisperAPI() whispertypes.PublicWhisperAPI {
|
||||
return NewGethPublicWhisperAPIWrapper(whisper.NewPublicWhisperAPI(w.whisper))
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) NewMessageStore() whispertypes.MessageStore {
|
||||
return NewGethMessageStoreWrapper(w.whisper.NewMessageStore())
|
||||
}
|
||||
|
||||
// MinPow returns the PoW value required by this node.
|
||||
func (w *gethWhisperWrapper) MinPow() float64 {
|
||||
return w.whisper.MinPow()
|
||||
}
|
||||
|
||||
// BloomFilter returns the aggregated bloom filter for all the topics of interest.
|
||||
// The nodes are required to send only messages that match the advertised bloom filter.
|
||||
// If a message does not match the bloom, it will tantamount to spam, and the peer will
|
||||
// be disconnected.
|
||||
func (w *gethWhisperWrapper) BloomFilter() []byte {
|
||||
return w.whisper.BloomFilter()
|
||||
}
|
||||
|
||||
// GetCurrentTime returns current time.
|
||||
func (w *gethWhisperWrapper) GetCurrentTime() time.Time {
|
||||
return w.whisper.GetCurrentTime()
|
||||
}
|
||||
|
||||
// SetTimeSource assigns a particular source of time to a whisper object.
|
||||
func (w *gethWhisperWrapper) SetTimeSource(timesource func() time.Time) {
|
||||
w.whisper.SetTimeSource(timesource)
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) SubscribeEnvelopeEvents(eventsProxy chan<- whispertypes.EnvelopeEvent) whispertypes.Subscription {
|
||||
events := make(chan whisper.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
|
||||
go func() {
|
||||
for e := range events {
|
||||
eventsProxy <- *NewGethEnvelopeEventWrapper(&e)
|
||||
}
|
||||
}()
|
||||
|
||||
return NewGethSubscriptionWrapper(w.whisper.SubscribeEnvelopeEvents(events))
|
||||
}
|
||||
|
||||
// SelectedKeyPairID returns the id of currently selected key pair.
|
||||
// It helps distinguish between different users w/o exposing the user identity itself.
|
||||
func (w *gethWhisperWrapper) SelectedKeyPairID() string {
|
||||
return w.whisper.SelectedKeyPairID()
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
|
||||
return w.whisper.GetPrivateKey(id)
|
||||
}
|
||||
|
||||
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
|
||||
func (w *gethWhisperWrapper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
|
||||
return w.whisper.AddKeyPair(key)
|
||||
}
|
||||
|
||||
// DeleteKeyPair deletes the specified key if it exists.
|
||||
func (w *gethWhisperWrapper) DeleteKeyPair(key string) bool {
|
||||
return w.whisper.DeleteKeyPair(key)
|
||||
}
|
||||
|
||||
// SelectKeyPair adds cryptographic identity, and makes sure
|
||||
// that it is the only private key known to the node.
|
||||
func (w *gethWhisperWrapper) SelectKeyPair(key *ecdsa.PrivateKey) error {
|
||||
return w.whisper.SelectKeyPair(key)
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) AddSymKeyDirect(key []byte) (string, error) {
|
||||
return w.whisper.AddSymKeyDirect(key)
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) AddSymKeyFromPassword(password string) (string, error) {
|
||||
return w.whisper.AddSymKeyFromPassword(password)
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) DeleteSymKey(id string) bool {
|
||||
return w.whisper.DeleteSymKey(id)
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) GetSymKey(id string) ([]byte, error) {
|
||||
return w.whisper.GetSymKey(id)
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) Subscribe(f whispertypes.Filter) (string, error) {
|
||||
return w.whisper.Subscribe(GetGethFilterFrom(f))
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) GetFilter(id string) whispertypes.Filter {
|
||||
return NewGethFilterWrapper(w.whisper.GetFilter(id))
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) Unsubscribe(id string) error {
|
||||
return w.whisper.Unsubscribe(id)
|
||||
}
|
||||
|
||||
func (w *gethWhisperWrapper) CreateFilterWrapper(keyAsym *ecdsa.PrivateKey, keySym []byte, pow float64, topics [][]byte, messages whispertypes.MessageStore) whispertypes.Filter {
|
||||
return NewGethFilterWrapper(&whisper.Filter{
|
||||
KeyAsym: keyAsym,
|
||||
KeySym: keySym,
|
||||
PoW: pow,
|
||||
AllowP2P: true,
|
||||
Topics: topics,
|
||||
Messages: GetGethMessageStoreFrom(messages),
|
||||
})
|
||||
}
|
||||
|
||||
// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
|
||||
// which is known to implement MailServer interface, and is supposed to process this
|
||||
// request and respond with a number of peer-to-peer messages (possibly expired),
|
||||
// which are not supposed to be forwarded any further.
|
||||
// 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 {
|
||||
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, GetGethEnvelopeFrom(envelope), timeout)
|
||||
}
|
||||
|
||||
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
||||
func (w *gethWhisperWrapper) SyncMessages(peerID []byte, req whispertypes.SyncMailRequest) error {
|
||||
return w.whisper.SyncMessages(peerID, *GetGethSyncMailRequestFrom(&req))
|
||||
}
|
81
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/envelopes.go
generated
vendored
Normal file
81
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/envelopes.go
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
package whispertypes
|
||||
|
||||
import statusproto "github.com/status-im/status-protocol-go/types"
|
||||
|
||||
// Envelope represents a clear-text data packet to transmit through the Whisper
|
||||
// network. Its contents may or may not be encrypted and signed.
|
||||
type Envelope interface {
|
||||
Hash() statusproto.Hash // Cached hash of the envelope to avoid rehashing every time.
|
||||
Bloom() []byte
|
||||
}
|
||||
|
||||
// EventType used to define known envelope events.
|
||||
type EventType string
|
||||
|
||||
// NOTE: This list of event names is extracted from Geth. It must be kept in sync, or otherwise a mapping layer needs to be created
|
||||
const (
|
||||
// EventEnvelopeSent fires when envelope was sent to a peer.
|
||||
EventEnvelopeSent EventType = "envelope.sent"
|
||||
// EventEnvelopeExpired fires when envelop expired
|
||||
EventEnvelopeExpired EventType = "envelope.expired"
|
||||
// EventEnvelopeReceived is sent once envelope was received from a peer.
|
||||
// EventEnvelopeReceived must be sent to the feed even if envelope was previously in the cache.
|
||||
// And event, ideally, should contain information about peer that sent envelope to us.
|
||||
EventEnvelopeReceived EventType = "envelope.received"
|
||||
// EventBatchAcknowledged is sent when batch of envelopes was acknowleged by a peer.
|
||||
EventBatchAcknowledged EventType = "batch.acknowleged"
|
||||
// EventEnvelopeAvailable fires when envelop is available for filters
|
||||
EventEnvelopeAvailable EventType = "envelope.available"
|
||||
// EventMailServerRequestSent fires when such request is sent.
|
||||
EventMailServerRequestSent EventType = "mailserver.request.sent"
|
||||
// EventMailServerRequestCompleted fires after mailserver sends all the requested messages
|
||||
EventMailServerRequestCompleted EventType = "mailserver.request.completed"
|
||||
// EventMailServerRequestExpired fires after mailserver the request TTL ends.
|
||||
// This event is independent and concurrent to EventMailServerRequestCompleted.
|
||||
// Request should be considered as expired only if expiry event was received first.
|
||||
EventMailServerRequestExpired EventType = "mailserver.request.expired"
|
||||
// EventMailServerEnvelopeArchived fires after an envelope has been archived
|
||||
EventMailServerEnvelopeArchived EventType = "mailserver.envelope.archived"
|
||||
// EventMailServerSyncFinished fires when the sync of messages is finished.
|
||||
EventMailServerSyncFinished EventType = "mailserver.sync.finished"
|
||||
)
|
||||
|
||||
const (
|
||||
EnvelopeTimeNotSynced uint = 1000
|
||||
EnvelopeOtherError
|
||||
)
|
||||
|
||||
// EnvelopeEvent used for envelopes events.
|
||||
type EnvelopeEvent struct {
|
||||
Event EventType
|
||||
Hash statusproto.Hash
|
||||
Batch statusproto.Hash
|
||||
Peer EnodeID
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
// EnvelopeError code and optional description of the error.
|
||||
type EnvelopeError struct {
|
||||
Hash statusproto.Hash
|
||||
Code uint
|
||||
Description string
|
||||
}
|
||||
|
||||
// Subscription represents a stream of events. The carrier of the events is typically a
|
||||
// channel, but isn't part of the interface.
|
||||
//
|
||||
// Subscriptions can fail while established. Failures are reported through an error
|
||||
// channel. It receives a value if there is an issue with the subscription (e.g. the
|
||||
// network connection delivering the events has been closed). Only one value will ever be
|
||||
// sent.
|
||||
//
|
||||
// The error channel is closed when the subscription ends successfully (i.e. when the
|
||||
// source of events is closed). It is also closed when Unsubscribe is called.
|
||||
//
|
||||
// The Unsubscribe method cancels the sending of events. You must call Unsubscribe in all
|
||||
// cases to ensure that resources related to the subscription are released. It can be
|
||||
// called any number of times.
|
||||
type Subscription interface {
|
||||
Err() <-chan error // returns the error channel
|
||||
Unsubscribe() // cancels sending of events, closing the error channel
|
||||
}
|
17
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/filter.go
generated
vendored
Normal file
17
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/filter.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
package whispertypes
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
)
|
||||
|
||||
// Filter represents a Whisper message filter
|
||||
type Filter interface {
|
||||
KeyAsym() *ecdsa.PrivateKey // Private Key of recipient
|
||||
KeySym() []byte // Key associated with the Topic
|
||||
}
|
||||
|
||||
// MessageStore defines the interface for a temporary message store.
|
||||
type MessageStore interface {
|
||||
Add(ReceivedMessage) error
|
||||
Pop() ([]ReceivedMessage, error)
|
||||
}
|
32
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/mailserver.go
generated
vendored
Normal file
32
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/mailserver.go
generated
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
package whispertypes
|
||||
|
||||
import statusproto "github.com/status-im/status-protocol-go/types"
|
||||
|
||||
// MailServerResponse is the response payload sent by the mailserver
|
||||
type MailServerResponse struct {
|
||||
LastEnvelopeHash statusproto.Hash
|
||||
Cursor []byte
|
||||
Error error
|
||||
}
|
||||
|
||||
// SyncMailRequest contains details which envelopes should be synced
|
||||
// between Mail Servers.
|
||||
type SyncMailRequest struct {
|
||||
// Lower is a lower bound of time range for which messages are requested.
|
||||
Lower uint32
|
||||
// Upper is a lower bound of time range for which messages are requested.
|
||||
Upper uint32
|
||||
// Bloom is a bloom filter to filter envelopes.
|
||||
Bloom []byte
|
||||
// Limit is the max number of envelopes to return.
|
||||
Limit uint32
|
||||
// Cursor is used for pagination of the results.
|
||||
Cursor []byte
|
||||
}
|
||||
|
||||
// SyncEventResponse is a response from the Mail Server
|
||||
// form which the peer received envelopes.
|
||||
type SyncEventResponse struct {
|
||||
Cursor []byte
|
||||
Error string
|
||||
}
|
10
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/negotiated_secret.go
generated
vendored
Normal file
10
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/negotiated_secret.go
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
package whispertypes
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
)
|
||||
|
||||
type NegotiatedSecret struct {
|
||||
PublicKey *ecdsa.PublicKey
|
||||
Key []byte
|
||||
}
|
11
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/node.go
generated
vendored
Normal file
11
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/node.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package whispertypes
|
||||
|
||||
import "fmt"
|
||||
|
||||
// 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[:])
|
||||
}
|
6
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/received_message.go
generated
vendored
Normal file
6
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/received_message.go
generated
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
package whispertypes
|
||||
|
||||
// ReceivedMessage represents a data packet to be received through the
|
||||
// Whisper protocol and successfully decrypted.
|
||||
type ReceivedMessage interface {
|
||||
}
|
67
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/rpc.go
generated
vendored
Normal file
67
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/rpc.go
generated
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
package whispertypes
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
// NewMessage represents a new whisper message that is posted through the RPC.
|
||||
type NewMessage struct {
|
||||
SymKeyID string `json:"symKeyID"`
|
||||
PublicKey []byte `json:"pubKey"`
|
||||
Sig string `json:"sig"`
|
||||
TTL uint32 `json:"ttl"`
|
||||
Topic TopicType `json:"topic"`
|
||||
Payload []byte `json:"payload"`
|
||||
Padding []byte `json:"padding"`
|
||||
PowTime uint32 `json:"powTime"`
|
||||
PowTarget float64 `json:"powTarget"`
|
||||
TargetPeer string `json:"targetPeer"`
|
||||
}
|
||||
|
||||
// Message is the RPC representation of a whisper message.
|
||||
type Message struct {
|
||||
Sig []byte `json:"sig,omitempty"`
|
||||
TTL uint32 `json:"ttl"`
|
||||
Timestamp uint32 `json:"timestamp"`
|
||||
Topic TopicType `json:"topic"`
|
||||
Payload []byte `json:"payload"`
|
||||
Padding []byte `json:"padding"`
|
||||
PoW float64 `json:"pow"`
|
||||
Hash []byte `json:"hash"`
|
||||
Dst []byte `json:"recipientPublicKey,omitempty"`
|
||||
P2P bool `json:"bool,omitempty"`
|
||||
}
|
||||
|
||||
// Criteria holds various filter options for inbound messages.
|
||||
type Criteria struct {
|
||||
SymKeyID string `json:"symKeyID"`
|
||||
PrivateKeyID string `json:"privateKeyID"`
|
||||
Sig []byte `json:"sig"`
|
||||
MinPow float64 `json:"minPow"`
|
||||
Topics []TopicType `json:"topics"`
|
||||
AllowP2P bool `json:"allowP2P"`
|
||||
}
|
||||
|
||||
// PublicWhisperAPI provides the whisper RPC service that can be
|
||||
// use publicly without security implications.
|
||||
type PublicWhisperAPI interface {
|
||||
// AddPrivateKey imports the given private key.
|
||||
AddPrivateKey(ctx context.Context, privateKey statusproto.HexBytes) (string, error)
|
||||
// GenerateSymKeyFromPassword derives a key from the given password, stores it, and returns its ID.
|
||||
GenerateSymKeyFromPassword(ctx context.Context, passwd string) (string, error)
|
||||
// DeleteKeyPair removes the key with the given key if it exists.
|
||||
DeleteKeyPair(ctx context.Context, key string) (bool, error)
|
||||
|
||||
// Post posts a message on the Whisper network.
|
||||
// returns the hash of the message in case of success.
|
||||
Post(ctx context.Context, req NewMessage) ([]byte, error)
|
||||
|
||||
// NewMessageFilter creates a new filter that can be used to poll for
|
||||
// (new) messages that satisfy the given criteria.
|
||||
NewMessageFilter(req Criteria) (string, error)
|
||||
// GetFilterMessages returns the messages that match the filter criteria and
|
||||
// are received between the last poll and now.
|
||||
GetFilterMessages(id string) ([]*Message, error)
|
||||
}
|
88
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/topic.go
generated
vendored
Normal file
88
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/topic.go
generated
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
package whispertypes
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// TopicLength is the expected length of the topic, in bytes
|
||||
TopicLength = 4
|
||||
BloomFilterSize = 64 // in bytes
|
||||
)
|
||||
|
||||
// TopicType represents a cryptographically secure, probabilistic partial
|
||||
// classifications of a message, determined as the first (left) 4 bytes of the
|
||||
// SHA3 hash of some arbitrary data given by the original author of the message.
|
||||
type TopicType [TopicLength]byte
|
||||
|
||||
// BytesToTopic converts from the byte array representation of a topic
|
||||
// into the TopicType type.
|
||||
func BytesToTopic(b []byte) (t TopicType) {
|
||||
sz := TopicLength
|
||||
if x := len(b); x < TopicLength {
|
||||
sz = x
|
||||
}
|
||||
for i := 0; i < sz; i++ {
|
||||
t[i] = b[i]
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// String converts a topic byte array to a string representation.
|
||||
func (t *TopicType) String() string {
|
||||
return statusproto.EncodeHex(t[:])
|
||||
}
|
||||
|
||||
// MarshalText returns the hex representation of t.
|
||||
func (t TopicType) MarshalText() ([]byte, error) {
|
||||
return statusproto.HexBytes(t[:]).MarshalText()
|
||||
}
|
||||
|
||||
// UnmarshalText parses a hex representation to a topic.
|
||||
func (t *TopicType) UnmarshalText(input []byte) error {
|
||||
return hexutil.UnmarshalFixedText("Topic", input, t[:])
|
||||
}
|
||||
|
||||
// TopicToBloom converts the topic (4 bytes) to the bloom filter (64 bytes)
|
||||
func TopicToBloom(topic TopicType) []byte {
|
||||
b := make([]byte, BloomFilterSize)
|
||||
var index [3]int
|
||||
for j := 0; j < 3; j++ {
|
||||
index[j] = int(topic[j])
|
||||
if (topic[3] & (1 << uint(j))) != 0 {
|
||||
index[j] += 256
|
||||
}
|
||||
}
|
||||
|
||||
for j := 0; j < 3; j++ {
|
||||
byteIndex := index[j] / 8
|
||||
bitIndex := index[j] % 8
|
||||
b[byteIndex] = (1 << uint(bitIndex))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func BloomFilterMatch(filter, sample []byte) bool {
|
||||
if filter == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
for i := 0; i < BloomFilterSize; i++ {
|
||||
f := filter[i]
|
||||
s := sample[i]
|
||||
if (f | s) != f {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func MakeFullNodeBloom() []byte {
|
||||
bloom := make([]byte, BloomFilterSize)
|
||||
for i := 0; i < BloomFilterSize; i++ {
|
||||
bloom[i] = 0xFF
|
||||
}
|
||||
return bloom
|
||||
}
|
61
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/whisper.go
generated
vendored
Normal file
61
vendor/github.com/status-im/status-protocol-go/transport/whisper/types/whisper.go
generated
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
package whispertypes
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Whisper represents a dark communication interface through the Ethereum
|
||||
// network, using its very own P2P communication layer.
|
||||
type Whisper interface {
|
||||
PublicWhisperAPI() PublicWhisperAPI
|
||||
NewMessageStore() MessageStore
|
||||
|
||||
// MinPow returns the PoW value required by this node.
|
||||
MinPow() float64
|
||||
// BloomFilter returns the aggregated bloom filter for all the topics of interest.
|
||||
// The nodes are required to send only messages that match the advertised bloom filter.
|
||||
// If a message does not match the bloom, it will tantamount to spam, and the peer will
|
||||
// be disconnected.
|
||||
BloomFilter() []byte
|
||||
// SetTimeSource assigns a particular source of time to a whisper object.
|
||||
SetTimeSource(timesource func() time.Time)
|
||||
// GetCurrentTime returns current time.
|
||||
GetCurrentTime() time.Time
|
||||
|
||||
// SelectedKeyPairID returns the id of currently selected key pair.
|
||||
// It helps distinguish between different users w/o exposing the user identity itself.
|
||||
SelectedKeyPairID() string
|
||||
// GetPrivateKey retrieves the private key of the specified identity.
|
||||
GetPrivateKey(id string) (*ecdsa.PrivateKey, error)
|
||||
|
||||
SubscribeEnvelopeEvents(events chan<- EnvelopeEvent) Subscription
|
||||
|
||||
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
|
||||
AddKeyPair(key *ecdsa.PrivateKey) (string, error)
|
||||
// DeleteKeyPair deletes the specified key if it exists.
|
||||
DeleteKeyPair(key string) bool
|
||||
// SelectKeyPair adds cryptographic identity, and makes sure
|
||||
// that it is the only private key known to the node.
|
||||
SelectKeyPair(key *ecdsa.PrivateKey) error
|
||||
AddSymKeyDirect(key []byte) (string, error)
|
||||
AddSymKeyFromPassword(password string) (string, error)
|
||||
DeleteSymKey(id string) bool
|
||||
GetSymKey(id string) ([]byte, error)
|
||||
|
||||
Subscribe(f Filter) (string, error)
|
||||
GetFilter(id string) Filter
|
||||
Unsubscribe(id string) error
|
||||
|
||||
CreateFilterWrapper(keyAsym *ecdsa.PrivateKey, keySym []byte, pow float64, topics [][]byte, messages MessageStore) Filter
|
||||
|
||||
// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
|
||||
// which is known to implement MailServer interface, and is supposed to process this
|
||||
// request and respond with a number of peer-to-peer messages (possibly expired),
|
||||
// which are not supposed to be forwarded any further.
|
||||
// The whisper protocol is agnostic of the format and contents of envelope.
|
||||
// A timeout of 0 never expires.
|
||||
RequestHistoricMessagesWithTimeout(peerID []byte, envelope Envelope, timeout time.Duration) error
|
||||
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
|
||||
SyncMessages(peerID []byte, req SyncMailRequest) error
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package whisper
|
||||
|
||||
import (
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
)
|
||||
|
||||
type RequestOptions struct {
|
||||
Topics []whisper.TopicType
|
||||
Topics []whispertypes.TopicType
|
||||
Password string
|
||||
Limit int
|
||||
From int64 // in seconds
|
||||
|
@ -16,8 +16,8 @@ const (
|
|||
defaultPowTime = 1
|
||||
)
|
||||
|
||||
func DefaultWhisperMessage() whisper.NewMessage {
|
||||
msg := whisper.NewMessage{}
|
||||
func DefaultWhisperMessage() whispertypes.NewMessage {
|
||||
msg := whispertypes.NewMessage{}
|
||||
|
||||
msg.TTL = 10
|
||||
msg.PowTarget = 0.002
|
||||
|
|
108
vendor/github.com/status-im/status-protocol-go/transport/whisper/whisper_service.go
generated
vendored
108
vendor/github.com/status-im/status-protocol-go/transport/whisper/whisper_service.go
generated
vendored
|
@ -7,11 +7,12 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/pkg/errors"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
"go.uber.org/zap"
|
||||
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -20,7 +21,7 @@ var (
|
|||
)
|
||||
|
||||
type whisperServiceKeysManager struct {
|
||||
shh *whisper.Whisper
|
||||
shh whispertypes.Whisper
|
||||
|
||||
// Identity of the current user.
|
||||
privateKey *ecdsa.PrivateKey
|
||||
|
@ -67,8 +68,8 @@ func SetGenericDiscoveryTopicSupport(val bool) Option {
|
|||
|
||||
// WhisperServiceTransport is a transport based on Whisper service.
|
||||
type WhisperServiceTransport struct {
|
||||
shh *whisper.Whisper
|
||||
shhAPI *whisper.PublicWhisperAPI // only PublicWhisperAPI implements logic to send messages
|
||||
shh whispertypes.Whisper
|
||||
shhAPI whispertypes.PublicWhisperAPI // only PublicWhisperAPI implements logic to send messages
|
||||
keysManager *whisperServiceKeysManager
|
||||
filters *filtersManager
|
||||
logger *zap.Logger
|
||||
|
@ -79,9 +80,9 @@ type WhisperServiceTransport struct {
|
|||
genericDiscoveryTopicEnabled bool
|
||||
}
|
||||
|
||||
// NewWhisperService returns a new WhisperServiceTransport.
|
||||
// NewWhisperServiceTransport returns a new WhisperServiceTransport.
|
||||
func NewWhisperServiceTransport(
|
||||
shh *whisper.Whisper,
|
||||
shh whispertypes.Whisper,
|
||||
privateKey *ecdsa.PrivateKey,
|
||||
db *sql.DB,
|
||||
mailservers []string,
|
||||
|
@ -96,13 +97,17 @@ func NewWhisperServiceTransport(
|
|||
|
||||
var envelopesMonitor *EnvelopesMonitor
|
||||
if envelopesMonitorConfig != nil {
|
||||
envelopesMonitor = NewEnvelopesMonitor(shh, envelopesMonitorConfig)
|
||||
envelopesMonitor = NewEnvelopesMonitor(shh, *envelopesMonitorConfig)
|
||||
envelopesMonitor.Start()
|
||||
}
|
||||
|
||||
var shhAPI whispertypes.PublicWhisperAPI
|
||||
if shh != nil {
|
||||
shhAPI = shh.PublicWhisperAPI()
|
||||
}
|
||||
t := &WhisperServiceTransport{
|
||||
shh: shh,
|
||||
shhAPI: whisper.NewPublicWhisperAPI(shh),
|
||||
shhAPI: shhAPI,
|
||||
envelopesMonitor: envelopesMonitor,
|
||||
keysManager: &whisperServiceKeysManager{
|
||||
shh: shh,
|
||||
|
@ -145,7 +150,7 @@ func (a *WhisperServiceTransport) Reset() error {
|
|||
return a.filters.Reset()
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) ProcessNegotiatedSecret(secret NegotiatedSecret) (*Filter, error) {
|
||||
func (a *WhisperServiceTransport) ProcessNegotiatedSecret(secret whispertypes.NegotiatedSecret) (*Filter, error) {
|
||||
filter, err := a.filters.LoadNegotiated(secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -181,7 +186,7 @@ func (a *WhisperServiceTransport) LeavePrivate(publicKey *ecdsa.PublicKey) error
|
|||
}
|
||||
|
||||
type Message struct {
|
||||
Message *whisper.ReceivedMessage // TODO: should it be whisper.Message?
|
||||
Message *whispertypes.Message
|
||||
Public bool
|
||||
}
|
||||
|
||||
|
@ -189,12 +194,12 @@ func (a *WhisperServiceTransport) RetrieveAllMessages() ([]Message, error) {
|
|||
var messages []Message
|
||||
|
||||
for _, filter := range a.filters.Filters() {
|
||||
f := a.shh.GetFilter(filter.FilterID)
|
||||
if f == nil {
|
||||
return nil, errors.New("failed to return a filter")
|
||||
filterMsgs, err := a.shhAPI.GetFilterMessages(filter.FilterID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, m := range f.Retrieve() {
|
||||
for _, m := range filterMsgs {
|
||||
messages = append(messages, Message{
|
||||
Message: m,
|
||||
Public: filter.IsPublic(),
|
||||
|
@ -205,36 +210,31 @@ func (a *WhisperServiceTransport) RetrieveAllMessages() ([]Message, error) {
|
|||
return messages, nil
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) RetrievePublicMessages(chatID string) ([]*whisper.ReceivedMessage, error) {
|
||||
func (a *WhisperServiceTransport) RetrievePublicMessages(chatID string) ([]*whispertypes.Message, error) {
|
||||
filter, err := a.filters.LoadPublic(chatID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f := a.shh.GetFilter(filter.FilterID)
|
||||
if f == nil {
|
||||
return nil, errors.New("failed to return a filter")
|
||||
}
|
||||
|
||||
return f.Retrieve(), nil
|
||||
return a.shhAPI.GetFilterMessages(filter.FilterID)
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) RetrievePrivateMessages(publicKey *ecdsa.PublicKey) ([]*whisper.ReceivedMessage, error) {
|
||||
func (a *WhisperServiceTransport) RetrievePrivateMessages(publicKey *ecdsa.PublicKey) ([]*whispertypes.Message, error) {
|
||||
chats := a.filters.FiltersByPublicKey(publicKey)
|
||||
discoveryChats, err := a.filters.Init(nil, nil, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []*whisper.ReceivedMessage
|
||||
var result []*whispertypes.Message
|
||||
|
||||
for _, chat := range append(chats, discoveryChats...) {
|
||||
f := a.shh.GetFilter(chat.FilterID)
|
||||
if f == nil {
|
||||
return nil, errors.New("failed to return a filter")
|
||||
filterMsgs, err := a.shhAPI.GetFilterMessages(chat.FilterID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, f.Retrieve()...)
|
||||
result = append(result, filterMsgs...)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
@ -242,35 +242,19 @@ func (a *WhisperServiceTransport) RetrievePrivateMessages(publicKey *ecdsa.Publi
|
|||
|
||||
// DEPRECATED
|
||||
// Use RetrieveAllMessages instead.
|
||||
func (a *WhisperServiceTransport) RetrieveRawAll() (map[Filter][]*whisper.ReceivedMessage, error) {
|
||||
result := make(map[Filter][]*whisper.ReceivedMessage)
|
||||
|
||||
allFilters := a.filters.Filters()
|
||||
for _, filter := range allFilters {
|
||||
f := a.shh.GetFilter(filter.FilterID)
|
||||
if f == nil {
|
||||
return nil, errors.New("failed to return a filter")
|
||||
}
|
||||
|
||||
result[*filter] = append(result[*filter], f.Retrieve()...)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
func (a *WhisperServiceTransport) RetrieveRawAll() (map[Filter][]*whispertypes.Message, error) {
|
||||
return nil, errors.New("not implemented")
|
||||
}
|
||||
|
||||
// DEPRECATED
|
||||
func (a *WhisperServiceTransport) RetrieveRaw(filterID string) ([]*whisper.ReceivedMessage, error) {
|
||||
f := a.shh.GetFilter(filterID)
|
||||
if f == nil {
|
||||
return nil, errors.New("failed to return a filter")
|
||||
}
|
||||
return f.Retrieve(), nil
|
||||
func (a *WhisperServiceTransport) RetrieveRaw(filterID string) ([]*whispertypes.Message, error) {
|
||||
return a.shhAPI.GetFilterMessages(filterID)
|
||||
}
|
||||
|
||||
// SendPublic sends a new message using the Whisper service.
|
||||
// For public filters, chat name is used as an ID as well as
|
||||
// a topic.
|
||||
func (a *WhisperServiceTransport) SendPublic(ctx context.Context, newMessage *whisper.NewMessage, chatName string) ([]byte, error) {
|
||||
func (a *WhisperServiceTransport) SendPublic(ctx context.Context, newMessage *whispertypes.NewMessage, chatName string) ([]byte, error) {
|
||||
if err := a.addSig(newMessage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -281,17 +265,17 @@ func (a *WhisperServiceTransport) SendPublic(ctx context.Context, newMessage *wh
|
|||
}
|
||||
|
||||
newMessage.SymKeyID = filter.SymKeyID
|
||||
newMessage.Topic = filter.Topic
|
||||
newMessage.Topic = whispertypes.TopicType(filter.Topic)
|
||||
|
||||
return a.shhAPI.Post(ctx, *newMessage)
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) SendPrivateWithSharedSecret(ctx context.Context, newMessage *whisper.NewMessage, publicKey *ecdsa.PublicKey, secret []byte) ([]byte, error) {
|
||||
func (a *WhisperServiceTransport) SendPrivateWithSharedSecret(ctx context.Context, newMessage *whispertypes.NewMessage, publicKey *ecdsa.PublicKey, secret []byte) ([]byte, error) {
|
||||
if err := a.addSig(newMessage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filter, err := a.filters.LoadNegotiated(NegotiatedSecret{
|
||||
filter, err := a.filters.LoadNegotiated(whispertypes.NegotiatedSecret{
|
||||
PublicKey: publicKey,
|
||||
Key: secret,
|
||||
})
|
||||
|
@ -300,13 +284,13 @@ func (a *WhisperServiceTransport) SendPrivateWithSharedSecret(ctx context.Contex
|
|||
}
|
||||
|
||||
newMessage.SymKeyID = filter.SymKeyID
|
||||
newMessage.Topic = filter.Topic
|
||||
newMessage.Topic = whispertypes.TopicType(filter.Topic)
|
||||
newMessage.PublicKey = nil
|
||||
|
||||
return a.shhAPI.Post(ctx, *newMessage)
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) SendPrivateWithPartitioned(ctx context.Context, newMessage *whisper.NewMessage, publicKey *ecdsa.PublicKey) ([]byte, error) {
|
||||
func (a *WhisperServiceTransport) SendPrivateWithPartitioned(ctx context.Context, newMessage *whispertypes.NewMessage, publicKey *ecdsa.PublicKey) ([]byte, error) {
|
||||
if err := a.addSig(newMessage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -316,13 +300,13 @@ func (a *WhisperServiceTransport) SendPrivateWithPartitioned(ctx context.Context
|
|||
return nil, err
|
||||
}
|
||||
|
||||
newMessage.Topic = filter.Topic
|
||||
newMessage.Topic = whispertypes.TopicType(filter.Topic)
|
||||
newMessage.PublicKey = crypto.FromECDSAPub(publicKey)
|
||||
|
||||
return a.shhAPI.Post(ctx, *newMessage)
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) SendPrivateOnDiscovery(ctx context.Context, newMessage *whisper.NewMessage, publicKey *ecdsa.PublicKey) ([]byte, error) {
|
||||
func (a *WhisperServiceTransport) SendPrivateOnDiscovery(ctx context.Context, newMessage *whispertypes.NewMessage, publicKey *ecdsa.PublicKey) ([]byte, error) {
|
||||
if err := a.addSig(newMessage); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -333,7 +317,7 @@ func (a *WhisperServiceTransport) SendPrivateOnDiscovery(ctx context.Context, ne
|
|||
// TODO: change this anyway, it should be explicit
|
||||
// and idempotent.
|
||||
|
||||
newMessage.Topic = whisper.BytesToTopic(
|
||||
newMessage.Topic = whispertypes.BytesToTopic(
|
||||
ToTopic(discoveryTopic),
|
||||
)
|
||||
newMessage.PublicKey = crypto.FromECDSAPub(publicKey)
|
||||
|
@ -341,7 +325,7 @@ func (a *WhisperServiceTransport) SendPrivateOnDiscovery(ctx context.Context, ne
|
|||
return a.shhAPI.Post(ctx, *newMessage)
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) addSig(newMessage *whisper.NewMessage) error {
|
||||
func (a *WhisperServiceTransport) addSig(newMessage *whispertypes.NewMessage) error {
|
||||
sigID, err := a.keysManager.AddOrGetKeyPair(a.keysManager.privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -350,9 +334,9 @@ func (a *WhisperServiceTransport) addSig(newMessage *whisper.NewMessage) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (a *WhisperServiceTransport) Track(identifiers [][]byte, hash []byte, newMessage whisper.NewMessage) {
|
||||
func (a *WhisperServiceTransport) Track(identifiers [][]byte, hash []byte, newMessage *whispertypes.NewMessage) {
|
||||
if a.envelopesMonitor != nil {
|
||||
a.envelopesMonitor.Add(identifiers, common.BytesToHash(hash), newMessage)
|
||||
a.envelopesMonitor.Add(identifiers, statusproto.BytesToHash(hash), *newMessage)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,10 +369,10 @@ type MessagesRequest struct {
|
|||
|
||||
// Topic is a regular Whisper topic.
|
||||
// DEPRECATED
|
||||
Topic whisper.TopicType `json:"topic"`
|
||||
Topic whispertypes.TopicType `json:"topic"`
|
||||
|
||||
// Topics is a list of Whisper topics.
|
||||
Topics []whisper.TopicType `json:"topics"`
|
||||
Topics []whispertypes.TopicType `json:"topics"`
|
||||
|
||||
// SymKeyID is an ID of a symmetric key to authenticate to MailServer.
|
||||
// It's derived from MailServer password.
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/types.go
|
||||
|
||||
package statusproto
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
const (
|
||||
// HashLength is the expected length of the hash
|
||||
HashLength = 32
|
||||
)
|
||||
|
||||
// Hash represents the 32 byte Keccak256 hash of arbitrary data.
|
||||
type Hash [HashLength]byte
|
||||
|
||||
// Encode encodes b as a hex string with 0x prefix.
|
||||
func encode(b []byte) string {
|
||||
enc := make([]byte, len(b)*2+2)
|
||||
copy(enc, "0x")
|
||||
hex.Encode(enc[2:], b)
|
||||
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.
|
||||
// s may be prefixed with "0x".
|
||||
func FromHex(s string) []byte {
|
||||
if has0xPrefix(s) {
|
||||
s = s[2:]
|
||||
}
|
||||
if len(s)%2 == 1 {
|
||||
s = "0" + s
|
||||
}
|
||||
return Hex2Bytes(s)
|
||||
}
|
||||
|
||||
// HexToHash sets byte representation of s to hash.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
|
||||
|
||||
// Hex converts a hash to a hex string.
|
||||
func (h *Hash) Hex() string { return encode(h[:]) }
|
||||
|
||||
// Bytes gets the byte representation of the underlying hash.
|
||||
func (h Hash) Bytes() []byte { return h[:] }
|
||||
|
||||
// String implements the stringer interface and is used also by the logger when
|
||||
// doing full logging into a file.
|
||||
func (h *Hash) String() string {
|
||||
return h.Hex()
|
||||
}
|
||||
|
||||
// SetBytes sets the hash to the value of b.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func (h *Hash) SetBytes(b []byte) {
|
||||
if len(b) > len(h) {
|
||||
b = b[len(b)-HashLength:]
|
||||
}
|
||||
|
||||
copy(h[HashLength-len(b):], b)
|
||||
}
|
||||
|
||||
// BytesToHash sets b to hash.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func BytesToHash(b []byte) Hash {
|
||||
var h Hash
|
||||
h.SetBytes(b)
|
||||
return h
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/hexutil.go
|
||||
|
||||
package statusproto
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var (
|
||||
bytesT = reflect.TypeOf(HexBytes(nil))
|
||||
)
|
||||
|
||||
// HexBytes marshals/unmarshals as a JSON string with 0x prefix.
|
||||
// The empty slice marshals as "0x".
|
||||
type HexBytes []byte
|
||||
|
||||
// MarshalText implements encoding.TextMarshaler
|
||||
func (b HexBytes) MarshalText() ([]byte, error) {
|
||||
result := make([]byte, len(b)*2+2)
|
||||
copy(result, `0x`)
|
||||
hex.Encode(result[2:], b)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler.
|
||||
func (b *HexBytes) UnmarshalJSON(input []byte) error {
|
||||
if !isString(input) {
|
||||
return errNonString(bytesT)
|
||||
}
|
||||
return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT)
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
// Code extracted from vendor/github.com/ethereum/go-ethereum/common/hexutil/json.go
|
||||
|
||||
package statusproto
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
badNibble = ^uint64(0)
|
||||
uintBits = 32 << (uint64(^uint(0)) >> 63)
|
||||
)
|
||||
|
||||
// Errors
|
||||
var (
|
||||
ErrEmptyString = &decError{"empty hex string"}
|
||||
ErrSyntax = &decError{"invalid hex string"}
|
||||
ErrMissingPrefix = &decError{"hex string without 0x prefix"}
|
||||
ErrOddLength = &decError{"hex string of odd length"}
|
||||
ErrEmptyNumber = &decError{"hex string \"0x\""}
|
||||
ErrLeadingZero = &decError{"hex number with leading zero digits"}
|
||||
ErrUint64Range = &decError{"hex number > 64 bits"}
|
||||
ErrUintRange = &decError{fmt.Sprintf("hex number > %d bits", uintBits)}
|
||||
ErrBig256Range = &decError{"hex number > 256 bits"}
|
||||
)
|
||||
|
||||
type decError struct{ msg string }
|
||||
|
||||
func (err decError) Error() string { return err.msg }
|
||||
|
||||
func decodeNibble(in byte) uint64 {
|
||||
switch {
|
||||
case in >= '0' && in <= '9':
|
||||
return uint64(in - '0')
|
||||
case in >= 'A' && in <= 'F':
|
||||
return uint64(in - 'A' + 10)
|
||||
case in >= 'a' && in <= 'f':
|
||||
return uint64(in - 'a' + 10)
|
||||
default:
|
||||
return badNibble
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (b *HexBytes) UnmarshalText(input []byte) error {
|
||||
raw, err := checkText(input, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dec := make([]byte, len(raw)/2)
|
||||
if _, err = hex.Decode(dec, raw); err != nil {
|
||||
err = mapError(err)
|
||||
} else {
|
||||
*b = dec
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UnmarshalFixedHexText decodes the input as a string with 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 UnmarshalFixedHexText(typname string, input, out []byte) error {
|
||||
raw, err := checkText(input, true)
|
||||
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
|
||||
}
|
||||
}
|
||||
_, err = hex.Decode(out, raw)
|
||||
return err
|
||||
}
|
||||
|
||||
// String returns the hex encoding of b.
|
||||
func (b HexBytes) String() string {
|
||||
return EncodeHex(b)
|
||||
}
|
||||
|
||||
// EncodeHex encodes b as a hex string with 0x prefix.
|
||||
func EncodeHex(b []byte) string {
|
||||
enc := make([]byte, len(b)*2+2)
|
||||
copy(enc, "0x")
|
||||
hex.Encode(enc[2:], b)
|
||||
return string(enc)
|
||||
}
|
||||
|
||||
// DecodeHex decodes a hex string with 0x prefix.
|
||||
func DecodeHex(input string) ([]byte, error) {
|
||||
if len(input) == 0 {
|
||||
return nil, ErrEmptyString
|
||||
}
|
||||
if !has0xPrefix(input) {
|
||||
return nil, ErrMissingPrefix
|
||||
}
|
||||
b, err := hex.DecodeString(input[2:])
|
||||
if err != nil {
|
||||
err = mapError(err)
|
||||
}
|
||||
return b, err
|
||||
}
|
||||
|
||||
// MustDecodeHex decodes a hex string with 0x prefix. It panics for invalid input.
|
||||
func MustDecodeHex(input string) []byte {
|
||||
dec, err := DecodeHex(input)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return dec
|
||||
}
|
||||
|
||||
func isString(input []byte) bool {
|
||||
return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"'
|
||||
}
|
||||
|
||||
func bytesHave0xPrefix(input []byte) bool {
|
||||
return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X')
|
||||
}
|
||||
|
||||
func checkText(input []byte, wantPrefix bool) ([]byte, error) {
|
||||
if len(input) == 0 {
|
||||
return nil, nil // empty strings are allowed
|
||||
}
|
||||
if bytesHave0xPrefix(input) {
|
||||
input = input[2:]
|
||||
} else if wantPrefix {
|
||||
return nil, ErrMissingPrefix
|
||||
}
|
||||
if len(input)%2 != 0 {
|
||||
return nil, ErrOddLength
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func mapError(err error) error {
|
||||
if err, ok := err.(*strconv.NumError); ok {
|
||||
switch err.Err {
|
||||
case strconv.ErrRange:
|
||||
return ErrUint64Range
|
||||
case strconv.ErrSyntax:
|
||||
return ErrSyntax
|
||||
}
|
||||
}
|
||||
if _, ok := err.(hex.InvalidByteError); ok {
|
||||
return ErrSyntax
|
||||
}
|
||||
if err == hex.ErrLength {
|
||||
return ErrOddLength
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func wrapTypeError(err error, typ reflect.Type) error {
|
||||
if _, ok := err.(*decError); ok {
|
||||
return &json.UnmarshalTypeError{Value: err.Error(), Type: typ}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func errNonString(typ reflect.Type) error {
|
||||
return &json.UnmarshalTypeError{Value: "non-string", Type: typ}
|
||||
}
|
192
vendor/github.com/status-im/status-protocol-go/v1/membership_update_message.go
generated
vendored
192
vendor/github.com/status-im/status-protocol-go/v1/membership_update_message.go
generated
vendored
|
@ -1,6 +1,24 @@
|
|||
package statusproto
|
||||
|
||||
import "bytes"
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/status-im/status-protocol-go/crypto"
|
||||
)
|
||||
|
||||
const (
|
||||
MembershipUpdateChatCreated = "chat-created"
|
||||
MembershipUpdateNameChanged = "name-changed"
|
||||
MembershipUpdateMembersAdded = "members-added"
|
||||
MembershipUpdateMemberJoined = "member-joined"
|
||||
MembershipUpdateMemberRemoved = "member-removed"
|
||||
MembershipUpdateAdminsAdded = "admins-added"
|
||||
MembershipUpdateAdminRemoved = "admin-removed"
|
||||
)
|
||||
|
||||
// MembershipUpdateMessage is a message used to propagate information
|
||||
// about group membership changes.
|
||||
|
@ -18,6 +36,34 @@ type MembershipUpdate struct {
|
|||
Events []MembershipUpdateEvent `json:"events"`
|
||||
}
|
||||
|
||||
// Sign creates a signature from MembershipUpdateEvents
|
||||
// and updates MembershipUpdate's signature.
|
||||
// It follows the algorithm describe in the spec:
|
||||
// https://github.com/status-im/specs/blob/master/status-group-chats-spec.md#signature.
|
||||
func (u *MembershipUpdate) Sign(identity *ecdsa.PrivateKey) error {
|
||||
sort.Slice(u.Events, func(i, j int) bool {
|
||||
return u.Events[i].ClockValue < u.Events[j].ClockValue
|
||||
})
|
||||
tuples := make([]interface{}, len(u.Events))
|
||||
for idx, event := range u.Events {
|
||||
tuples[idx] = tupleMembershipUpdateEvent(event)
|
||||
}
|
||||
structureToSign := []interface{}{
|
||||
tuples,
|
||||
u.ChatID,
|
||||
}
|
||||
data, err := json.Marshal(structureToSign)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
signature, err := crypto.SignBytesAsHex(data, identity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Signature = signature
|
||||
return nil
|
||||
}
|
||||
|
||||
type MembershipUpdateEvent struct {
|
||||
Type string `json:"type"`
|
||||
ClockValue int64 `json:"clockValue"`
|
||||
|
@ -26,6 +72,62 @@ type MembershipUpdateEvent struct {
|
|||
Name string `json:"name,omitempty"` // name of the group chat
|
||||
}
|
||||
|
||||
func NewChatCreatedEvent(name string, clock int64) MembershipUpdateEvent {
|
||||
return MembershipUpdateEvent{
|
||||
Type: MembershipUpdateChatCreated,
|
||||
Name: name,
|
||||
ClockValue: clock,
|
||||
}
|
||||
}
|
||||
|
||||
func NewNameChangedEvent(name string, clock int64) MembershipUpdateEvent {
|
||||
return MembershipUpdateEvent{
|
||||
Type: MembershipUpdateNameChanged,
|
||||
Name: name,
|
||||
ClockValue: clock,
|
||||
}
|
||||
}
|
||||
|
||||
func NewMembersAddedEvent(members []string, clock int64) MembershipUpdateEvent {
|
||||
return MembershipUpdateEvent{
|
||||
Type: MembershipUpdateMembersAdded,
|
||||
Members: members,
|
||||
ClockValue: clock,
|
||||
}
|
||||
}
|
||||
|
||||
func NewMemberJoinedEvent(member string, clock int64) MembershipUpdateEvent {
|
||||
return MembershipUpdateEvent{
|
||||
Type: MembershipUpdateMemberJoined,
|
||||
Member: member,
|
||||
ClockValue: clock,
|
||||
}
|
||||
}
|
||||
|
||||
func NewAdminsAddedEvent(admins []string, clock int64) MembershipUpdateEvent {
|
||||
return MembershipUpdateEvent{
|
||||
Type: MembershipUpdateAdminsAdded,
|
||||
Members: admins,
|
||||
ClockValue: clock,
|
||||
}
|
||||
}
|
||||
|
||||
func NewMemberRemovedEvent(member string, clock int64) MembershipUpdateEvent {
|
||||
return MembershipUpdateEvent{
|
||||
Type: MembershipUpdateMemberRemoved,
|
||||
Member: member,
|
||||
ClockValue: clock,
|
||||
}
|
||||
}
|
||||
|
||||
func NewAdminRemovedEvent(admin string, clock int64) MembershipUpdateEvent {
|
||||
return MembershipUpdateEvent{
|
||||
Type: MembershipUpdateAdminRemoved,
|
||||
Member: admin,
|
||||
ClockValue: clock,
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeMembershipUpdateMessage encodes a MembershipUpdateMessage using Transit serialization.
|
||||
func EncodeMembershipUpdateMessage(value MembershipUpdateMessage) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
|
@ -35,3 +137,91 @@ func EncodeMembershipUpdateMessage(value MembershipUpdateMessage) ([]byte, error
|
|||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var membershipUpdateEventFieldNamesCompat = map[string]string{
|
||||
"ClockValue": "clock-value",
|
||||
"Name": "name",
|
||||
"Type": "type",
|
||||
"Member": "member",
|
||||
"Members": "members",
|
||||
}
|
||||
|
||||
func tupleMembershipUpdateEvent(update MembershipUpdateEvent) [][]interface{} {
|
||||
// Sort all slices first.
|
||||
sort.Slice(update.Members, func(i, j int) bool {
|
||||
return update.Members[i] < update.Members[j]
|
||||
})
|
||||
v := reflect.ValueOf(update)
|
||||
result := make([][]interface{}, 0, v.NumField())
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
fieldName := v.Type().Field(i).Name
|
||||
if name, exists := membershipUpdateEventFieldNamesCompat[fieldName]; exists {
|
||||
fieldName = name
|
||||
}
|
||||
field := v.Field(i)
|
||||
if !isZeroValue(field) {
|
||||
result = append(result, []interface{}{fieldName, field.Interface()})
|
||||
}
|
||||
}
|
||||
// Sort the result lexicographically.
|
||||
// We know that the first item of a tuple is a string
|
||||
// because it's a field name.
|
||||
sort.Slice(result, func(i, j int) bool {
|
||||
return result[i][0].(string) < result[j][0].(string)
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
ChatID string
|
||||
Admins []string
|
||||
Contacts []string
|
||||
}
|
||||
|
||||
// ValidateEvent returns true if a given event is valid.
|
||||
func (g *Group) ValidateEvent(from string, event MembershipUpdateEvent) bool {
|
||||
switch event.Type {
|
||||
case MembershipUpdateChatCreated:
|
||||
return len(g.Admins) == 0 && len(g.Contacts) == 0
|
||||
case MembershipUpdateNameChanged:
|
||||
return stringSliceContains(g.Admins, from) && len(event.Name) > 0
|
||||
case MembershipUpdateMembersAdded:
|
||||
return stringSliceContains(g.Admins, from)
|
||||
case MembershipUpdateMemberJoined:
|
||||
return stringSliceContains(g.Contacts, from) && from == event.Member
|
||||
case MembershipUpdateMemberRemoved:
|
||||
// Member can remove themselves or admin can remove a member.
|
||||
return from == event.Member || (stringSliceContains(g.Admins, from) && !stringSliceContains(g.Admins, event.Member))
|
||||
case MembershipUpdateAdminsAdded:
|
||||
return stringSliceContains(g.Admins, from) && stringSliceSubset(event.Members, g.Contacts)
|
||||
case MembershipUpdateAdminRemoved:
|
||||
return stringSliceContains(g.Admins, from) && from == event.Member
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func stringSliceContains(slice []string, item string) bool {
|
||||
for _, s := range slice {
|
||||
if s == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func stringSliceSubset(subset []string, set []string) bool {
|
||||
for _, item1 := range set {
|
||||
var found bool
|
||||
for _, item2 := range subset {
|
||||
if item1 == item2 {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if found {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/pkg/errors"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -152,7 +152,7 @@ func EncodeMessage(value Message) ([]byte, error) {
|
|||
|
||||
// MessageID calculates the messageID from author's compressed public key
|
||||
// and not encrypted but encoded payload.
|
||||
func MessageID(author *ecdsa.PublicKey, data []byte) hexutil.Bytes {
|
||||
func MessageID(author *ecdsa.PublicKey, data []byte) statusproto.HexBytes {
|
||||
keyBytes := crypto.FromECDSAPub(author)
|
||||
return crypto.Keccak256(append(keyBytes, data...))
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"log"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/jinzhu/copier"
|
||||
|
@ -12,13 +11,14 @@ import (
|
|||
"github.com/status-im/status-protocol-go/applicationmetadata"
|
||||
"github.com/status-im/status-protocol-go/datasync"
|
||||
"github.com/status-im/status-protocol-go/encryption"
|
||||
whisper "github.com/status-im/whisper/whisperv6"
|
||||
whispertypes "github.com/status-im/status-protocol-go/transport/whisper/types"
|
||||
statusproto "github.com/status-im/status-protocol-go/types"
|
||||
)
|
||||
|
||||
// StatusMessage is any Status Protocol message.
|
||||
type StatusMessage struct {
|
||||
// TransportMessage is the parsed message received from the transport layer, i.e the input
|
||||
TransportMessage *whisper.Message
|
||||
TransportMessage *whispertypes.Message
|
||||
// ParsedMessage is the parsed message by the application layer, i.e the output
|
||||
ParsedMessage interface{}
|
||||
|
||||
|
@ -28,7 +28,7 @@ type StatusMessage struct {
|
|||
DecryptedPayload []byte
|
||||
|
||||
// ID is the canonical ID of the message
|
||||
ID hexutil.Bytes
|
||||
ID statusproto.HexBytes
|
||||
// Hash is the transport layer hash
|
||||
Hash []byte
|
||||
|
||||
|
@ -54,7 +54,7 @@ func (s *StatusMessage) Clone() (*StatusMessage, error) {
|
|||
return copy, err
|
||||
}
|
||||
|
||||
func (m *StatusMessage) HandleTransport(shhMessage *whisper.Message) error {
|
||||
func (m *StatusMessage) HandleTransport(shhMessage *whispertypes.Message) error {
|
||||
publicKey, err := crypto.UnmarshalPubkey(shhMessage.Sig)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get signature")
|
||||
|
|
11
vendor/github.com/status-im/status-protocol-go/v1/value_is_zero.go
generated
vendored
Normal file
11
vendor/github.com/status-im/status-protocol-go/v1/value_is_zero.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// +build go1.13
|
||||
|
||||
package statusproto
|
||||
|
||||
import "reflect"
|
||||
|
||||
// isZeroValue reports whether v is the zero value for its type.
|
||||
// It panics if the argument is invalid.
|
||||
func isZeroValue(v reflect.Value) bool {
|
||||
return v.IsZero()
|
||||
}
|
48
vendor/github.com/status-im/status-protocol-go/v1/value_is_zero_1_12.go
generated
vendored
Normal file
48
vendor/github.com/status-im/status-protocol-go/v1/value_is_zero_1_12.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
// +build !go1.13
|
||||
|
||||
package statusproto
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// isZeroValue reports whether v is the zero value for its type.
|
||||
// It panics if the argument is invalid.
|
||||
func isZeroValue(v reflect.Value) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return math.Float64bits(v.Float()) == 0
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
c := v.Complex()
|
||||
return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
|
||||
case reflect.Array:
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if !isZeroValue(v.Index(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
|
||||
return v.IsNil()
|
||||
case reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Struct:
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if !isZeroValue(v.Field(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
default:
|
||||
// This should never happens, but will act as a safeguard for
|
||||
// later, as a default value doesn't makes sense here.
|
||||
panic(&reflect.ValueError{Method: "reflect.Value.IsZero", Kind: v.Kind()})
|
||||
}
|
||||
}
|
|
@ -102,7 +102,7 @@ func (api *PublicWhisperAPI) SetBloomFilter(ctx context.Context, bloom hexutil.B
|
|||
// MarkTrustedPeer marks a peer trusted, which will allow it to send historic (expired) messages.
|
||||
// Note: This function is not adding new nodes, the node needs to exists as a peer.
|
||||
func (api *PublicWhisperAPI) MarkTrustedPeer(ctx context.Context, url string) (bool, error) {
|
||||
n, err := enode.ParseV4(url)
|
||||
n, err := enode.Parse(enode.ValidSchemes, url)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (hexutil.
|
|||
|
||||
// send to specific node (skip PoW check)
|
||||
if len(req.TargetPeer) > 0 {
|
||||
n, err := enode.ParseV4(req.TargetPeer)
|
||||
n, err := enode.Parse(enode.ValidSchemes, req.TargetPeer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse target peer: %s", err)
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
|
@ -65,7 +66,7 @@ const (
|
|||
signatureFlag = byte(4)
|
||||
|
||||
TopicLength = 4 // in bytes
|
||||
signatureLength = 65 // in bytes
|
||||
signatureLength = crypto.SignatureLength // in bytes
|
||||
aesKeyLength = 32 // in bytes
|
||||
aesNonceLength = 12 // in bytes; for more info please see cipher.gcmStandardNonceSize & aesgcm.NonceSize()
|
||||
keyIDSize = 32 // in bytes
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/crypto/ecies"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
|
@ -82,7 +81,7 @@ func (e *Envelope) Seal(options *MessageParams) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var target, bestBit int
|
||||
var target, bestLeadingZeros int
|
||||
if options.PoW < 0 {
|
||||
// target is not set - the function should run for a period
|
||||
// of time specified in WorkTime param. Since we can predict
|
||||
|
@ -92,19 +91,21 @@ func (e *Envelope) Seal(options *MessageParams) error {
|
|||
target = e.powToFirstBit(options.PoW)
|
||||
}
|
||||
|
||||
buf := make([]byte, 64)
|
||||
h := crypto.Keccak256(e.rlpWithoutNonce())
|
||||
copy(buf[:32], h)
|
||||
rlp := e.rlpWithoutNonce()
|
||||
buf := make([]byte, len(rlp)+8)
|
||||
copy(buf, rlp)
|
||||
asAnInt := new(big.Int)
|
||||
|
||||
finish := time.Now().Add(time.Duration(options.WorkTime) * time.Second).UnixNano()
|
||||
for nonce := uint64(0); time.Now().UnixNano() < finish; {
|
||||
for i := 0; i < 1024; i++ {
|
||||
binary.BigEndian.PutUint64(buf[56:], nonce)
|
||||
d := new(big.Int).SetBytes(crypto.Keccak256(buf))
|
||||
firstBit := math.FirstBitSet(d)
|
||||
if firstBit > bestBit {
|
||||
e.Nonce, bestBit = nonce, firstBit
|
||||
if target > 0 && bestBit >= target {
|
||||
binary.BigEndian.PutUint64(buf[len(rlp):], nonce)
|
||||
h := crypto.Keccak256(buf)
|
||||
asAnInt.SetBytes(h)
|
||||
leadingZeros := 256 - asAnInt.BitLen()
|
||||
if leadingZeros > bestLeadingZeros {
|
||||
e.Nonce, bestLeadingZeros = nonce, leadingZeros
|
||||
if target > 0 && bestLeadingZeros >= target {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +113,7 @@ func (e *Envelope) Seal(options *MessageParams) error {
|
|||
}
|
||||
}
|
||||
|
||||
if target > 0 && bestBit < target {
|
||||
if target > 0 && bestLeadingZeros < target {
|
||||
return fmt.Errorf("failed to reach the PoW target, specified pow time (%d seconds) was insufficient", options.WorkTime)
|
||||
}
|
||||
|
||||
|
@ -129,14 +130,14 @@ func (e *Envelope) PoW() float64 {
|
|||
}
|
||||
|
||||
func (e *Envelope) calculatePoW(diff uint32) {
|
||||
buf := make([]byte, 64)
|
||||
h := crypto.Keccak256(e.rlpWithoutNonce())
|
||||
copy(buf[:32], h)
|
||||
binary.BigEndian.PutUint64(buf[56:], e.Nonce)
|
||||
d := new(big.Int).SetBytes(crypto.Keccak256(buf))
|
||||
firstBit := math.FirstBitSet(d)
|
||||
x := gmath.Pow(2, float64(firstBit))
|
||||
x /= float64(e.size())
|
||||
rlp := e.rlpWithoutNonce()
|
||||
buf := make([]byte, len(rlp)+8)
|
||||
copy(buf, rlp)
|
||||
binary.BigEndian.PutUint64(buf[len(rlp):], e.Nonce)
|
||||
powHash := new(big.Int).SetBytes(crypto.Keccak256(buf))
|
||||
leadingZeroes := 256 - powHash.BitLen()
|
||||
x := gmath.Pow(2, float64(leadingZeroes))
|
||||
x /= float64(len(rlp))
|
||||
x /= float64(e.TTL + diff)
|
||||
e.pow = x
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ func (peer *Peer) handshake() error {
|
|||
}
|
||||
}
|
||||
|
||||
isRemotePeerLightNode, err := s.Bool()
|
||||
isRemotePeerLightNode, _ := s.Bool()
|
||||
if isRemotePeerLightNode && isLightNode && isRestrictedLightNodeConnection {
|
||||
return fmt.Errorf("peer [%x] is useless: two light client communication restricted", peer.ID())
|
||||
}
|
||||
|
|
|
@ -1,712 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
//go:generate go run gen.go
|
||||
//go:generate go run gen.go -test
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// identifier converts s to a Go exported identifier.
|
||||
// It converts "div" to "Div" and "accept-charset" to "AcceptCharset".
|
||||
func identifier(s string) string {
|
||||
b := make([]byte, 0, len(s))
|
||||
cap := true
|
||||
for _, c := range s {
|
||||
if c == '-' {
|
||||
cap = true
|
||||
continue
|
||||
}
|
||||
if cap && 'a' <= c && c <= 'z' {
|
||||
c -= 'a' - 'A'
|
||||
}
|
||||
cap = false
|
||||
b = append(b, byte(c))
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
var test = flag.Bool("test", false, "generate table_test.go")
|
||||
|
||||
func genFile(name string, buf *bytes.Buffer) {
|
||||
b, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := ioutil.WriteFile(name, b, 0644); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var all []string
|
||||
all = append(all, elements...)
|
||||
all = append(all, attributes...)
|
||||
all = append(all, eventHandlers...)
|
||||
all = append(all, extra...)
|
||||
sort.Strings(all)
|
||||
|
||||
// uniq - lists have dups
|
||||
w := 0
|
||||
for _, s := range all {
|
||||
if w == 0 || all[w-1] != s {
|
||||
all[w] = s
|
||||
w++
|
||||
}
|
||||
}
|
||||
all = all[:w]
|
||||
|
||||
if *test {
|
||||
var buf bytes.Buffer
|
||||
fmt.Fprintln(&buf, "// Code generated by go generate gen.go; DO NOT EDIT.\n")
|
||||
fmt.Fprintln(&buf, "//go:generate go run gen.go -test\n")
|
||||
fmt.Fprintln(&buf, "package atom\n")
|
||||
fmt.Fprintln(&buf, "var testAtomList = []string{")
|
||||
for _, s := range all {
|
||||
fmt.Fprintf(&buf, "\t%q,\n", s)
|
||||
}
|
||||
fmt.Fprintln(&buf, "}")
|
||||
|
||||
genFile("table_test.go", &buf)
|
||||
return
|
||||
}
|
||||
|
||||
// Find hash that minimizes table size.
|
||||
var best *table
|
||||
for i := 0; i < 1000000; i++ {
|
||||
if best != nil && 1<<(best.k-1) < len(all) {
|
||||
break
|
||||
}
|
||||
h := rand.Uint32()
|
||||
for k := uint(0); k <= 16; k++ {
|
||||
if best != nil && k >= best.k {
|
||||
break
|
||||
}
|
||||
var t table
|
||||
if t.init(h, k, all) {
|
||||
best = &t
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if best == nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to construct string table\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Lay out strings, using overlaps when possible.
|
||||
layout := append([]string{}, all...)
|
||||
|
||||
// Remove strings that are substrings of other strings
|
||||
for changed := true; changed; {
|
||||
changed = false
|
||||
for i, s := range layout {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
for j, t := range layout {
|
||||
if i != j && t != "" && strings.Contains(s, t) {
|
||||
changed = true
|
||||
layout[j] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Join strings where one suffix matches another prefix.
|
||||
for {
|
||||
// Find best i, j, k such that layout[i][len-k:] == layout[j][:k],
|
||||
// maximizing overlap length k.
|
||||
besti := -1
|
||||
bestj := -1
|
||||
bestk := 0
|
||||
for i, s := range layout {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
for j, t := range layout {
|
||||
if i == j {
|
||||
continue
|
||||
}
|
||||
for k := bestk + 1; k <= len(s) && k <= len(t); k++ {
|
||||
if s[len(s)-k:] == t[:k] {
|
||||
besti = i
|
||||
bestj = j
|
||||
bestk = k
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if bestk > 0 {
|
||||
layout[besti] += layout[bestj][bestk:]
|
||||
layout[bestj] = ""
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
text := strings.Join(layout, "")
|
||||
|
||||
atom := map[string]uint32{}
|
||||
for _, s := range all {
|
||||
off := strings.Index(text, s)
|
||||
if off < 0 {
|
||||
panic("lost string " + s)
|
||||
}
|
||||
atom[s] = uint32(off<<8 | len(s))
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
// Generate the Go code.
|
||||
fmt.Fprintln(&buf, "// Code generated by go generate gen.go; DO NOT EDIT.\n")
|
||||
fmt.Fprintln(&buf, "//go:generate go run gen.go\n")
|
||||
fmt.Fprintln(&buf, "package atom\n\nconst (")
|
||||
|
||||
// compute max len
|
||||
maxLen := 0
|
||||
for _, s := range all {
|
||||
if maxLen < len(s) {
|
||||
maxLen = len(s)
|
||||
}
|
||||
fmt.Fprintf(&buf, "\t%s Atom = %#x\n", identifier(s), atom[s])
|
||||
}
|
||||
fmt.Fprintln(&buf, ")\n")
|
||||
|
||||
fmt.Fprintf(&buf, "const hash0 = %#x\n\n", best.h0)
|
||||
fmt.Fprintf(&buf, "const maxAtomLen = %d\n\n", maxLen)
|
||||
|
||||
fmt.Fprintf(&buf, "var table = [1<<%d]Atom{\n", best.k)
|
||||
for i, s := range best.tab {
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(&buf, "\t%#x: %#x, // %s\n", i, atom[s], s)
|
||||
}
|
||||
fmt.Fprintf(&buf, "}\n")
|
||||
datasize := (1 << best.k) * 4
|
||||
|
||||
fmt.Fprintln(&buf, "const atomText =")
|
||||
textsize := len(text)
|
||||
for len(text) > 60 {
|
||||
fmt.Fprintf(&buf, "\t%q +\n", text[:60])
|
||||
text = text[60:]
|
||||
}
|
||||
fmt.Fprintf(&buf, "\t%q\n\n", text)
|
||||
|
||||
genFile("table.go", &buf)
|
||||
|
||||
fmt.Fprintf(os.Stdout, "%d atoms; %d string bytes + %d tables = %d total data\n", len(all), textsize, datasize, textsize+datasize)
|
||||
}
|
||||
|
||||
type byLen []string
|
||||
|
||||
func (x byLen) Less(i, j int) bool { return len(x[i]) > len(x[j]) }
|
||||
func (x byLen) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
func (x byLen) Len() int { return len(x) }
|
||||
|
||||
// fnv computes the FNV hash with an arbitrary starting value h.
|
||||
func fnv(h uint32, s string) uint32 {
|
||||
for i := 0; i < len(s); i++ {
|
||||
h ^= uint32(s[i])
|
||||
h *= 16777619
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
// A table represents an attempt at constructing the lookup table.
|
||||
// The lookup table uses cuckoo hashing, meaning that each string
|
||||
// can be found in one of two positions.
|
||||
type table struct {
|
||||
h0 uint32
|
||||
k uint
|
||||
mask uint32
|
||||
tab []string
|
||||
}
|
||||
|
||||
// hash returns the two hashes for s.
|
||||
func (t *table) hash(s string) (h1, h2 uint32) {
|
||||
h := fnv(t.h0, s)
|
||||
h1 = h & t.mask
|
||||
h2 = (h >> 16) & t.mask
|
||||
return
|
||||
}
|
||||
|
||||
// init initializes the table with the given parameters.
|
||||
// h0 is the initial hash value,
|
||||
// k is the number of bits of hash value to use, and
|
||||
// x is the list of strings to store in the table.
|
||||
// init returns false if the table cannot be constructed.
|
||||
func (t *table) init(h0 uint32, k uint, x []string) bool {
|
||||
t.h0 = h0
|
||||
t.k = k
|
||||
t.tab = make([]string, 1<<k)
|
||||
t.mask = 1<<k - 1
|
||||
for _, s := range x {
|
||||
if !t.insert(s) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// insert inserts s in the table.
|
||||
func (t *table) insert(s string) bool {
|
||||
h1, h2 := t.hash(s)
|
||||
if t.tab[h1] == "" {
|
||||
t.tab[h1] = s
|
||||
return true
|
||||
}
|
||||
if t.tab[h2] == "" {
|
||||
t.tab[h2] = s
|
||||
return true
|
||||
}
|
||||
if t.push(h1, 0) {
|
||||
t.tab[h1] = s
|
||||
return true
|
||||
}
|
||||
if t.push(h2, 0) {
|
||||
t.tab[h2] = s
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// push attempts to push aside the entry in slot i.
|
||||
func (t *table) push(i uint32, depth int) bool {
|
||||
if depth > len(t.tab) {
|
||||
return false
|
||||
}
|
||||
s := t.tab[i]
|
||||
h1, h2 := t.hash(s)
|
||||
j := h1 + h2 - i
|
||||
if t.tab[j] != "" && !t.push(j, depth+1) {
|
||||
return false
|
||||
}
|
||||
t.tab[j] = s
|
||||
return true
|
||||
}
|
||||
|
||||
// The lists of element names and attribute keys were taken from
|
||||
// https://html.spec.whatwg.org/multipage/indices.html#index
|
||||
// as of the "HTML Living Standard - Last Updated 16 April 2018" version.
|
||||
|
||||
// "command", "keygen" and "menuitem" have been removed from the spec,
|
||||
// but are kept here for backwards compatibility.
|
||||
var elements = []string{
|
||||
"a",
|
||||
"abbr",
|
||||
"address",
|
||||
"area",
|
||||
"article",
|
||||
"aside",
|
||||
"audio",
|
||||
"b",
|
||||
"base",
|
||||
"bdi",
|
||||
"bdo",
|
||||
"blockquote",
|
||||
"body",
|
||||
"br",
|
||||
"button",
|
||||
"canvas",
|
||||
"caption",
|
||||
"cite",
|
||||
"code",
|
||||
"col",
|
||||
"colgroup",
|
||||
"command",
|
||||
"data",
|
||||
"datalist",
|
||||
"dd",
|
||||
"del",
|
||||
"details",
|
||||
"dfn",
|
||||
"dialog",
|
||||
"div",
|
||||
"dl",
|
||||
"dt",
|
||||
"em",
|
||||
"embed",
|
||||
"fieldset",
|
||||
"figcaption",
|
||||
"figure",
|
||||
"footer",
|
||||
"form",
|
||||
"h1",
|
||||
"h2",
|
||||
"h3",
|
||||
"h4",
|
||||
"h5",
|
||||
"h6",
|
||||
"head",
|
||||
"header",
|
||||
"hgroup",
|
||||
"hr",
|
||||
"html",
|
||||
"i",
|
||||
"iframe",
|
||||
"img",
|
||||
"input",
|
||||
"ins",
|
||||
"kbd",
|
||||
"keygen",
|
||||
"label",
|
||||
"legend",
|
||||
"li",
|
||||
"link",
|
||||
"main",
|
||||
"map",
|
||||
"mark",
|
||||
"menu",
|
||||
"menuitem",
|
||||
"meta",
|
||||
"meter",
|
||||
"nav",
|
||||
"noscript",
|
||||
"object",
|
||||
"ol",
|
||||
"optgroup",
|
||||
"option",
|
||||
"output",
|
||||
"p",
|
||||
"param",
|
||||
"picture",
|
||||
"pre",
|
||||
"progress",
|
||||
"q",
|
||||
"rp",
|
||||
"rt",
|
||||
"ruby",
|
||||
"s",
|
||||
"samp",
|
||||
"script",
|
||||
"section",
|
||||
"select",
|
||||
"slot",
|
||||
"small",
|
||||
"source",
|
||||
"span",
|
||||
"strong",
|
||||
"style",
|
||||
"sub",
|
||||
"summary",
|
||||
"sup",
|
||||
"table",
|
||||
"tbody",
|
||||
"td",
|
||||
"template",
|
||||
"textarea",
|
||||
"tfoot",
|
||||
"th",
|
||||
"thead",
|
||||
"time",
|
||||
"title",
|
||||
"tr",
|
||||
"track",
|
||||
"u",
|
||||
"ul",
|
||||
"var",
|
||||
"video",
|
||||
"wbr",
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/indices.html#attributes-3
|
||||
//
|
||||
// "challenge", "command", "contextmenu", "dropzone", "icon", "keytype", "mediagroup",
|
||||
// "radiogroup", "spellcheck", "scoped", "seamless", "sortable" and "sorted" have been removed from the spec,
|
||||
// but are kept here for backwards compatibility.
|
||||
var attributes = []string{
|
||||
"abbr",
|
||||
"accept",
|
||||
"accept-charset",
|
||||
"accesskey",
|
||||
"action",
|
||||
"allowfullscreen",
|
||||
"allowpaymentrequest",
|
||||
"allowusermedia",
|
||||
"alt",
|
||||
"as",
|
||||
"async",
|
||||
"autocomplete",
|
||||
"autofocus",
|
||||
"autoplay",
|
||||
"challenge",
|
||||
"charset",
|
||||
"checked",
|
||||
"cite",
|
||||
"class",
|
||||
"color",
|
||||
"cols",
|
||||
"colspan",
|
||||
"command",
|
||||
"content",
|
||||
"contenteditable",
|
||||
"contextmenu",
|
||||
"controls",
|
||||
"coords",
|
||||
"crossorigin",
|
||||
"data",
|
||||
"datetime",
|
||||
"default",
|
||||
"defer",
|
||||
"dir",
|
||||
"dirname",
|
||||
"disabled",
|
||||
"download",
|
||||
"draggable",
|
||||
"dropzone",
|
||||
"enctype",
|
||||
"for",
|
||||
"form",
|
||||
"formaction",
|
||||
"formenctype",
|
||||
"formmethod",
|
||||
"formnovalidate",
|
||||
"formtarget",
|
||||
"headers",
|
||||
"height",
|
||||
"hidden",
|
||||
"high",
|
||||
"href",
|
||||
"hreflang",
|
||||
"http-equiv",
|
||||
"icon",
|
||||
"id",
|
||||
"inputmode",
|
||||
"integrity",
|
||||
"is",
|
||||
"ismap",
|
||||
"itemid",
|
||||
"itemprop",
|
||||
"itemref",
|
||||
"itemscope",
|
||||
"itemtype",
|
||||
"keytype",
|
||||
"kind",
|
||||
"label",
|
||||
"lang",
|
||||
"list",
|
||||
"loop",
|
||||
"low",
|
||||
"manifest",
|
||||
"max",
|
||||
"maxlength",
|
||||
"media",
|
||||
"mediagroup",
|
||||
"method",
|
||||
"min",
|
||||
"minlength",
|
||||
"multiple",
|
||||
"muted",
|
||||
"name",
|
||||
"nomodule",
|
||||
"nonce",
|
||||
"novalidate",
|
||||
"open",
|
||||
"optimum",
|
||||
"pattern",
|
||||
"ping",
|
||||
"placeholder",
|
||||
"playsinline",
|
||||
"poster",
|
||||
"preload",
|
||||
"radiogroup",
|
||||
"readonly",
|
||||
"referrerpolicy",
|
||||
"rel",
|
||||
"required",
|
||||
"reversed",
|
||||
"rows",
|
||||
"rowspan",
|
||||
"sandbox",
|
||||
"spellcheck",
|
||||
"scope",
|
||||
"scoped",
|
||||
"seamless",
|
||||
"selected",
|
||||
"shape",
|
||||
"size",
|
||||
"sizes",
|
||||
"sortable",
|
||||
"sorted",
|
||||
"slot",
|
||||
"span",
|
||||
"spellcheck",
|
||||
"src",
|
||||
"srcdoc",
|
||||
"srclang",
|
||||
"srcset",
|
||||
"start",
|
||||
"step",
|
||||
"style",
|
||||
"tabindex",
|
||||
"target",
|
||||
"title",
|
||||
"translate",
|
||||
"type",
|
||||
"typemustmatch",
|
||||
"updateviacache",
|
||||
"usemap",
|
||||
"value",
|
||||
"width",
|
||||
"workertype",
|
||||
"wrap",
|
||||
}
|
||||
|
||||
// "onautocomplete", "onautocompleteerror", "onmousewheel",
|
||||
// "onshow" and "onsort" have been removed from the spec,
|
||||
// but are kept here for backwards compatibility.
|
||||
var eventHandlers = []string{
|
||||
"onabort",
|
||||
"onautocomplete",
|
||||
"onautocompleteerror",
|
||||
"onauxclick",
|
||||
"onafterprint",
|
||||
"onbeforeprint",
|
||||
"onbeforeunload",
|
||||
"onblur",
|
||||
"oncancel",
|
||||
"oncanplay",
|
||||
"oncanplaythrough",
|
||||
"onchange",
|
||||
"onclick",
|
||||
"onclose",
|
||||
"oncontextmenu",
|
||||
"oncopy",
|
||||
"oncuechange",
|
||||
"oncut",
|
||||
"ondblclick",
|
||||
"ondrag",
|
||||
"ondragend",
|
||||
"ondragenter",
|
||||
"ondragexit",
|
||||
"ondragleave",
|
||||
"ondragover",
|
||||
"ondragstart",
|
||||
"ondrop",
|
||||
"ondurationchange",
|
||||
"onemptied",
|
||||
"onended",
|
||||
"onerror",
|
||||
"onfocus",
|
||||
"onhashchange",
|
||||
"oninput",
|
||||
"oninvalid",
|
||||
"onkeydown",
|
||||
"onkeypress",
|
||||
"onkeyup",
|
||||
"onlanguagechange",
|
||||
"onload",
|
||||
"onloadeddata",
|
||||
"onloadedmetadata",
|
||||
"onloadend",
|
||||
"onloadstart",
|
||||
"onmessage",
|
||||
"onmessageerror",
|
||||
"onmousedown",
|
||||
"onmouseenter",
|
||||
"onmouseleave",
|
||||
"onmousemove",
|
||||
"onmouseout",
|
||||
"onmouseover",
|
||||
"onmouseup",
|
||||
"onmousewheel",
|
||||
"onwheel",
|
||||
"onoffline",
|
||||
"ononline",
|
||||
"onpagehide",
|
||||
"onpageshow",
|
||||
"onpaste",
|
||||
"onpause",
|
||||
"onplay",
|
||||
"onplaying",
|
||||
"onpopstate",
|
||||
"onprogress",
|
||||
"onratechange",
|
||||
"onreset",
|
||||
"onresize",
|
||||
"onrejectionhandled",
|
||||
"onscroll",
|
||||
"onsecuritypolicyviolation",
|
||||
"onseeked",
|
||||
"onseeking",
|
||||
"onselect",
|
||||
"onshow",
|
||||
"onsort",
|
||||
"onstalled",
|
||||
"onstorage",
|
||||
"onsubmit",
|
||||
"onsuspend",
|
||||
"ontimeupdate",
|
||||
"ontoggle",
|
||||
"onunhandledrejection",
|
||||
"onunload",
|
||||
"onvolumechange",
|
||||
"onwaiting",
|
||||
}
|
||||
|
||||
// extra are ad-hoc values not covered by any of the lists above.
|
||||
var extra = []string{
|
||||
"acronym",
|
||||
"align",
|
||||
"annotation",
|
||||
"annotation-xml",
|
||||
"applet",
|
||||
"basefont",
|
||||
"bgsound",
|
||||
"big",
|
||||
"blink",
|
||||
"center",
|
||||
"color",
|
||||
"desc",
|
||||
"face",
|
||||
"font",
|
||||
"foreignObject", // HTML is case-insensitive, but SVG-embedded-in-HTML is case-sensitive.
|
||||
"foreignobject",
|
||||
"frame",
|
||||
"frameset",
|
||||
"image",
|
||||
"isindex",
|
||||
"listing",
|
||||
"malignmark",
|
||||
"marquee",
|
||||
"math",
|
||||
"mglyph",
|
||||
"mi",
|
||||
"mn",
|
||||
"mo",
|
||||
"ms",
|
||||
"mtext",
|
||||
"nobr",
|
||||
"noembed",
|
||||
"noframes",
|
||||
"plaintext",
|
||||
"prompt",
|
||||
"public",
|
||||
"rb",
|
||||
"rtc",
|
||||
"spacer",
|
||||
"strike",
|
||||
"svg",
|
||||
"system",
|
||||
"tt",
|
||||
"xmp",
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue