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

Kadcast functional implementation #141

Merged
merged 126 commits into from Dec 11, 2019
Merged

Kadcast functional implementation #141

merged 126 commits into from Dec 11, 2019

Conversation

CPerezz
Copy link
Contributor

@CPerezz CPerezz commented Nov 18, 2019

References:

Adds functionality for the bootstrapping and syncronization on the network.

CPerezz added 30 commits November 6, 2019 16:33
Add message.go, peer.go and bucket.go files to
kadcast implementation.
Includes:
- makePeer
- addIp
- addPort
- addID
- computePeerDistance
`Bucket` has now a dynamic array of peers instead of a fixed-
length one.

Implemented `Tree` struct which holds the routing info containing
the L `Bucket` structures.

Implemented for `Tree`:
- makeTree
- addPeer
Implemented:
`idXor` which computes the XOR between to `Peer` ID's.
`collapseDistance` which allows to classify the
XOR distance in one of the L `Bucket` that the `Peer`
holds into the ROUTING `Tree`.

Implemented tests for `idXor` function.
- `Peer` distance is expressed now as `uint16` to hold the
max range value `128` unsoported on the `byte` type.
- Instead of using math logarithms, we work with bitwise ops.

- `collapseDistance` has been ranamed as `classifyDistance` and
optimized since now only counts the ammount of `1` of a byte that
comes from an XOR op.
- `idXor` just performs the XOR between the two `Peer-ID` arrays
and computes the number of different bits on the result, using this
counter as the result for the distance classification value.
NOTE that this value has the range (0 - 128] to match the `L-buckets`.
The ID matches the 16 first bytes of the output that
comes from applying the sha3-256 to the Wallet's Pk
as a 32-byte array input.
In order to implement LRU for Bucket managing,
we need to use arrays whoose key is a Peer and
since one of it's fields was a Slice (IP field)
we will now represent it as a 4-byte array.
Implemented almost all of the LRU-continuous
policy with optimizations done to avoid array
looping by using maps.
Finnished the implementation for `Bucket`.
Everytime we need to add a Peer, now it is done
under this policy which is specified on the Kadcast
paper.
- makeTree allocates space for a new routing tree
and sets it's own Peer info on the lowest order
bucket.
- addPeer computes the distance between it's own
peer info and the other peer to be included.
Then it adds the peer to its corresponding bucket

If the peer it's the same as our peer, the function
simply doesn't do anything.
This functions allow us to move from UDP packet style
to Peer network info style/types.
This function should be responsible of getting
a received UDP packet, parse it and also
call the needed processes according to the packet.
This function takes a tree and gets the UDPAddr data
of the peer that is running the node.
Refactored all of the functions to return and get
inputs and outputs as references or pointers in
order to save memory and to not copy thoose values
everytime on the stack on each function call.
This is needed in order to compute the IdNonce of
each Peer.
Now the tree holds the k-buckets and also:
- Peer info in `Peer` fmt.
- Peer UDP info as `UDPAddr`
- Peer Id Nonce.

Refactored the makeTree function to build the
propper `Tree` with our personal Peer info.
This two messages are used to test if a peer
is actually connected or not to the network.
The function that converts uint32 to bytes was using
references, so it setted the nonce to 0 everytime.
This has been solved and everything works now.

With this setup, it takes aprox 1min to compute the ID
on an Intel Core i5-7x series.
Now the Peer constructor gets the externalIP
address of the peer and a port and computes
the ID returning the whole Peer struct.
Since we can get the local UDP Addr quickly, there's
no need to pass it as a parameter.

- Now sendUDPPacket gets the parameters per value instead
of by-reference.
processPacket now it's just a debugging tool to catch
the packets recieved and print the content.
Refactored function arguments to be used by value
and not by reference.
Moved UDPAddr<->PeerInfo transformations.
`Router` holds the Routing tree data structure and
also quick access to the owner `Peer` info.

Added `sendPing` and `sendPong` methods passing and
recieving arguments by-value
CPerezz added 20 commits December 5, 2019 20:26
Instead of asking for 3 bytes of 0s we will
just ask for 1 since will be faster for testing
purposes.

Also refactored logs to use `logrus`.
Refactored the code to allow the code to panic
when we exceeded the maximum ammount of tries
of bootstrapping.

Also refactored logs to work with `logrus`.
Since `Sleep` was not an option as discussed in
 #141, the waitGroup has been implemented in order to
make the program itself trigger the protocol methods
once a packet type in concrete is received.

Also, added state-vars in order to force the
`packetProcessor` gorutine to just activate the
waitGroup if a bootstrapping or network discovery
process is in progress.

Now we need to add timeouts in order to prevent the
app to get stucked at any protocol method execution.
On this way, we speed up the app by copying directly in the stack.
Now that we are using a different aproach with
waitgroups, we can get rid of this state variables.
Now the `Router` provides blocking methods to
poll Bootstrapp node and closestPeers (FIND_NODES)
to allow a better and more logical library construction
also featuring waitGroups and removing the timeouts.
Now that the `Router` offers blocking methods to
search for the closest `alpha` peers and for polling
the bootstrapping nodes, the logic can be leaved there
and the protocol functions just take car of the logic of
the algorithms itself.
We should not send the poll messages inside of the
afterFunc, instead, we should send the messages on
polling methods and wait on the afterFunc to execute
the getters to our tree.
With lower timings we should be able to get all
of the info we are expecting on the polling methods.
@CPerezz
Copy link
Contributor Author

CPerezz commented Dec 10, 2019

This is the error that Travis found:

--- FAIL: TestLockedInputs (0.01s)

    transaction_test.go:40: 

        	Error Trace:	transaction_test.go:40

        	Error:      	Received unexpected error:

        	            	EOF

        	Test:       	TestLockedInputs

panic: runtime error: invalid memory address or nil pointer dereference [recovered]

	panic: runtime error: invalid memory address or nil pointer dereference

[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x7d935b]

@autholykos @julesdesmit can we merge since this is not related to the kadcast module??

Also, are you aware of that?

@CPerezz CPerezz changed the title WIP - Kadcast functional implementation Kadcast functional implementation Dec 10, 2019
@autholykos autholykos merged commit 3b47dba into master Dec 11, 2019
@autholykos autholykos deleted the kadcast branch December 11, 2019 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need:investigation Proposal to be raised with the team for further refinement type:rfc Changing the behaviour of something already defined
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants