Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
464 changes: 464 additions & 0 deletions docs/svs-v4.md
Comment thread
a-thieme marked this conversation as resolved.

Large diffs are not rendered by default.

29 changes: 15 additions & 14 deletions dv/dv/advert_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/named-data/ndnd/std/log"
"github.com/named-data/ndnd/std/ndn"
spec "github.com/named-data/ndnd/std/ndn/spec_2022"
spec_svs "github.com/named-data/ndnd/std/ndn/svs/v3"
spec_svs "github.com/named-data/ndnd/std/ndn/svs/v4"
"github.com/named-data/ndnd/std/object/storage"
"github.com/named-data/ndnd/std/types/optional"
"github.com/named-data/ndnd/std/utils"
Expand Down Expand Up @@ -50,17 +50,18 @@ func (a *advertModule) sendSyncInterest() (err error) {

// (AI GENERATED DESCRIPTION): Sends a signed state‑vector Data packet as the payload of a sync Interest to the given `syncName`, expressing the Interest locally without expecting a reply.
func (a *advertModule) sendSyncInterestImpl(syncName enc.Name) (err error) {
// State Vector for our group
sv := &spec_svs.SvsData{
StateVector: &spec_svs.StateVector{
Entries: []*spec_svs.StateVectorEntry{{
Name: a.dv.config.RouterName(),
SeqNoEntries: []*spec_svs.SeqNoEntry{{
BootstrapTime: a.bootTime,
SeqNo: a.seq,
}},
// DV's advertisement Sync Data carries a single-entry StateVector
// directly. SVS v4's wire (FullStateVector/PartialStateVector/SvsDataRef
// tagged union) is a different protocol layer; DV keeps its own simpler
// shape to remain independent of SVS v4 changes.
sv := &spec_svs.StateVector{
Entries: []*spec_svs.StateVectorEntry{{
Name: a.dv.config.RouterName(),
SeqNoEntries: []*spec_svs.SeqNoEntry{{
BootstrapTime: a.bootTime,
SeqNo: a.seq,
}},
},
}},
}

// Sign the Sync Data
Expand Down Expand Up @@ -136,14 +137,14 @@ func (a *advertModule) OnSyncInterest(args ndn.InterestHandlerArgs, active bool)

// Decode state vector
svWire := data.Content()
params, err := spec_svs.ParseSvsData(enc.NewWireView(svWire), false)
if err != nil || params.StateVector == nil {
params, err := spec_svs.ParseStateVector(enc.NewWireView(svWire), false)
if err != nil {
log.Warn(a, "Failed to parse StateVec", "err", err)
return
}

// Process the state vector
go a.onStateVector(params.StateVector, args.IncomingFaceId.Unwrap(), active)
go a.onStateVector(params, args.IncomingFaceId.Unwrap(), active)
},
})
}
Expand Down
2 changes: 1 addition & 1 deletion e2e/dv_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def setup(ndn: Minindn, network=DEFAULT_NETWORK) -> None:
info('Starting ndn-dv on nodes\n')
AppManager(ndn, ndn.net.hosts, NDNd_DV, network=network)

def converge(nodes: list[Node], deadline=30, network=DEFAULT_NETWORK, use_nfdc=False) -> int:
def converge(nodes: list[Node], deadline=90, network=DEFAULT_NETWORK, use_nfdc=False) -> int:
info('Waiting for routing to converge\n')
start = time.time()
while time.time() - start < deadline:
Expand Down
2 changes: 1 addition & 1 deletion e2e/test_001.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def scenario(ndn: Minindn, fw=None, network='/minindn'):
node.cmd(cmd)

info('Waiting for put to complete\n')
time.sleep(30)
time.sleep(90)

for node in cat_nodes:
put_node = random.choice(put_nodes)
Expand Down
36 changes: 0 additions & 36 deletions std/ndn/svs/v3/definitions.go

This file was deleted.

54 changes: 54 additions & 0 deletions std/ndn/svs/v4/accessors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package svs

// VectorKind identifies which direct form an SvsData carries on the wire.
// Publish-only Sync Data carries neither FullStateVector nor
// PartialStateVector; instead it has SvsDataRef. The choice of wire TLV
// replaces the previous VectorType discriminator field.
type VectorKind int

const (
// VectorKindNone is the publish-only form: no embedded vector, only a
// retrievable SvsDataRef.
VectorKindNone VectorKind = iota
// VectorKindFull is a complete State Vector (FULL).
VectorKindFull
// VectorKindPartial is a sender-selected subset (PARTIAL).
VectorKindPartial
)

// GetStateVector returns the embedded StateVector for direct forms (FULL
// or PARTIAL), or nil for the publish-only form.
func (d *SvsData) GetStateVector() *StateVector {
switch {
case d.FullStateVector != nil:
return d.FullStateVector.StateVector
case d.PartialStateVector != nil:
return d.PartialStateVector.StateVector
}
return nil
}

// Kind reports which direct form (or none) the SvsData carries on the wire.
// An SvsData carrying both FullStateVector and PartialStateVector is
// reported as KindFull (the more specific case wins).
func (d *SvsData) Kind() VectorKind {
switch {
case d.FullStateVector != nil:
return VectorKindFull
case d.PartialStateVector != nil:
return VectorKindPartial
}
return VectorKindNone
}

// IsPartial reports whether the embedded StateVector is a PARTIAL subset.
// Returns false for the publish-only form (callers that branch on this
// should also check SvsDataRef for the publish-only recovery path).
func (d *SvsData) IsPartial() bool {
return d.PartialStateVector != nil
}

// IsFull reports whether the embedded StateVector is a FULL State Vector.
func (d *SvsData) IsFull() bool {
return d.FullStateVector != nil
}
72 changes: 72 additions & 0 deletions std/ndn/svs/v4/definitions.go

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

move to ndn/svs/v4

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//go:generate gondn_tlv_gen
package svs

import (
enc "github.com/named-data/ndnd/std/encoding"
)

// FullStateVector is the wire form of a complete State Vector carried in a
// Sync message or published at .../32=sv/<version>. The presence of this
// TLV (rather than PartialStateVector) tells the receiver that the embedded
// StateVector represents the sender's full membership view.
type FullStateVector struct {
//+field:struct:StateVector
StateVector *StateVector `tlv:"0xc9"`
}

// PartialStateVector is the wire form of a publication-time subset State
// Vector. The presence of this TLV tells the receiver that omitted entries
// are a sender-selected subset (not a partition or out-of-date sender).
type PartialStateVector struct {
//+field:struct:StateVector
StateVector *StateVector `tlv:"0xc9"`
}

// SvsData is a tagged union: the wire carries exactly one of
// FullStateVector, PartialStateVector, or SvsDataRef. The choice of TLV
// type replaces the previous VectorType discriminator. MemberSetHash
// (`mhash`) is present on all three forms and lets receivers detect
// membership mismatches without walking a full StateVector.
type SvsData struct {
//+field:binary:optional
MemberSetHash []byte `tlv:"0xcb"`
//+field:struct:FullStateVector
FullStateVector *FullStateVector `tlv:"0xcd"`
//+field:struct:PartialStateVector
PartialStateVector *PartialStateVector `tlv:"0xce"`
//+field:name
SvsDataRef enc.Name `tlv:"0x07"`
}

type StateVector struct {
//+field:sequence:*StateVectorEntry:struct:StateVectorEntry
Entries []*StateVectorEntry `tlv:"0xca"`
}

type StateVectorEntry struct {
//+field:name
Name enc.Name `tlv:"0x07"`
//+field:sequence:*SeqNoEntry:struct:SeqNoEntry
SeqNoEntries []*SeqNoEntry `tlv:"0xd2"`
}

type SeqNoEntry struct {
//+field:natural
BootstrapTime uint64 `tlv:"0xd4"`
//+field:natural
SeqNo uint64 `tlv:"0xd6"`
}

// MembershipTuple is one (Name, BootstrapTime) pair used to compute MemberSetHash.
type MembershipTuple struct {
//+field:name
Name enc.Name `tlv:"0x07"`
//+field:natural
BootstrapTime uint64 `tlv:"0xd4"`
}

// +tlv-model:nocopy
type PassiveState struct {
//+field:sequence:[]byte:binary:[]byte
Data [][]byte `tlv:"0xfa0"`
}
Loading
Loading