Skip to content
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

Merged
merged 8 commits into from
Mar 19, 2024
Merged

Conversation

bajtos
Copy link
Member

@bajtos bajtos commented Mar 7, 2024

  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

Links:

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]>
@bajtos bajtos requested a review from juliangruber March 7, 2024 15:42
test/integration.js Outdated Show resolved Hide resolved
Signed-off-by: Miroslav Bajtoš <[email protected]>
@@ -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) => {
Copy link
Member

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

Copy link
Member Author

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!

Copy link
Member

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.

Copy link
Member Author

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/miner-lookup.js Outdated Show resolved Hide resolved
lib/spark.js Outdated Show resolved Hide resolved
lib/spark.js Outdated
Comment on lines 50 to 67
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
Copy link
Member

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:

Suggested change
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

Copy link
Member Author

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.

Copy link
Member

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?

  1. Rename to error.setActivityToOffline = false
  2. Let the outer error handler handle logging, to be more consistent with other errors

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See db3b2ae

lib/constants.js Show resolved Hide resolved
lib/miner-lookup.js Outdated Show resolved Hide resolved
lib/spark.js Outdated
Comment on lines 50 to 67
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
Copy link
Member

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?

  1. Rename to error.setActivityToOffline = false
  2. Let the outer error handler handle logging, to be more consistent with other errors

bajtos added 2 commits March 19, 2024 14:00
Signed-off-by: Miroslav Bajtoš <[email protected]>
Signed-off-by: Miroslav Bajtoš <[email protected]>
@bajtos bajtos requested a review from juliangruber March 19, 2024 13:18
@bajtos bajtos merged commit 66202a3 into main Mar 19, 2024
1 check passed
@bajtos bajtos deleted the feat-miner-lookup branch March 19, 2024 13:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ done
Development

Successfully merging this pull request may close these issues.

2 participants