前些天一个交易所的小伙伴在一个微信群里说HIVE分叉后,他们的程序受到一些影响,比如transfer功能报错,以及condenser_api.get_transaction返回中缺少了irreversible字段。
(图源 :pixabay)
然后@abit 建议他们去Telegram群里问问,可能是时差的问题,Telegram群里活跃的技术专家都不在,于是
@abit让我来瞧瞧是怎么回事。
帮交易所就是帮hive社区,就是帮我们自己,当然义不容辞喽。
transfer出错
他们使用的是HIveJS,我首先怀疑就是版本的问题,因为HF24修改了HIVE的chainid,而交易序列化/签名的时候要用到chainid,一旦chainid设错,那么签名出来的就是错误的结果,广播出去的内容当然不会被接受啦。
和他们核实一下,他们确实使用的是老版本的库,于是在我的建议下升级了库,可是还是出错,那这就不科学了。去看了一下他们的出错信息:
AssertionError [ERR_ASSERTION]: Expected version 128, instead got 8
然后去看了一下HiveJS的源码,是代码中这句引起的出错信息:
assert.equal(0x80, version,Expected version ${0x80}, instead got ${version});
而上述代码是在解析私钥的函数中,还没涉及到序列化/签名/广播等操作呢,所以一定是他们用错私钥了,而且大概率是把密码当成私钥使用了。
和他们确认一下,确实是这个问题,然后放置正确的私钥后,transfer功能正常使用了。
所以他们所遇到的transfer的问题是使用了旧版本的库以及将密码错当成私钥,解决的方法就是使用新版本的库以及使用正确的私钥。
get_transaction & irreversible字段
按着他们技术人员的描述,condenser_api.get_transaction这个调用以前会返回一个irreversible字段,用来判断transaction是否不可逆,但是HF24后,这个字段不见了。
我大概看了一下代码,根绝代码我的猜测是condenser_api.get_transaction只会返回不可逆的交易,但是我并不确认这个事,于是在开发者频道中向大家请教,@blocktrades 给了我如下答复:
The call has only ever returned irreversible transactions for the rocksdb plugin. At some point, we'll probably add support for this new flag to get_transaction as well, but despite the number of programmers we have working on hived/hivemind, we have to prioritize some.
后来看代码发现可以使用类似如下的方式来只查询不可逆交易:
{"jsonrpc":"2.0", "method":"account_history_api.get_transaction", "params":{"id":"6fde0190a97835ea6d9e651293e90c89911f933c", "include_reversible":false}, "id":1}
但是实质上include_reversible这个标志尽管在,然而其实并不起作用,@blocktrades 给我的答复:
The parameter was added for future implementation, but it's effectively ignored right now. You can ssee that here: https://gitlab.syncad.com/hive/hive/-/blob/master/libraries/plugins/account_history_rocksdb/account_history_rocksdb_plugin.cpp#L1429
那么如何判断交易是否是不可逆的呢?@arcange 给出了如下建议,看起来也不错:
One thing they can do is to call
condenser_api.get_transactionand compare theblock_numvalue returned againstlast_irreversible_block_numreturned bydatabase_api.get_dynamic_global_properties
但是后来 @gtg 给出如下建议:
Please note that there's also a
transaction_statusandtransaction_status_api
我测试了一下,transaction_status_api工作正常,可以通过txid查询交易的状态,那么这个问题也算是解决啦。
总结一下就是HF24以后condenser_api.get_transaction不返回irreversible字段,尽管“The call has only ever returned irreversible transactions for the rocksdb plugin”,但是用transaction_status_api查一下状态更放心,反正都是程序再做,多加一条语句累不到。
其它
他们还遇到公共节点没法查询账户历史记录的问题(返回为空),这个我建议他们换一个节点就解决啦。
感谢@blocktrades
@arcange
@gtg 以及其它小伙伴在这个过程中给予的帮助(排名不分先后)。