-
Notifications
You must be signed in to change notification settings - Fork 458
Update loader module in chain to use network module and fix the tests - Closes #2875 #3243
Update loader module in chain to use network module and fix the tests - Closes #2875 #3243
Conversation
@ManuGowda I added you because it would be nice if QA team could test this branch on the network to verify that synching still works and that it doesn't introduce any new issues. I was able to verify that synching still works by running on my local machine and synching with testnet (it was correctly adding blocks to the DB table). I did notice some disconnection errors (which is expected because my node was not exposed to the internet). It would be good to check that these errors do not show up when running the node on a remote instance as part of testnet. |
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.
Overall the PR LGTM, I have made few comments related to function and variable naming and also log messages and log level usage. Also the network tests were removed, I hope the removed tests are covered somewhere?
framework/src/modules/chain/chain.js
Outdated
@@ -181,7 +181,9 @@ module.exports = class Chain { | |||
scope.bus.message('bind', scope); | |||
|
|||
// Listen to websockets | |||
await scope.webSocket.listen(); | |||
if (scope.config.peers.enabled) { |
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 think this has been fixed in the development
branch, can you rebase `development branch?
framework/src/modules/chain/chain.js
Outdated
true, | ||
global.constants.MAX_SHARED_TRANSACTIONS | ||
); | ||
const multisignatures = []; |
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.
we can rewrite this to
return transactions.map(transaction => {
if (transaction.signatures && transaction.signatures.length) {
return ({
transaction: transaction.id,
signatures: transaction.signatures,
});
}
});
framework/src/modules/chain/chain.js
Outdated
limit: 34, // 1977100 bytes | ||
lastId: query.lastBlockId, | ||
}, | ||
(err, data) => { |
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.
to avoid variable shadowing, we can name err
to specific error here. and same for data
async function getFromNetwork() { | ||
// TODO: If there is an error, invoke the applyPenalty action on the Network module once it is implemented. | ||
// TODO: Rename procedure to include target module name. E.g. chain:blocks | ||
const result = await library.channel.invoke('network:request', { |
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.
use destructuring const { data } =
}, | ||
}); | ||
|
||
if (!result.data) { |
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.
update here and below after destructure changes
|
||
try { | ||
await validate(result, definitions.WSTransactionsResponse); | ||
} catch (validateErrors) { |
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 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.
please do the same for signatures
try { | ||
library.logic.transaction.objectNormalize(transaction); | ||
} catch (error) { | ||
library.logger.debug('Transaction normalization failed', { |
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.
logger.debug
? not logger.error
?
); | ||
}); | ||
} catch (error) { | ||
library.logger.debug(error); |
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.
same as above
this.p2p.on(EVENT_FAILED_TO_FETCH_PEER_INFO, error => { | ||
this.logger.debug(error.message); | ||
this.logger.debug(error.message || error); |
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.
why logger.debug
? why not logger.error
? same for below.
} catch (error) { | ||
request.error(error); // Send an error back to the peer. | ||
this.logger.debug( |
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.
same here as well.
lastId: query.lastBlockId, | ||
}, | ||
(err, data) => { | ||
(data || []).forEach(block => { |
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.
prefer early return if data` is undefined
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.
Most of the concerns are covered by comments from others, just a minor comment. Also, if you need the whole config to come to network module then maybe you can add below line,
app.overrideModuleOptions('network', { config });
to src/index.js
. I have added it in my PR though.
@@ -12,8 +12,11 @@ const { | |||
EVENT_REQUEST_RECEIVED, |
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 miss tests for this entire file.
@@ -455,286 +379,4 @@ describe('loader', () => { | |||
}); | |||
}); | |||
}); | |||
|
|||
describe('__private.loadBlocksFromNetwork', () => { |
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.
Why do we remove this instead of adapting it to the new times?
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.
These unit tests and the underlying logic were poorly implemented. This refactoring improves this a bit but it's still not in a sufficiently clean/settled state to be unit tested.
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.
So how do you assure it's working well?
definitions.WSSignaturesResponse, | ||
validateErr => setImmediate(waterCb, validateErr, res.signatures) | ||
); | ||
__private.loadSignatures = async function() { |
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.
We should cover now this function with unit tests.
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 think it's better to focus more on functional tests at this stage because the implementation details are still not in a settled state.
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.
If the implementation details should be clear enough because what we want it's to replicate the exact behaviour that it's currently working. Anyways, I might agree if we add new functional test cases and we don't skip any network test.
peer.string | ||
); | ||
modules.peers.remove(peer); | ||
__private.loadTransactions = async function() { |
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.
We should cover now this function with unit tests.
const query = action.params[0] || {}; | ||
this.scope.modules.blocks.utils.loadBlocksData( | ||
{ | ||
limit: 34, // 1977100 bytes |
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.
We should research and update this number. If I remember well it's not accurate. Block size varies depending on the transaction associated to it. We might be able to increase the number significantly.
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.
We should raise a new issue.
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.
For this current protocol, let's keep it this way because it's not really a protocol change, and we don't want to risk here.
However, please create an issue to address this, and we can tackle this when we change the p2p protocol
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.
@jondubois would you mind to open the issue?
@@ -272,6 +295,40 @@ module.exports = class Chain { | |||
action.params[0], | |||
action.params[1] | |||
), | |||
blocks: async action => |
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 would suggest to pass the requested number of blocks as a variable, or returning a dynamic number depending on the sizes of the requested blocks.
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.
Yes I think as a new issue.
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.
@jondubois @diego-G same as above, we don't want to change the behavior now, so please create a new issue, and we will tackle later
…eracting with peers directly
c06ed9d
to
4211761
Compare
(err, res) => { | ||
// If comparison failed and current consensus is low - perform chain recovery | ||
if (comparisonFailed && modules.transport.poorConsensus()) { | ||
return modules.blocks.chain.recoverChain(cb); |
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.
this logic needs to stay
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 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.
Ah yep, we need the recoverChain(...)
feature but it should be possible to use it as part of the loadBlocksFromNetwork
logic instead (we may be able to use that logic to detect a fork) - It would be nice to remove the commonBlocks
logic.
@jondubois @shuse2 in order to move on with PRs from P2P epic, what would you say about creating at least thoughtful test skeletons? That way we can tackle then later without forgetting the acknowledged context. |
@diego-G I think we need more (and better) functional tests but it should be a separate issue which we can work towards gradually. I don't think that we should write unit tests (or the skeleton) until the logic has settled into a desirable working state first - Until we finish migrating to the new Network module, our internal logic is still likely to change and we should keep this flexibility. But we can raise an issue for later. |
What was the problem?
The loader was interacting with individual peers directly (e.g. for synching).
How did I fix it?
How to test it?
Review checklist