Skip to content

Commit 860180c

Browse files
robinbryceRobin Bryce
andauthored
fix: replciation issue local log and seal corruption (#34)
When replicating the remote log file and the remote seal to local disc the files must be opened in O_TRUNC mode. The single corner case where this happens required file system based tests and we only have those in veracity. Follow on work required if we want those tests to exist in this repo. AB#10163 Co-authored-by: Robin Bryce <[email protected]>
1 parent 4d53d75 commit 860180c

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

massifs/localmassifreader.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ type DirResolver interface {
2323
ResolveSealDir(tenantIdentityOrLocalPath string) (string, error)
2424
}
2525
type WriteAppendOpener interface {
26+
// Open ensures the named file exists and is writable. Writes are appended to any existing content.
2627
Open(string) (io.WriteCloser, error)
28+
// Create ensures the named file exists, is empty and is writable
29+
// If the named file already exists it is truncated
30+
Create(string) (io.WriteCloser, error)
2731
}
2832

2933
type VerifiedContextReader interface {
@@ -183,27 +187,28 @@ func (r *LocalReader) VerifyContext(
183187

184188
// ReplaceVerifiedContext writes the content from the verified remote to the
185189
// local replica. is the callers responsibility to ensure the context was
186-
// verified, and that the writeOpener opens the file in append mode if it
190+
// verified, and that the writeOpener opens the file in *truncate* mode if it
187191
// already exists.
188192
func (r *LocalReader) ReplaceVerifiedContext(
189193
vc *VerifiedContext, writeOpener WriteAppendOpener,
190194
) error {
191195

196+
// We are always provided the full massif data, not a delta. So the open
197+
// mode is O_TRUNC (empty the file if it exists). The caller is responsible
198+
// for checking the local is consistent with the remote before replacing.
192199
logFilename := r.GetMassifLocalPath(vc.TenantIdentity, vc.Start.MassifIndex)
193-
err := writeAll(writeOpener, logFilename, vc.Data)
200+
err := writeAll(writeOpener.Create, logFilename, vc.Data)
194201
if err != nil {
195202
return err
196203
}
197204

198205
sealFilename := r.GetSealLocalPath(vc.TenantIdentity, vc.Start.MassifIndex)
199-
if err != nil {
200-
return err
201-
}
206+
202207
sealBytes, err := vc.Sign1Message.MarshalCBOR()
203208
if err != nil {
204209
return err
205210
}
206-
err = writeAll(writeOpener, sealFilename, sealBytes)
211+
err = writeAll(writeOpener.Create, sealFilename, sealBytes)
207212
if err != nil {
208213
return err
209214
}
@@ -401,8 +406,10 @@ func copyCachedMassif(cached *MassifContext) MassifContext {
401406
return mc
402407
}
403408

404-
func writeAll(wo WriteAppendOpener, filename string, data []byte) error {
405-
f, err := wo.Open(filename)
409+
type WriteOpener func(name string) (io.WriteCloser, error)
410+
411+
func writeAll(wo WriteOpener, filename string, data []byte) error {
412+
f, err := wo(filename)
406413
if err != nil {
407414
return err
408415

0 commit comments

Comments
 (0)