catapult cache
Posted
※ アイキャッチ画像のロゴは私が勝手に書いたものです。決められたロゴはこれを書いている時点ではありません
catapultのキャッシュについて。
キャッシュは、メモリー上にトランザクションやブロック、各アカウントの状態などが貯められる場所だと思えば良い。
CatapultCache
catapultのキャッシュは、下記図のようなイメージの構造になっている。
実のところ、下記図は分かりやすくするために嘘をついていて、実際にはCatapultCache
が管理するのはSubCachesPlugin
のベクターで、そこに各キャッシュをあてるために、SubCachesPluginAdapter
を使って各キャッシュをCatapultCache
にaddしている。
SubCaches
これを書いている時点でcatapult cacheに登録されているサブキャッシュは下記表の通り。
no | name | id | supportMerkleRoot |
---|---|---|---|
1 | AccountStateCache | 0 | true |
2 | BlockDifficultyCache | 1 | false |
3 | HashCache | 2 | false |
4 | NamespaceCache | 3 | true |
5 | MosaicCache | 4 | true |
6 | MultisigCache | 5 | true |
7 | HashLockInfoCache | 6 | true |
8 | SecretLockInfoCache | 7 | true |
9 | PropertyCache | 8 | true |
StateHash
state hash
は、上記キャッシュのうち、supportMerkleRoot
がtrue
のものの状態を集計したハッシュ値になる。
catapultではこのstate hash
をBlockHeaderに詰めて、peerとのキャッシュの状態の整合性を確認できるようになっている。
つまり、生のトランザクションだけ送信し合うだけでなく、キャッシュの状態をハッシュ値としてやり取りする。これにより、状態が違う相手から送られてきたエンティティを判定して捨てることが出来る。
state hash
はLogの設定がDebug
の時に出力されるログから確認することが出来る。LogがDebug
モードの時、下記のようがログが出力されているはず。
2019-05-06 08:26:30.456527 0x00007f1eb4e2e700: <debug> (consumers::BlockChainProcessor.cpp@49) cache state hash (7 components) at height 10000
peer-node-1_1 | 1085E6C3C7F759181FDD0CC28C091528F134F1F1471C985CDF523021E0FF1D74 // これがcacheStateHash
peer-node-1_1 | + 114B6BAEFE4BAF7558CE68E26DA8584E5A7B7A53B4889CB0C7B0E838298FA4E0 // これが1つめのSubCacheのMerkelRootHash
peer-node-1_1 | + 6CD069EE3347EEBDED158E48B99765BD9614789631883C117E28037B42D6C187 // これが2つめのSubCacheのMerkelRootHash
peer-node-1_1 | + 65D0CDEB6F8C29A9B164C64FFBC7AD97DF2BA407FE868E1BBC11983DBFF3FB5A // これが3つめのSubCacheのMerkelRootHash
peer-node-1_1 | + 77943B010F0EFA3DEEB436E96D28841933E0710A91D236830DCD580676040CA1 // これが4つめのSubCacheのMerkelRootHash
peer-node-1_1 | + C2C2E584F0B5E0F865905FAC78815077D4065286EFAA80AF69563152A46D589D // これが5つめのSubCacheのMerkelRootHash
peer-node-1_1 | + 0000000000000000000000000000000000000000000000000000000000000000 // これが6つめのSubCacheのMerkelRootHash
peer-node-1_1 | + 9003CAB7B09CF23431FAFB9768AB10D27097A49A0587F61D9D6CB4CE4BB91962 // これが7つめのSubCacheのMerkelRootHash
state hash
の計算方法は、StateHash = Hash256( 1番目のCacheのMerkleRootHash | 2番目のCacheのMerkleRootHash | 3番目のCacheのMerkleRootHash... )
であり、上記ログの場合だと、下記のようになる。(疑似コード)
strBuffer = 114B6BAEFE4BAF7558CE68E26DA8584E5A7B7A53B4889CB0C7B0E838298FA4E0 // ID 0
+ 6CD069EE3347EEBDED158E48B99765BD9614789631883C117E28037B42D6C187 // ID 3
+ 65D0CDEB6F8C29A9B164C64FFBC7AD97DF2BA407FE868E1BBC11983DBFF3FB5A // ID 4
+ 77943B010F0EFA3DEEB436E96D28841933E0710A91D236830DCD580676040CA1 // ID 5
+ C2C2E584F0B5E0F865905FAC78815077D4065286EFAA80AF69563152A46D589D // ID 6
+ 0000000000000000000000000000000000000000000000000000000000000000 // ID 7
+ 9003CAB7B09CF23431FAFB9768AB10D27097A49A0587F61D9D6CB4CE4BB91962 // ID 8
byteBuffer = hex2byte( strBuffer )
hash = Hash::Sha3::256.hexDigest( byteBuffer )
hash == 1085E6C3C7F759181FDD0CC28C091528F134F1F1471C985CDF523021E0FF1D74 // true
下記、CatapultCache.cpp
内のCollectSubCacheMerkleRoots関数
によって集計されるCacheのIDを出力させてみた結果。これにより、上記MerkleRootHashの順番は、IDによってソートされていることが分かる。
2019-05-09 00:40:12.171045 0x00007f2986f2fac0: <debug> (cache::CatapultCache.cpp@59) CollectSubCacheMerkleRoots CaheID : 0
2019-05-09 00:40:12.171235 0x00007f2986f2fac0: <debug> (cache::CatapultCache.cpp@59) CollectSubCacheMerkleRoots CaheID : 3
2019-05-09 00:40:12.171543 0x00007f2986f2fac0: <debug> (cache::CatapultCache.cpp@59) CollectSubCacheMerkleRoots CaheID : 4
2019-05-09 00:40:12.171667 0x00007f2986f2fac0: <debug> (cache::CatapultCache.cpp@59) CollectSubCacheMerkleRoots CaheID : 5
2019-05-09 00:40:12.171757 0x00007f2986f2fac0: <debug> (cache::CatapultCache.cpp@59) CollectSubCacheMerkleRoots CaheID : 6
2019-05-09 00:40:12.171839 0x00007f2986f2fac0: <debug> (cache::CatapultCache.cpp@59) CollectSubCacheMerkleRoots CaheID : 7
2019-05-09 00:40:12.171950 0x00007f2986f2fac0: <debug> (cache::CatapultCache.cpp@59) CollectSubCacheMerkleRoots CaheID : 8
ちなみに、キャッシュが空の時のMerkleRootは0000000000000000000000000000000000000000000000000000000000000000
になる。