Skip to content
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

[wallet]Run geth in an infura-like mode #1108

Merged
merged 2 commits into from
Oct 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/mobile/.env
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
ENVIRONMENT=local
DEFAULT_TESTNET=integration
# -1 == ZeroSync, 5 == Ultralight, see src/geth/consts.ts for more info
DEFAULT_SYNC_MODE=5
DEV_SETTINGS_ACTIVE_INITIALLY=true
FIREBASE_ENABLED=true
SECRETS_KEY=debug
SHOW_TESTNET_BANNER=true
SHOW_TESTNET_BANNER=true
2 changes: 1 addition & 1 deletion packages/mobile/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'node-libs-react-native/globals'
import 'src/btoa'
import 'src/missingGlobals'
import { AppRegistry } from 'react-native'
import Logger from 'src/utils/Logger'
import App from 'src/app/App'
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/Account.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import { createMockStore } from 'test/utils'

jest.useFakeTimers()

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('Account', () => {
it('renders correctly', () => {
const tree = renderer.create(
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/DollarEducation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import * as renderer from 'react-test-renderer'
import DollarEducation from 'src/account/DollarEducation'
import { createMockStore } from 'test/utils'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('DollarEducation', () => {
it('renders correctly', () => {
const tree = renderer.create(
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/EditProfile.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { setName } from 'src/account/actions'
import { EditProfile } from 'src/account/EditProfile'
import { createMockStore, getMockI18nProps } from 'test/utils'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

it('renders the EditProfile Component', () => {
const store = createMockStore()
const tree = renderer.create(
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/Education.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ const educationProps = {
onFinish: jest.fn(),
}

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('Education', () => {
it('renders correctly', () => {
const tree = renderer.create(
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/GoldEducation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import * as renderer from 'react-test-renderer'
import GoldEducation from 'src/account/GoldEducation'
import { createMockStore } from 'test/utils'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('GoldEducation', () => {
it('renders correctly', () => {
const tree = renderer.create(
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/Invite.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import Invite from 'src/account/Invite'
import { createMockStore } from 'test/utils'
import { mockE164NumberToInvitableRecipient, mockNavigation } from 'test/values'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('Invite', () => {
it('renders correctly with recipients', () => {
const tree = renderer.create(
Expand Down
9 changes: 9 additions & 0 deletions packages/mobile/src/account/InviteReview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ jest.mock('src/identity/verification', () => {
return { isPhoneVerified: jest.fn(() => true) }
})

jest.mock('src/web3/contracts', () => ({
web3: {
utils: {
fromWei: jest.fn((x: any) => x / 1e18),
},
},
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('InviteReview', () => {
it('renders correctly', () => {
const tree = renderer.create(
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/PhotosEducation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import * as renderer from 'react-test-renderer'
import PhotosEducation from 'src/account/PhotosEducation'
import { createMockStore } from 'test/utils'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('PhotosEducation', () => {
it('renders correctly', () => {
const tree = renderer.create(
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/account/Profile.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import { Screens } from 'src/navigator/Screens'
import { createMockStore } from 'test/utils'
import { mockNavigation } from 'test/values'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

function profileFactory() {
return (
<Provider store={createMockStore({})}>
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/app/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ jest.mock('src/redux/sagas', () => {
}
})

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('App', () => {
it('renders an ApolloProvider', () => {
const wrapper = shallow(<App />)
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/app/Debug.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import * as renderer from 'react-test-renderer'
import Debug from 'src/app/Debug'
import { createMockStore } from 'test/utils'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('Debug', () => {
it('renders correctly', () => {
const tree = renderer.create(
Expand Down
9 changes: 9 additions & 0 deletions packages/mobile/src/app/saga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ jest.mock('src/firebase/firebase', () => ({
getVersionInfo: jest.fn(async () => ({ deprecated: false })),
}))

jest.mock('src/web3/contracts', () => ({
web3: {
utils: {
fromWei: jest.fn((x: any) => x / 1e18),
},
},
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

const { navigate } = require('src/navigator/NavigationService')
const { getVersionInfo } = require('src/firebase/firebase')

Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/components/AccountOverview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import { getMockI18nProps } from 'test/utils'
const SAMPLE_BALANCE = '55.00001'
const exchangeRatePair: ExchangeRatePair = { goldMaker: '0.11', dollarMaker: '10' }

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

it('renders correctly when ready', () => {
const tree = renderer.create(
<AccountOverview
Expand Down
1 change: 1 addition & 0 deletions packages/mobile/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const FIREBASE_ENABLED = stringToBoolean(Config.FIREBASE_ENABLED || 'true
// react-native-config is undefined.
export const DEFAULT_TESTNET: Testnets = Config.DEFAULT_TESTNET || 'integration'
export const BLOCKCHAIN_API_URL = config[DEFAULT_TESTNET].blockchainApiUrl
export const DEFAULT_INFURA_URL = `https://${DEFAULT_TESTNET}-infura.celo-testnet.org/`

export const SEGMENT_API_KEY = keyOrUndefined(secretsFile, Config.SECRETS_KEY, 'SEGMENT_API_KEY')
export const FIREBASE_WEB_KEY = keyOrUndefined(secretsFile, Config.SECRETS_KEY, 'FIREBASE_WEB_KEY')
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/escrow/EscrowedPaymentLineItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import * as renderer from 'react-test-renderer'
import PaymentRequestNotificationInner from 'src/paymentRequest/PaymentRequestNotificationInner'
import { mockRecipientWithPhoneNumber } from 'test/values'

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

it('renders correctly', () => {
const tree = renderer.create(
<PaymentRequestNotificationInner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ import { mockE164Number, mockRecipient } from 'test/values'

const store = createMockStore()

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe('ReclaimPaymentConfirmationCard', () => {
it('renders correctly for send payment confirmation', () => {
const tree = renderer.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ const TEST_FEE = new BigNumber(10000000000000000)

jest.mock('src/escrow/saga')

jest.mock('src/web3/contracts', () => ({
web3: {
utils: {
fromWei: jest.fn((x: any) => x / 1e18),
},
},
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

const mockedGetReclaimEscrowFee = getReclaimEscrowFee as jest.Mock

const store = createMockStore()
Expand Down
28 changes: 21 additions & 7 deletions packages/mobile/src/escrow/saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { TransactionStatus, TransactionTypes } from 'src/transactions/reducer'
import { sendAndMonitorTransaction } from 'src/transactions/saga'
import { sendTransaction } from 'src/transactions/send'
import Logger from 'src/utils/Logger'
import { web3 } from 'src/web3/contracts'
import { addLocalAccount, isZeroSyncMode, web3 } from 'src/web3/contracts'
import { getConnectedAccount, getConnectedUnlockedAccount } from 'src/web3/saga'

const TAG = 'escrow/saga'
Expand Down Expand Up @@ -105,14 +105,19 @@ function* withdrawFromEscrow(action: EndVerificationAction) {

const escrow: Escrow = yield call(getEscrowContract, web3)
const account: string = yield call(getConnectedUnlockedAccount)
const inviteCode: string = yield select((state: RootState) => state.invite.redeemedInviteCode)
const tmpWalletPrivateKey: string = yield select(
(state: RootState) => state.invite.redeemedInviteCode
)

if (!isValidPrivateKey(inviteCode)) {
if (!isValidPrivateKey(tmpWalletPrivateKey)) {
Logger.warn(TAG + '@withdrawFromEscrow', 'Invalid private key, skipping escrow withdrawal')
return
}

const tempWalletAddress = web3.eth.accounts.privateKeyToAccount(inviteCode).address
const tempWalletAddress = web3.eth.accounts.privateKeyToAccount(tmpWalletPrivateKey).address
if (isZeroSyncMode()) {
addLocalAccount(web3, tmpWalletPrivateKey)
}
Logger.debug(TAG + '@withdrawFromEscrow', 'Added temp account to wallet: ' + tempWalletAddress)

// Check if there is a payment associated with this invite code
Expand All @@ -123,13 +128,22 @@ function* withdrawFromEscrow(action: EndVerificationAction) {
return
}

// Unlock temporary account
yield call(web3.eth.personal.unlockAccount, tempWalletAddress, TEMP_PW, 600)
if (isZeroSyncMode()) {
Logger.info(
TAG + '@withdrawFromEscrow',
'Geth free mode is on, no need to unlock the temporary account'
)
} else {
// Unlock temporary account
yield call(web3.eth.personal.unlockAccount, tempWalletAddress, TEMP_PW, 600)
}

const msgHash = web3.utils.soliditySha3({ type: 'address', value: account })

Logger.debug(TAG + '@withdrawFromEscrow', `Signing message hash ${msgHash}`)
// using the temporary wallet account to sign a message. The message is the current account.
let signature = yield web3.eth.sign(msgHash, tempWalletAddress)
let signature: string = (yield web3.eth.accounts.sign(msgHash, tmpWalletPrivateKey)).signature
Logger.debug(TAG + '@withdrawFromEscrow', `Signed message hash signature is ${signature}`)
signature = signature.slice(2)
const r = `0x${signature.slice(0, 64)}`
const s = `0x${signature.slice(64, 128)}`
Expand Down
4 changes: 4 additions & 0 deletions packages/mobile/src/exchange/ExchangeTradeScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ jest.mock('src/shared/DisconnectBanner', () => ({
DisconnectBanner: () => null,
}))

jest.mock('src/web3/contracts', () => ({
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

const store = createMockStore({
exchange: {
exchangeRatePair,
Expand Down
3 changes: 2 additions & 1 deletion packages/mobile/src/exchange/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { roundDown } from 'src/utils/formatting'
import Logger from 'src/utils/Logger'
import { web3 } from 'src/web3/contracts'
import { getConnectedAccount, getConnectedUnlockedAccount } from 'src/web3/saga'
import * as util from 'util'

const TAG = 'exchange/actions'
const LARGE_DOLLARS_SELL_AMOUNT_IN_WEI = new BigNumber(1000 * 1000000000000000000) // To estimate exchange rate from exchange contract
Expand Down Expand Up @@ -233,7 +234,7 @@ export function* exchangeGoldAndStableTokens(action: ExchangeTokensAction) {
return
}
yield call(sendTransaction, approveTx, account, TAG, 'approval')
Logger.debug(TAG, `Transaction approved: ${approveTx}`)
Logger.debug(TAG, `Transaction approved: ${util.inspect(approveTx.arguments)}`)

const tx = exchangeContract.methods.exchange(
convertedMakerAmount.toString(),
Expand Down
10 changes: 10 additions & 0 deletions packages/mobile/src/fees/saga.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ jest.mock('@celo/walletkit', () => ({
},
}))

jest.mock('src/web3/contracts', () => ({
web3: {
utils: {
fromWei: jest.fn((x: any) => x / 1e18),
toWei: jest.fn((x: any) => x * 1e18),
},
},
isZeroSyncMode: jest.fn().mockReturnValueOnce(false),
}))

describe(estimateFeeSaga, () => {
beforeAll(() => {
jest.useRealTimers()
Expand Down
16 changes: 11 additions & 5 deletions packages/mobile/src/geth/consts.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
export const WEI_PER_CELO = 1000000000000000000.0
export const UNLOCK_DURATION = 600

// Valid sync mode values can be seen at https://github.com/celo-org/celo-blockchain/blob/8be27f7c044e35dbf63a42500a79805f1bddcfb8/mobile/geth.go#L43-L47
// Anything invalid will cause Geth to panic and app to crash.
export const SYNC_MODE_LIGHT = 3
// Value of 4 corresponds to a deprecated sync mode.
export const SYNC_MODE_ULTRALIGHT = 5
export enum GethSyncMode {
// Sync mode to imply no local geth node but an infura-like setup.
// This mode is internal to Celo wallet app and won't be propagated to
// geth node.
ZeroSync = -1,
// Valid sync mode values can be seen at https://github.com/celo-org/celo-blockchain/blob/8be27f7c044e35dbf63a42500a79805f1bddcfb8/mobile/geth.go#L43-L47
// Anything invalid will cause Geth to panic and app to crash.
Light = 3,
// Value of 4 corresponds to a deprecated sync mode.
Ultralight = 5,
}

// Re-export from utils for convinience since we use these often
export {
Expand Down
13 changes: 6 additions & 7 deletions packages/mobile/src/geth/network-config.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import { SYNC_MODE_ULTRALIGHT } from 'src/geth/consts'
import { Testnets } from 'src/web3/testnets'
import { DEFAULT_SYNC_MODE, Testnets } from 'src/web3/testnets'

export default {
[Testnets.integration]: {
nodeDir: `.${Testnets.integration}`,
syncMode: SYNC_MODE_ULTRALIGHT,
syncMode: DEFAULT_SYNC_MODE,
blockchainApiUrl: 'https://integration-dot-celo-testnet.appspot.com/',
},
[Testnets.alfajoresstaging]: {
nodeDir: `.${Testnets.alfajoresstaging}`,
syncMode: SYNC_MODE_ULTRALIGHT,
syncMode: DEFAULT_SYNC_MODE,
blockchainApiUrl: 'https://alfajoresstaging-dot-celo-testnet.appspot.com/',
},
[Testnets.alfajores]: {
nodeDir: `.${Testnets.alfajores}`,
syncMode: SYNC_MODE_ULTRALIGHT,
syncMode: DEFAULT_SYNC_MODE,
blockchainApiUrl: 'https://alfajores-dot-celo-testnet-production.appspot.com/',
},
[Testnets.pilot]: {
nodeDir: `.${Testnets.pilot}`,
syncMode: SYNC_MODE_ULTRALIGHT,
syncMode: DEFAULT_SYNC_MODE,
blockchainApiUrl: 'https://pilot-dot-celo-testnet-production.appspot.com/',
},
[Testnets.pilotstaging]: {
nodeDir: `.${Testnets.pilotstaging}`,
syncMode: SYNC_MODE_ULTRALIGHT,
syncMode: DEFAULT_SYNC_MODE,
blockchainApiUrl: 'https://pilotstaging-dot-celo-testnet.appspot.com/',
},
}
Loading