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

rpc: Add admin_addTrustedPeer and admin_removeTrustedPeer. #16333

Merged
merged 7 commits into from
Aug 6, 2018

Conversation

shazow
Copy link
Contributor

@shazow shazow commented Mar 18, 2018

These RPC calls are analogous to Parity's parity_addReservedPeer and
parity_removeReservedPeer.

They are useful for adjusting the trusted peer set during runtime,
without requiring restarting the server.

Also includes a test which should help exercise #16189 as well.

@shazow
Copy link
Contributor Author

shazow commented Mar 22, 2018

Ping. Anyone up for a review? (Maybe @karalabe since you looked at #16189?)

@shazow
Copy link
Contributor Author

shazow commented Apr 3, 2018

I think the test failures are flakes. Anyone have a chance to take a look?

@shazow
Copy link
Contributor Author

shazow commented Apr 30, 2018

Rebased on latest master.

Polite ping for feedback please. :)

@holiman
Copy link
Contributor

holiman commented May 17, 2018

Apologies for the long lead-time. It tentatively looks good to me, but could either @fjl or @zsfelfoldi PTAL at this one?

@holiman
Copy link
Contributor

holiman commented May 17, 2018

@shazow
Copy link
Contributor Author

shazow commented May 17, 2018

@holiman Thanks!

FWIW I've been using this patch in my live vipnode deployment for the last couple of weeks and it's working as expected.

@ryanschneider
Copy link
Contributor

Any chance this could get tagged with the 1.8.9 milestone? I'd love to see this in the next release.

@holiman
Copy link
Contributor

holiman commented May 22, 2018

Please @zsfelfoldi take a look?

Copy link
Contributor

@zsfelfoldi zsfelfoldi left a comment

Choose a reason for hiding this comment

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

Looks good to me in general, see comments

p2p/server.go Outdated
trusted[n.ID] = true
// Mark any already-connected peer as trusted
if p, ok := peers[n.ID]; ok {
p.rw.flags |= trustedConn
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this can happen any time during the peer's lifecycle, can't this write collide with a read in func (p *Peer) Info() ? I am not very familiar with this part but it looks like we assumed until now that flags don't change after the peer is connected. @fjl opinion? Should we not use locks or atomic read/write if we change the flags of live peers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's a good question. go test -race ./p2p didn't catch it but you might be right.

I'm happy to bolt the flags down with a mutex or atomic. Let me know what you'd prefer. :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's OK to just add the ID to the trusted set without modifying flags of existing connections. The flag is not used after handshake anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@fjl Hm, I worry that has potential for breaking other code that relies on the peer state. Such as if you do admin.peers, it will return incorrect metadata, right?

Copy link
Contributor

Choose a reason for hiding this comment

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

We would need a lock then and I want to avoid that ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@fjl Just rebased and pushed another commit with more testing for this, still passes with -race on. I'm fairly convinced that these variables are only ever written and read inside the server event loop, so I don't think there is a race condition.

If you still prefer, I can get rid of updating the flags. We might be able to get rid of the flags altogether and just read the state from the server lookup maps on-demand, but that may be a somewhat larger refactor.

Copy link
Contributor

Choose a reason for hiding this comment

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

It passes because nothing calls p.Inbound in those tests. That would race. Maybe the best way to avoid a race is to just cache inbound flag in peer as a bool.

Sorry for being so pedantic about this, the PR is good otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@fjl Nah that's not pedantic; I don't want to introduce a race, but I was being fixated on the parts that I used.

Let me make some more tweaks, will ping again.

p2p/server.go Outdated
// This channel is used by RemoveTrustedPeer to remove an enode
// from the trusted node set
srv.log.Debug("Removing trusted node", "node", n)
if _, ok := trusted[n.ID]; ok {
Copy link
Contributor

Choose a reason for hiding this comment

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

This check seems to be unnecessary, deleting a non-existent key should not cost more than checking its existence.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call, fixed.

@shazow
Copy link
Contributor Author

shazow commented Jun 7, 2018

@fjl I pushed a few changes, but I'm still unable to reproduce the race in testing for whatever reason: E.g. 291fcfb still passes, I tried that block in a separate goroutine also, not sure why it's not getting caught (let me know if you have a suggestion here). I do agree that it should be a race since AddTrustedPeer modifies the flags and p.Inbound() reads the flags. Maybe a bug in the Go race detector where it doesn't notice bitwise operations?

I also pushed 4e5f57a which moves the p.Inbound() check against a locally cached value set when the peer is created. Could probably get rid of the inboundConn flag altogether and update the code to just check the p.isInbound if we prefer?

In general, feels like the flags bitwise int should just be a bunch of bools to start with. What was the thinking behind the conn.flags int?

@shazow
Copy link
Contributor Author

shazow commented Jun 7, 2018

Ah managed to find the right combination of goroutine'ing to get the race conditions to trigger in ce10c1e, will play around with some fixes next.

@shazow
Copy link
Contributor Author

shazow commented Jun 8, 2018

I ended up wrapping the flag ops with atomic as @zsfelfoldi originally suggested (and rolling back the isInbound cached value for consistency), this makes the failing test pass and is a reasonably small change: 07ef2cc

@fjl Please take another look.

@shazow
Copy link
Contributor Author

shazow commented Jun 15, 2018

Ping. Please take another look. ❤️

@shazow
Copy link
Contributor Author

shazow commented Jun 21, 2018

Rebased latest master.

@shazow
Copy link
Contributor Author

shazow commented Jul 30, 2018

Ping ping.

@tinybike
Copy link
Member

@karalabe @zsfelfoldi is there anything further this PR needs before merging?

@zsfelfoldi
Copy link
Contributor

@shazow I am sorry, I totally forgot about this and then left for a long vacation. I checked it again, there is one small issue, see my comment. If that it fixed, I think we can merge it immediately.

} else {
flags &= ^f
}
atomic.StoreInt32((*int32)(&c.flags), int32(flags))
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not atomic :) Please use CompareAndSwap here just to be totally safe.

Copy link
Contributor

@zsfelfoldi zsfelfoldi left a comment

Choose a reason for hiding this comment

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

I'll merge this now and fix the atomic issue myself because it was waiting for such a long time...

@zsfelfoldi zsfelfoldi merged commit c4df674 into ethereum:master Aug 6, 2018
@karalabe karalabe added this to the 1.8.14 milestone Aug 6, 2018
@shazow
Copy link
Contributor Author

shazow commented Aug 6, 2018

@zsfelfoldi Thank you!

@shazow shazow deleted the addremovetrustedpeer branch August 6, 2018 13:45
@evertonfraga
Copy link
Member

Amazing! thanks for the contribution @shazow

wanwiset25 pushed a commit to XinFinOrg/XDPoSChain that referenced this pull request May 20, 2024
@wanwiset25 wanwiset25 mentioned this pull request Jun 3, 2024
19 tasks
wanwiset25 pushed a commit to XinFinOrg/XDPoSChain that referenced this pull request Jun 19, 2024
wanwiset25 pushed a commit to XinFinOrg/XDPoSChain that referenced this pull request Jun 28, 2024
wanwiset25 added a commit to XinFinOrg/XDPoSChain that referenced this pull request Aug 23, 2024
wanwiset25 pushed a commit to XinFinOrg/XDPoSChain that referenced this pull request Oct 10, 2024
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Nov 8, 2024
gzliudan added a commit to gzliudan/XDPoSChain that referenced this pull request Nov 13, 2024
wanwiset25 pushed a commit to XinFinOrg/XDPoSChain that referenced this pull request Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants