-
Notifications
You must be signed in to change notification settings - Fork 206
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cosmic-swingset): Add chainStorage interface (#5385)
* feat(cosmic-swingset): Add chainStorage interface Fixes #4558 * refactor(cosmic-swingset): Move makeChainStorageNode into a vat * chore(cosmic-swingset): Respond to PR feedback * refactor(cosmic-swingset): Move chainStorage logic into a library * chore: Improve child key checks and explanations * test: Add tests for chainStorage * chore: Allow "-" in chain storage key segments * chore: Try to appease TypeScript * chore: Try harder to appease TypeScript * style: Use a better TypeScript-compatible map initialization * refactor: Create Go and JS constants for top-level chain storage paths * refactor: Replace chain storage "key" with "path" * refactor: Move chain-storage-paths.js to avoid a module cycle * chore: Appease eslint * fix: Try adding a delay to fix CI https://github.com/Agoric/agoric-sdk/runs/6728088019?check_suite_focus=true * chore: Include relevant lines from failing CI log * fix(swingset): louder anachrophobio * ci(vats): correct `chainStorage` bundle in decentral configs Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Michael FIG <mfig@agoric.com>
- Loading branch information
1 parent
c6db041
commit 109ff65
Showing
13 changed files
with
365 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* These identify top-level paths for SwingSet chain storage | ||
* (and serve as prefixes, with the exception of ACTIVITYHASH). | ||
* To avoid collisions, they should remain synchronized with | ||
* golang/cosmos/x/swingset/keeper/keeper.go | ||
*/ | ||
export const ACTIVITYHASH = 'activityhash'; | ||
export const BEANSOWING = 'beansOwing'; | ||
export const EGRESS = 'egress'; | ||
export const MAILBOX = 'mailbox'; | ||
export const CUSTOM = 'published'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// @ts-check | ||
|
||
import { Far } from '@endo/far'; | ||
|
||
const { details: X } = assert; | ||
|
||
// TODO: Formalize segment constraints. | ||
// Must be nonempty and disallow (unescaped) `.`, and for simplicity | ||
// (and future possibility of e.g. escaping) we currently limit to | ||
// ASCII alphanumeric plus underscore. | ||
const pathSegmentPattern = /^[a-zA-Z0-9_-]{1,100}$/; | ||
|
||
/** | ||
* Create a root storage node for a given backing function and root path. | ||
* | ||
* @param {(message: any) => any} toStorage a function for sending a storageMessage object to the storage implementation (cf. golang/cosmos/x/swingset/storage.go) | ||
* @param {string} storeName currently limited to "swingset" | ||
* @param {string} rootPath | ||
*/ | ||
export function makeChainStorageRoot(toStorage, storeName, rootPath) { | ||
assert.equal( | ||
storeName, | ||
'swingset', | ||
'the only currently-supported store is "swingset"', | ||
); | ||
assert.typeof(rootPath, 'string'); | ||
|
||
function makeChainStorageNode(path) { | ||
const node = { | ||
getStoreKey() { | ||
// This duplicates the Go code at | ||
// https://github.com/Agoric/agoric-sdk/blob/cb272ae97a042ceefd3af93b1b4601ca49dfe3a7/golang/cosmos/x/swingset/keeper/keeper.go#L295 | ||
return { storeName, storeSubkey: `swingset/data:${path}` }; | ||
}, | ||
getChildNode(name) { | ||
assert.typeof(name, 'string'); | ||
assert( | ||
pathSegmentPattern.test(name), | ||
X`Path segment must be a short ASCII identifier: ${name}`, | ||
); | ||
return makeChainStorageNode(`${path}.${name}`); | ||
}, | ||
setValue(value) { | ||
assert.typeof(value, 'string'); | ||
toStorage({ key: path, method: 'set', value }); | ||
}, | ||
async delete() { | ||
assert(path !== rootPath); | ||
// A 'set' with no value deletes a key if it has no children, but | ||
// otherwise sets data to the empty string and leaves all nodes intact. | ||
// We want to reject silently incomplete deletes (at least for now). | ||
// This check is unfortunately racy (e.g., a vat could wake up | ||
// and set data for a child before _this_ vat receives an | ||
// already-enqueued response claiming no children), but we can tolerate | ||
// that because transforming a deletion into a set-to-empty is | ||
// effectively indistinguishable from a valid reordering where a fully | ||
// successful 'delete' is followed by a child-key 'set' (for which | ||
// absent parent keys are automatically created with empty-string data). | ||
const childCount = await toStorage({ key: path, method: 'size' }); | ||
if (childCount > 0) { | ||
assert.fail(X`Refusing to delete node with children: ${path}`); | ||
} | ||
toStorage({ key: path, method: 'set' }); | ||
}, | ||
// Possible extensions: | ||
// * getValue() | ||
// * getChildNames() and/or getChildNodes() | ||
// * getName() | ||
// * recursive delete | ||
// * batch operations | ||
// * local buffering (with end-of-block commit) | ||
}; | ||
return Far('chainStorageNode', node); | ||
} | ||
|
||
const rootNode = makeChainStorageNode(rootPath); | ||
return rootNode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { E, Far } from '@endo/far'; | ||
import { makeChainStorageRoot } from './lib-chainStorage.js'; | ||
|
||
export function buildRootObject(_vatPowers) { | ||
function makeBridgedChainStorageRoot(bridgeManager, bridgeId, rootPath) { | ||
// Note that the uniqueness of rootPath is not validated here, | ||
// and is instead the responsibility of callers. | ||
const toStorage = message => E(bridgeManager).toBridge(bridgeId, message); | ||
const rootNode = makeChainStorageRoot(toStorage, 'swingset', rootPath); | ||
return rootNode; | ||
} | ||
|
||
return Far('root', { | ||
makeBridgedChainStorageRoot, | ||
}); | ||
} |
Oops, something went wrong.