-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add a simple implementation of solarkraft list
#64
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,13 @@ | |
import JSONbigint from 'json-bigint' | ||
import { OrderedMap } from 'immutable' | ||
import { join } from 'node:path/posix' | ||
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs' | ||
import { | ||
existsSync, | ||
mkdirSync, | ||
readFileSync, | ||
readdirSync, | ||
writeFileSync, | ||
} from 'node:fs' | ||
|
||
const JSONbig = JSONbigint({ useNativeBigInt: true }) | ||
|
||
|
@@ -68,6 +74,16 @@ export interface ContractCallEntry { | |
oldFields: FieldsMap | ||
} | ||
|
||
/** | ||
* A listing entry. | ||
*/ | ||
export interface ListEntry { | ||
contractId: string | ||
height: number | ||
txHash: string | ||
verification: 'ok' | 'fail' | 'unverified' | ||
} | ||
|
||
/** | ||
* Serializable fetcher state. | ||
*/ | ||
|
@@ -128,6 +144,42 @@ export function loadContractCallEntry(filename: string): ContractCallEntry { | |
} | ||
} | ||
|
||
/** | ||
* Generate storage entries for a given contract id in a path. | ||
* @param contractId contract identifier (address) | ||
* @param path the path to the contract storage | ||
*/ | ||
export function* yieldListEntriesForContract( | ||
contractId: string, | ||
path: string | ||
): Generator<ListEntry> { | ||
for (const dirent of readdirSync(path, { withFileTypes: true })) { | ||
// match ledger heights, which are positive integers | ||
if (dirent.isDirectory() && /^[0-9]+$/.exec(dirent.name)) { | ||
// This directory may contain several transactions for the same height. | ||
const height = Number.parseInt(dirent.name) | ||
for (const ledgerDirent of readdirSync(join(path, dirent.name), { | ||
withFileTypes: true, | ||
})) { | ||
// match all storage entries, which may be reported in different cases | ||
const matcher = /^entry-([0-9a-fA-F]+)\.json$/.exec( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are we using mixed-case HEX here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would be ok with lowercase, but neither Windows, nor MacOS agree with me on the capitalization of filenames There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah right, OS jank There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added a comment |
||
ledgerDirent.name | ||
) | ||
if (ledgerDirent.isFile() && matcher) { | ||
const txHash = matcher[1] | ||
// TODO: read the verification result and report it | ||
yield { | ||
contractId, | ||
height, | ||
txHash, | ||
verification: 'unverified', | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Load fetcher state from the storage. | ||
* @param root the storage root directory | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Integration tests for the `verify` command | ||
|
||
import { describe, it } from 'mocha' | ||
|
||
import { spawn } from 'nexpect' | ||
import { mkdtempSync } from 'node:fs' | ||
import { tmpdir } from 'node:os' | ||
import { join } from 'node:path' | ||
import { saveContractCallEntry } from '../../src/fetcher/storage.js' | ||
import { OrderedMap } from 'immutable' | ||
|
||
const TX_HASH = | ||
'9fb12935fbadcd28aa220d076f11be631590d22c60977a53997a746898322ca3' | ||
const CONTRACT_ID = 'CC22QGTOUMERDNIYN7TPNX3V6EMPHQXVSRR3XY56EADF7YTFISD2ROND' | ||
|
||
describe('list', () => { | ||
it('lists a single entry', function (done) { | ||
// create a single entry in a temporary directory | ||
const root = join(tmpdir(), 'solarkraft-storage-') | ||
mkdtempSync(root) | ||
saveContractCallEntry(root, { | ||
height: 1000, | ||
txHash: TX_HASH, | ||
contractId: CONTRACT_ID, | ||
method: 'set_i32', | ||
methodArgs: [42], | ||
returnValue: 0, | ||
fields: OrderedMap<string, any>(), | ||
oldFields: OrderedMap<string, any>(), | ||
}) | ||
|
||
this.timeout(50000) | ||
spawn(`solarkraft list --home ${root}`) | ||
.wait(`Contract ${CONTRACT_ID}`) | ||
.wait(' [unverified]') | ||
.wait(' height: 1000') | ||
.wait(` tx: ${TX_HASH}`) | ||
.run(done) | ||
}) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment explaining this regex