micw/server/core/blocks_creator.go

57 lines
1.5 KiB
Go

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)
}