mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
whisper: made PoW and MaxMsgSize customizable
This commit is contained in:
parent
a02cf9a0ad
commit
709d6e47f8
8 changed files with 51 additions and 36 deletions
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue