学习记录:fabric(6)- 系统设计(2)

新开一节,继续做项目

出现一个很有趣的问题,ENDORSEMENT_POLICY_FAILURE。官网教程可以搜得到,但其实不是那样的。

后来发现是我调用mysql,创建表,然后肯定另一个节点运行不通啊。。。那一个节点成功,另一个不成功,那肯定返回出错呀。。。

所以这就需要考虑到背书阶段,看看怎么在背书之后再执行。

现在两个思路,1,如果能够找到入口,那就可以;2,不行就用定时器,任务队列这样。3.两步法,第一步日志上链,返回交易id,第二步调用交易id执行命令ExecTx2SQL。

所以,现在以便排除这个错误,一边先把其他的SQL语句构建弄好。

条件的构建,可能还是得用sql-build,这个能简单些。

现在弄好了,CreateTable,TableExist,DropTable,RenameTable,InsertRecord,UpdateRecord,DeleteRecord,GetRecord。

现在的核心问题依然是:需要先共识,再执行SQL。所以还是考虑那两个方法1)弄一个定时任务,就是隔一段时间,查询当达成了共识,则执行。(也就是有一些延迟)。2)查看能不能通过客户端两步执行。

第一个方法要关注一下能不能获得账本信息;第二个方法是要看peer能不能实时的获得共识结果。

// GetState returns the value of the specified `key` from the
	// ledger. Note that GetState doesn't read data from the writeset, which
	// has not been committed to the ledger. In other words, GetState doesn't
	// consider data modified by PutState that has not been committed.
	// If the key does not exist in the state database, (nil, nil) is returned.
	GetState(key string) ([]byte, error)

	// PutState puts the specified `key` and `value` into the transaction's
	// writeset as a data-write proposal. PutState doesn't effect the ledger
	// until the transaction is validated and successfully committed.
	// Simple keys must not be an empty string and must not start with a
	// null character (0x00) in order to avoid range query collisions with
	// composite keys, which internally get prefixed with 0x00 as composite
	// key namespace. In addition, if using CouchDB, keys can only contain
	// valid UTF-8 strings and cannot begin with an underscore ("_").
	PutState(key string, value []byte) error

GetState可以获取账本信息,获取不到还未达成共识的。

应该是做成一个队列,定时器不断的检测队列。

在同一个方法内部是不能等待的,肯定得不到结果。因为节点上还没执行完成,所以必须二次才会有结果。只能是发送,返回一个已经提交任务。二次请求才行。

现在尝试一下这种做法。当然,同时队列也加上,在查到数据后,自动执行SQL。这样我可以看看到底多久可以查到数据

不行,使用go语句执行异步线程不成功,出现了Failed to handle GET_STATE. error: no ledger context。无法获取到账本的信息。

通过在客户端再次调用GetValue,看到,其实已经提交成功。但是在链码中使用go语句异步执行是不行的。
学习记录:fabric(6)- 系统设计(2)其实这里,就有一个问题,就是得改fabric本身了,也就是队列要构建在fabric中,这样才能在共识执行完成之后,一个挨着一个去执行。其实就是peer节点内部。那这样一来,mysql的连接操作,也得放进mysql了。链码中,其实就成了一个SQL语句组织和方法的调用。
学习记录:fabric(6)- 系统设计(2)按照chainsql的这个内容,其实就是应该返回一个交易id,在链码中,我是使用交易ID作为key写入了SQL语句。
所以,在fabric中应当可以查到相关内容,并进行读取。
这一点还需验证,就是顺着fabric的peer部分,查看一下,为peer添加逻辑:1.队列,2.mysql数据库操作

转进fabric

现在的任务变成了如何把fabric自主编译一下。先看fabric代码如何编译,这样才能修改。

fabric编译遇到一个问题:go install: cannot install cross-compiled binaries when GOBIN is set

先看懂makefile。

注意:把go的GOARCH设为amd64,因为本机是linux/amd64,不要设为别的,之前设为386,算是跨平台。
注意:注意开启*,有些东西要下载。

这里还能打包自定义的docker镜像。

学习记录:fabric(6)- 系统设计(2)

等下专门写一个MakeFile的解析。

或者应当搞清楚链码的执行流程。

第二种方法

客户端两步执行,
学习记录:fabric(6)- 系统设计(2)
看到了这个东西,如果能够监听到区块变化,然后真正执行,那就没问题了。

反正把SDK封装成一个新的SDK,chainsql也是封装了ripple。

学习记录:fabric(6)- 系统设计(2)测试得到,每一次putstate,会出现新的区块。

解析一下区块数据是什么,看看能不能找到真正的数据.

可以的,二步法是可行的。可以获取到区块内部的详细信息。

// listener内部
var block  = event.blockData;
var payload = block.data.data[0].payload 
var rwset = payload.data.actions[0].payload.action.proposal_response_payload.extension.results.ns_rwset


network.addBlockListener(listener);

block的一些介绍
学习记录:fabric(6)- 系统设计(2)那个listener也不用加什么option,默认就是监听最近的一个块。那刚刚提交了,肯定是获取包含刚刚交易的最近一个块。

现在就是还得试试不能达成一致的时候会不会获取不到东西,处理一下错误情况。
不用担心了,共识失败,外部直接会出错。

这是暂时比较靠谱的一个玩法,先把这个弄通。

现在把重要的表操作都真正实现,不过这里注意,表创建还是不行的,因为这里我操作的是同一个数据库

现在不需要,其实直接从第一次的result中提取txid即可,然后调用。现在写一下chaincode的执行SQL。

可以了,扩展。

现在还有一个时间过长需要检查数据库连接的问题。因为可能断开。而且也不能长时间保持连接。

  1. 数据加密
  2. 节点间同步
  3. 表权限

第一个是基础,先得能够加密,然后构造表

ClientID, table_name, table_name_in_db, tx hash, block hash, block num, deleted, autosync, tx_time

主要是有一个自动同步的东西比较难操作,这个东西如果纯用链码,需要参照账本中的信息,进行操作。

参考

  • https://blog.csdn.net/qq_22211217/article/details/102729151
  • http://cn.piliapp.com/mysql-syntax-check/ SQL语法检查
  • https://blog.csdn.net/darmao/article/details/81077055
  • https://my.oschina.net/jamesren/blog/3123882
上一篇:基于Actor模型的CQRS/ES解决方案分享


下一篇:fabric安装环境和运行测试网络时的踩坑合集!