Skip to content
This repository has been archived by the owner on Feb 1, 2023. It is now read-only.

feat: add peer block filter option #549

Merged
merged 9 commits into from
Mar 17, 2022

Conversation

laurentsenta
Copy link
Contributor

@laurentsenta laurentsenta commented Feb 25, 2022

This feature lets a user configure a filter to allow / deny request according to the request's peer ID and the content id.

For example, a user may use this option to implement a dynamic peer-based authorization.

@welcome
Copy link

welcome bot commented Feb 25, 2022

Thank you for submitting this PR!
A maintainer will be here shortly to review it.
We are super grateful, but we are also overloaded! Help us by making sure that:

  • The context for this PR is clear, with relevant discussion, decisions
    and stakeholders linked/mentioned.

  • Your contribution itself is clear (code comments, self-review for the
    rest) and in its best form. Follow the code contribution
    guidelines

    if they apply.

Getting other community members to do a review would be great help too on complex PRs (you can ask in the chats/forums). If you are unsure about something, just leave us a comment.
Next steps:

  • A maintainer will triage and assign priority to this PR, commenting on
    any missing things and potentially assigning a reviewer for high
    priority items.

  • The PR gets reviews, discussed and approvals as needed.

  • The PR is merged by maintainers when it has been approved and comments addressed.

We currently aim to provide initial feedback/triaging within two business days. Please keep an eye on any labelling actions, as these will indicate priorities and status of your contribution.
We are very grateful for your contribution!

@laurentsenta
Copy link
Contributor Author

laurentsenta commented Feb 25, 2022

@aschmahmann we talked about this feature during ip stewart colo,
according to my shallow knowledge of the go stack, it is complete, but I might be missing an iceberg of side-effects & implementation details.

May I ask for your guidance on how to finish this?

@laurentsenta
Copy link
Contributor Author

laurentsenta commented Feb 28, 2022

Thanks for running the workflow,

I just rebased on master, but the previous run is here.

Everything passed, except the TestSessionFailingToGetFirstBlock.
I don't think this is related to this branch, master has a similar error around TestSessionFailingToGetFirstBlock, and another older branch too.

edit:
Maybe that workflow never went green, this was introduced here: https://github.com/ipfs/go-bitswap/commits/master?after=dbfc6a1d986e18402d8301c7535a0c39b2461cb7+69&branch=master (logs unavailable sadly)

internal/decision/engine.go Outdated Show resolved Hide resolved
internal/decision/engine.go Outdated Show resolved Hide resolved
internal/decision/engine.go Outdated Show resolved Hide resolved
bitswap.go Show resolved Hide resolved
Copy link
Contributor

@aschmahmann aschmahmann left a comment

Choose a reason for hiding this comment

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

Left a couple small comments, but looks pretty good.

internal/decision/engine.go Outdated Show resolved Hide resolved
internal/decision/engine_test.go Outdated Show resolved Hide resolved
Copy link

@kylehuntsman kylehuntsman left a comment

Choose a reason for hiding this comment

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

I actually really like the way you broke out denials. I agree that altering the wantKs to later control what blocks are not found feels weird. blockSizes and wants would not have been in sync.

I don't mind the anonymous function. Reworking it so that those scoped variables are altered in a function feels worse in my opinion. I'd rather have this.

This feature lets a user configure a function that will
allow / deny request for a block coming from a peer.
Split the different cases (wants, cancel, denies) early to prevent
calling blocksize on rejected blocks.
}
e.MessageReceived(context.Background(), partner, add)
}

func partnerWantBlocksHaves(e *Engine, keys []string, wantHaves []string, sendDontHave bool, partner peer.ID) {
func partnerWantBlocksHaves(e *Engine, wantBlocks []string, wantHaves []string, sendDontHave bool, partner peer.ID) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

rationale: I didn't understand this call at first so I made the parameters name symmetric, wantHave <-> wantBlocks.
Which lead me to rename the parameter in the other function above (since it was probably a copy and paste).

@laurentsenta laurentsenta force-pushed the feat/peer-block-filter branch 2 times, most recently from e151ec0 to dbe1555 Compare March 3, 2022 09:10
allowList: "c",
wantBlks: "bc", // Note: We request a block here to force a response from the node
},
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note the detail here: when a node sends a want-[have/block], if the response is positive (we have the block), sending the same request for the same block will get ignored.

That make sense in practice
but in testing, if a node loses access to a piece of data, it's /hard/ to test, that's why here we switch from want-have to want-block.

@BigLep
Copy link

BigLep commented Mar 3, 2022

2022-03-03 verbal: lets create an issue that explains what a user will get when this is all done. I assume there will be a checklist for the go-bitswap side and plumbing it through to go-ipfs.

Great work!

@laurentsenta
Copy link
Contributor Author

Created issue here: ipfs/kubo#8763

keys := []string{"a", "b", "c", "d"}
blks := make([]blocks.Block, 0, len(keys))
for _, letter := range keys {
block := blocks.NewBlock([]byte(letter))
Copy link
Contributor

Choose a reason for hiding this comment

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

For testing this is fine, but wanted to give you a heads up that this is not really a valid IPLD block since it's creating a CIDv0 (which must be dag-pb) with the value "a".

Instead I'd use NewBlockWithCid and pass it a CIDv1 with the Raw codec

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
No open projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants