Skip to content

Commit

Permalink
Saving TTL data seperately (#315)
Browse files Browse the repository at this point in the history
* seperate ttl data into different directory

* remove unrequired conditional

* offset value increment before writing in prooffiles

* update currentoffset outisde loop add 0s bytes for each leaf created with new channel

* add filewait for the leafblock channel

* function for writes seperation and goroutines

* add loop for each channel write operations and update offsets operation for the ttls

* incorrect append value fixed
  • Loading branch information
DiptoChakrabarty authored Sep 6, 2021
1 parent 9606c8a commit b89cdab
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 48 deletions.
17 changes: 17 additions & 0 deletions bridgenode/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,19 @@ type undoDir struct {
undoFile string
offsetFile string
}
type ttlDir struct {
base string
ttlsetFile 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
TtlDir ttlDir
Ttldb string
}

Expand Down Expand Up @@ -139,13 +145,20 @@ func initUtreeDir(basePath string) utreeDir {
offsetFile: filepath.Join(undoBase, "offset.dat"),
}

ttlBase := filepath.Join(basePath, "ttldata")
ttl := ttlDir{
base: ttlBase,
ttlsetFile: filepath.Join(ttlBase, "ttldata.dat"),
OffsetFile: filepath.Join(ttlBase, "offsetfile.dat"),
}
ttldb := filepath.Join(basePath, "ttldb")

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

Expand Down
133 changes: 87 additions & 46 deletions bridgenode/flatfileworker.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,9 @@ type flatFileState struct {
// pFileWorker takes in blockproof and height information from the channel
// and writes to disk. MUST NOT have more than one worker as the proofs need to be
// in order
func flatFileWorker(

func flatFileWorkerProofBlocks(
proofChan chan btcacc.UData,
ttlResultChan chan ttlResultBlock,
undoChan chan accumulator.UndoBlock,
utreeDir utreeDir,
fileWait *sync.WaitGroup) {

Expand All @@ -87,8 +86,23 @@ func flatFileWorker(
panic(err)
}

// for the undofiles
for {
ud := <-proofChan
err = ff.writeProofBlock(ud)
if err != nil {
panic(err)
}
}
}

func flatFileWorkerUndoBlocks(
undoChan chan accumulator.UndoBlock,
utreeDir utreeDir,
fileWait *sync.WaitGroup) {

var uf flatFileState
var err error

uf.offsetFile, err = os.OpenFile(
utreeDir.UndoDir.offsetFile, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
Expand All @@ -107,48 +121,63 @@ func flatFileWorker(
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
// buffer fills, then eventually it'll block...?
// Also, is it OK to have 2 different workers here? It probably is, with the
// ttl side having read access to the proof writing side's last written proof.
// then the TTL side can do concurrent writes. Also the TTL writes might be
// slow since they're all over the place. Also the offsets should definitely
// be in ram since they'll be accessed a lot.

// TODO ^^^^^^ all that stuff.

// main selector - Write block proofs whenever you get them
// if you get TTLs, write them only if they're not too high
// if they are too high, keep writing proof blocks until they're not
for {
select {
case ud := <-proofChan:
err = ff.writeProofBlock(ud)
if err != nil {
panic(err)
}
case ttlRes := <-ttlResultChan:
for ttlRes.Height > ff.currentHeight {
ud := <-proofChan
err = ff.writeProofBlock(ud)
if err != nil {
panic(err)
}
}
undo := <-undoChan
err = uf.writeUndoBlock(undo)
if err != nil {
panic(err)
}

err = ff.writeTTLs(ttlRes)
if err != nil {
panic(err)
}
case undo := <-undoChan:
err = uf.writeUndoBlock(undo)
if err != nil {
panic(err)
}
}

}

func flatFileWorkerTTlBlocks(
ttlResultChan chan ttlResultBlock,
leafblockChan chan int,
utreeDir utreeDir,
fileWait *sync.WaitGroup) {

var tf flatFileState
var err error

tf.offsetFile, err = os.OpenFile(
utreeDir.TtlDir.OffsetFile, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
panic(err)
}

tf.proofFile, err = os.OpenFile(
utreeDir.TtlDir.ttlsetFile, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
panic(err)
}
tf.fileWait = fileWait

err = tf.ffInit()
if err != nil {
panic(err)
}

for {
size := <-leafblockChan
bytesTtlWrite := make([]byte, size*4)
_, err = tf.proofFile.WriteAt(bytesTtlWrite, tf.currentOffset)
tf.fileWait.Done()
if err != nil {
panic(err)
}
ttlRes := <-ttlResultChan
err = tf.writeTTLs(ttlRes)
if err != nil {
panic(err)
}
// append tf offsets after writing ttl data
tf.offsets = append(tf.offsets, tf.currentOffset)
// increment currentoffset value
tf.currentOffset = tf.currentOffset + int64(size*4)
}

}

func (ff *flatFileState) ffInit() error {
Expand Down Expand Up @@ -312,6 +341,15 @@ func (ff *flatFileState) writeProofBlock(ud btcacc.UData) error {

func (ff *flatFileState) writeTTLs(ttlRes ttlResultBlock) error {
var ttlArr [4]byte
var buffer [8]byte

// write ttl offset to offsetfile
binary.BigEndian.PutUint64(buffer[:], uint64(ff.currentOffset))
_, err := ff.offsetFile.WriteAt(buffer[:], int64(8*ttlRes.Height))
if err != nil {
return err
}

// for all the TTLs, seek and overwrite the empty values there
for _, c := range ttlRes.Created {
// seek to the location of that txo's ttl value in the proof file
Expand All @@ -321,14 +359,17 @@ func (ff *flatFileState) writeTTLs(ttlRes ttlResultBlock) error {

// write it's lifespan as a 4 byte int32 (bit of a waste as
// 2 or 3 bytes would work)
// add 16: 4 for magic, 4 for size, 4 for height, 4 numTTL, then ttls start
_, err := ff.proofFile.WriteAt(ttlArr[:],
ff.offsets[c.createHeight]+16+int64(c.indexWithinBlock*4))
_, err = ff.proofFile.WriteAt(ttlArr[:],
ff.offsets[c.createHeight]+int64(c.indexWithinBlock*4))
if err != nil {
return err
}

}

// increment value of offset 4 bytes of each ttlRes Created
ff.currentOffset = ff.currentOffset + int64(len(ttlRes.Created)*4)
// increment height by 1
ff.currentHeight = ff.currentHeight + 1
ff.fileWait.Done()
return nil
}
8 changes: 6 additions & 2 deletions bridgenode/genproofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func BuildProofs(cfg *Config, sig chan bool) error {
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
leafblockChan := make(chan int, 10) // from blocksadd to ttl writer

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

var fileWait sync.WaitGroup

go flatFileWorker(proofChan, ttlResultChan, undoChan, cfg.UtreeDir, &fileWait)
go flatFileWorkerProofBlocks(proofChan, cfg.UtreeDir, &fileWait) // flat file worker for proof blocks
go flatFileWorkerUndoBlocks(undoChan, cfg.UtreeDir, &fileWait) // flat file worker for the undo blocks
go flatFileWorkerTTlBlocks(ttlResultChan, leafblockChan, cfg.UtreeDir, &fileWait) // flat file worker for the ttl blocks

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

Expand All @@ -133,7 +136,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(3) // flatFileWorker calls Done() when done writing ttls and proof and undoBlocks.
fileWait.Add(4) // flatFileWorker calls Done() when done writing ttls and proof and undoBlocks and also blockadds for leafs.

// Writes the new txos to leveldb,
// and generates TTL for txos spent in the block
Expand All @@ -146,6 +149,7 @@ func BuildProofs(cfg *Config, sig chan bool) error {
if err != nil {
return err
}
leafblockChan <- len(blockAdds) // send size of 0s needed to be added to disk

// use the accumulator to get inclusion proofs, and produce a block
// proof with all data needed to verify the block
Expand Down

0 comments on commit b89cdab

Please sign in to comment.