Skip to content

Commit

Permalink
Merge pull request #2510 from ethereum/refactor_logic2
Browse files Browse the repository at this point in the history
Refactor executionContext and udapp, into common class
  • Loading branch information
iurimatias committed Jan 22, 2020
2 parents 5df44c9 + 5dc2ff2 commit 1ff9e8c
Show file tree
Hide file tree
Showing 16 changed files with 342 additions and 346 deletions.
17 changes: 12 additions & 5 deletions src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ var CompilerImport = require('./app/compiler/compiler-imports')

var executionContext = remixLib.execution.executionContext

const Blockchain = require('./app/tabs/runTab/model/blockchain.js')

const PluginManagerComponent = require('./app/components/plugin-manager-component')
const CompilersArtefacts = require('./app/compiler/compiler-artefacts')

Expand Down Expand Up @@ -222,14 +224,18 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
// ----------------- fileManager servive ----------------------------
const fileManager = new FileManager(editor)
registry.put({api: fileManager, name: 'filemanager'})

// ----------------- universal dapp: run transaction, listen on transactions, decode events
const udapp = new UniversalDApp(registry.get('config').api, executionContext)
const blockchain = new Blockchain(executionContext, udapp)

// ----------------- compilation metadata generation servive ----------------------------
const compilerMetadataGenerator = new CompilerMetadata(executionContext, fileManager, registry.get('config').api)
const compilerMetadataGenerator = new CompilerMetadata(blockchain, fileManager, registry.get('config').api)
// ----------------- compilation result service (can keep track of compilation results) ----------------------------
const compilersArtefacts = new CompilersArtefacts() // store all the compilation results (key represent a compiler name)
registry.put({api: compilersArtefacts, name: 'compilersartefacts'})
// ----------------- universal dapp: run transaction, listen on transactions, decode events
const udapp = new UniversalDApp(registry.get('config').api, executionContext)
const {eventsDecoder, txlistener} = makeUdapp(udapp, executionContext, compilersArtefacts, (domEl) => mainview.getTerminal().logHtml(domEl))

const {eventsDecoder, txlistener} = makeUdapp(blockchain, compilersArtefacts, (domEl) => mainview.getTerminal().logHtml(domEl))
// ----------------- network service (resolve network id / name) ----------------------------
const networkModule = new NetworkModule(executionContext)
// ----------------- convert offset to line/column service ----------------------------
Expand All @@ -249,7 +255,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org

// LAYOUT & SYSTEM VIEWS
const appPanel = new MainPanel()
const mainview = new MainView(editor, appPanel, fileManager, appManager, txlistener, eventsDecoder, executionContext)
const mainview = new MainView(editor, appPanel, fileManager, appManager, txlistener, eventsDecoder, blockchain)
registry.put({ api: mainview, name: 'mainview' })

