whisper: made PoW and MaxMsgSize customizable

This commit is contained in:
Vlad 2017-03-01 13:22:55 +01:00
parent a02cf9a0ad
commit 709d6e47f8
8 changed files with 51 additions and 36 deletions

View file

@ -84,8 +84,8 @@ var (
argVerbosity = flag.Int("verbosity", int(log.LvlWarn), "log verbosity level") argVerbosity = flag.Int("verbosity", int(log.LvlWarn), "log verbosity level")
argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds") argTTL = flag.Uint("ttl", 30, "time-to-live for messages in seconds")
argWorkTime = flag.Uint("work", 5, "work time in seconds") argWorkTime = flag.Uint("work", 5, "work time in seconds")
argPoW = flag.Float64("pow", whisper.MinimumPoW, "PoW for normal messages in float format (e.g. 2.7)") argPoW = flag.Float64("pow", whisper.DefaultMinimumPoW, "PoW for normal messages in float format (e.g. 2.7)")
argServerPoW = flag.Float64("mspow", whisper.MinimumPoW, "PoW requirement for Mail Server request") argServerPoW = flag.Float64("mspow", whisper.DefaultMinimumPoW, "PoW requirement for Mail Server request")
argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)") argIP = flag.String("ip", "", "IP address and port of this node (e.g. 127.0.0.1:30303)")
argPub = flag.String("pub", "", "public key for asymmetric encryption") argPub = flag.String("pub", "", "public key for asymmetric encryption")

View file

@ -72,6 +72,20 @@ func (api *PublicWhisperAPI) Stats() (string, error) {
return api.whisper.Stats(), nil return api.whisper.Stats(), nil
} }
func (api *PublicWhisperAPI) SetMaxMessageLength(val int) error {
if api.whisper == nil {
return whisperOffLineErr
}
return api.whisper.SetMaxMessageLength(val)
}
func (api *PublicWhisperAPI) SetMinimumPoW(val float64) error {
if api.whisper == nil {
return whisperOffLineErr
}
return api.whisper.SetMinimumPoW(val)
}
// MarkPeerTrusted marks specific peer trusted, which will allow it // MarkPeerTrusted marks specific peer trusted, which will allow it
// to send historic (expired) messages. // to send historic (expired) messages.
func (api *PublicWhisperAPI) MarkPeerTrusted(peerID hexutil.Bytes) error { func (api *PublicWhisperAPI) MarkPeerTrusted(peerID hexutil.Bytes) error {
@ -352,7 +366,7 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error {
log.Error(fmt.Sprintf(err.Error())) log.Error(fmt.Sprintf(err.Error()))
return err return err
} }
if envelope.size() > MaxMessageLength { if envelope.size() > api.whisper.maxMsgLength {
info := "Post: message is too big" info := "Post: message is too big"
log.Error(fmt.Sprintf(info)) log.Error(fmt.Sprintf(info))
return errors.New(info) return errors.New(info)

View file

@ -323,7 +323,7 @@ func TestIntegrationAsym(t *testing.T) {
f.To = key f.To = key
f.From = sig f.From = sig
f.Topics = topics[:] f.Topics = topics[:]
f.PoW = MinimumPoW / 2 f.PoW = DefaultMinimumPoW / 2
f.AcceptP2P = true f.AcceptP2P = true
id, err := api.NewFilter(f) id, err := api.NewFilter(f)
@ -337,7 +337,7 @@ func TestIntegrationAsym(t *testing.T) {
p.To = f.To p.To = f.To
p.Padding = []byte("test string") p.Padding = []byte("test string")
p.Payload = []byte("extended test string") p.Payload = []byte("extended test string")
p.PoW = MinimumPoW p.PoW = DefaultMinimumPoW
p.Topic = TopicType{0xf2, 0x6e, 0x77, 0x79} p.Topic = TopicType{0xf2, 0x6e, 0x77, 0x79}
p.WorkTime = 2 p.WorkTime = 2
@ -427,7 +427,7 @@ func TestIntegrationSym(t *testing.T) {
p.From = f.From p.From = f.From
p.Padding = []byte("test string") p.Padding = []byte("test string")
p.Payload = []byte("extended test string") p.Payload = []byte("extended test string")
p.PoW = MinimumPoW p.PoW = DefaultMinimumPoW
p.Topic = TopicType{0xf2, 0x6e, 0x77, 0x79} p.Topic = TopicType{0xf2, 0x6e, 0x77, 0x79}
p.WorkTime = 2 p.WorkTime = 2
@ -517,7 +517,7 @@ func TestIntegrationSymWithFilter(t *testing.T) {
p.From = sig p.From = sig
p.Padding = []byte("test string") p.Padding = []byte("test string")
p.Payload = []byte("extended test string") p.Payload = []byte("extended test string")
p.PoW = MinimumPoW p.PoW = DefaultMinimumPoW
p.Topic = TopicType{0xf2, 0x6e, 0x77, 0x79} p.Topic = TopicType{0xf2, 0x6e, 0x77, 0x79}
p.WorkTime = 2 p.WorkTime = 2

View file

@ -55,8 +55,8 @@ const (
saltLength = 12 saltLength = 12
AESNonceMaxLength = 12 AESNonceMaxLength = 12
MaxMessageLength = 1024 * 1024 DefaultMaxMessageLength = 1024 * 1024
MinimumPoW = 10.0 // todo: review after testing. DefaultMinimumPoW = 10.0 // todo: review after testing.
padSizeLimitLower = 128 // it can not be less - we don't want to reveal the absence of signature padSizeLimitLower = 128 // it can not be less - we don't want to reveal the absence of signature
padSizeLimitUpper = 256 // just an arbitrary number, could be changed without losing compatibility padSizeLimitUpper = 256 // just an arbitrary number, could be changed without losing compatibility

View file

@ -215,17 +215,6 @@ func (msg *SentMessage) encryptSymmetric(key []byte) (salt []byte, nonce []byte,
} }
// Wrap bundles the message into an Envelope to transmit over the network. // Wrap bundles the message into an Envelope to transmit over the network.
//
// pow (Proof Of Work) controls how much time to spend on hashing the message,
// inherently controlling its priority through the network (smaller hash, bigger
// priority).
//
// The user can control the amount of identity, privacy and encryption through
// the options parameter as follows:
// - options.From == nil && options.To == nil: anonymous broadcast
// - options.From != nil && options.To == nil: signed broadcast (known sender)
// - options.From == nil && options.To != nil: encrypted anonymous message
// - options.From != nil && options.To != nil: encrypted signed message
func (msg *SentMessage) Wrap(options *MessageParams) (envelope *Envelope, err error) { func (msg *SentMessage) Wrap(options *MessageParams) (envelope *Envelope, err error) {
if options.TTL == 0 { if options.TTL == 0 {
options.TTL = DefaultTTL options.TTL = DefaultTTL
@ -236,10 +225,6 @@ func (msg *SentMessage) Wrap(options *MessageParams) (envelope *Envelope, err er
return nil, err return nil, err
} }
} }
if len(msg.Raw) > MaxMessageLength {
log.Error(fmt.Sprintf("Message size must not exceed %d bytes", MaxMessageLength))
return nil, errors.New("Oversized message")
}
var salt, nonce []byte var salt, nonce []byte
if options.Dst != nil { if options.Dst != nil {
err = msg.encryptAsymmetric(options.Dst) err = msg.encryptAsymmetric(options.Dst)
@ -258,11 +243,6 @@ func (msg *SentMessage) Wrap(options *MessageParams) (envelope *Envelope, err er
if err != nil { if err != nil {
return nil, err return nil, err
} }
if envelope.size() > MaxMessageLength {
log.Error(fmt.Sprintf("Envelope size must not exceed %d bytes", MaxMessageLength))
return nil, errors.New("Oversized message")
}
return envelope, nil return envelope, nil
} }

View file

@ -114,7 +114,7 @@ func initialize(t *testing.T) {
for i := 0; i < NumNodes; i++ { for i := 0; i < NumNodes; i++ {
var node TestNode var node TestNode
node.shh = New() node.shh = New()
node.shh.test = true node.shh.SetMinimumPoW(0.00000001)
node.shh.Start(nil) node.shh.Start(nil)
topics := make([]TopicType, 0) topics := make([]TopicType, 0)
topics = append(topics, sharedTopic) topics = append(topics, sharedTopic)

View file

@ -66,8 +66,9 @@ type Whisper struct {
stats Statistics stats Statistics
minPoW float64
maxMsgLength int
overflow bool overflow bool
test bool
} }
// New creates a Whisper client ready to communicate through the Ethereum P2P network. // New creates a Whisper client ready to communicate through the Ethereum P2P network.
@ -82,6 +83,8 @@ func New() *Whisper {
messageQueue: make(chan *Envelope, messageQueueLimit), messageQueue: make(chan *Envelope, messageQueueLimit),
p2pMsgQueue: make(chan *Envelope, messageQueueLimit), p2pMsgQueue: make(chan *Envelope, messageQueueLimit),
quit: make(chan struct{}), quit: make(chan struct{}),
minPoW: DefaultMinimumPoW,
maxMsgLength: DefaultMaxMessageLength,
} }
whisper.filters = NewFilters(whisper) whisper.filters = NewFilters(whisper)
@ -122,6 +125,22 @@ func (w *Whisper) Version() uint {
return w.protocol.Version return w.protocol.Version
} }
func (w *Whisper) SetMaxMessageLength(val int) error {
if val <= 0 {
return fmt.Errorf("Invalid message length: %d", val)
}
w.maxMsgLength = val
return nil
}
func (w *Whisper) SetMinimumPoW(val float64) error {
if val <= 0.0 {
return fmt.Errorf("Invalid PoW: %f", val)
}
w.minPoW = val
return nil
}
func (w *Whisper) getPeer(peerID []byte) (*Peer, error) { func (w *Whisper) getPeer(peerID []byte) (*Peer, error) {
w.peerMu.Lock() w.peerMu.Lock()
defer w.peerMu.Unlock() defer w.peerMu.Unlock()
@ -358,7 +377,7 @@ func (wh *Whisper) runMessageLoop(p *Peer, rw p2p.MsgReadWriter) error {
if err != nil { if err != nil {
return err return err
} }
if packet.Size > MaxMessageLength { if packet.Size > uint32(wh.maxMsgLength) {
return fmt.Errorf("oversized message received") return fmt.Errorf("oversized message received")
} }
@ -441,7 +460,7 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) {
} }
} }
if envelope.size() > MaxMessageLength { if envelope.size() > wh.maxMsgLength {
return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash()) return false, fmt.Errorf("huge messages are not allowed [%x]", envelope.Hash())
} }
@ -459,7 +478,7 @@ func (wh *Whisper) add(envelope *Envelope) (bool, error) {
return false, fmt.Errorf("oversized salt [%x]", envelope.Hash()) return false, fmt.Errorf("oversized salt [%x]", envelope.Hash())
} }
if envelope.PoW() < MinimumPoW && !wh.test { if envelope.PoW() < wh.minPoW {
log.Debug(fmt.Sprintf("envelope with low PoW dropped: %f [%x]", envelope.PoW(), envelope.Hash())) log.Debug(fmt.Sprintf("envelope with low PoW dropped: %f [%x]", envelope.PoW(), envelope.Hash()))
return false, nil // drop envelope without error return false, nil // drop envelope without error
} }
@ -519,6 +538,7 @@ func (w *Whisper) checkOverflow() {
} else if queueSize <= messageQueueLimit/2 { } else if queueSize <= messageQueueLimit/2 {
if w.overflow { if w.overflow {
w.overflow = false w.overflow = false
log.Warn(fmt.Sprint("message queue overflow fixed (back to normal)"))
} }
} }
} }

View file

@ -305,7 +305,8 @@ func TestExpiry(t *testing.T) {
InitSingleTest() InitSingleTest()
w := New() w := New()
w.test = true w.SetMinimumPoW(0.0000001)
defer w.SetMinimumPoW(DefaultMinimumPoW)
w.Start(nil) w.Start(nil)
defer w.Stop() defer w.Stop()