November 16, 2019

cmux 源码分析

cmux cmux 是soheilhy实现的一个复用连接的Go库,可以在同一个TCP listener上面监听多种服务 源码分析 cmux 项目结构如下,整个代码量包含test代码总共2k行,核心代码几百行,很适合阅读 ➜ cmux git:(master) ✗ tree -L 2 . ├── CONTRIBUTORS ├── LICENSE ├── README.md ├── bench_test.go ├── buffer.go ├── cmd │ └── cmd.go ├── cmux.go ├── cmux_test.go ├── doc.go ├── example_recursive_test.go ├── example_test.go ├── example_tls_test.go ├── go.mod ├── go.sum ├── matchers.go ├── patricia.go └── patricia_test.go 在看cmux实现之前,可以先从README中看怎么使用cmux // Create the main listener. l, err := net.Listen("tcp", ":23456") if err != nil { log. Read more

January 5, 2018

0x protocol分析

0x protocol是当前币价比较高的一种token exchange协议。提供了一种以太坊网络中token交换的去中心化解决方案。 协议概述 下图为0x protocol的off-chain order转发和on-chain settlement的逻辑图。 上图中灰色的矩形和圆形分别代表以太坊上的智能合约和账户。具体的逻辑: 1. maker同意DEX(去中心化交易所合约)获取他们关于Token A的信息。 2. Maker创建一笔关于Token A兑换为Token B的订单,并且声明了期望的交易rate和过期时间。将以上订单签名。 3. Maker 通过网络传输层将此订单广播 4. Taker接收到这笔订单,并且决定来完成此项订单。 5. Taker同意DEX来获取他的关于Token B的信息。 6. Taker提交maker的那条以签名的order到DEX合约。 7. DEX合约认证maker的签名,验证通过后,然后将两者的Token按照拟定的rate进行交换。 其中,关于上述的操作3和操作4off-chain的行为,0x protocol的网络传输层和会话层以及应用层来负责Order的relay,展示,以及推送。当然,用户也可以将签好名的order通过email,twitter等方式广播出去,Taker一旦获取之后,将order发送至DEX合约即可完成交易。 消息格式 0x protocols的order的消息格式定义为: Name Data Type Description version address DEX 地址 maker address order的创建者 taker address 接单者地址 token A address ERC20 token 地址 token B address ERC20 token 地址 value A uint256 token A 的数量 value B uint256 token B 的数量 expiration uint256 过期时间 v uint8 ECDSA 签名参数 r bytes32 ECDSA 签名参数 s bytes32 ECDSA 签名参数 Order广播 0x protocols采用了off-chain的模式来传送order,用户可以自发的广播自己的订单。 同时,0x protocol 设计了一个简单的转发order的机制,maker也可以通过寻找relayer来上传自己的order。 其中relayer,maker,taker三者的关系如下: 协议提供了feeRecipient来促进order的转发,具体order广播逻辑如下: 1. Read more

December 7, 2017

以太坊交易池逻辑分析

发送一笔以太坊网络转账交易,除了成功之外,会遇到各种问题,比如发送的一笔交易在etherscan中查不到,或者查到是pending的状态,后来过了几个小时消失了,这些都与节点的交易池的处理逻辑相关,而交易池的逻辑可以有各种实现,目前官方的go-ethereum 的交易池逻辑如下。 当一条交易进入挖矿节点的交易池(tx_pool)时,此节点会做出以下逻辑: 通过判断交易hash,当这条交易已经在节点的交易池里面时,就会丢弃掉当前收到的这一个交易。 如果是一个全新的hash,就会更具共识协议,对这一条交易做基本的验证。验证包括:长度,value,是否溢出当前区块的gaslimit,Nonce值,转账提供的gas大小是否太小等。 如果验证不通过就会返回相应的错误代码。 当验证通过的话,需要根据当前交易池的状态来决定,如果交易池满了的话,那么判断当前的转账交易提供的gas是否高于交易池里当前提供gas最低的那条交易。如果低了,就返回错误ErrUnderpriced,这是返回的错误经常在etherscan中看到。如果当前交易提供的gas值高的话,那么就剔除掉了那一条提供最低gas的转账交易,为当前交易腾出空间。这种情况发生之后,往往在etherscan中会观察到正在pending的交易消失了,找不到了。(也有很大机率依然能够查到pending的交易,原因是etherscan连接了很多节点,每个节点的交易池的状态都是不一样的,那条被踢出的交易在别的节点依然pending) 如果当前交易的Nonce已经在交易池里面了,说明了这个用户想替代之前发出的相同的Nonce的交易。这时节点会判断当前交易的gas是否高出上一条相同Nonce的交易gas某一个阈值(比如默认的是10%)。如果高出了,那么就会剔除之前的那个交易,新的交易就会保留,如果没有高出,当前的交易就会返回失败。 以上逻辑都通过了,那么此条交易便成功存在交易池中等待打包,当然也有可能会被别的高gas的转账交易剔除的概率。 总结,如果你发送了一笔交易碰巧赶上了以太坊网络拥堵,那么你的交易很有可能发送失败。原因是所有的挖矿节点都不接受这么低的gas交易了,或者你本来在交易池中,被剔除了。

October 7, 2017

ethereum rpc 调用分析

以太坊以JSON RPC的方式提供API service。本文将从go-ethereum源码中挖掘服务端如何提供JSON RPC 服务。 服务端启动rpc server ➜ go-ethereum git:(master) ✗ tree -d -L 1 ├── cmd ├── geth ├── main.go ├── internal ├── ethapi ├── api.go ├── node ├── rpc ... go-ethereum的代码很多,单从发起一笔转账这样一个api而言,geth节点涉及的代码相对简单。 首先,cmd/geth/main.go是整个geth节点的entrypoint,main函数会实例化一个全功能的节点: func geth(ctx *cli.Context) error { node := makeFullNode(ctx) startNode(ctx, node) node.Wait() return nil } 实例化之后,将调用node/node.go中的Start方法,来配置node相应的服务, 然后启动,等到所有的服务启动完成之后,节点开启RPC服务,根据config将相应的服务注册到RPC服务的白名单中: func (s *Server) RegisterName(name string, rcvr interface{}) error { ... methods, subscriptions := suitableCallbacks(rcvrVal, svc.typ) ... svc.name = name svc. Read more

September 26, 2017

IPFS - 内容寻址的版本化点对点文件系统(草稿3) 翻译

IPFS - Content Addressed, Versioned, P2P File System (draft 3) 摘要 星际文件系统是一个点对点分布式文件系统, 旨在使用相同的文件系统连接所有的计算设备。在某种情形下,IPFS很类似Web,不过IPFS可以被看作一个独立的使用Git仓库来交换对象的BitTorrent集群。换句话说,IPFS提供了一个高吞吐量的以内容可寻址的块存储模型,具有内容寻址的超链接。这便形成了广义的Merkle DAG数据结构,这种数据结构可以构建成一个文件版本系统,区块链,甚至一个永久性Web。IPFS使用分布式哈希表,激励化的块交易模型和自我认证的命名空间。IPFS没有单独的故障节点,节点之间不需要完全信任基础。 1.介绍 关于构建全球分布式文件系统,已经有许多尝试。一些系统已经取得了重大的成功, 而一些却完全失败了。在学术尝试中, AFS[6] 就是成功的例子,并且得到广泛的应用。 然而,其他的[7, ?] 却没有成功。学术界之外,最成功的系统是面向音视频媒体的点对点文件共享系统。 最值得注意的是, Napster, KaZaA 和BitTorrent[2] 部署的文件分发系统可以支持1亿用户同时在线。即使今天, BitTorrent 也维持着每天千万节点的活跃数[16]。 相比学术文件系统,这些应用获得了更多的用户和文件分发,然而这些应用并没有被设计为基础设施。虽然这些应用已经取得了成功的回报,但目前还没有出现为全球提供低延迟和分散式分发的广义的文件系统。 也许是因为HTTP这样“足够好“的系统已经存在。到目前为止,HTTP作为最成功的“分布式文件系统“的协议已经大量部署,再与浏览器相结合,具有巨大的技术和社会影响力。它已经成为互联网传输文件的事实标准。然而,他没有采用最近15年的发明的数十种先进的文件分发技术。 从一方面讲, 由于向后兼容的限制和当前模式的强烈投入, 进化目前的Web基础架构几乎不可能。但从另一个角度看,自从出现了HTTP,新的协议已经出现并被广泛使用。目前的难题缺是升级设计:不会降低用户体验情况下引入新功能,以增强目前的HTTP Web。 长期使用HTTP的业界已经消失了,因为移动小文件是非常便宜,即使是具有大量流量的小型组织。但是,随着新的挑战,我们正在进入数据分发的新时代: (a)托管和分发PB级数据集 (b)计算跨组织的大数据 (c)按需量或实时媒体流量大规模高清晰度定义 (d)大规模数据集的版本化和链接 (e)防止重要文件的意外消失等。 许多这些可以归结为“大量数据,无处不在”。由于关键功能和带宽问题,我们已经放弃了不同数据的HTTP分发协议。下一步是使它们成为一部分的Web本身。 2.背景 本节回顾了IPFS所采用的点对点系统的重要技术特性。 2.1 分布式哈希表 分布式哈希表(DHTs)广泛的使用于定位和维持点对点系统的元数据。例如BitTorrent的MainlineDHT技术跟踪torrent集群的对等节点。 2.1.1 Kademlia DHT Kademlia[10] 是一个广泛流行的DHT,提供了一下特点: 大规模网络下高效查询:查询平均访问O(log2N)节点。(例如,1000万节点的网络需要20跳查询) 低协调开销:优化控制消息发送到其他节点的数量。 使用长时间在线节点来抵抗各种攻击。 广泛使用于点对点应用中,包括Gnutella和BitTorrent,形成了超过2000万个节点的网络[16]。 2.1.2 Coral DSHT 虽然一些对等文件系统直接在DHT中存储数据块,“不应该存储在节点的数据存储在节点会浪费存储和带宽”[5]。Coral DSHT通过以下三种方式扩展了Kademlia: Kademlia将值存储在距离其key最接近(使用XOR-distance)的节点中。这不考虑应用数据的局部性,忽略“远处”可能已经拥有此数据的节点,并强制“最近”节点存储它,无论它们是否需要。这将浪费了大量的存储和带宽。相反, Coral 存储了地址, 该地址的对等节点可以提供相应的数据块。 Coral将DHT API的get_value(key)换成了get_any_values(key)(DSHT中的“sloppy”)。这将依旧工作,是因为Coral用户只需要一个(工作)的对等节点,而不是完整的列表。作为回报,Coral可以仅将子集分配到“最近”的节点,避免热点(当密钥变得流行时,重载所有最近的节点)。 另外,Coral根据区域和大小组织了一个称为clusters的独立DSHT层次结构。这使得节点首先查询其区域中的对等体,“查找附近的数据而不查询远程节点”[5]并大大减少查找的延迟。 2. Read more

© Wade Van 2019

Powered by Hugo & Kiss.