appManager.register([
Expand Down Expand Up @@ -293,6 +299,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
registry.get('filemanager').api
)
const run = new RunTab(
blockchain,
udapp,
executionContext,
registry.get('config').api,
Expand Down
22 changes: 10 additions & 12 deletions src/app/files/compiler-metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ const profile = {
}

class CompilerMetadata extends Plugin {
constructor (executionContext, fileManager, config) {
constructor (blockchain, fileManager, config) {
super(profile)
var self = this
self.executionContext = executionContext
self.fileManager = fileManager
self.config = config
self.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'görli:5', 'Custom']
self.innerPath = 'artifacts'
this.blockchain = blockchain
this.fileManager = fileManager
this.config = config
this.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'görli:5', 'Custom']
this.innerPath = 'artifacts'
}

_JSONFileName (path, contractName) {
Expand Down Expand Up @@ -93,15 +92,14 @@ class CompilerMetadata extends Plugin {
// TODO: is only called by dropdownLogic and can be moved there
deployMetadataOf (contractName) {
return new Promise((resolve, reject) => {
var self = this
var provider = self.fileManager.currentFileProvider()
var path = self.fileManager.currentPath()
var provider = this.fileManager.currentFileProvider()
var path = this.fileManager.currentPath()
if (provider && path) {
self.executionContext.detectNetwork((err, { id, name } = {}) => {
this.blockchain.detectNetwork((err, { id, name } = {}) => {
if (err) {
console.log(err)
} else {
var fileName = self._JSONFileName(path, contractName)
var fileName = this._JSONFileName(path, contractName)
provider.get(fileName, (error, content) => {
if (error) return reject(error)
if (!content) return resolve()
Expand Down
6 changes: 3 additions & 3 deletions src/app/panels/main-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var css = csjs`
`

export class MainView {
constructor (editor, mainPanel, fileManager, appManager, txListener, eventsDecoder, executionContext) {
constructor (editor, mainPanel, fileManager, appManager, txListener, eventsDecoder, blockchain) {
var self = this
self.event = new EventManager()
self._view = {}
Expand All @@ -31,7 +31,7 @@ export class MainView {
self.mainPanel = mainPanel
self.txListener = txListener
self.eventsDecoder = eventsDecoder
self.executionContext = executionContext
self.blockchain = blockchain
this.appManager = appManager
this.init()
}
Expand Down Expand Up @@ -101,7 +101,7 @@ export class MainView {
appManager: this.appManager,
eventsDecoder: this.eventsDecoder,
txListener: this.txListener,
executionContext: this.executionContext
blockchain: this.blockchain
},
{
getPosition: (event) => {
Expand Down
12 changes: 6 additions & 6 deletions src/app/panels/terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Terminal extends Plugin {
super(profile)
var self = this
self.event = new EventManager()
self.executionContext = opts.executionContext
self.blockchain = opts.blockchain
self._api = api
self._opts = opts
self.data = {
Expand All @@ -52,7 +52,7 @@ class Terminal extends Plugin {
}
self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null }
self._components = {}
self._components.cmdInterpreter = new CommandInterpreterAPI(this, null, self.executionContext)
self._components.cmdInterpreter = new CommandInterpreterAPI(this, null, self.blockchain)
self._components.autoCompletePopup = new AutoCompletePopup(self._opts)
self._components.autoCompletePopup.event.register('handleSelect', function (input) {
let textList = self._view.input.innerText.split(' ')
Expand Down Expand Up @@ -437,7 +437,7 @@ class Terminal extends Plugin {
self._shell('remix.help()', self.commands, () => {})
self.commands.html(intro)

self._components.txLogger = new TxLogger(self._opts.eventsDecoder, self._opts.txListener, this, self.executionContext)
self._components.txLogger = new TxLogger(self._opts.eventsDecoder, self._opts.txListener, this, self.blockchain)
self._components.txLogger.event.register('debuggingRequested', (hash) => {
// TODO should probably be in the run module
if (!self._opts.appManager.isActive('debugger')) self._opts.appManager.activateOne('debugger')
Expand Down Expand Up @@ -668,7 +668,7 @@ class Terminal extends Plugin {
return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.')
}
var self = this
var context = domTerminalFeatures(self, scopedCommands, self.executionContext)
var context = domTerminalFeatures(self, scopedCommands, self.blockchain)
try {
var cmds = vm.createContext(Object.assign(self._jsSandboxContext, context, self._jsSandboxRegistered))
var result = vm.runInContext(script, cmds)
Expand All @@ -680,12 +680,12 @@ class Terminal extends Plugin {
}
}

function domTerminalFeatures (self, scopedCommands, executionContext) {
function domTerminalFeatures (self, scopedCommands, blockchain) {
return {
swarmgw,
ethers,
remix: self._components.cmdInterpreter,
web3: new Web3(executionContext.web3().currentProvider),
web3: new Web3(blockchain.web3().currentProvider),
console: {
log: function () { scopedCommands.log.apply(scopedCommands, arguments) },
info: function () { scopedCommands.info.apply(scopedCommands, arguments) },
Expand Down
6 changes: 3 additions & 3 deletions src/app/tabs/runTab/contractDropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,8 @@ class ContractDropdownUI {
if (network.name !== 'Main') {
return continueTxExecution(null)
}
const amount = this.dropdownLogic.fromWei(tx.value, true, 'ether')
const content = confirmDialog(tx, amount, gasEstimation, null, this.dropdownLogic.determineGasFees(tx), this.blockchain.determineGasPrice)
const amount = this.blockchain.fromWei(tx.value, true, 'ether')
const content = confirmDialog(tx, amount, gasEstimation, null, this.blockchain.determineGasFees(tx), this.blockchain.determineGasPrice)

modalDialog('Confirm transaction', content,
{ label: 'Confirm',
Expand All @@ -220,7 +220,7 @@ class ContractDropdownUI {
if (!content.gasPriceStatus) {
cancelCb('Given gas price is not correct')
} else {
var gasPrice = this.dropdownLogic.toWei(content.querySelector('#gasprice').value, 'gwei')
var gasPrice = this.blockchain.toWei(content.querySelector('#gasprice').value, 'gwei')
continueTxExecution(gasPrice)
}
}}, {
Expand Down
172 changes: 172 additions & 0 deletions src/app/tabs/runTab/model/blockchain.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,47 @@ const remixLib = require('remix-lib')
const txFormat = remixLib.execution.txFormat
const txExecution = remixLib.execution.txExecution
const typeConversion = remixLib.execution.typeConversion
const Txlistener = remixLib.execution.txListener
const EventManager = remixLib.EventManager
const ethJSUtil = require('ethereumjs-util')
const Personal = require('web3-eth-personal')
const Web3 = require('web3')

class Blockchain {

constructor (executionContext, udapp) {
this.event = new EventManager()
this.executionContext = executionContext
this.udapp = udapp

this.networkcallid = 0
this.setupEvents()
}

setupEvents () {
this.executionContext.event.register('contextChanged', (context, silent) => {
this.event.trigger('contextChanged', [context, silent])
})

this.executionContext.event.register('addProvider', (network) => {
this.event.trigger('addProvider', [network])
})

this.executionContext.event.register('removeProvider', (name) => {
this.event.trigger('removeProvider', [name])
})

this.udapp.event.register('initiatingTransaction', (timestamp, tx, payLoad) => {
this.event.trigger('initiatingTransaction', [timestamp, tx, payLoad])
})

this.udapp.event.register('transactionExecuted', (error, from, to, data, call, txResult, timestamp) => {
this.event.trigger('transactionExecuted', [error, from, to, data, call, txResult, timestamp])
})

this.udapp.event.register('transactionBroadcasted', (txhash, networkName) => {
this.event.trigger('transactionBroadcasted', [txhash, networkName])
})
}

async deployContract (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) {
Expand Down Expand Up @@ -93,6 +127,144 @@ class Blockchain {
return Web3.utils.fromWei(value.toString(10), unit || 'ether')
}

toWei (value, unit) {
return Web3.utils.toWei(value, unit || 'gwei')
}

calculateFee (gas, gasPrice, unit) {
return Web3.utils.toBN(gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), unit || 'gwei')))
}

determineGasFees (tx) {
const determineGasFeesCb = (gasPrice, cb) => {
let txFeeText, priceStatus
// TODO: this try catch feels like an anti pattern, can/should be
// removed, but for now keeping the original logic
try {
var fee = this.calculateFee(tx.gas, gasPrice)
txFeeText = ' ' + this.fromWei(fee, false, 'ether') + ' Ether'
priceStatus = true
} catch (e) {
txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
priceStatus = false
}
cb(txFeeText, priceStatus)
}

return determineGasFeesCb
}

getAddressFromTransactionResult (txResult) {
return this.executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress
}

changeExecutionContext (context, confirmCb, infoCb, cb) {
return this.executionContext.executionContextChange(context, null, confirmCb, infoCb, cb)
}

setProviderFromEndpoint (target, context, cb) {
return this.executionContext.setProviderFromEndpoint(target, context, cb)
}

getProvider () {
return this.executionContext.getProvider()
}

getAccountBalanceForAddress (address, cb) {
return this.udapp.getBalanceInEther(address, cb)
}

updateNetwork (cb) {
this.networkcallid++
((callid) => {
this.executionContext.detectNetwork((err, { id, name } = {}) => {
if (this.networkcallid > callid) return
this.networkcallid++
if (err) {
return cb(err)
}
cb(null, {id, name})
})
})(this.networkcallid)
}

detectNetwork (cb) {
return this.executionContext.detectNetwork(cb)
}

newAccount (passphraseCb, cb) {
return this.udapp.newAccount('', passphraseCb, cb)
}

getAccounts (cb) {
return this.udapp.getAccounts(cb)
}

isWeb3Provider () {
var isVM = this.executionContext.isVM()
var isInjected = this.executionContext.getProvider() === 'injected'
return (!isVM && !isInjected)
}

isInjectedWeb3 () {
return this.executionContext.getProvider() === 'injected'
}

signMessage (message, account, passphrase, cb) {
var isVM = this.executionContext.isVM()
var isInjected = this.executionContext.getProvider() === 'injected'

if (isVM) {
const personalMsg = ethJSUtil.hashPersonalMessage(Buffer.from(message))
var privKey = this.udapp.accounts[account].privateKey
try {
var rsv = ethJSUtil.ecsign(personalMsg, privKey)
var signedData = ethJSUtil.toRpcSig(rsv.v, rsv.r, rsv.s)
cb(null, '0x' + personalMsg.toString('hex'), signedData)
} catch (e) {
cb(e.message)
}
return
}
if (isInjected) {
const hashedMsg = Web3.utils.sha3(message)
try {
this.executionContext.web3().eth.sign(account, hashedMsg, (error, signedData) => {
cb(error.message, hashedMsg, signedData)
})
} catch (e) {
cb(e.message)
}
return
}

const hashedMsg = Web3.utils.sha3(message)
try {
var personal = new Personal(this.executionContext.web3().currentProvider)
personal.sign(hashedMsg, account, passphrase, (error, signedData) => {
cb(error.message, hashedMsg, signedData)
})
} catch (e) {
cb(e.message)
}
}

web3 () {
return this.executionContext.web3()
}

getTxListener (opts) {
opts.event = {
udapp: this.udapp.event
}
const txlistener = new Txlistener(opts, this.executionContext)
return txlistener
}

startListening (txlistener) {
this.udapp.startListening(txlistener)
}

}

module.exports = Blockchain
Loading

0 comments on commit 1ff9e8c

Please sign in to comment.