Skip to content

Commit

Permalink
fix decoder (#133)
Browse files Browse the repository at this point in the history
* fix decoder

* update

* update template to include deltas
  • Loading branch information
ermalkaleci authored Jan 10, 2023
1 parent fe7c53e commit 8391a19
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 33 deletions.
8 changes: 4 additions & 4 deletions e2e/decoder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ const TOKENS_ACCOUNTS =

describe('decoder', () => {
it('decode keys', async () => {
const [storage, key] = await decodeKey(chain.head, SYSTEM_ACCOUNT)
expect(storage.section).eq('system')
expect(storage.method).eq('account')
expect(key.args.map((x) => x.toHuman())).contains('25fqepuLngYL2DK9ApTejNzqPadUUZ9ALYyKWX2jyvEiuZLa')
const { storage, decodedKey } = await decodeKey(chain.head, SYSTEM_ACCOUNT)
expect(storage?.section).eq('system')
expect(storage?.method).eq('account')
expect(decodedKey?.args.map((x) => x.toHuman())).contains('25fqepuLngYL2DK9ApTejNzqPadUUZ9ALYyKWX2jyvEiuZLa')
})

it('decode key-value', async () => {
Expand Down
15 changes: 9 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const defaultOptions = {
},
block: {
desc: 'Block hash or block number. Default to latest block',
string: true,
},
'wasm-override': {
desc: 'Path to wasm override',
Expand Down Expand Up @@ -144,11 +143,15 @@ yargs(hideBin(process.argv))
}),
async (argv) => {
const context = await setup(processArgv(argv))
const [storage, decodedKey] = await decodeKey(context.chain.head, argv.key as HexString)
console.log(
`${storage.section}.${storage.method}`,
decodedKey.args.map((x) => JSON.stringify(x.toHuman())).join(', ')
)
const { storage, decodedKey } = await decodeKey(context.chain.head, argv.key as HexString)
if (storage && decodedKey) {
console.log(
`${storage.section}.${storage.method}`,
decodedKey.args.map((x) => JSON.stringify(x.toHuman())).join(', ')
)
} else {
console.log('Unknown')
}
process.exit(0)
}
)
Expand Down
66 changes: 46 additions & 20 deletions src/utils/decoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { StorageEntry } from '@polkadot/types/primitive/types'
import { StorageKey } from '@polkadot/types'
import { create } from 'jsondiffpatch'
import { hexToU8a, u8aToHex } from '@polkadot/util'
import { merge, zipObjectDeep } from 'lodash'
import _ from 'lodash'

const diffPatcher = create({ array: { detectMove: false } })

Expand All @@ -28,29 +28,57 @@ const getStorageEntry = async (block: Block, key: HexString) => {
throw new Error(`Cannot find key ${key}`)
}

export const decodeKey = async (block: Block, key: HexString): Promise<[StorageEntry, StorageKey]> => {
export const decodeKey = async (
block: Block,
key: HexString
): Promise<{ storage?: StorageEntry; decodedKey?: StorageKey }> => {
const meta = await block.meta
const storage = await getStorageEntry(block, key)
const storage = await getStorageEntry(block, key).catch(() => undefined)
const decodedKey = meta.registry.createType('StorageKey', key)
decodedKey.setMeta(storage.meta)
return [storage, decodedKey]
if (storage) {
decodedKey.setMeta(storage.meta)
return { storage, decodedKey }
}
return {}
}

export const decodeKeyValue = async (block: Block, key: HexString, value?: HexString | null) => {
const meta = await block.meta
const [entry, storageKey] = await decodeKey(block, key)
const { storage, decodedKey } = await decodeKey(block, key)

if (!storage || !decodedKey) {
return { [key]: value }
}

const decodedValue = meta.registry.createType(storageKey.outputType, hexToU8a(value))
const decodedValue = meta.registry.createType(decodedKey.outputType, hexToU8a(value))

return {
[entry.section]: {
[entry.method]:
storageKey.args.length > 0
? {
...zipObjectDeep([storageKey.args.map((x) => x.toString()).join('.')], [decodedValue.toHuman()]),
}
: decodedValue.toHuman(),
},
switch (decodedKey.args.length) {
case 2: {
return {
[storage.section]: {
[storage.method]: {
[decodedKey.args[0].toString()]: {
[decodedKey.args[1].toString()]: decodedValue.toHuman(),
},
},
},
}
}
case 1: {
return {
[storage.section]: {
[storage.method]: {
[decodedKey.args[0].toString()]: decodedValue.toHuman(),
},
},
}
}
default:
return {
[storage.section]: {
[storage.method]: decodedValue.toHuman(),
},
}
}
}

Expand All @@ -61,10 +89,8 @@ export const decodeStorageDiff = async (block: Block, diff: [HexString, HexStrin
const oldState = {}
const newState = {}
for (const [key, value] of diff) {
// ignore keys less than 32 chars long because they're not pallet storage
if (key.length < 66) continue
merge(oldState, await decodeKeyValue(block, key as HexString, (await parent.get(key)) as any))
merge(newState, await decodeKeyValue(block, key as HexString, value))
_.merge(oldState, await decodeKeyValue(block, key as HexString, (await parent.get(key)) as any))
_.merge(newState, await decodeKeyValue(block, key as HexString, value))
}
return [oldState, newState, diffPatcher.diff(oldState, newState)]
}
25 changes: 22 additions & 3 deletions template/diff.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@
.unchanged {
color: #666;
}
.delta {
color: #ccc;
font-size: 12px;
margin: 0 10px;
}
</style>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js" crossorigin></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js" crossorigin></script>
Expand Down Expand Up @@ -102,6 +107,17 @@
);
}

function renderDelta(value) {
if (/^\d+(,\d+)*$/.test(value[1])) {
const oldValue = parseInt(value[0].replace(/,/g, ''))
const newValue = parseInt(value[1].replace(/,/g, ''))
if (oldValue > 0 && newValue > 0) {
const delta = newValue - oldValue
return (<span className="delta" >{delta > 0 ? '+' : ''}{delta}</span>)
}
}
}

if (isDelta && Array.isArray(value)) {
switch (value.length) {
case 0:
Expand Down Expand Up @@ -131,6 +147,7 @@
'diffUpdateTo',
stringifyAndShrink(value[1])
)}
{renderDelta(value)}
</span>
);
case 3:
Expand All @@ -150,7 +167,9 @@
};

function prepareDelta(value) {
if (value && value._t === 'a') {
if (!value) return value;

if (value._t === 'a') {
const res = {};
for (const key in value) {
if (key !== '_t') {
Expand All @@ -165,7 +184,7 @@
}
return res;
} else {
if (Array.isArray(value) && value.length === 3 && value[0].length > 2 && value[0].slice(0, 2) === '@@') {
if (Array.isArray(value) && value.length === 3 && typeof value[0] === 'string' && value[0].startsWith('@@')) {
const [left, right] = value[0].split("@@").filter(x => x.length > 0)
const items = right.split("\n").slice(1).filter(x => x.length > 0)
const oldValue = items.filter(x => x[0] !== '+').map(x => x.slice(1)).join('')
Expand Down Expand Up @@ -216,7 +235,7 @@
<ReactJsonTree.JSONTree
theme={theme}
invertTheme={false}
data={this.state.showUnchanged ? _.merge(left, delta): delta}
data={this.state.showUnchanged ? _.merge(_.cloneDeep(left), delta): delta}
valueRenderer={valueRenderer}
postprocessValue={prepareDelta}
isCustomNode={Array.isArray}
Expand Down

0 comments on commit 8391a19

Please sign in to comment.