Skip to content

Commit

Permalink
node: Drop placement code copy
Browse files Browse the repository at this point in the history
It was added only due to a temporary SDK's interface problem. SDK RC10 has
solved it.
NOTE: generally, the placement for container estimations changed with this
commit: another pivot is used. We do this change cause SDK used to have a
bug related to the placement func and placement changes are expected
after RC9 -> RC10 update anyway.

Signed-off-by: Pavel Karpy <[email protected]>
  • Loading branch information
carpawell committed Aug 10, 2023
1 parent 1684eee commit 34ee6fb
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 91 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ an old engine `*operation_name*_duration` a new `*operation_name*_time` is avail
For an old `*operation_name*_req_duration` RPC a new `rpc_*operation_name*_time` is
available. The old ones (the counters) have been deprecated and will be removed with
the following minor release.
Container estimation main node calculation has been changed. A new 32-byte long
array is taken as a sorting pivot: the estimated container with the first 8 bytes
replaced with the target epoch in a little-endian encoding.

Deprecated `morph.rpc_endpoint` SN and `morph.endpoint.client` IR configurations
have been removed. Use `morph.endpoints` for both instead.
Expand Down
102 changes: 11 additions & 91 deletions cmd/neofs-node/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"bytes"
"context"
"crypto/ecdsa"
"crypto/sha256"
"encoding/binary"
"errors"
"fmt"
"strconv"

"github.com/nspcc-dev/hrw"
containerV2 "github.com/nspcc-dev/neofs-api-go/v2/container"
containerGRPC "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
containercontract "github.com/nspcc-dev/neofs-contract/container"
Expand All @@ -31,6 +31,7 @@ import (
containerSDK "github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/user"
"go.uber.org/zap"
)
Expand Down Expand Up @@ -408,101 +409,20 @@ func (l *loadPlacementBuilder) BuildPlacement(epoch uint64, cnr cid.ID) ([][]net
return nil, err
}

const pivotPrefix = "load_announcement_"
buf := make([]byte, sha256.Size)

pivot := []byte(
pivotPrefix + strconv.FormatUint(epoch, 10),
)

return placementVectors(cnrNodes, nm, hrw.Hash(pivot)), nil
}

func placementVectors(cnrNodes [][]netmap.NodeInfo, nm *netmap.NetMap, hash uint64) [][]netmap.NodeInfo {
minimumPrice := minPrice(nm.Nodes())
meanCap := meanCapacity(nm.Nodes())
sortedVectors := make([][]netmap.NodeInfo, len(cnrNodes))

for i, v := range cnrNodes {
sortedVectors[i] = make([]netmap.NodeInfo, len(v))
copy(sortedVectors[i], v)

hrw.SortSliceByWeightValue(sortedVectors[i], weights(sortedVectors[i], minimumPrice, meanCap), hash)
}

return sortedVectors
}

func weights(nn []netmap.NodeInfo, minPrice, meanCap float64) []float64 {
w := make([]float64, 0, len(nn))
for _, n := range nn {
w = append(w, reverseMinNorm(float64(n.Price()), minPrice)*sigmoidNorm(float64(capacity(n)), meanCap))
}

return w
}

func reverseMinNorm(v, base float64) float64 {
if v == 0 || base == 0 {
return 0
}

return base / v
}

func sigmoidNorm(v, base float64) float64 {
if v == 0 || base == 0 {
return 0
}

x := v / base

return x / (1 + x)
}

func meanCapacity(nn []netmap.NodeInfo) float64 {
l := len(nn)
if l == 0 {
return 0
}

var sum uint64
for _, n := range nn {
sum += capacity(n)
}

return float64(sum) / float64(l)
}

func minPrice(nn []netmap.NodeInfo) float64 {
l := len(nn)
if l == 0 {
return 0
}
cnr.Encode(buf)
binary.LittleEndian.PutUint64(buf, epoch)

var min uint64
for i := 0; i < l; i++ {
if p := nn[i].Price(); min == 0 || p < min { // That is how min looks in SDK in RC8: https:/nspcc-dev/neofs-sdk-go/issues/438
min = p
}
}

return float64(min)
}

// capacity is copied with minor changed from SDK.
// See https:/nspcc-dev/neofs-sdk-go/blob/v1.0.0-rc.8/netmap/node_info.go#L283.
func capacity(n netmap.NodeInfo) uint64 {
val := n.Attribute("Capacity")
if val == "" {
return 0
}
var pivot oid.ID
_ = pivot.Decode(buf)

capParsed, err := strconv.ParseUint(val, 10, 64)
placement, err := nm.PlacementVectors(cnrNodes, pivot)
if err != nil {
return 0
return nil, fmt.Errorf("could not build placement vectors: %w", err)
}

return capParsed
return placement, nil
}

func (l *loadPlacementBuilder) buildPlacement(epoch uint64, idCnr cid.ID) ([][]netmap.NodeInfo, *netmap.NetMap, error) {
Expand Down

0 comments on commit 34ee6fb

Please sign in to comment.