Skip to content

Commit

Permalink
Merge pull request #312 from DiptoChakrabarty/undo_save
Browse files Browse the repository at this point in the history
Saving UndoBlocks in Undoblock directory
  • Loading branch information
adiabat authored Aug 23, 2021
2 parents 15451ed + 689784d commit 25af856
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 6 deletions.
1 change: 1 addition & 0 deletions accumulator/undo.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ although actually it can make sense for non-bridge nodes to undo as well...
// blockUndo is all the data needed to undo a block: number of adds,
// and all the hashes that got deleted and where they were from
type UndoBlock struct {
Height int32 // height of block
numAdds uint32 // number of adds in the block
positions []uint64 // position of all deletions this block
hashes []Hash // hashes that were deleted
Expand Down
19 changes: 19 additions & 0 deletions bridgenode/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,18 @@ type offsetDir struct {
lastIndexOffsetHeightFile string
}

type undoDir struct {
base string
undoFile string
offsetFile string
}

// All your utreexo bridgenode file paths in a nice and convinent struct
type utreeDir struct {
OffsetDir offsetDir
ProofDir proofDir
ForestDir forestDir
UndoDir undoDir
Ttldb string
}

Expand Down Expand Up @@ -125,12 +132,20 @@ func initUtreeDir(basePath string) utreeDir {
cowForestCurFile: filepath.Join(cowDir, "CURRENT"),
}

undoBase := filepath.Join(basePath, "undoblockdata")
undo := undoDir{
base: undoBase,
undoFile: filepath.Join(undoBase, "undo.dat"),
offsetFile: filepath.Join(undoBase, "offset.dat"),
}

ttldb := filepath.Join(basePath, "ttldb")

return utreeDir{
OffsetDir: off,
ProofDir: proof,
ForestDir: forest,
UndoDir: undo,
Ttldb: ttldb,
}
}
Expand All @@ -153,6 +168,10 @@ func makePaths(dir utreeDir) error {
if err != nil {
return fmt.Errorf("init makePaths error %s")
}
err = os.MkdirAll(dir.UndoDir.base, os.ModePerm)
if err != nil {
return fmt.Errorf("init makePaths error %s")
}
return nil
}

Expand Down
76 changes: 76 additions & 0 deletions bridgenode/flatfileworker.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"sync"

"github.com/mit-dci/utreexo/accumulator"
"github.com/mit-dci/utreexo/btcacc"
)

Expand Down Expand Up @@ -60,6 +61,7 @@ type flatFileState struct {
func flatFileWorker(
proofChan chan btcacc.UData,
ttlResultChan chan ttlResultBlock,
undoChan chan accumulator.UndoBlock,
utreeDir utreeDir,
fileWait *sync.WaitGroup) {

Expand All @@ -85,6 +87,26 @@ func flatFileWorker(
panic(err)
}

// for the undofiles
var uf flatFileState
uf.offsetFile, err = os.OpenFile(
utreeDir.UndoDir.offsetFile, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
panic(err)
}

uf.proofFile, err = os.OpenFile(
utreeDir.UndoDir.undoFile, os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
panic(err)
}

uf.fileWait = fileWait

err = uf.ffInit()
if err != nil {
panic(err)
}
// Grab either proof bytes and write em to offset / proof file, OR, get a TTL result
// and write that. Will this lock up if it keeps doing proofs and ignores ttls?
// it should keep both buffers about even. If it keeps doing proofs and the ttl
Expand Down Expand Up @@ -120,6 +142,11 @@ func flatFileWorker(
if err != nil {
panic(err)
}
case undo := <-undoChan:
err = uf.writeUndoBlock(undo)
if err != nil {
panic(err)
}
}
}
}
Expand Down Expand Up @@ -175,6 +202,55 @@ func (ff *flatFileState) ffInit() error {
return nil
}

