feat: persist and transfer script command payloads

This commit is contained in:
2026-09-06 11:11:36 +00:00
parent 26ac4c1cac
commit 3f84d3b2f1
18 changed files with 1155 additions and 31 deletions
+47
View File
@@ -0,0 +1,47 @@
package agent
import (
"context"
"crypto/sha256"
"errors"
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
"github.com/rvbox/rvbox/internal/agentproto"
"github.com/rvbox/rvbox/internal/client/spool"
"github.com/rvbox/rvbox/internal/domain"
)
var ErrInvalidScriptTransfer = errors.New("invalid script transfer")
// ApplyScriptChunk validates one server script frame and appends it to the
// durable client spool. The spool accepts only the next contiguous range or
// an exact replay, so reconnects cannot create holes or duplicate bytes.
func ApplyScriptChunk(ctx context.Context, store *spool.Store, session Session, chunk *rvboxv1.ScriptChunk, limits agentproto.Limits) (spool.ScriptStatus, error) {
if store == nil || session.Generation == 0 || chunk == nil || chunk.GetOffset() > limits.MaxScriptBytes || uint64(len(chunk.GetData())) > limits.MaxRawChunkBytes || len(chunk.GetSha256()) != sha256.Size {
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
}
issue, err := domain.ParseUUIDv7(chunk.GetIssueUuid())
if err != nil || sha256.Sum256(chunk.GetData()) != bytesToDigest(chunk.GetSha256()) {
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
}
return store.AppendScriptChunk(ctx, issue, chunk.GetOffset(), chunk.GetData(), bytesToDigest(chunk.GetSha256()))
}
// ApplyScriptCommit marks a fully received script launch-eligible only after
// the spool verifies the declared size and whole-body SHA-256.
func ApplyScriptCommit(ctx context.Context, store *spool.Store, session Session, commit *rvboxv1.ScriptCommit, limits agentproto.Limits) (spool.ScriptStatus, error) {
if store == nil || session.Generation == 0 || commit == nil || commit.GetSizeBytes() > limits.MaxScriptBytes || len(commit.GetSha256()) != sha256.Size {
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
}
issue, err := domain.ParseUUIDv7(commit.GetIssueUuid())
if err != nil {
return spool.ScriptStatus{}, ErrInvalidScriptTransfer
}
return store.CommitScript(ctx, issue, spool.ScriptDescriptor{SizeBytes: commit.GetSizeBytes(), SHA256: bytesToDigest(commit.GetSha256())})
}
func bytesToDigest(value []byte) [sha256.Size]byte {
var digest [sha256.Size]byte
copy(digest[:], value)
return digest
}