Skip to content

auxiliary info disemination msm only - #524

Merged
samliok merged 9 commits into
mainfrom
aux-dis-1
Aug 27, 2026
Merged

auxiliary info disemination msm only#524
samliok merged 9 commits into
mainfrom
aux-dis-1

Conversation

@samliok

@samliok samliok commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Blocks now embed an AuxiliaryInfoBatch holding one entry per node. The builder collects legal entries from a new auxInfoStore mempool (populated by HandleAuxiliaryInfo) instead of calling Generate itself.
SignApproval is exported so the transition listener (next PR) can sign and broadcast approvals, and GetAuxiliaryHistory exposes the aux history traversal.

In future prs, the HandleAuxiliaryInfo and HandleApproval methods will be called by the instance that feeds in messages.

@samliok
samliok force-pushed the aux-dis-1 branch 2 times, most recently from 68a788d to d8290b2 Compare August 26, 2026 14:13
Base automatically changed from move-wal-function to main August 26, 2026 14:20
Comment thread instance_test.go
)

func TestInstanceMixedNodeType(t *testing.T) {
t.Skip("skipping until test instance refactor")

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

im skipping these because i didn't want to spend time updating the tests since i have them passing here

#508

@yacovm yacovm left a comment

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.

Made a first pass.

The most important comment is regarding resetting the aux info store between epochs.

Comment thread common/msg.go Outdated
Comment thread common/msg.go Outdated
Comment thread common/msg.go Outdated
Comment thread common/msg.go Outdated
// Can be used for backward-compatibility and upgrade purposes.
Version VersionID `canoto:"uint,1"`

// Info is opaque bytes that can be used by applications to encode any information that describes

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.

Info is opaque bytes that can be used by applications to encode any information that describes the current state for the application.

That's the most ambiguous definition I've read for quite some time, but I can only blame myself.

Comment thread msm/auxiliary.go
Comment thread msm/msm.go Outdated
Comment thread common/msg.go

// AuxiliaryInfo defines application-specific information for applications that might care about epoch change,
// such as threshold distributed public key generation.
type AuxiliaryInfo struct {

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.

We should add an epoch field here, otherwise we may get a misunderstanding if a node is lagging and sends information regarding the wrong epoch.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

shouldn't this be handled by Data and the auxiliary info application?

I think the only source of truth for whether AuxiliaryInfo is valid should be the IsLegalAppend function call. It shouldn't be up to the msm/instance to filter aux infos. If the application cared about epochs, they can encode that information in Data or maybe encode a timestamp.

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.

But there is no point in putting stuff into memory that if that stuff belongs to the wrong epoch.

The framework should do its best to provide reliable data delivery.

If the node is correct but it's just behind, we should exclude its contribution at the protocol layer, not at the app layer.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

ok, will add

i still think a malicious node can bypass this by encoding a different epoch. Therefore, we would still need some sort of check in the application layer

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

added the epoch to the struct, but I'll set up blocking old auxiliary info for when I wire it into the Instance since the MSM isn't aware of the current epoch.

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.

i still think a malicious node can bypass this by encoding a different epoch. Therefore, we would still need some sort of check in the application layer

Yeah but we should offload protection of malicious input to the application, but not let correct but stale input be regarded as malicious

Comment thread msm/auxiliary.go
a.lock.Lock()
defer a.lock.Unlock()

// Iterate in node ID order so the returned entries are deterministic.

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.

why do we need it to be deterministic? So that anyone verifying this would iterate in the same order when applying IsLegalAppend?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

it's helpful for testing. i don't think it matters for production, because this is only called by the block builder.

Comment thread msm/msm.go
return asn1.Marshal(signedMsg)
}

func SignApproval(signer common.Signer, nextPChainReferenceHeight uint64, auxInfoDigest [32]byte) ([]byte, error) {

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.

what's the reason this is exported? This was createSelfApproval before.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

it's used in a future PR

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Comment thread common/msg.go
VerifiedBlockMessage *VerifiedBlockMessage
VerifiedReplicationResponse *VerifiedReplicationResponse

// Epoch Transition Messages

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.

I'm missing the part where we send these two...?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@yacovm yacovm left a comment

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.

Some more comments. Will make another pass after they're addressed.

Comment thread msm/auxiliary.go
Comment thread msm/auxiliary.go
}

if err := a.app.IsLegalAppend(info.Version, validators, legalHistory, info.Data); err != nil {
// we don't remove this info from the mempool. maybe it can be added in a different block

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.

This is a good decision, because DKG material is linear in the size of the validator set, so we may not be able to add more than a single entry per block.

Comment thread msm/msm.go Outdated
if auxInfoHistory.OldestVersionID != info.Version {
return nil, [32]byte{}, false, fmt.Errorf("proposed auxiliary info does not have the proper version %d: %w", auxInfoHistory.OldestVersionID, err)
}
if err := sm.AuxiliaryInfoApp.IsLegalAppend(auxInfoHistory.OldestVersionID, validators, auxInfoHistory.Data, info.Data); err != nil {

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.

This just checks that adding info is allowed if we just add this info.

But it might be that adding the first info is allowed on its own, adding the second info is allowed on its own, but adding the first info and then the second info is forbidden.

For example, if proposedAuxInfos contains several info that are the same one, we should only be able to add the first one, not the rest.

We need to accumulate the history as we go through the auxiliary info we check are legal appends.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

ah good catch, we need to have some better testing with the auxiliary info stuff. maybe in some future prs or when DKG is added we can create some better aux tests

Comment thread common/msg.go Outdated
Comment thread msm/encoding.go Outdated
Comment thread msm/msm.go Outdated
Comment thread msm/encoding.go Outdated
if ai.data != nil {
cloned.data = make([]common.AuxiliaryInfo, len(ai.data))
for i, entry := range ai.data {
entry.Data = slices.Clone(entry.Data)

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.

There is no reason to clone the data. We are cloning to avoid cloning the canoto fields.

Comment thread msm/encoding.go Outdated
}
if ai.data != nil {
cloned.data = make([]common.AuxiliaryInfo, len(ai.data))
for i, entry := range ai.data {

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.

for i, entry := range ai.data { - this is racy.

We should only use i to access otherwise we copy canotoData too.

@yacovm yacovm left a comment

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.

Two important comments and then LGTM

@samliok
samliok merged commit 652700b into main Aug 27, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants