Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
a57aa65a
Unverified
Commit
a57aa65a
authored
Sep 06, 2019
by
yann300
Committed by
GitHub
Sep 06, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1267 from ethereum/improve_remix_sim3
working websocket support; implement eth_subscribe; eth_unsubscribe; eth_getLogs
parents
0dcd0957
b4d42a33
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
206 additions
and
17 deletions
+206
-17
execution-context.js
remix-lib/src/execution/execution-context.js
+9
-0
logsManager.js
remix-lib/src/execution/logsManager.js
+123
-0
txRunner.js
remix-lib/src/execution/txRunner.js
+1
-1
README.md
remix-simulator/README.md
+3
-3
ethsim
remix-simulator/bin/ethsim
+3
-1
package.json
remix-simulator/package.json
+2
-1
genesis.js
remix-simulator/src/genesis.js
+1
-1
filters.js
remix-simulator/src/methods/filters.js
+32
-0
txProcess.js
remix-simulator/src/methods/txProcess.js
+10
-4
provider.js
remix-simulator/src/provider.js
+9
-0
server.js
remix-simulator/src/server.js
+11
-4
blocks.js
remix-simulator/test/blocks.js
+2
-2
No files found.
remix-lib/src/execution/execution-context.js
View file @
a57aa65a
...
...
@@ -7,6 +7,8 @@ var ethUtil = require('ethereumjs-util')
var
StateManager
=
require
(
'ethereumjs-vm/dist/stateManager'
)
var
Web3VMProvider
=
require
(
'../web3Provider/web3VmProvider'
)
var
LogsManager
=
require
(
'./logsManager.js'
)
var
rlp
=
ethUtil
.
rlp
var
injectedProvider
...
...
@@ -105,6 +107,8 @@ function ExecutionContext () {
var
self
=
this
this
.
event
=
new
EventManager
()
this
.
logsManager
=
new
LogsManager
()
var
executionContext
=
null
this
.
blockGasLimitDefault
=
4300000
...
...
@@ -298,10 +302,15 @@ function ExecutionContext () {
this
.
addBlock
=
function
(
block
)
{
let
blockNumber
=
'0x'
+
block
.
header
.
number
.
toString
(
'hex'
)
if
(
blockNumber
===
'0x'
)
{
blockNumber
=
'0x0'
}
blockNumber
=
web3
.
toHex
(
web3
.
toBigNumber
(
blockNumber
))
self
.
blocks
[
'0x'
+
block
.
hash
().
toString
(
'hex'
)]
=
block
self
.
blocks
[
blockNumber
]
=
block
this
.
logsManager
.
checkBlock
(
blockNumber
,
block
,
this
.
web3
())
}
this
.
trackTx
=
function
(
tx
,
block
)
{
...
...
remix-lib/src/execution/logsManager.js
0 → 100644
View file @
a57aa65a
const
async
=
require
(
'async'
)
const
crypto
=
require
(
'crypto'
)
class
LogsManager
{
constructor
()
{
this
.
notificationCallbacks
=
[]
this
.
subscriptions
=
{}
this
.
oldLogs
=
[]
}
checkBlock
(
blockNumber
,
block
,
web3
)
{
async
.
eachOf
(
block
.
transactions
,
(
tx
,
i
,
next
)
=>
{
let
txHash
=
'0x'
+
tx
.
hash
().
toString
(
'hex'
)
web3
.
eth
.
getTransactionReceipt
(
txHash
,
(
_error
,
receipt
)
=>
{
for
(
let
log
of
receipt
.
logs
)
{
this
.
oldLogs
.
push
({
type
:
'block'
,
blockNumber
,
block
,
tx
,
log
,
txNumber
:
i
})
let
subscriptions
=
this
.
getSubscriptionsFor
({
type
:
'block'
,
blockNumber
,
block
,
tx
,
log
})
for
(
let
subscriptionId
of
subscriptions
)
{
let
result
=
{
'logIndex'
:
'0x1'
,
// 1
'blockNumber'
:
blockNumber
,
'blockHash'
:
(
'0x'
+
block
.
hash
().
toString
(
'hex'
)),
'transactionHash'
:
(
'0x'
+
tx
.
hash
().
toString
(
'hex'
)),
'transactionIndex'
:
'0x'
+
i
.
toString
(
16
),
// TODO: if it's a contract deploy, it should be that address instead
'address'
:
log
.
address
,
'data'
:
log
.
data
,
'topics'
:
log
.
topics
}
if
(
result
.
address
===
'0x'
)
{
delete
result
.
address
}
let
response
=
{
'jsonrpc'
:
'2.0'
,
'method'
:
'eth_subscription'
,
params
:
{
'result'
:
result
,
'subscription'
:
subscriptionId
}
}
this
.
transmit
(
response
)
}
}
})
},
(
_err
)
=>
{
})
}
eventMatchesFilter
(
changeEvent
,
queryType
,
queryFilter
)
{
if
(
queryFilter
.
topics
.
filter
((
logTopic
)
=>
changeEvent
.
log
.
topics
.
indexOf
(
logTopic
)
>=
0
).
length
===
0
)
return
false
if
(
queryType
===
'logs'
)
{
if
((
queryFilter
.
address
===
(
'0x'
+
changeEvent
.
tx
.
to
.
toString
(
'hex'
)))
&&
(
queryFilter
.
address
===
(
'0x'
+
changeEvent
.
tx
.
from
.
toString
(
'hex'
))))
{
if
(
!
queryFilter
.
toBlock
)
{
return
true
}
else
if
(
parseInt
(
queryFilter
.
toBlock
)
>
parseInt
(
changeEvent
.
blockNumber
))
{
return
true
}
}
}
return
false
}
getSubscriptionsFor
(
changeEvent
)
{
let
matchedSubscriptions
=
[]
for
(
let
subscriptionId
of
Object
.
keys
(
this
.
subscriptions
))
{
const
subscriptionParams
=
this
.
subscriptions
[
subscriptionId
]
const
[
queryType
,
queryFilter
]
=
subscriptionParams
if
(
this
.
eventMatchesFilter
(
changeEvent
,
queryType
,
queryFilter
))
{
matchedSubscriptions
.
push
(
subscriptionId
)
}
}
return
matchedSubscriptions
}
transmit
(
result
)
{
this
.
notificationCallbacks
.
forEach
((
callback
)
=>
{
if
(
result
.
params
.
result
.
raw
)
{
result
.
params
.
result
.
data
=
result
.
params
.
result
.
raw
.
data
result
.
params
.
result
.
topics
=
result
.
params
.
result
.
raw
.
topics
}
callback
(
result
)
})
}
addListener
(
_type
,
cb
)
{
this
.
notificationCallbacks
.
push
(
cb
)
}
subscribe
(
params
)
{
let
subscriptionId
=
'0x'
+
crypto
.
randomBytes
(
16
).
toString
(
'hex'
)
this
.
subscriptions
[
subscriptionId
]
=
params
return
subscriptionId
}
unsubscribe
(
subscriptionId
)
{
delete
this
.
subscriptions
[
subscriptionId
]
}
getLogsFor
(
params
)
{
let
results
=
[]
for
(
let
log
of
this
.
oldLogs
)
{
if
(
this
.
eventMatchesFilter
(
log
,
'logs'
,
params
))
{
results
.
push
({
'logIndex'
:
'0x1'
,
// 1
'blockNumber'
:
log
.
blockNumber
,
'blockHash'
:
(
'0x'
+
log
.
block
.
hash
().
toString
(
'hex'
)),
'transactionHash'
:
(
'0x'
+
log
.
tx
.
hash
().
toString
(
'hex'
)),
'transactionIndex'
:
'0x'
+
log
.
txNumber
.
toString
(
16
),
// TODO: if it's a contract deploy, it should be that address instead
'address'
:
log
.
log
.
address
,
'data'
:
log
.
log
.
data
,
'topics'
:
log
.
log
.
topics
})
}
}
return
results
}
}
module
.
exports
=
LogsManager
remix-lib/src/execution/txRunner.js
View file @
a57aa65a
...
...
@@ -14,7 +14,7 @@ class TxRunner {
this
.
runAsync
=
true
if
(
executionContext
.
isVM
())
{
// this.blockNumber = 1150000 // The VM is running in Homestead mode, which started at this block.
this
.
blockNumber
=
2
// The VM is running in Homestead mode, which started at this block.
this
.
blockNumber
=
0
// The VM is running in Homestead mode, which started at this block.
this
.
runAsync
=
false
// We have to run like this cause the VM Event Manager does not support running multiple txs at the same time.
}
this
.
pendingTxs
=
{}
...
...
remix-simulator/README.md
View file @
a57aa65a
...
...
@@ -46,7 +46,7 @@ Implemented:
*
[
_
]
eth_uninstallFilter
*
[
_
]
eth_getFilterChanges
*
[
_
]
eth_getFilterLogs
*
[
_
]
eth_getLogs
*
[
X
]
eth_getLogs
*
[
_
]
eth_getWork
*
[
_
]
eth_submitWork
*
[
_
]
eth_submitHashrate
...
...
@@ -68,8 +68,8 @@ Implemented:
*
[
_
]
bzz_hive (stub)
*
[
_
]
bzz_info (stub)
*
[
_
]
debug_traceTransaction
*
[
_
]
eth_subscribe
*
[
_
]
eth_unsubscribe
*
[
X
]
eth_subscribe
*
[
X
]
eth_unsubscribe
*
[
_
]
miner_start
*
[
_
]
miner_stop
*
[
_
]
personal_listAccounts
...
...
remix-simulator/bin/ethsim
View file @
a57aa65a
...
...
@@ -23,11 +23,13 @@ program
.
option
(
'-p, --port [port]'
,
'specify port'
)
.
option
(
'-b, --ip [host]'
,
'specify host'
)
.
option
(
'-c, --coinbase [coinbase]'
,
'specify host'
)
.
option
(
'--rpc'
,
'run rpc server only'
)
.
parse
(
process
.
argv
)
const
Server
=
require
(
'../src/server'
)
const
server
=
new
Server
({
coinbase
:
program
.
coinbase
||
"0x0000000000000000000000000000000000000000"
coinbase
:
program
.
coinbase
||
"0x0000000000000000000000000000000000000000"
,
rpc
:
program
.
rpc
})
server
.
start
(
program
.
host
||
'127.0.0.1'
,
program
.
port
||
8545
)
remix-simulator/package.json
View file @
a57aa65a
...
...
@@ -15,6 +15,7 @@
"main"
:
"./index.js"
,
"dependencies"
:
{
"ansi-gray"
:
"^0.1.1"
,
"async"
:
"^3.1.0"
,
"body-parser"
:
"^1.18.2"
,
"color-support"
:
"^1.1.3"
,
"commander"
:
"^2.19.0"
,
...
...
@@ -28,7 +29,7 @@
"remix-lib"
:
"0.4.12"
,
"standard"
:
"^10.0.3"
,
"time-stamp"
:
"^2.0.0"
,
"web3"
:
"
1.0.0-beta.2
7"
"web3"
:
"
^1.0.0-beta.3
7"
},
"devDependencies"
:
{
"@babel/core"
:
"^7.4.5"
,
...
...
remix-simulator/src/genesis.js
View file @
a57aa65a
...
...
@@ -8,7 +8,7 @@ function generateBlock () {
var
block
=
new
EthJSBlock
({
header
:
{
timestamp
:
(
new
Date
().
getTime
()
/
1000
|
0
),
number
:
1
,
number
:
0
,
coinbase
:
'0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a'
,
difficulty
:
(
new
BN
(
'69762765929000'
,
10
)),
gasLimit
:
new
BN
(
'8000000'
).
imuln
(
1
)
...
...
remix-simulator/src/methods/filters.js
0 → 100644
View file @
a57aa65a
var
RemixLib
=
require
(
'remix-lib'
)
var
executionContext
=
RemixLib
.
execution
.
executionContext
var
Filters
=
function
(
_options
)
{
// const options = _options || {}
}
Filters
.
prototype
.
methods
=
function
()
{
return
{
eth_getLogs
:
this
.
eth_getLogs
.
bind
(
this
),
eth_subscribe
:
this
.
eth_subscribe
.
bind
(
this
),
eth_unsubscribe
:
this
.
eth_unsubscribe
.
bind
(
this
)
}
}
// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs
Filters
.
prototype
.
eth_getLogs
=
function
(
payload
,
cb
)
{
let
results
=
executionContext
.
logsManager
.
getLogsFor
(
payload
.
params
[
0
])
cb
(
null
,
results
)
}
Filters
.
prototype
.
eth_subscribe
=
function
(
payload
,
cb
)
{
let
subscriptionId
=
executionContext
.
logsManager
.
subscribe
(
payload
.
params
)
cb
(
null
,
subscriptionId
)
}
Filters
.
prototype
.
eth_unsubscribe
=
function
(
payload
,
cb
)
{
executionContext
.
logsManager
.
unsubscribe
(
payload
.
params
[
0
])
cb
(
null
,
true
)
}
module
.
exports
=
Filters
remix-simulator/src/methods/txProcess.js
View file @
a57aa65a
...
...
@@ -41,6 +41,8 @@ function createContract (payload, from, data, value, gasLimit, txRunner, callbac
TxExecution
.
createContract
(
from
,
data
,
value
,
gasLimit
,
txRunner
,
callbacks
,
finalCallback
)
}
let
txRunnerInstance
function
processTx
(
accounts
,
payload
,
isCall
,
callback
)
{
let
api
=
{
logMessage
:
(
msg
)
=>
{
...
...
@@ -65,7 +67,11 @@ function processTx (accounts, payload, isCall, callback) {
executionContext
.
init
(
api
.
config
)
let
txRunner
=
new
TxRunner
(
accounts
,
api
)
// let txRunner = new TxRunner(accounts, api)
if
(
!
txRunnerInstance
)
{
txRunnerInstance
=
new
TxRunner
(
accounts
,
api
)
}
txRunnerInstance
.
vmaccounts
=
accounts
let
{
from
,
to
,
data
,
value
,
gas
}
=
payload
.
params
[
0
]
gas
=
gas
||
3000000
...
...
@@ -85,11 +91,11 @@ function processTx (accounts, payload, isCall, callback) {
}
if
(
isCall
)
{
runCall
(
payload
,
from
,
to
,
data
,
value
,
gas
,
txRunner
,
callbacks
,
callback
)
runCall
(
payload
,
from
,
to
,
data
,
value
,
gas
,
txRunner
Instance
,
callbacks
,
callback
)
}
else
if
(
to
)
{
runTx
(
payload
,
from
,
to
,
data
,
value
,
gas
,
txRunner
,
callbacks
,
callback
)
runTx
(
payload
,
from
,
to
,
data
,
value
,
gas
,
txRunner
Instance
,
callbacks
,
callback
)
}
else
{
createContract
(
payload
,
from
,
data
,
value
,
gas
,
txRunner
,
callbacks
,
callback
)
createContract
(
payload
,
from
,
data
,
value
,
gas
,
txRunner
Instance
,
callbacks
,
callback
)
}
}
...
...
remix-simulator/src/provider.js
View file @
a57aa65a
var
RemixLib
=
require
(
'remix-lib'
)
var
executionContext
=
RemixLib
.
execution
.
executionContext
const
log
=
require
(
'./utils/logs.js'
)
const
merge
=
require
(
'merge'
)
const
Accounts
=
require
(
'./methods/accounts.js'
)
const
Blocks
=
require
(
'./methods/blocks.js'
)
const
Filters
=
require
(
'./methods/filters.js'
)
const
Misc
=
require
(
'./methods/misc.js'
)
const
Net
=
require
(
'./methods/net.js'
)
const
Transactions
=
require
(
'./methods/transactions.js'
)
...
...
@@ -18,6 +22,7 @@ var Provider = function (options) {
this
.
methods
=
merge
(
this
.
methods
,
this
.
Accounts
.
methods
())
this
.
methods
=
merge
(
this
.
methods
,
(
new
Blocks
(
options
)).
methods
())
this
.
methods
=
merge
(
this
.
methods
,
(
new
Misc
()).
methods
())
this
.
methods
=
merge
(
this
.
methods
,
(
new
Filters
()).
methods
())
this
.
methods
=
merge
(
this
.
methods
,
(
new
Net
()).
methods
())
this
.
methods
=
merge
(
this
.
methods
,
(
this
.
Transactions
.
methods
()))
this
.
methods
=
merge
(
this
.
methods
,
(
new
Whisper
()).
methods
())
...
...
@@ -54,4 +59,8 @@ Provider.prototype.isConnected = function () {
return
true
}
Provider
.
prototype
.
on
=
function
(
type
,
cb
)
{
executionContext
.
logsManager
.
addListener
(
type
,
cb
)
}
module
.
exports
=
Provider
remix-simulator/src/server.js
View file @
a57aa65a
...
...
@@ -14,6 +14,7 @@ class Server {
}).
catch
((
error
)
=>
{
log
(
error
)
})
this
.
rpcOnly
=
options
.
rpc
}
start
(
host
,
port
)
{
...
...
@@ -27,25 +28,31 @@ class Server {
res
.
send
(
'Welcome to remix-simulator'
)
})
if
(
this
.
rpcOnly
)
{
app
.
use
((
req
,
res
)
=>
{
this
.
provider
.
sendAsync
(
req
.
body
,
(
err
,
jsonResponse
)
=>
{
if
(
err
)
{
return
res
.
send
(
JSON
.
stringify
({
error
:
err
}))
return
res
.
send
(
JSON
.
stringify
({
error
:
err
}))
}
res
.
send
(
jsonResponse
)
})
})
}
else
{
app
.
ws
(
'/'
,
(
ws
,
req
)
=>
{
ws
.
on
(
'message'
,
function
(
msg
)
{
ws
.
on
(
'message'
,
(
msg
)
=>
{
this
.
provider
.
sendAsync
(
JSON
.
parse
(
msg
),
(
err
,
jsonResponse
)
=>
{
if
(
err
)
{
return
ws
.
send
(
JSON
.
stringify
({
error
:
err
}))
return
ws
.
send
(
JSON
.
stringify
({
error
:
err
}))
}
ws
.
send
(
JSON
.
stringify
(
jsonResponse
))
})
})
this
.
provider
.
on
(
'data'
,
(
result
)
=>
{
ws
.
send
(
JSON
.
stringify
(
result
))
})
})
}
app
.
listen
(
port
,
host
,
()
=>
log
(
'Remix Simulator listening on port '
+
host
+
':'
+
port
))
}
...
...
remix-simulator/test/blocks.js
View file @
a57aa65a
...
...
@@ -13,7 +13,7 @@ describe('blocks', function () {
})
it
(
'should get block given its number'
,
async
function
()
{
let
block
=
await
web3
.
eth
.
getBlock
(
1
)
let
block
=
await
web3
.
eth
.
getBlock
(
0
)
let
expectedBlock
=
{
difficulty
:
'69762765929000'
,
...
...
@@ -24,7 +24,7 @@ describe('blocks', function () {
logsBloom
:
'0xe670ec64341771606e55d6b4ca35a1a6b75ee3d5145a99d05921026d1527331'
,
miner
:
'0x0000000000000000000000000000000000000001'
,
nonce
:
'0x0000000000000000'
,
number
:
1
,
number
:
0
,
parentHash
:
'0x0000000000000000000000000000000000000000000000000000000000000000'
,
sha3Uncles
:
'0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347'
,
size
:
163591
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment