7
"gitverse.ru/IvanTimofeev/cranberry/internal/db"
8
"gitverse.ru/IvanTimofeev/cranberry/internal/log"
9
"gitverse.ru/IvanTimofeev/cranberry/internal/merkle"
10
pbapi "gitverse.ru/IvanTimofeev/cranberry/pkg/grpc"
11
utility "gitverse.ru/IvanTimofeev/cranberry/pkg/utility"
15
type ValidatorService struct {
17
logger *zap.SugaredLogger
18
privKey *ecdsa.PrivateKey
22
func NewValidatorService(db *db.Db, seed string) *ValidatorService {
23
logger := log.GetLogger()
24
privKey, err := utility.GeneratePrivKeyBySeed(seed)
26
logger.Fatal("Error generate private key", zap.Error(err))
28
validatorAddr := utility.GetAddrFromPubKey(utility.PubKeyToBytes(&privKey.PublicKey))
29
logger.Infof("validator id = %s", validatorAddr)
30
return &ValidatorService{
34
validatorAddr: validatorAddr,
38
func (vs *ValidatorService) ValidateBlock(bc *pbapi.BlockContainer) (bool, error) {
39
hash := utility.BlockHeaderToHash(bc.Header)
40
if !strings.EqualFold(hash, bc.Hash) {
41
log.GetLogger().Warnf("invalid block hash: expected %v, actual %v", hash, bc.Hash)
44
height, ok, err := vs.db.GetUint64Param(LAST_BLOCK_HEIGHT_PARAM_NAME)
51
if height+1 != bc.Header.Height {
52
log.GetLogger().Warnf("invalid block height: expected %v, actual %v", height, bc.Header.Height)
55
merkleRoot := merkle.MerkleRoot(bc.Txs)
56
if !strings.EqualFold(merkleRoot, bc.Header.MerkleRoot) {
57
log.GetLogger().Warnf("invalid block merkle: expected %v, actual %v", merkleRoot, bc.Header.MerkleRoot)
60
for order, txc := range bc.Txs {
61
verified, err := vs.ValidateTx(txc)
68
if txc.OrderInBlock == nil || uint64(order) != *txc.OrderInBlock {
69
log.GetLogger().Warnf("invalid order in block for tx with hash = %v: expected %v, actual %v",
70
txc.Hash, order, txc.OrderInBlock)
75
for _, s := range bc.ValidatorSignatures {
76
validator, ok, err := vs.db.GetValidator(s.Addr)
81
log.GetLogger().Warnf("validator id = %v is not found in database", s.Addr)
84
verified := utility.VerifyBlock(utility.BytesToPubKey(validator.PubKey), s.Signature, bc.Header)
86
log.GetLogger().Warnf("invalid block signature with hash = %s", hash)
93
func (vs *ValidatorService) ValidateTx(txc *pbapi.TxContainer) (bool, error) {
94
hash := utility.TxToHash(txc.Tx)
95
if !strings.EqualFold(hash, txc.Hash) {
96
log.GetLogger().Warnf("invalid tx hash: expected %v, actual %v", hash, txc.Hash)
100
verified := utility.VerifyTx(utility.BytesToPubKey(txc.PubKey), txc)
102
log.GetLogger().Warnf("invalid tx signature with hash = %s", string(hash))
105
from := utility.GetAddrFromPubKey(txc.PubKey)
106
fromAcc, ok, err := vs.db.GetAccount(from)
111
log.GetLogger().Warnf("account with address = %s is not found in database", from)
114
if fromAcc.Balance-txc.Tx.Amount < 0 {
115
log.GetLogger().Warnf("insufficient funds for account with id = %s. Current balance = %d, tx amount = %d",
116
from, fromAcc.Balance, txc.Tx.Amount)
122
func (vs *ValidatorService) GetValidatorAddr() string {
123
return vs.validatorAddr
126
func (vs *ValidatorService) GetPrivKey() *ecdsa.PrivateKey {