Skip to content
This repository was archived by the owner on Aug 2, 2021. It is now read-only.

Conversation

@nolash
Copy link
Contributor

@nolash nolash commented Jun 29, 2019

This PR is the implementation of part of https://github.com/ethersphere/SWIP/blob/master/lightnode_caps_msg.md (ethersphere/SWIPs#7)

  • introduce capabilities types
  • remove the lightnode field in handshake, replace with capabilities
  • test that capabilities are set as expected through the provided calls

(API will be added in separate PR)

@nolash nolash self-assigned this Jun 29, 2019
@nolash nolash force-pushed the adaptive-capabilities-msg branch from 1d2e6f7 to 212c90c Compare July 2, 2019 00:01
@nolash nolash requested review from acud and nonsense July 2, 2019 08:01
@nolash nolash requested review from agazso and nagydani and removed request for nonsense July 2, 2019 08:01
@nolash nolash force-pushed the adaptive-capabilities-msg branch 2 times, most recently from 40b4581 to ac5d56c Compare July 3, 2019 06:03
@nolash
Copy link
Contributor Author

nolash commented Jul 3, 2019

I've reverted the changes I made to use the bitvector message. It turned a lot messier and difficult to understand, and its design is unintuitive for the case of capabilities:

In bitvector the Get(..) and set(..) use index which indexes the total bit number (2 bytes = 0-15). Commands treat order of bits within bytes as Right-To-Left, and the bytes slices as Left-To-Right.

Exampe: If I NewFromBytes([]byte{0x80, 0x08}) (10000000 00001000) then I'd expect set(1, true) (turn bit idx 1 on) to result no change, but instead I get 0x8108 (10000001 00001000). If I set(12, false) (turn bit idx 12 off) the result is 0x8000 (10000000 00000000).

Merely changing the way Get(..) and set(..) interprets the underlying vector (0x01<<(8-(idx%8)) instead of 0x01<<(idx%8)) messes up the tests in network/stream so it seems that package interprets byte slices passed to and/or gotten from it (NewFromBytes(..),Bytes(..)) in this "inside out" fashion.

Perhaps the additions I made to bitvector previously - the SetBytes, UnsetBytes and Stringshould be reverted, as they will not now be used.

@nolash
Copy link
Contributor Author

nolash commented Jul 3, 2019

I understand why it's made this way, of course; it's more efficient to avoid the extra subtraction in the index calculation. But for the sake of the capabilities this is not really a factor since the interface only operates on fully-defined bit vectors rather than individual bits.

@holisticode
Copy link
Contributor

Maybe it's a good idea to add the capability swap_enabled, but if does not fit this PR, it's fine to add it later

@nolash
Copy link
Contributor Author

nolash commented Jul 3, 2019

@holisticode swap is a separate module right? You notice PSS also hasn't been included in this PR. Only the strictly bzz related stuff... I would imagine Swap would use API (upcoming PR) to add itself as a module to the capabilities vector.

@holisticode
Copy link
Contributor

It is however an interesting question to ponder: when swap will be available, then how to deal with nodes who do not support swap? Do we simply drop them? Is there some way between?

@nolash nolash force-pushed the adaptive-capabilities-msg branch from c8fb856 to 057d742 Compare July 4, 2019 13:42
Copy link
Contributor

@acud acud left a comment

Choose a reason for hiding this comment

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

@nolash i have my traditional aesthetic code-style disagreements. otherwise i am a bit afraid of this whole notification concept - i think this is more dangerous than constructive at this point as our configuration infrastructure does not support this, thus developers should not get the possibility to mingle with run time configuration when the underlying infrastructure does not support it.
my 2 cents

}

// NewCapabilities creates a new Capabilities container
//
Copy link
Contributor

Choose a reason for hiding this comment

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

remove this line, unnecessary

