57 lines
1.5 KiB
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)
|
||
|
}
|