Skip to content

Commit

Permalink
feat(lib/blocktree): reduce the entries in the runtimes mapping (#3151)
Browse files Browse the repository at this point in the history
Co-authored-by: Quentin McGaw <quentin.mcgaw@gmail.com>
  • Loading branch information
EclesioMeloJunior and qdm12 committed Jun 7, 2023
1 parent 9116bcf commit 1a34972
Show file tree
Hide file tree
Showing 13 changed files with 1,352 additions and 157 deletions.
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ services:
- ./docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
# The following line can be uncommented to persist metrics data.
# - gossamer-prometheus:/prometheus
ports:
- 9090:9090/tcp # HTTP Web interface at http://localhost:9090/
expose:
- 9090/tcp # Prometheus metrics for Grafana

Expand Down
176 changes: 116 additions & 60 deletions docker/grafana/provisioning/dashboards/gossamer.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,65 +155,6 @@
"title": "Threads",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus_id"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "fixed"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "bytes"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 3,
"x": 6,
"y": 1
},
"id": 38,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"lastNotNull"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "9.0.4",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus_id"
},
"expr": "process_resident_memory_bytes{instance=~\".*gossamer.*\"}",
"refId": "A"
}
],
"title": "Memory usage",
"type": "stat"
},
{
"datasource": {
"type": "prometheus",
Expand Down Expand Up @@ -309,6 +250,30 @@
"range": true,
"refId": "B"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus_id"
},
"editorMode": "code",
"expr": "go_memstats_heap_idle_bytes{instance=~\".*gossamer.*\"}",
"hide": false,
"legendFormat": "Heap Idle Bytes",
"range": true,
"refId": "C"
},
{
"datasource": {
"type": "prometheus",
"uid": "prometheus_id"
},
"editorMode": "code",
"expr": "go_memstats_heap_released_bytes{instance=~\".*gossamer.*\"}",
"hide": false,
"legendFormat": "Heap Idle Bytes",
"range": true,
"refId": "D"
},
{
"datasource": {
"type": "prometheus",
Expand All @@ -319,12 +284,103 @@
"hide": false,
"legendFormat": "Stack",
"range": true,
"refId": "C"
"refId": "E"
}
],
"title": "Memory usage",
"type": "timeseries"
},
{
"datasource": {
"uid": "prometheus_id",
"type": "prometheus"
},
"fieldConfig": {
"defaults": {
"custom": {
"drawStyle": "line",
"lineInterpolation": "linear",
"barAlignment": 0,
"lineWidth": 1,
"fillOpacity": 0,
"gradientMode": "none",
"spanNulls": false,
"showPoints": "auto",
"pointSize": 5,
"stacking": {
"mode": "none",
"group": "A"
},
"axisPlacement": "auto",
"axisLabel": "",
"axisColorMode": "text",
"scaleDistribution": {
"type": "linear"
},
"axisCenteredZero": false,
"hideFrom": {
"tooltip": false,
"viz": false,
"legend": false
},
"thresholdsStyle": {
"mode": "off"
}
},
"color": {
"mode": "palette-classic"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "bytes"
},
"overrides": []
},
"gridPos": {
"h": 9,
"w": 12,
"x": 0,
"y": 16
},
"id": 40,
"options": {
"tooltip": {
"mode": "multi",
"sort": "none"
},
"legend": {
"showLegend": true,
"displayMode": "list",
"placement": "bottom",
"calcs": []
}
},
"pluginVersion": "9.0.4",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "prometheus_id"
},
"refId": "A",
"editorMode": "builder",
"expr": "gossamer_inmemory_runtimes_total{instance=~\".*gossamer.*\"}",
"legendFormat": "Runtimes",
"range": true
}
],
"title": "In Memory Runtimes",
"type": "timeseries",
"description": ""
},
{
"gridPos": {
"h": 1,
Expand Down
2 changes: 2 additions & 0 deletions docker/prometheus/prometheus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ scrape_configs:
- job_name: gossamer
metrics_path: /metrics
static_configs:
# for mac users, change to host.docker.internal:9876 if you want to
# communicate prometheus container with gossamer running locally
- targets: ["gossamer:9876"]
5 changes: 3 additions & 2 deletions dot/core/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,14 @@ func (s *Service) handleBlock(block *types.Block, state *rtstorage.TrieState) er
logger.Debugf("imported block %s and stored state trie with root %s",
block.Header.Hash(), state.MustRoot())

rt, err := s.blockState.GetRuntime(block.Header.ParentHash)
parentRuntimeInstance, err := s.blockState.GetRuntime(block.Header.ParentHash)
if err != nil {
return err
}

// check for runtime changes
if err := s.blockState.HandleRuntimeChanges(state, rt, block.Header.Hash()); err != nil {
err = s.blockState.HandleRuntimeChanges(state, parentRuntimeInstance, block.Header.Hash())
if err != nil {
logger.Criticalf("failed to update runtime code: %s", err)
return err
}
Expand Down
119 changes: 72 additions & 47 deletions dot/core/service_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,86 +497,111 @@ func TestService_GetMetadata(t *testing.T) {
}

func TestService_HandleRuntimeChanges(t *testing.T) {
const (
updatedSpecVersion = uint32(262)
updateNodeRuntimeWasmPath = "../../tests/polkadotjs_test/test/node_runtime.compact.wasm"
)
s := NewTestService(t, nil)
genesisHeader, err := s.blockState.BestBlockHeader()
require.NoError(t, err)

bestBlockHash := s.blockState.BestBlockHash()
rt, err := s.blockState.GetRuntime(bestBlockHash)
genesisBlockHash := genesisHeader.Hash()
genesisStateRoot := genesisHeader.StateRoot

ts, err := s.storageState.TrieState(&genesisStateRoot) // Pass genesis root
require.NoError(t, err)

v, err := rt.Version()
firstBlockHash := createBlockUsingOldRuntime(t, genesisBlockHash, ts, s.blockState)
updateNodeRuntimeWasmPath, err := runtime.GetRuntime(context.Background(), runtime.WESTEND_RUNTIME_v0929)
require.NoError(t, err)

currSpecVersion := v.SpecVersion // genesis runtime version.
hash := s.blockState.BestBlockHash() // genesisHash
secondBlockHash := createBlockUsingNewRuntime(t, genesisBlockHash, updateNodeRuntimeWasmPath, ts, s.blockState)

digest := types.NewDigest()
err = digest.Add(types.PreRuntimeDigest{
ConsensusEngineID: types.BabeEngineID,
Data: common.MustHexToBytes("0x0201000000ef55a50f00000000"),
})
// firstBlockHash runtime should not be updated
genesisRuntime, err := s.blockState.GetRuntime(genesisBlockHash)
require.NoError(t, err)

newBlock1 := &types.Block{
Header: types.Header{
ParentHash: hash,
Number: 1,
Digest: types.NewDigest()},
Body: *types.NewBody([]types.Extrinsic{[]byte("Old Runtime")}),
}
firstBlockRuntime, err := s.blockState.GetRuntime(firstBlockHash)
require.NoError(t, err)

newBlockRTUpdate := &types.Block{
Header: types.Header{
ParentHash: hash,
Number: 1,
Digest: digest,
},
Body: *types.NewBody([]types.Extrinsic{[]byte("Updated Runtime")}),
}
genesisRuntimeVersion, err := genesisRuntime.Version()
require.NoError(t, err)

ts, err := s.storageState.TrieState(nil) // Pass genesis root
firstBlockRuntimeVersion, err := firstBlockRuntime.Version()
require.NoError(t, err)

parentRt, err := s.blockState.GetRuntime(hash)
require.Equal(t, genesisRuntimeVersion, firstBlockRuntimeVersion)

secondBlockRuntime, err := s.blockState.GetRuntime(secondBlockHash)
require.NoError(t, err)

v, err = parentRt.Version()
const updatedSpecVersion = uint32(9290)
secondBlockRuntimeVersion, err := secondBlockRuntime.Version()
require.NoError(t, err)

require.Equal(t, v.SpecVersion, currSpecVersion)
require.Equal(t, updatedSpecVersion, secondBlockRuntimeVersion.SpecVersion)
}

bhash1 := newBlock1.Header.Hash()
err = s.blockState.HandleRuntimeChanges(ts, parentRt, bhash1)
func createBlockUsingOldRuntime(t *testing.T, bestBlockHash common.Hash, trieState *rtstorage.TrieState,
blockState BlockState) (blockHash common.Hash) {
parentRt, err := blockState.GetRuntime(bestBlockHash)
require.NoError(t, err)

testRuntime, err := os.ReadFile(updateNodeRuntimeWasmPath)
primaryDigestData := types.NewBabePrimaryPreDigest(0, uint64(0), [32]byte{}, [64]byte{})
digest := types.NewDigest()
preRuntimeDigest, err := primaryDigestData.ToPreRuntimeDigest()
require.NoError(t, err)
err = digest.Add(*preRuntimeDigest)
require.NoError(t, err)

ts.Put(common.CodeKey, testRuntime)
rtUpdateBhash := newBlockRTUpdate.Header.Hash()
newBlock := &types.Block{
Header: types.Header{
ParentHash: bestBlockHash,
Number: 1,
Digest: digest,
},
Body: *types.NewBody([]types.Extrinsic{[]byte("Old Runtime")}),
}
err = blockState.AddBlock(newBlock)
require.NoError(t, err)

// update runtime for new block
err = s.blockState.HandleRuntimeChanges(ts, parentRt, rtUpdateBhash)
newBlockHash := newBlock.Header.Hash()
err = blockState.HandleRuntimeChanges(trieState, parentRt, newBlockHash)
require.NoError(t, err)

// bhash1 runtime should not be updated
rt, err = s.blockState.GetRuntime(bhash1)
return newBlockHash
}

func createBlockUsingNewRuntime(t *testing.T, bestBlockHash common.Hash, newRuntimePath string,
trieState *rtstorage.TrieState, blockState BlockState) (blockHash common.Hash) {
parentRt, err := blockState.GetRuntime(bestBlockHash)
require.NoError(t, err)

v, err = rt.Version()
testRuntime, err := os.ReadFile(newRuntimePath)
require.NoError(t, err)
require.Equal(t, v.SpecVersion, currSpecVersion)

rt, err = s.blockState.GetRuntime(rtUpdateBhash)
trieState.Put(common.CodeKey, testRuntime)

primaryDigestData := types.NewBabePrimaryPreDigest(0, uint64(1), [32]byte{}, [64]byte{})
digest := types.NewDigest()
preRuntimeDigest, err := primaryDigestData.ToPreRuntimeDigest()
require.NoError(t, err)
err = digest.Add(*preRuntimeDigest)
require.NoError(t, err)

newBlockRuntimeUpdate := &types.Block{
Header: types.Header{
ParentHash: bestBlockHash,
Number: 1,
Digest: digest,
},
Body: *types.NewBody([]types.Extrinsic{[]byte("Updated Runtime")}),
}

err = blockState.AddBlock(newBlockRuntimeUpdate)
require.NoError(t, err)

v, err = rt.Version()
newBlockRTUpdateHash := newBlockRuntimeUpdate.Header.Hash()
err = blockState.HandleRuntimeChanges(trieState, parentRt, newBlockRTUpdateHash)
require.NoError(t, err)

require.Equal(t, v.SpecVersion, updatedSpecVersion)
return newBlockRTUpdateHash
}

func TestService_HandleCodeSubstitutes(t *testing.T) {
Expand Down
Loading

0 comments on commit 1a34972

Please sign in to comment.