aboutsummaryrefslogtreecommitdiff
path: root/pkg/blockchain/chainwriter/chainwriter.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/blockchain/chainwriter/chainwriter.go')
-rw-r--r--pkg/blockchain/chainwriter/chainwriter.go60
1 files changed, 56 insertions, 4 deletions
diff --git a/pkg/blockchain/chainwriter/chainwriter.go b/pkg/blockchain/chainwriter/chainwriter.go
index 67a7d49..e1dd512 100644
--- a/pkg/blockchain/chainwriter/chainwriter.go
+++ b/pkg/blockchain/chainwriter/chainwriter.go
@@ -8,6 +8,7 @@ import (
"google.golang.org/protobuf/proto"
"log"
"os"
+ "strconv"
)
// ChainWriter handles all I/O for the BlockChain. It stores and retrieves
@@ -95,15 +96,66 @@ func (cw *ChainWriter) StoreBlock(bl *block.Block, undoBlock *UndoBlock, height
// WriteBlock writes a serialized Block to Disk and returns
// a FileInfo for storage information.
func (cw *ChainWriter) WriteBlock(serializedBlock []byte) *FileInfo {
- //TODO
- return nil
+ // need to know the length of the block
+ length := uint32(len(serializedBlock))
+ // if we don't have enough space for this block in the current file,
+ // we have to update our file by changing the current file number
+ // and resetting the start offset to zero (so we write at the beginning
+ // of the file again.
+ // (recall format from above: "data/block_0.txt")
+ if cw.CurrentBlockOffset+length >= cw.MaxBlockFileSize {
+ cw.CurrentBlockOffset = 0
+ cw.CurrentBlockFileNumber++
+ }
+ // create path to correct file, following format
+ // "DataDirectory/BlockFileName_CurrentBlockFileNumber.FileExtension"
+ // Ex: "data/block_0.txt"
+ fileName := cw.DataDirectory + "/" + cw.BlockFileName + "_" + strconv.Itoa(int(cw.CurrentBlockFileNumber)) + cw.FileExtension
+ // write serialized block to disk
+ writeToDisk(fileName, serializedBlock)
+ // create a file info object with the starting and ending offsets of the serialized block
+ fi := &FileInfo{
+ FileName: fileName,
+ StartOffset: cw.CurrentBlockOffset,
+ EndOffset: cw.CurrentBlockOffset + length,
+ }
+ // update offset for next write
+ cw.CurrentBlockOffset += length
+ // return the file info
+ return fi
}
// WriteUndoBlock writes a serialized UndoBlock to Disk and returns
// a FileInfo for storage information.
func (cw *ChainWriter) WriteUndoBlock(serializedUndoBlock []byte) *FileInfo {
- //TODO
- return nil
+ // need to know the length of the block
+ length := uint32(len(serializedUndoBlock))
+ // if we don't have enough space for this undo block in the current undo file,
+ // we have to update our undo file by changing the current undo file number
+ // and resetting the start undo offset to zero (so we write at the beginning
+ // of the undo file again.
+ // (recall format from above: "data/undo_0.txt")
+ if cw.CurrentUndoOffset+length >= cw.MaxUndoFileSize {
+ cw.CurrentUndoOffset = 0
+ cw.CurrentUndoFileNumber++
+ }
+ // create path to correct file, following format
+ // "DataDirectory/BlockFileName_CurrentBlockFileNumber.FileExtension"
+ // Ex: "data/undo_0.txt"
+ fileName := cw.DataDirectory + "/" + cw.UndoFileName + "_" + strconv.Itoa(int(cw.CurrentUndoFileNumber)) + cw.FileExtension
+ // write serialized undo block to disk
+ writeToDisk(fileName, serializedUndoBlock)
+ // create a file info object with the starting and ending undo offsets of the serialized
+ // undo block
+ fi := &FileInfo{
+ FileName: fileName,
+ StartOffset: cw.CurrentUndoOffset,
+ EndOffset: cw.CurrentUndoOffset + length,
+ }
+ // update offset for next write
+ cw.CurrentUndoOffset += length
+ // return the file info
+ return fi
}
// ReadBlock returns a Block given a FileInfo.