Skip to content

Commit

Permalink
feat: Preset mainnet network configuration
Browse files Browse the repository at this point in the history
TODO: set genesis hash.
  • Loading branch information
ashchan committed Nov 15, 2019
1 parent df3eb0e commit 1979e8a
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 93 deletions.
4 changes: 2 additions & 2 deletions packages/neuron-wallet/src/controllers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ export default class ApiController {
}

@MapApiResponse
public static async createNetwork({ name, remote, type = NetworkType.Normal, chain = 'ckb' }: Network) {
return NetworksController.create({ name, remote, type, chain })
public static async createNetwork({ name, remote, type = NetworkType.Normal, genesisHash = '0x', chain = 'ckb' }: Network) {
return NetworksController.create({ name, remote, type, genesisHash, chain })
}

@MapApiResponse
Expand Down
24 changes: 0 additions & 24 deletions packages/neuron-wallet/src/env.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { app as electronApp, remote } from 'electron'
import os from 'os'
import * as path from 'path'
import { NetworkWithID } from 'types/network'

const app = electronApp || (remote && remote.app) || {
getPath(aPath: string): string {
Expand Down Expand Up @@ -35,36 +34,13 @@ interface ENV {
fileBasePath: string
mainURL: string
remote: string
presetNetworks: {
current: 'testnet'
list: NetworkWithID[]
}
isTestMode: boolean
}
const env: ENV = {
isDevMode,
fileBasePath: path.resolve(app.getPath('userData'), fileBase),
mainURL: isDevMode ? 'http://localhost:3000' : `file://${path.join(__dirname, '../dist/neuron-ui/index.html')}`,
remote: 'http://localhost:8114',
presetNetworks: {
current: 'testnet',
list: [
{
id: 'testnet',
name: 'Testnet',
remote: 'http://localhost:8114',
type: 0,
chain: '',
},
{
id: 'local',
name: 'Local',
remote: 'http://localhost:8114',
type: 1,
chain: '',
},
],
},
isTestMode,
}

Expand Down
52 changes: 40 additions & 12 deletions packages/neuron-wallet/src/services/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,29 @@ import { BehaviorSubject } from 'rxjs'
import { LackOfDefaultNetwork, DefaultNetworkUnremovable } from 'exceptions/network'

import Store from 'models/store'
import env from 'env'

import { Validate, Required } from 'decorators'
import { UsedName, NetworkNotFound, InvalidFormat } from 'exceptions'
import { NetworkListSubject, CurrentNetworkIDSubject } from 'models/subjects/networks'
import { NetworkID, NetworkName, NetworkRemote, NetworksKey, NetworkType, Network, NetworkWithID } from 'types/network'
import { MAINNET_GENESIS_HASH, NetworkID, NetworkName, NetworkRemote, NetworksKey, NetworkType, Network, NetworkWithID } from 'types/network'
import logger from 'utils/logger'

export const networkSwitchSubject = new BehaviorSubject<undefined | NetworkWithID>(undefined)

const presetNetworks: { selected: string, networks: NetworkWithID[] } = {
selected: 'mainnet',
networks: [
{
id: 'mainnet',
name: 'Mainnet',
remote: 'http://localhost:8114',
genesisHash: MAINNET_GENESIS_HASH,
type: NetworkType.Default,
chain: 'ckb',
}
]
}

export default class NetworksService extends Store {
private static instance: NetworksService

Expand All @@ -25,7 +38,7 @@ export default class NetworksService extends Store {
}

constructor() {
super('networks', 'index.json', JSON.stringify(env.presetNetworks))
super('networks', 'index.json', JSON.stringify(presetNetworks))

this.getAll().then(currentNetworkList => {
if (currentNetworkList) {
Expand Down Expand Up @@ -88,7 +101,7 @@ export default class NetworksService extends Store {

public getAll = async () => {
const list = await this.read<NetworkWithID[]>(NetworksKey.List)
return list || []
return list || presetNetworks.networks
}

@Validate
Expand All @@ -102,15 +115,11 @@ export default class NetworksService extends Store {
if (!Array.isArray(networks)) {
throw new InvalidFormat('Networks')
}
await this.writeSync(NetworksKey.List, networks)
this.writeSync(NetworksKey.List, networks)
}

@Validate
public async create(
@Required name: NetworkName,
@Required remote: NetworkRemote,
type: NetworkType = NetworkType.Normal,
) {
public async create(@Required name: NetworkName, @Required remote: NetworkRemote, type: NetworkType = NetworkType.Normal) {
const list = await this.getAll()
if (list.some(item => item.name === name)) {
throw new UsedName('Network')
Expand All @@ -122,11 +131,15 @@ export default class NetworksService extends Store {
.getBlockchainInfo()
.then(info => info.chain)
.catch(() => '')
const genesisHash = await core.rpc
.getBlockHash('0x0')
.catch(() => '0x')

const newOne = {
id: uuid(),
name,
remote,
genesisHash,
type,
chain,
}
Expand All @@ -146,11 +159,17 @@ export default class NetworksService extends Store {
Object.assign(network, options)
if (!options.chain) {
const core = new Core(network.remote)

const chain = await core.rpc
.getBlockchainInfo()
.then(info => info.chain)
.catch(() => '')
network.chain = chain

const genesisHash = await core.rpc
.getBlockHash('0x0')
.catch(() => '0x')
network.genesisHash = genesisHash
}

this.updateAll(list)
Expand Down Expand Up @@ -183,15 +202,24 @@ export default class NetworksService extends Store {
}
this.writeSync(NetworksKey.Current, id)

// No need to update the default mainnet
if (network.type === NetworkType.Default) {
return
}

const core = new Core(network.remote)

const chain = await core.rpc
.getBlockchainInfo()
.then(info => info.chain)
.catch(() => '')

if (chain && chain !== network.chain) {
this.update(id, { chain })
const genesisHash = await core.rpc
.getBlockHash('0x0')
.catch(() => '0x')

if (chain && chain !== network.chain && genesisHash && genesisHash !== network.genesisHash) {
this.update(id, { chain, genesisHash })
}
}

Expand Down
12 changes: 9 additions & 3 deletions packages/neuron-wallet/src/types/network.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
export type NetworkID = string
export type NetworkName = string
export type NetworkRemote = string
export type NetworkGenesisHash = string

export enum NetworksKey {
List = 'list',
Current = 'current',
List = 'networks',
Current = 'selected',
}

export enum NetworkType {
Default,
Default, // Preset mainnet node
Normal,
}

export const MAINNET_GENESIS_HASH = "0x" // TODO: set this when mainnet launches!

export interface Network {
name: NetworkName
remote: NetworkRemote
type: NetworkType
genesisHash: NetworkGenesisHash
chain: 'ckb' | 'ckb_testnet' | 'ckb_dev' | string // returned by rpc.getBlockchainInfo
}

export interface NetworkWithID extends Network {
id: NetworkID
}
86 changes: 34 additions & 52 deletions packages/neuron-wallet/tests/services/networks.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import NetworksService from '../../src/services/networks'
import { NetworkWithID } from '../../src/types/network'
import env from '../../src/env'
import i18n from '../../src/utils/i18n'

const ERROR_MESSAGE = {
Expand All @@ -9,23 +8,19 @@ const ERROR_MESSAGE = {
NETWORK_ID_NOT_FOUND: `messages.network-not-found`,
}

const {
presetNetworks: { current, list },
} = env
const [testnetNetwork, localNetwork] = list

describe(`Unit tests of networks service`, () => {
const newNetwork: NetworkWithID = {
name: `new network`,
remote: `http://new-network.localhost.com`,
remote: `http://localhost:8114`,
type: 0,
genesisHash: '',
id: '',
chain: '',
}

const newNetworkWithDefaultTypeOf1 = {
name: `new network with the default type of 1`,
remote: `http://test.localhost.com`,
remote: `http://localhost:8114`,
id: '',
}

Expand All @@ -52,28 +47,18 @@ describe(`Unit tests of networks service`, () => {

it(`has preset networks`, async () => {
const networks = await service.getAll()
expect(networks).toEqual(list)
expect(networks.length).toBe(1)
expect(networks[0].id).toEqual('mainnet')
})

it(`get the default network`, async () => {
const network = await service.defaultOne()
expect(network && network.type).toBe(0)
})

it(`testnet should be type of default network`, async () => {
const defaultNetwork = await service.defaultOne()
expect(defaultNetwork).toEqual(testnetNetwork)
})

it(`testnet should be the current one by default`, async () => {
it(`mainnet should be the current one by default`, async () => {
const currentNetworkID = await service.getCurrentID()
expect(currentNetworkID).toBe(current)
expect(currentNetworkID).toBe(testnetNetwork.id)
})

it(`get network by id ${current}`, async () => {
const currentNetwork = await service.get(current)
expect(currentNetwork).toEqual(list.find(network => network.id === current))
expect(currentNetworkID).toBe('mainnet')
})

it(`getting a non-exsiting network should return null`, async () => {
Expand All @@ -94,35 +79,31 @@ describe(`Unit tests of networks service`, () => {
expect(res.type).toBe(1)
})

it(`update the local networks's name`, async () => {
const name = `new local network name`
await service.update(localNetwork.id, { name })
const network = await service.get(localNetwork.id)
expect(network && network.name).toBe(name)
})

it(`update the local network address`, async () => {
const addr = `http://updated-address.com`
await service.update(localNetwork.id, { remote: addr })
const network = await service.get(localNetwork.id)
expect(network && network.remote).toBe(addr)
it(`update the networks's name`, async () => {
const network = await service.create(newNetworkWithDefaultTypeOf1.name, newNetworkWithDefaultTypeOf1.remote)
const name = `new network name`
await service.update(network.id, { name })
const updated = await service.get(network.id)
expect(updated && updated.name).toBe(name)
})

it(`update the local network type to 1`, async () => {
const type = 1
await service.update(localNetwork.id, { type })
const network = await service.get(localNetwork.id)
expect(network && network.type).toBe(type)
it(`update the network' address`, async () => {
const network = await service.create(newNetworkWithDefaultTypeOf1.name, newNetworkWithDefaultTypeOf1.remote)
const address = `http://localhost:8115`
await service.update(network.id, { remote: address })
const updated = await service.get(network.id)
expect(updated && updated.remote).toBe(address)
})

it(`set the local network to be the current one`, async () => {
await service.activate(localNetwork.id)
it(`set the network to be the current one`, async () => {
const network = await service.create(newNetworkWithDefaultTypeOf1.name, newNetworkWithDefaultTypeOf1.remote)
await service.activate(network.id)
const currentNetworkID = await service.getCurrentID()
expect(currentNetworkID).toBe(localNetwork.id)
expect(currentNetworkID).toBe(network.id)
})

it(`delete an inactive network`, async () => {
const inactiveNetwork = localNetwork
const inactiveNetwork = await service.create(newNetworkWithDefaultTypeOf1.name, newNetworkWithDefaultTypeOf1.remote)
const prevCurrentID = (await service.getCurrentID()) || ''
const prevNetworks = await service.getAll()
await service.delete(inactiveNetwork.id)
Expand All @@ -134,12 +115,13 @@ describe(`Unit tests of networks service`, () => {
expect(currentID).toBe(prevCurrentID)
})

it(`activate the local network and delete it, the current networks should switch to the testnet network`, async () => {
await service.activate(localNetwork.id)
it(`activate a network and delete it, the current networks should switch to the default network`, async () => {
const network = await service.create(newNetworkWithDefaultTypeOf1.name, newNetworkWithDefaultTypeOf1.remote)
await service.activate(network.id)
const prevCurrentID = await service.getCurrentID()
const prevNetworks = await service.getAll()
expect(prevCurrentID).toBe(localNetwork.id)
expect(prevNetworks.map(n => n.id)).toEqual(list.map(n => n.id))
expect(prevCurrentID).toBe(network.id)
expect(prevNetworks.map(n => n.id)).toEqual(['Mainnet', network.id])
await service.delete(prevCurrentID || '')
const currentNetworks = await service.getAll()
expect(currentNetworks.map(n => n.id)).toEqual(prevNetworks.filter(n => n.id !== prevCurrentID).map(n => n.id))
Expand All @@ -148,16 +130,16 @@ describe(`Unit tests of networks service`, () => {
service.getCurrentID().then(cID => resolve(cID))
}, 500)
})
expect(currentID).toBe(testnetNetwork.id)
expect(currentID).toBe('mainnet')
})

it(`reset the netowrks`, async () => {
await service.create(newNetwork.name, newNetwork.remote)
const newNetworkList = await service.getAll()
expect(newNetworkList.length).toBe(list.length + 1)
expect(newNetworkList.length).toBe(2)
service.clear()
const networks = await service.getAll()
expect(networks.length).toBe(list.length)
expect(networks.length).toBe(1)
})
})

Expand Down Expand Up @@ -192,8 +174,8 @@ describe(`Unit tests of networks service`, () => {
})

describe(`validation on network existence`, () => {
it(`create network with existing name of ${list[0].name}`, () => {
expect(service.create(list[0].name, list[0].remote)).rejects.toThrowError(i18n.t(ERROR_MESSAGE.NAME_USED))
it(`create network with existing name of Mainnet`, () => {
expect(service.create('Mainnet', 'http://localhost:8114')).rejects.toThrowError(i18n.t(ERROR_MESSAGE.NAME_USED))
})

it(`update network which is not existing`, () => {
Expand Down

0 comments on commit 1979e8a

Please sign in to comment.