-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Labels
Performanceimprove performanceimprove performance
Description
当前的实现
- 向钱包导入地址后,对于每个分支,从创世块开始向下遍历长链。
- 将每个块从block.dat读取出来,再序列化
- 从交易集合中选择与导入地址相关的放入到wallet中
优点
- 当地址相关的交易非常多时,效率高
- 使用
resyncwallet时,如果wallet中地址较多、关联的交易较多,效率高
缺点
- 当地址相关的交易较少时,效率很低
- 实际情况下,单个地址导入的平均效率低
改进方案
- 扩展block.dat的结构在CBlockEx基础上增加一个相关地址前序交易位置的数组
- block.dat中每个交易对应数组中的一项,每项数据包含两个二元组,第一个二元组是from地址的,第二个二元组是to地址的。每个二元组有两个数据(PrevDiskPos, txDiskPos),PrevDiskPos表示该地址上一个交易索引的位置,txDiskPos表示当前交易内容的位置
- 对于每一条分支创建一个leveldb数据库AddrTxIndex,key是上链的地址,value是最后一个交易索引的位置
- 当长链发生变化时,需要回滚更新AddrTxIndex(类似unspent表)
- 兼容性:
- 需要根据原block.dat重构所有文件和数据库
- 重构依据是block.dat中是否使用了新的nMagicNum,重构入口在checkrepair之前
- 首选清除原数据库(除block.dat,votedata.dat)
- 依次读取block.dat的块,不验证交易、块,写入到newblock.dat中
- 全部更新后,将newblock.dat改名为block.dat
查询某个地址的所有交易
- 查询每个fork的AddrTxIndex,如果没有则没有交易,如果有记录获得最后一个交易索引位置IndexPos
- 读取文件索引位置的二元组(PrevDiskPos, txDiskPos),获得了最后一个交易的位置txDiskPos保存下来,和上一个交易索引的位置
- 依次类推,直到PrevDiskPos = 0表明再无交易
- 将交易的位置信息由早到晚将交易从block.dat中取出,交由wallet。
优点
- 扩展性强
- 精准度高,检索的仅仅是该地址的交易所有交易
- 对于交易不多的地址效率高
缺点
- 交易量大的地址效率低于原实现
两种方案同时存在
- 在RPC
importprivkey,importpubkey,importkey,importtemplate中增加参数synctype,在参数sync开启时,默认使用新方式,也可以设置为旧方式(交易量大的地址) - 优化RPC
importwallet,在地址全部导入后调用resyncwallet(旧方式) - 再RPC
resyncwallet中增加参数synctype,默认使用旧方式,也可以设置为新方式
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Performanceimprove performanceimprove performance