func (ff *flatFileState) writeUndoBlock(ub accumulator.UndoBlock) error {
undoSize := ub.SerializeSize()
buf := make([]byte, undoSize)

// write the offset of current of undo block to offset file
buf = buf[:8]
ff.offsets = append(ff.offsets, ff.currentOffset)

binary.BigEndian.PutUint64(buf, uint64(ff.currentOffset))
_, err := ff.offsetFile.WriteAt(buf, int64(8*ub.Height))
if err != nil {
return err
}

// write to undo file
_, err = ff.proofFile.WriteAt([]byte{0xaa, 0xff, 0xaa, 0xff}, ff.currentOffset)
if err != nil {
return err
}

//prefix with size of the undoblocks
buf = buf[:4]
binary.BigEndian.PutUint32(buf, uint32(undoSize))
_, err = ff.proofFile.WriteAt(buf, ff.currentOffset+4)
if err != nil {
return err
}

// Serialize UndoBlock
buf = buf[:0]
bytesBuf := bytes.NewBuffer(buf)
err = ub.Serialize(bytesBuf)
if err != nil {
return err
}

_, err = ff.proofFile.WriteAt(bytesBuf.Bytes(), ff.currentOffset+4+4)
if err != nil {
return err
}

ff.currentOffset = ff.currentOffset + int64(undoSize) + 8
ff.currentHeight++

ff.fileWait.Done()

return nil
}

func (ff *flatFileState) writeProofBlock(ud btcacc.UData) error {
// get the new block proof
// put offset in ram
Expand Down
18 changes: 12 additions & 6 deletions bridgenode/genproofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"sync"
"time"

"github.com/mit-dci/utreexo/accumulator"
"github.com/mit-dci/utreexo/btcacc"
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/opt"
Expand Down Expand Up @@ -67,9 +68,10 @@ func BuildProofs(cfg *Config, sig chan bool) error {

// async ttldb variables
var dbwg sync.WaitGroup
dbWriteChan := make(chan ttlRawBlock, 10) // from block processing to db worker
ttlResultChan := make(chan ttlResultBlock, 10) // from db worker to flat ttl writer
proofChan := make(chan btcacc.UData, 10) // from proof processing to proof writer
dbWriteChan := make(chan ttlRawBlock, 10) // from block processing to db worker
ttlResultChan := make(chan ttlResultBlock, 10) // from db worker to flat ttl writer
proofChan := make(chan btcacc.UData, 10) // from proof processing to proof writer
undoChan := make(chan accumulator.UndoBlock, 10) // from undoblocks to undoblock writer

// sorta ugly as in one of these will just be sitting around
// doing nothing
Expand Down Expand Up @@ -109,7 +111,7 @@ func BuildProofs(cfg *Config, sig chan bool) error {

var fileWait sync.WaitGroup

go flatFileWorker(proofChan, ttlResultChan, cfg.UtreeDir, &fileWait)
go flatFileWorker(proofChan, ttlResultChan, undoChan, cfg.UtreeDir, &fileWait)

fmt.Println("Building Proofs and ttldb...")

Expand All @@ -131,7 +133,7 @@ func BuildProofs(cfg *Config, sig chan bool) error {
// start waitgroups, beyond this point we have to finish all the
// disk writes for this iteration of the loop
dbwg.Add(1) // DbWorker calls Done()
fileWait.Add(2) // flatFileWorker calls Done() when done writing ttls and proof.
fileWait.Add(3) // flatFileWorker calls Done() when done writing ttls and proof and undoBlocks.

// Writes the new txos to leveldb,
// and generates TTL for txos spent in the block
Expand All @@ -158,10 +160,14 @@ func BuildProofs(cfg *Config, sig chan bool) error {

// TODO: Don't ignore undoblock
// Modifies the forest with the given TXINs and TXOUTs
_, err = forest.Modify(blockAdds, ud.AccProof.Targets)
// return the undoBlock Data
undoblock, err := forest.Modify(blockAdds, ud.AccProof.Targets)
if err != nil {
return err
}
undoblock.Height = bnr.Height // set undoBlocks Height
// send undoBlock data to undo channel to be written to the disk
undoChan <- *undoblock

if bnr.Height%100 == 0 {
fmt.Println("On block :", bnr.Height+1)
Expand Down

0 comments on commit 25af856

Please sign in to comment.