mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-22 10:57:42 +08:00
64 lines
1.4 KiB
Go
64 lines
1.4 KiB
Go
package namesys
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
|
|
pb "github.com/ipfs/go-ipfs/namesys/pb"
|
|
|
|
u "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
|
|
proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
|
|
)
|
|
|
|
// IpnsSelectorFunc selects the best record by checking which has the highest
|
|
// sequence number and latest EOL
|
|
func IpnsSelectorFunc(k string, vals [][]byte) (int, error) {
|
|
var recs []*pb.IpnsEntry
|
|
for _, v := range vals {
|
|
e := new(pb.IpnsEntry)
|
|
err := proto.Unmarshal(v, e)
|
|
if err == nil {
|
|
recs = append(recs, e)
|
|
} else {
|
|
recs = append(recs, nil)
|
|
}
|
|
}
|
|
|
|
return selectRecord(recs, vals)
|
|
}
|
|
|
|
func selectRecord(recs []*pb.IpnsEntry, vals [][]byte) (int, error) {
|
|
var bestSeq uint64
|
|
besti := -1
|
|
|
|
for i, r := range recs {
|
|
if r == nil || r.GetSequence() < bestSeq {
|
|
continue
|
|
}
|
|
rt, err := u.ParseRFC3339(string(r.GetValidity()))
|
|
if err != nil {
|
|
log.Errorf("failed to parse ipns record EOL %s", r.GetValidity())
|
|
continue
|
|
}
|
|
|
|
if besti == -1 || r.GetSequence() > bestSeq {
|
|
bestSeq = r.GetSequence()
|
|
besti = i
|
|
} else if r.GetSequence() == bestSeq {
|
|
bestt, _ := u.ParseRFC3339(string(recs[besti].GetValidity()))
|
|
if rt.After(bestt) {
|
|
besti = i
|
|
} else if rt == bestt {
|
|
if bytes.Compare(vals[i], vals[besti]) > 0 {
|
|
besti = i
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if besti == -1 {
|
|
return 0, errors.New("no usable records in given set")
|
|
}
|
|
|
|
return besti, nil
|
|
}
|