catapult cache

catapult

※ アイキャッチ画像のロゴは私が勝手に書いたものです。決められたロゴはこれを書いている時点ではありません

catapultのキャッシュについて。

キャッシュは、メモリー上にトランザクションやブロック、各アカウントの状態などが貯められる場所だと思えば良い。

CatapultCache

catapultのキャッシュは、下記図のようなイメージの構造になっている。

実のところ、下記図は分かりやすくするために嘘をついていて、実際にはCatapultCacheが管理するのはSubCachesPluginのベクターで、そこに各キャッシュをあてるために、SubCachesPluginAdapterを使って各キャッシュをCatapultCacheにaddしている。

draw1

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は、上記キャッシュのうち、supportMerkleRoottrueのものの状態を集計したハッシュ値になる。

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になる。