whisper客服源码_深入ethereum源码-whisper协议解读

Whisper - DApps 相互通信的通信协议, 以太坊 web3 技术栈的基础层服务

概述

whisper是完全基于ID的消息系统,它的设计目的是形成一套p2p节点间的异步广播系统。whisper网络上的消息是加密传送的,完全可以暴露在公网进行传输;此外,为了防范DDos攻击,whisper使用了proof-of-work(PoW)工作量证明提高消息发送门槛。

whisper基础构件

whisper协议对上层暴露出一套类似于订阅-发布的API模型,节点可以申请自己感兴趣的topic,那么就只会接收到这些topic的消息,无关主题的消息将被丢弃。在这套体系内,有几个基础构件需要说明下:

Envelope信封

envelope即信封是whisper网络节点传输数据的基本形式。信封包含了加密的数据体和明文的元数据,元数据主要用于基本的消息校验和消息体的解密。

信封是以RLP编码的格式传输:Version:最多4字节(目前仅使用了1字节),如果信封的Version比本节点当前值高,将无法解密,仅做转发

Expiry:4字节(unix时间戳秒数),过期时间

TTL:4字节,剩余存活时间秒数

Topic:4字节,信封主题

AESNonce:12字节随机数据,仅在对称加密时有效

Data:消息体

EnvNonce:8字节任意数据(用于PoW计算)

如果节点无法解密信封,那么节点对信封内的消息内容一无所知,单这并不影响节点将消息进行转发扩散。

Message消息

信封内的消息体解密后即得到消息内容。

Topic主题

每个信封上都有一个主题,注意主题可以仅使用部分前缀

Filter过滤器

filter即订阅-发布模型中的订阅者

PoW工作量证明

PoW的存在是为了反垃圾信息以及降低网络负担。计算PoW所付出的代价可以理解为抵扣节点为传播和存储信息锁花费的资源.

在whisperv5中,PoW定义为:BestBit是hash计算值的前导0个数

size是消息大小

TTL

具有高PoW的消息具有优先处理权。

whisper节点发送消息需要经过创建消息whisper.NewSentMessage()—->封装入信封msg.Wrap(msg)—->shh.Send(),消息的工作量证明就在第二步装入信封的时候进行计算。

func (e *Envelope) Seal(options *MessageParams) error {

var target, bestBit int // target是需要达到的目标前置0位数

if options.PoW == 0 {

// 将消息过期时间调整到工作量计算完成后

e.Expiry += options.WorkTime

} else {

// 根据公式 PoW = (2^BestBit) / (size * TTL) 从预设的PoW阈值反解出BestBit

target = e.powToFirstBit(options.PoW)

if target < 1 {

target = 1

}

}

buf := make([]byte, 64)

// Keccak256是SHA-3的一种,Keccak已可以抵御最小的复杂度为2n的攻击,其中N为散列的大小。它具有广泛的安全边际。至目前为止,第三方密码分析已经显示出Keccak没有严重的弱点

h := crypto.Keccak256(e.rlpWithoutNonce())

copy(buf[:32], h)

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++ {

// 暴力尝试nonce值

binary.BigEndian.PutUint64(buf[56:], nonce)

d := new(big.Int).SetBytes(crypto.Keccak256(buf))

firstBit := math.FirstBitSet(d)

if firstBit > bestBit {

e.EnvNonce, bestBit = nonce, firstBit

// 当尝试得到满足条件的EnvNonce,计算完成

if target > 0 && bestBit >= target {

return nil

}

}

nonce++

}

}

if target > 0 && bestBit < target {

return fmt.Errorf("failed to reach the PoW target, specified pow time (%d seconds) was insufficient", options.WorkTime)

}

return nil

}

通信流程

whisper协议的实现位于包github.com/ethereum/go-ethereum/whisper,该包下面有多个版本实现,目前最新协议包是whisperv6.

whisper main loop

whisper-main-loop

whisper节点启动后产生两个分支:一个分支负责清理shh.envelopes中的过期消息

另一个分支(proccessQueue)从两个队列取出新接收到的消息,根据消息对应topic投放(Trigger)到对应接收者(filter),从而交付给上层应用进行处理

补充说下whisper里两个队列messageQueue,p2pMsgQueue的不同作用,messageQueue接收普通的广播消息,p2pMsgQueue接收点对点的直接消息,可绕过pow和ttl限制.

whisper protocol

whisper协议的具体实现里,代码流程也非常清晰:

whisper-peer-loop

每个peer连接成功后,产生两个goroutine,进行消息接收和广播:接收消息协程不断从连接中读取新消息,并且将消息暂存到shh.envelopes中,如果发现是一条未接收过的新消息,则将消息转发到对应的队列(messageQueue,p2pMsgQueue)

广播协程负责将该peer未接收过的消息(本节点认为该peer未接收过,并非peer一定没接收过,p2p网络其他节点可能已经将消息广播到该节点了)投递到该peer

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值