code.vegaprotocol.io/vega@v0.79.0/datanode/sqlsubscribers/account.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package sqlsubscribers 17 18 import ( 19 "context" 20 "time" 21 22 "code.vegaprotocol.io/vega/core/events" 23 "code.vegaprotocol.io/vega/datanode/entities" 24 "code.vegaprotocol.io/vega/protos/vega" 25 26 "github.com/pkg/errors" 27 "github.com/shopspring/decimal" 28 ) 29 30 type AccountEvent interface { 31 events.Event 32 Account() vega.Account 33 } 34 35 type AccountService interface { 36 Obtain(ctx context.Context, a *entities.Account) error 37 AddAccountBalance(b entities.AccountBalance) error 38 Flush(ctx context.Context) error 39 } 40 41 type Account struct { 42 subscriber 43 accounts AccountService 44 } 45 46 func NewAccount(accounts AccountService) *Account { 47 return &Account{ 48 accounts: accounts, 49 } 50 } 51 52 func (as *Account) Types() []events.Type { 53 return []events.Type{events.AccountEvent} 54 } 55 56 func (as *Account) Flush(ctx context.Context) error { 57 err := as.accounts.Flush(ctx) 58 return errors.Wrap(err, "flushing balances") 59 } 60 61 func (as *Account) Push(ctx context.Context, evt events.Event) error { 62 return as.consume(ctx, evt.(AccountEvent)) 63 } 64 65 func (as *Account) consume(ctx context.Context, evt AccountEvent) error { 66 protoAcc := evt.Account() 67 acc, err := as.obtainAccountWithProto(ctx, &protoAcc, evt.TxHash(), as.vegaTime) 68 if err != nil { 69 return errors.Wrap(err, "obtaining account") 70 } 71 72 balance, err := decimal.NewFromString(protoAcc.Balance) 73 if err != nil { 74 return errors.Wrap(err, "parsing account balance") 75 } 76 77 ab := entities.AccountBalance{ 78 Balance: balance, 79 Account: &acc, 80 TxHash: entities.TxHash(evt.TxHash()), 81 VegaTime: as.vegaTime, 82 } 83 84 err = as.accounts.AddAccountBalance(ab) 85 if err != nil { 86 return errors.Wrap(err, "adding balance to store") 87 } 88 return nil 89 } 90 91 func (as *Account) obtainAccountWithProto(ctx context.Context, va *vega.Account, txHash string, vegaTime time.Time) (entities.Account, error) { 92 a, err := entities.AccountFromProto(va, entities.TxHash(txHash)) 93 if err != nil { 94 return entities.Account{}, errors.Wrap(err, "obtaining account for balance") 95 } 96 97 a.VegaTime = vegaTime 98 err = as.accounts.Obtain(ctx, &a) 99 if err != nil { 100 return entities.Account{}, errors.Wrap(err, "obtaining account") 101 } 102 return a, nil 103 } 104 105 func (as *Account) Name() string { 106 return "Account" 107 }