-
Notifications
You must be signed in to change notification settings - Fork 679
Conversation
d05ab71
to
d3c0181
Compare
d758778
to
2dc89a1
Compare
2dc89a1
to
9f83342
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @benjamincburns - couple comments / thoughts from a first read.
Looks great! Lots of bits and pieces moving around, but generally seems pretty intuitive.
Hat tip 👒 to @perissology for getting this started!
self.emit('block', block); | ||
} | ||
callback(err, result); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there risk of blocks being emitted out of order? Would that matter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There shouldn't be. pushBlock
is only called when processBlock
wants to commit a new block to the chain, when the genesis block is created, or on start with an existing db when latest
is read from that db. None of those things should be possible to order incorrectly.
|
||
if (options.ws) { | ||
wss = webSocketServer(server, provider, logger); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this get closed when the httpServer closes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought so at first as well, but after testing, I think this is the correct way to do it. webSocketServer
has a reference to the httpServer
, meaning it listens on the same socket, and its connections are tracked/managed by the httpServer
anyway.
lib/statemanager.js
Outdated
@@ -342,13 +336,12 @@ StateManager.prototype.queueTransaction = function(method, tx_params, callback) | |||
self.action_queue.push({ | |||
method: method, | |||
from: tx_params.from, | |||
tx: tx, | |||
tx: rawTx, | |||
callback: callback | |||
}); | |||
|
|||
// We know there's work, so get started. | |||
self.processNextAction(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent (L322-344)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
@@ -319,12 +319,6 @@ StateManager.prototype.queueTransaction = function(method, tx_params, callback) | |||
// Get the nonce for this address, taking account any transactions already queued. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment is out of date if you're moving nonce stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
lib/statemanager.js
Outdated
|
||
var tx_hash = to.hex(tx.hash()); | ||
let tx = new FakeTransaction(rawTx); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible suggestion: this getQueuedNonce
logic is now repeated 3 times - maybe worth abstracting into a prepareTx
function, or somesuch. Might make processCall
/processGasEstimate
/processTransaction
a lot easier to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
definitely.
lib/webSocketServer.js
Outdated
self.connections[ connection.id ] = { | ||
connection: connection, | ||
subscriptions: [], | ||
subscriptionCounter: 0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this is unused
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll double check, I think you're correct. I think it's likely hold over from the initial set of refactored changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't get to this yesterday. Will fix this now.
after('shutdown', function(done) { | ||
let provider = web3._provider; | ||
web3.setProvider(); | ||
provider.close(done); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does web3.setProvider()
do when not passing in a provider as a parameter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from memory it sets the provider to undefined
(it doesn't check the arg). I think I was being overly pedantic here though. My thought process was that web3 has a bunch of stuff it does in the background, and I didn't want it trying to run a request during or after provider close.
Further, I think calling provider.close
is a good idea in general when using the direct provider (probably need to make sure other tests do this), but unfortunately it's not a standard part of the interface, so I need to resort to something like provider.connection.close
for the WebSocket provider. Maybe I'll raise an issue for that.
This PR supersedes #14, as it is based on those changes. Thanks heaps to @perissology for his submission!
How this all works:
Subscription creation and notification:
SubscriptionSubprovider
which extends the existingFilterSubprovider
SubscriptionSubprovider
gets aneth_subscribe
request, it uses the underlyingFilterSubprovider
code to create a Filter (i.e.LogFilter
,BlockFilter
, orPendingBlockFilter
) for the subscription, then returns the id of this filter.LogFilter
,BlockFilter
andPendingBlockFilter
types to emit adata
event on updateSubscriptionSubprovider
creates a filter, it subscribes to the filter'sdata
event, and and emits its owndata
event when the Filter's event fires, clearing pending filter changes in the process.EventEmitter
and to proxydata
events from theSubscriptionSubprovider
.Routing notifications to clients:
Provider
type.ConnectionManager
.ConnectionManager
snoops on the traffic it's proxying to maintain a forward and reverse mapping of subscription ID to websocket connection.ConnectionManager
listens todata
events from the Provider, and uses its mapping of subscription ID to connection to route the subscription notifications to the correct websocket connection.eth_unsubscribe
request is handled,ConnectionManager
cleans up the relevant mapping.ConnectionManager
cleans up all mappings pertaining to that client.TODO: