长安链源码学习--账本 (七)

作者:明神特烦恼
公众号:明神特烦恼

在共识完成后进行区块提交阶段,对调用账本模块来对区块以及交易等进行持久化,本章节将一起分析一下账本模块实现过程。

带着问题读代码:
1)存储方式有哪些?
2)账本存储哪些内容,有哪些索引?
3)在写如多张数据库表,如果发生意外掉电,如何保证原子性?如何回滚?

第一个问题:存储方式有哪些?

   长安链支持nosql、sql两种形式的存储,其中nosql支持rocksdb、leveldb,sql支持mysql、sqlite。多种存储形式满足不同应用场景及业务要求。
   无论何种存储方式,上面已经高层封装,屏蔽掉底层存储逻辑,化简其他模块的操作复杂度,后面的分析以nosql为例。

const (
    UnknownDb EngineType = 0
    LevelDb   EngineType = 1
    RocksDb   EngineType = 2
    MySQL     EngineType = 3
    Sqlite    EngineType = 4
)

第二个问题:账本存储哪些内容,有哪些索引?(以nosql为例)

1.写块流程:

1)记录最新写入的块号lastBlockNumKeyStr

2)记录BlockHeightKeyBlockInfo关系:

  • BlockHeightKey = blockNumIdxKeyPrefix + blocknum
  • BlockInfo = 序列化(Header + Dag + TxIds + AdditionalData)

3)记录BlockHashKeyBlockHeight关系

  • BlockHashKey = blockHashIdxKeyPrefix + blockhash
  • BlockHeightKey

4)记录TxidKeyTxInfo 关系

  • TxidKey = txIDIdxKeyPrefix + txid
  • TxInfo = 序列化(Transaction)

5)记录BlockTxidKeyBlockHeightKey 关系

  • BlockTxidKey = blockTxIDIdxKeyPrefix + txid
  • BlockHeightKey

6)记录LastConfigKeyBlockHeightKey 关系(只有配置块记录该关系)

  • LastConfigKey = lastConfigBlockNumKey
  • BlockHeightKey

   账本模块通过上述记录的内容提供服务有:获取最后一个区块块号;通过块号获取块内容;通过块Hash获取块号;通过txid获取交易详情;通过txid获取其所在块号;获取最新配置块号。

2.写世界状态流程:

1)记录当前世界状态对应的最新块号stateDBSavepointKey

2)记录写入数据的KV值 Or 删除Key

  • Key:合约Name + WriteKey
  • Value:世界状态值
  • OP: 插入

Or

  • Key:合约Name + WriteKey
  • OP: 删除
3.写入历史数据库流程:

1)记录当前历史数据库对应的最新块号historyDBSavepointKey

2)记录操作的Key与块号、Txid关系

  • Key:合约Name + WriteKey + BlockHeight + Txid

3)记录操作账户与块号、Txid关系

  • Key:账号ID + BlockHeight + Txid

4)记录合约与块号、Txid关系

  • Key:合约名称 + BlockHeight + Txid
4. 写入合约结果流程:

1)记录当前合约结果数据库对应的最新块号:resultDBSavepointKey
2)记录RWSetsTxid与读写集之间的关系

  • RWSetsTxid:txRWSetIdxKeyPrefix + txid
  • 读写集:序列化(TxRWSet)

第三个问题:在写如多张数据库表,如果发生意外掉电,如何保证原子性?如何回滚?

   上面提到了多个流程,每个流程是原子操作,保证了事务一致性。但多个流程之间是非原子的,也就是世界状态写入完成,而写块流程还未完成,如果此时发生掉电(进程kill等),那么节点自身的数据将不完整,这是不被允许的。
   为解决掉电问题,长安链处理办法如下:
    - 同步写binlog,binlog非随机写入,机械硬盘执行速度较快。
    - 并发完成写块流程、写世界状态流程、历史数据库流程等。
    - 写入完成后,异步清理binlog。

   当进行crash后重启检测及恢复流程:
    - 创建存储Handler时判断binlog是否有内容,如果有下一步。
    - 获取binlog中记录最后一个log的块高度logSavepoint
    - 获取写块流程的最新块号lastBlockNumKeyStr,如果logSavepoint > lastBlockNumKeyStr,表示有区块数据未执行写块流程,调用CommitBlock进行写块。
    - 其他几个流程同理。

注意:
1) 这里要保证每个流程自身内部是原子的。
2) 恢复流程中并未删除binlog,这是因为binlog的处理是每100个块删除一次,并不需要实时删除,也不会产生存储泄露。
3)恢复流程没有回滚,只有继续写入。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容