// get a capability bitvector for the module
// the first two bytes returned are id and length, the following bytes contain the flags
// returns nil if id is not registered
func (c Capabilities) get(id uint8) capability {
Copy link
Contributor

Choose a reason for hiding this comment

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

i'd like to see a dedicated type here, in a similar manner to what is done in sctx/sctx.go.
i.e. func (c Capabilities) get (id CapabilityModule) capability

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe sctx/sctx.go could use some comments itself? There's no description of what that package does...


// Capabilities is a container that holds all capability bitvector flags for all registered modules
type Capabilities struct {
Flags []capability // the bitvector flags
Copy link
Contributor

Choose a reason for hiding this comment

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

why are you exporting a field with an underlying unexported type?
if Capabilities is exported I'd assume that a particular Capability should be too, no?
if you intend to use this only within the framework of the network package than please unexport both of them

// NewCapabilities creates a new Capabilities container
//
// It optionally takes a change notification channel as argument. If this is nil, notifications will not be issued.
func NewCapabilities(changeC chan<- capability) *Capabilities {
Copy link
Contributor

Choose a reason for hiding this comment

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

please describe a situation when a node capability would change during runtime.
as much as i'd love to support such an approach it would be dangerous with our current design. a lot of our configuration needs the node to be started afresh to take place. thus, without rewriting our configuration infrastructure I find it unfeasible to allow developers to change capabilities during runtime.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

please describe a situation when a node capability would change during runtime.

Changing during runtime is an explicit goal of the project with Status.

}

// adds a capability module to the bitvector collection
// does not protect against duplicate ids. Calling code should use registerModule instead
Copy link
Contributor

Choose a reason for hiding this comment

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

then why do you need this function in the first place? i don't see any reason to have an extra function call just to abstract the builtin append

return m
}

func (m CapabilitiesMsg) get(idx int) capability {
Copy link
Contributor

Choose a reason for hiding this comment

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

do you really need another function in order to abstract a native functionality of go? there's no array size check here, so the extra function provides no added value


func capArrayToString(b []capability) string {
var caps []string
for _, cap := range b {
Copy link
Contributor

Choose a reason for hiding this comment

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

what happens when len(b)==0?

)

var (
capabilitiesFlagRetrieve = []byte{0x00, 0x01} // node retrieves data for itself
Copy link
Contributor

Choose a reason for hiding this comment

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

as mentioned i'd be happy to see this in a more constructed manner with concrete types

capabilitiesFlagStorer = []byte{0x80, 0x00} // node is part of network storage (sync)

// temporary presets to emulate the legacy LightNode/full node regime
fullCapability capability
Copy link
Contributor

Choose a reason for hiding this comment

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

you're using the term fullCapability but above you use capability to refer to a certain capability within a certain module but as far as i understand this might infer capabilities over several modules...?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The "full" in this context is only about the bzz capabilities. Swap, pss etc will have other distinct capabilities.

// temporary convenience functions for legacy "full node"
func newFullCapability() capability {
c := newCapability(0, 2)
c.set(capabilitiesFlagRetrieve)
Copy link
Contributor

Choose a reason for hiding this comment

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

consider variadic function...?

Copy link
Member

@zelig zelig left a comment

Choose a reason for hiding this comment

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

This PR is a lot of code and complexity.
Agree with @acud that caps change may be premature to add now.
I would prefer binary caps implemented as bool fields on a simple struct.
that allows for get, set transparently without code.
You can then write a custom serialisation with a function implementing rlpEncoder interface. Then business logic is can remain readable and separated from bandwidth optimisation measures like bitvector representation.

@nolash
Copy link
Contributor Author

nolash commented Jul 28, 2019

thus developers should not get the possibility to mingle with run time configuration when the underlying infrastructure does not support it.

@acud I think this functionality is so exotic and obscure at this point that no developer would have endeavoured to try to hack with it.

However, since the code likewise turned out too exotic for everyone's taste, I'm rewriting the entire implementation. And (just) to make you happy I'll leave out the channel stuff in the rewrite ... for now :)

@nolash nolash force-pushed the adaptive-capabilities-msg branch from 20cf3b0 to 967ba7c Compare July 29, 2019 15:25
@nolash
Copy link
Contributor Author

nolash commented Jul 29, 2019

#obsoleted by #1619

@nolash nolash closed this Jul 29, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants