-
Notifications
You must be signed in to change notification settings - Fork 2
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
feat: use IPNI advertisements from the miner only #55
Conversation
1. Resolve `minerId` to miner's PeerId, which is the same value as `Provider.ID` in the IPNI records 2. Ignore IPNI records advertised by different miners 3. Report `minerId` and `providerId` as the new measurement fields Signed-off-by: Miroslav Bajtoš <[email protected]>
Signed-off-by: Miroslav Bajtoš <[email protected]>
test/integration.js
Outdated
@@ -16,14 +19,20 @@ test('integration', async () => { | |||
|
|||
test('retrieval check for our CID', async () => { | |||
const spark = new Spark() | |||
spark.getRetrieval = async () => ({ cid: KNOWN_CID }) | |||
spark.getRetrieval = async () => ({ cid: KNOWN_CID, minerId: OUR_FAKE_MINER_ID }) | |||
spark.lookupMinerPeerId = async (minerId) => { |
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.
wouldn't it be safer to push the function calls into an array, and then assert this function was called at all? This is the advice you give me with all these mocks I believe
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.
In this particular test, if my stubbed function isn't called, the retrieval check fails because Filecoin's RPC API call will reject the fake miner id.
The purpose of this test is not to verify how Spark works under the hood (and whether it calls all other functions we think it should call) but whether it can find the provider and retrieve the data for the CID served by our Frisbii instance.
However, if you think it's worth asserting that both functions were called, then I am fine with adding that. Let me know!
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 was also my understanding when I wrote tests like this, but through your reviews I understood that it's clearer and safer to assert the function calls. If in the future a condition is introduced which skips lookupMinerPeerId()
, then this test will still pass.
However,iIn my previous review I missed that this was an integration test and not a unit test. Please choose the testing method that you see fits best.
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.
push the function calls into an array, and then assert this function was called
added in 0a48986
lib/spark.js
Outdated
console.error(err) | ||
// There are three common error cases: | ||
// 1. We are offline | ||
// 2. The JSON RPC provider is down | ||
// 3. JSON RPC errors like when Miner ID is not a known actor | ||
// There isn't much we can do in the first two cases. We can notify the user that we are not | ||
// performing any jobs and wait until the problem is resolved. | ||
// The third case should not happen unless we made a mistake, so we want to learn about it | ||
if (err.name === 'FilecoinRpcError') { | ||
// TODO: report the error to Sentry | ||
console.error('The error printed above was not expected, please report it on GitHub:') | ||
console.error('https://github.com/filecoin-station/spark/issues/new') | ||
} else { | ||
this.#activity.onError() | ||
} | ||
err.reported = true | ||
// Abort the check, no measurement should be recorded | ||
throw err |
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 don't understand the need for this custom property .reported
here.
If we remove the console.error(err)
above, then we can let the outer catch handler log it. Also, the outer catch handler can call #activity.onError()
itself.
I think the only custom error handling we need here is when err.name === 'FilecoinRpcError'
, and in that case we can simply add a new log event. I'm proposing to refactor this catch handler like this:
console.error(err) | |
// There are three common error cases: | |
// 1. We are offline | |
// 2. The JSON RPC provider is down | |
// 3. JSON RPC errors like when Miner ID is not a known actor | |
// There isn't much we can do in the first two cases. We can notify the user that we are not | |
// performing any jobs and wait until the problem is resolved. | |
// The third case should not happen unless we made a mistake, so we want to learn about it | |
if (err.name === 'FilecoinRpcError') { | |
// TODO: report the error to Sentry | |
console.error('The error printed above was not expected, please report it on GitHub:') | |
console.error('https://github.com/filecoin-station/spark/issues/new') | |
} else { | |
this.#activity.onError() | |
} | |
err.reported = true | |
// Abort the check, no measurement should be recorded | |
throw err | |
// There are three common error cases: | |
// 1. We are offline | |
// 2. The JSON RPC provider is down | |
// 3. JSON RPC errors like when Miner ID is not a known actor | |
// There isn't much we can do in the first two cases. We can notify the user that we are not | |
// performing any jobs and wait until the problem is resolved. | |
// The third case should not happen unless we made a mistake, so we want to learn about it | |
if (err.name === 'FilecoinRpcError') { | |
// TODO: report the error to Sentry | |
console.error('Unexpected error, please report it on GitHub:') | |
console.error('https://github.com/filecoin-station/spark/issues/new') | |
} | |
// Abort the check, no measurement should be recorded | |
throw err |
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.
Let's discuss.
In my proposed implementation:
- FilecoinRpcError does not trigger
this.#activity.onError()
, therefore Spark stays in "online" mode - We print the call to report the issue after the error stack.
In your proposal:
- FilecoinRpcError triggers
this.#activity.onError()
and puts Spark to offline mode. - The call to report the issue is printed before the error to report. (I guess that's fine, we just need to tweak the message.)
Here is the important question we need to answer: How should we handle the case when we cannot get a miner's Peer ID because Filecoin RPC returns an error?
- This can be either because we are calling the RPC API incorrectly or because the miner ID is not a valid one. (I suppose we could also receive this error if the RPC API server has an internal problem; it can process the JSON-RPC part, but the called RPC method fails.)
- Do we want to indicate offline mode? The next retrieval check will likely be able fetch the round details from spark-api, which means Spark goes back to online mode, only to go offline again when the JSON RPC call fails.
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 understood! I thought the purpose of err.reported
was to prevent double log lines, now I see it's also to prevent reporting it to the activity state handler.
Could we be more explicit about this?
- Rename to
error.setActivityToOffline = false
- Let the outer error handler handle logging, to be more consistent with other errors
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.
See db3b2ae
Signed-off-by: Miroslav Bajtoš <[email protected]>
Signed-off-by: Miroslav Bajtoš <[email protected]>
lib/spark.js
Outdated
console.error(err) | ||
// There are three common error cases: | ||
// 1. We are offline | ||
// 2. The JSON RPC provider is down | ||
// 3. JSON RPC errors like when Miner ID is not a known actor | ||
// There isn't much we can do in the first two cases. We can notify the user that we are not | ||
// performing any jobs and wait until the problem is resolved. | ||
// The third case should not happen unless we made a mistake, so we want to learn about it | ||
if (err.name === 'FilecoinRpcError') { | ||
// TODO: report the error to Sentry | ||
console.error('The error printed above was not expected, please report it on GitHub:') | ||
console.error('https://github.com/filecoin-station/spark/issues/new') | ||
} else { | ||
this.#activity.onError() | ||
} | ||
err.reported = true | ||
// Abort the check, no measurement should be recorded | ||
throw err |
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 understood! I thought the purpose of err.reported
was to prevent double log lines, now I see it's also to prevent reporting it to the activity state handler.
Could we be more explicit about this?
- Rename to
error.setActivityToOffline = false
- Let the outer error handler handle logging, to be more consistent with other errors
Signed-off-by: Miroslav Bajtoš <[email protected]>
Signed-off-by: Miroslav Bajtoš <[email protected]>
Resolve
minerId
to miner's PeerId, which is the same value asProvider.ID
in the IPNI recordsIgnore IPNI records advertised by different miners
Report
minerId
andproviderId
as the new measurement fieldsLinks: