package core import ( "context" "errors" "github.com/matchsystems/werr" "mic-wallet/common" "time" ) type IBlocksCreator interface { Run(ctx context.Context) error WriteTx(opts *common.NewTxOpts) error // GetTx Searches for tx in every block GetTx(block int64, hash string) *common.NewTxOpts GetTxs() []*common.NewTxOpts } type BlocksCreator struct { blocks map[int64]*Block commiter IBlocksCommiter prevBlockHash []byte } func NewBlocksCreator(commiter IBlocksCommiter) *BlocksCreator { return &BlocksCreator{ blocks: make(map[int64]*Block), commiter: commiter, } } func (bc *BlocksCreator) Run(ctx context.Context) error { var blockID int64 for { blockID = common.GetBlockId(time.Now()) if oldBlock, ok := bc.blocks[blockID-100]; ok { // Commit and delete old block bc.prevBlockHash = oldBlock.CalcHash() bc.commiter.CommitBlock(ctx, oldBlock) delete(bc.blocks, blockID-100) } bc.blocks[blockID] = NewBlock(blockID, bc.prevBlockHash) time.Sleep(time.Until(time.Unix(blockID+100, 0))) } } func (bc *BlocksCreator) WriteTx(opts *common.NewTxOpts) error { currentBlockID := common.GetBlockId(time.Now()) if currentBlockID < opts.BlockId { return errors.New("block with such id wasn't created yet. " + "Ensure that you generate block IDs in UTC timezone") } else if currentBlockID > opts.BlockId { return errors.New("block id is out of date") } return werr.Wrapf(bc.blocks[currentBlockID].AddTx(opts), "error adding transaction to block %d", currentBlockID) }