mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-25 02:15:30 +00:00
Implement custom distance function (#827)
* Implement custom distance function * More docs about function equivalence
This commit is contained in:
parent
749069da5c
commit
58b11e683d
32
fluffy/network/state/custom_distance.nim
Normal file
32
fluffy/network/state/custom_distance.nim
Normal file
@ -0,0 +1,32 @@
|
||||
import stint
|
||||
|
||||
const MID* = u256(2).pow(u256(255))
|
||||
const MAX* = high(Uint256)
|
||||
|
||||
# Custom distance function described in: https://notes.ethereum.org/h58LZcqqRRuarxx4etOnGQ#Storage-Layout
|
||||
# The implementation looks different than in spec, due to the fact that in practice
|
||||
# we are operating on unsigned 256bit integers instead of signed big ints.
|
||||
# Thanks to this we do not need to use:
|
||||
# - modulo operations
|
||||
# - abs operation
|
||||
# and the results are eqivalent to function described in spec.
|
||||
#
|
||||
# The way it works is as follows. Let say we have integers modulo 8:
|
||||
# [0, 1, 2, 3, 4, 5, 6, 7]
|
||||
# and we want to calculate minimal distance between 0 and 5.
|
||||
# Raw difference is: 5 - 0 = 5, which is larger than mid point which is equal to 4.
|
||||
# From this we know that the shorter distance is the one wraping around 0, which
|
||||
# is equal to 3
|
||||
proc distance*(node_id: UInt256, content_id: UInt256): UInt256 =
|
||||
let rawDiff =
|
||||
if node_id > content_id:
|
||||
node_id - content_id
|
||||
else:
|
||||
content_id - node_id
|
||||
|
||||
if rawDiff > MID:
|
||||
# If rawDiff is larger than mid this means that distance between node_id and
|
||||
# content_id is smaller when going from max side.
|
||||
MAX - rawDiff + UInt256.one
|
||||
else:
|
||||
rawDiff
|
@ -13,7 +13,8 @@ import
|
||||
./test_portal_encoding,
|
||||
./test_portal,
|
||||
./test_content_network,
|
||||
./test_discovery_rpc
|
||||
./test_discovery_rpc,
|
||||
./test_custom_distance
|
||||
|
||||
cliBuilder:
|
||||
import
|
||||
|
30
fluffy/tests/test_custom_distance.nim
Normal file
30
fluffy/tests/test_custom_distance.nim
Normal file
@ -0,0 +1,30 @@
|
||||
# Nimbus - Portal Network
|
||||
# Copyright (c) 2021 Status Research & Development GmbH
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
{.used.}
|
||||
|
||||
import
|
||||
std/unittest,
|
||||
stint,
|
||||
../network/state/custom_distance
|
||||
|
||||
|
||||
suite "State network custom distance function":
|
||||
test "Calculate distance according to spec":
|
||||
check:
|
||||
# Test cases from spec
|
||||
distance(u256(10), u256(10)) == 0
|
||||
distance(u256(5), high(UInt256)) == 6
|
||||
distance(high(UInt256), u256(6)) == 7
|
||||
distance(u256(5), u256(1)) == 4
|
||||
distance(u256(1), u256(5)) == 4
|
||||
distance(UInt256.zero, MID) == MID
|
||||
distance(UInt256.zero, MID + UInt256.one) == MID - UInt256.one
|
||||
|
||||
# Additional test cases to check some basic properties
|
||||
distance(UInt256.zero, MID + MID) == UInt256.zero
|
||||
distance(UInt256.zero, UInt256.one) == distance(UInt256.zero, high(UInt256))
|
Loading…
x
Reference in New Issue
Block a user