上个月刚入职一家公司从事区块链研发工作,选型采用Hyperledger Fabric作为开发平台。团队的小组成员全部采用的是在VirtualBox上面安装桌面版的Ubuntu 16.04虚拟机,开发工具JetBrains GoLand也就直接在桌面版的虚拟机里面安装。而我因为之前比较习惯使用Vagrant + VirtualBox的方式快速加载我定制版的Ubuntu镜像从而创建Linux开发环境,这样一来的弊端就是我只能通过命令行来进行一切操作而没有桌面可操作,所以我的整个开发IDE就在本机的windows上进行。
我们的Fabric网络是采用的Docker方式启动,作为自己本地的测试环境自然就将网络搭建在Ubuntu虚拟机里面,前期由其它小组成员负责针对Go语言版本的SDK(Hyperledger子项目fabric-sdk-go)进行封装调用并利用Beego作为服务器将相应的API暴露出来,而我负责的便是将他们暴露出来的API进一步封装为标准Go版的SDK,所谓的标准就是对调用者而言无感是调用的区块链。这个时候问题就出现了,在我写SDK的过程中用单元测试对他们的API发起Http请求调用时一脸懵逼,观察Beego服务器打印的日志信息少的可怜几乎没有,以前从来不习惯用断点调试的我这个时候首先想到的便是希望能够在他们的API服务中加入适当的断点以便我这边的SDK发起请求时能够一步步跟踪到底,然而他们的API服务Beego也是部署在Ubuntu虚拟机中,对于他们自己开发来说反正开发工具IDE也在桌面版的Ubuntu中所以天然在IDE中启动断点调试没有丁点儿问题,那我的IDE在本地windows上,所以我需要在我的IDE中Debug运行他们的API服务,这个时候麻烦来了,API服务因为封装了对fabric-sdk-go的调用,也就意味着我需要做一些调整以便能够让他们的API服务能够从我的本地windows连接到虚拟机里面的Fabric网络,只有这样才可以完成从我的SDK发起Http请求到他们的API服务,再由API去通过fabric-sdk-go发起对Ubuntu虚拟机上Fabric网络的操作这样一个完整的流程。
说下我是如何让本地windows的API服务连接到Ubuntu虚拟机里面的Fabric网络的。其实连接Fabric网络是他们API所封装的fabric-sdk-go,那么最关键的配置无疑便是config_fabric.yaml配置文件。在那个配置文件中有一系列要访问Fabric网络所需的crypto,msp,tls等物理路径,所以自然需要将其中${GOPATH}全部替换为本地windows的GOPATH绝对路径。本以为这样就可以完事大吉,可没想到这个时候无论我怎样调用,他们的API始终在初始化fabric sdk的时候报错,无奈只好在初始化的时候打断点往进跟,跟的具体细节(坑也不少)就不展示了,关键部分如下图。
终于明白原来它从fabric_config.yaml中读取到systemCertPool属性的值应该为true,以致于调用了x509.SystemCertPool()方法,最终由于runtime.GOOS == "windows",自然就抛出"crypto/x509: system root pool is not available on Windows"这样的异常信息从而初始化SDK失败。
查看fabric_config.yaml配置文件,果然systemCertPool为true,如下图:
到这里本以为就算搞定了,便从我的SDK发起了一个创建Channel的单元测试,结果虽然没报错但是Ubuntu虚拟机上的Fabric网络后台一行日志都没打印,很显然Fabric网络的创建通道命令并没有被API端的fabric-sdk-go所触发,可是初始化已经成功了,只能再次在创建通道部分进行断点跟踪,发现在创建通道时候需要传递的通道配置文件txFile文件还是之前在Ubuntu虚拟机下的绝对路径,在SDK单元测试创建通道功能的时候将传递的txFile设为本地windows上的tx文件绝对路径,再次运行创建通道单元测试搞定!自此windows跟Ubuntu虚拟机的Fabric网络正式打通,以后便可以在windows上利用IDE以Debug模式启动他们的API服务,我的SDK发起调用时便可以轻松利用断点调试来跟踪底层执行逻辑。
作为一名纯软件工程专业毕业的程序猿,以前总觉得自己的逻辑思维能力够强,靠想象来感觉代码的执行流程,靠感觉来判断问题应该出在哪里,通过这次的经历深刻意识到断点调试的重要性,从今往后遇到bug一定第一时间用debug来执行调试,相信一定会节约不少宝贵的时间从而提高工作效率~
- 还没有人评论,欢迎说说您的想法!