Store the genesisHash along with code & contracts (load check) (#982)

* Store the genesisHash along with code & contracts (load check)

* Cleanup hanging promises

* contract:contract: -> contract:address: (storage)

* Update store.ts
This commit is contained in:
Jaco Greeff 2019-04-11 21:19:14 +02:00 committed by GitHub
parent 8e77bcf8c8
commit 26ff33678e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 84 additions and 33 deletions

View File

@ -225,7 +225,10 @@ class Deploy extends React.PureComponent<Props, State> {
return;
}
store.saveCode(new Hash(codeHash), { abi, name });
store.saveCode(new Hash(codeHash), { abi, name }).catch((error) => {
console.error('Unable to save code', error);
});
this.redirect();
}
@ -240,7 +243,10 @@ class Deploy extends React.PureComponent<Props, State> {
return;
}
store.saveCode(codeHash as Hash, { abi, name });
store.saveCode(codeHash as Hash, { abi, name }).catch((error) => {
console.error('Unable to save code', error);
});
this.redirect();
});
}

View File

@ -329,7 +329,10 @@ class Create extends React.PureComponent<Props, State> {
return;
}
store.saveContract(new AccountId(address), { abi, name });
store.saveContract(new AccountId(address), { abi, name }).catch((error) => {
console.error('Unable to save contract', error);
});
this.redirect();
}
@ -344,7 +347,10 @@ class Create extends React.PureComponent<Props, State> {
return;
}
store.saveContract(address as AccountId, { abi, name });
store.saveContract(address as AccountId, { abi, name }).catch((error) => {
console.error('Unable to save contract', error);
});
this.redirect();
});
}

View File

@ -34,6 +34,11 @@ class App extends React.PureComponent<Props, State> {
store.on('new-code', this.triggerUpdate);
store.on('new-contract', this.triggerUpdate);
// since we have a dep on the async API, we load here
store.loadAll().catch(() => {
// noop, handled internally
});
this.state = {
tabs: [
{

View File

@ -7,9 +7,11 @@ import { CodeJson, ContractJson } from './types';
import EventEmitter from 'eventemitter3';
import store from 'store';
import { AccountId, ContractAbi, Hash } from '@polkadot/types';
import { api } from '@polkadot/ui-api';
const KEY_CODE = 'contract:code:';
const KEY_CONTRACT = 'contract:contract:';
const PREFIX = 'contract:';
const KEY_CODE = `${PREFIX}code:`;
const KEY_CONTRACT = `${PREFIX}addr:`;
const codeRegex = new RegExp(`^${KEY_CODE}`, '');
const contractRegex = new RegExp(`^${KEY_CONTRACT}`, '');
@ -21,18 +23,6 @@ class Store extends EventEmitter {
private allCode: { [index: string]: CodeStored } = {};
private allContracts: { [index: string]: ContractStored } = {};
constructor () {
super();
store.each((json: CodeJson | ContractJson, key: string) => {
if (codeRegex.test(key)) {
this.addCode(json as CodeJson);
} else if (contractRegex.test(key)) {
this.addContract(json as ContractJson);
}
});
}
get hasCode (): boolean {
return Object.keys(this.allCode).length !== 0;
}
@ -57,22 +47,56 @@ class Store extends EventEmitter {
return this.allContracts[address];
}
saveCode (codeHash: Hash, partial: Partial<CodeJson>) {
const json = { ...partial, codeHash: codeHash.toHex() } as CodeJson;
async saveCode (codeHash: Hash, partial: Partial<CodeJson>) {
await api.isReady;
const json = {
...partial,
codeHash: codeHash.toHex(),
genesisHash: api.genesisHash.toHex()
} as CodeJson;
store.set(`${KEY_CODE}${json.codeHash}`, json);
this.addCode(json);
}
saveContract (address: AccountId, partial: Partial<ContractJson>) {
const json = { ...partial, address: address.toString() } as ContractJson;
async saveContract (address: AccountId, partial: Partial<ContractJson>) {
await api.isReady;
const json = {
...partial,
address: address.toString(),
genesisHash: api.genesisHash.toHex()
} as ContractJson;
store.set(`${KEY_CONTRACT}${address}`, json);
this.addContract(json);
}
async loadAll () {
try {
await api.isReady;
const genesisHash = api.genesisHash.toHex();
store.each((json: CodeJson | ContractJson, key: string) => {
if (json && json.genesisHash !== genesisHash) {
return;
}
if (codeRegex.test(key)) {
this.addCode(json as CodeJson);
} else if (contractRegex.test(key)) {
this.addContract(json as ContractJson);
}
});
} catch (error) {
console.error('Unable to load contracts', error);
}
}
private addCode (json: CodeJson) {
try {
this.allCode[json.codeHash] = {

View File

@ -12,14 +12,17 @@ export type LocationProps = {
export type ComponentProps = AppProps & LocationProps;
export type CodeJson = {
abi?: string | null,
codeHash: string,
name: string
type BaseInfo = {
name: string,
genesisHash: string
};
export type ContractJson = {
abi: string,
address: string,
name: string
export type CodeJson = BaseInfo & {
abi?: string | null,
codeHash: string
};
export type ContractJson = BaseInfo & {
abi: string,
address: string
};

View File

@ -18,6 +18,8 @@ import { formatBalance, isTestChain } from '@polkadot/util';
import ApiContext from './ApiContext';
let api: ApiPromise;
type Props = {
children: React.ReactNode,
queueExtrinsic: QueueTx$ExtrinsicAdd,
@ -29,6 +31,8 @@ type State = ApiProps & {
chain?: string
};
export { api };
export default class ApiWrapper extends React.PureComponent<Props, State> {
state: State = {} as State;
@ -40,7 +44,7 @@ export default class ApiWrapper extends React.PureComponent<Props, State> {
const signer = new ApiSigner(queueExtrinsic, queueSetTxStatus);
const setApi = (provider: ProviderInterface): void => {
const api = new ApiPromise({ provider, signer });
api = new ApiPromise({ provider, signer });
this.setState({ api }, () => {
this.subscribeEvents();
@ -49,10 +53,12 @@ export default class ApiWrapper extends React.PureComponent<Props, State> {
const setApiUrl = (url: string = defaults.WS_URL): void =>
setApi(new WsProvider(url));
api = new ApiPromise({ provider, signer });
this.state = {
isApiConnected: false,
isApiReady: false,
api: new ApiPromise({ provider, signer }),
api,
setApiUrl
} as State;
}

View File

@ -2,12 +2,13 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Api from './Api';
import Api, { api } from './Api';
import ApiContext from './ApiContext';
export * from './with';
export {
api,
Api,
ApiContext
};