code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/deposits.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 sqlstore
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  
    22  	"code.vegaprotocol.io/vega/datanode/entities"
    23  	"code.vegaprotocol.io/vega/datanode/metrics"
    24  	v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2"
    25  
    26  	"github.com/georgysavva/scany/pgxscan"
    27  )
    28  
    29  type Deposits struct {
    30  	*ConnectionSource
    31  }
    32  
    33  const (
    34  	sqlDepositsColumns = `id, status, party_id, asset, amount, foreign_tx_hash,
    35  		credited_timestamp, created_timestamp, tx_hash, vega_time`
    36  
    37  	depositsFilterDateColumn = "vega_time"
    38  )
    39  
    40  var depositOrdering = TableOrdering{
    41  	ColumnOrdering{Name: "vega_time", Sorting: ASC},
    42  	ColumnOrdering{Name: "id", Sorting: ASC},
    43  }
    44  
    45  func NewDeposits(connectionSource *ConnectionSource) *Deposits {
    46  	return &Deposits{
    47  		ConnectionSource: connectionSource,
    48  	}
    49  }
    50  
    51  func (d *Deposits) Upsert(ctx context.Context, deposit *entities.Deposit) error {
    52  	query := fmt.Sprintf(`insert into deposits(%s)
    53  values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
    54  on conflict (id, party_id, vega_time) do update
    55  set
    56  	status=EXCLUDED.status,
    57  	asset=EXCLUDED.asset,
    58  	amount=EXCLUDED.amount,
    59  	foreign_tx_hash=EXCLUDED.foreign_tx_hash,
    60  	credited_timestamp=EXCLUDED.credited_timestamp,
    61  	created_timestamp=EXCLUDED.created_timestamp,
    62  	tx_hash=EXCLUDED.tx_hash`, sqlDepositsColumns)
    63  
    64  	defer metrics.StartSQLQuery("Deposits", "Upsert")()
    65  	if _, err := d.Exec(ctx, query, deposit.ID, deposit.Status, deposit.PartyID, deposit.Asset, deposit.Amount,
    66  		deposit.ForeignTxHash, deposit.CreditedTimestamp, deposit.CreatedTimestamp, deposit.TxHash, deposit.VegaTime); err != nil {
    67  		err = fmt.Errorf("could not insert deposit into database: %w", err)
    68  		return err
    69  	}
    70  
    71  	return nil
    72  }
    73  
    74  func (d *Deposits) GetByID(ctx context.Context, depositID string) (entities.Deposit, error) {
    75  	var deposit entities.Deposit
    76  
    77  	query := `select id, status, party_id, asset, amount, foreign_tx_hash, credited_timestamp, created_timestamp, tx_hash, vega_time
    78  		from deposits_current
    79  		where id = $1
    80  		order by id, party_id, vega_time desc`
    81  
    82  	defer metrics.StartSQLQuery("Deposits", "GetByID")()
    83  	return deposit, d.wrapE(pgxscan.Get(
    84  		ctx, d.ConnectionSource, &deposit, query, entities.DepositID(depositID)))
    85  }
    86  
    87  func (d *Deposits) GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.Deposit, error) {
    88  	defer metrics.StartSQLQuery("Deposits", "GetByTxHash")()
    89  
    90  	var deposits []entities.Deposit
    91  	query := fmt.Sprintf(`SELECT %s FROM deposits WHERE tx_hash = $1`, sqlDepositsColumns)
    92  
    93  	err := pgxscan.Select(ctx, d.ConnectionSource, &deposits, query, txHash)
    94  	if err != nil {
    95  		return nil, d.wrapE(err)
    96  	}
    97  
    98  	return deposits, nil
    99  }
   100  
   101  func (d *Deposits) GetByParty(ctx context.Context, party string, openOnly bool, pagination entities.Pagination, dateRange entities.DateRange) (
   102  	[]entities.Deposit, entities.PageInfo, error,
   103  ) {
   104  	switch p := pagination.(type) {
   105  	case entities.CursorPagination:
   106  		return d.getByPartyCursorPagination(ctx, party, openOnly, p, dateRange)
   107  	default:
   108  		panic("unsupported pagination")
   109  	}
   110  }
   111  
   112  func (d *Deposits) getByPartyCursorPagination(ctx context.Context, party string, openOnly bool,
   113  	pagination entities.CursorPagination, dateRange entities.DateRange,
   114  ) ([]entities.Deposit, entities.PageInfo, error) {
   115  	var deposits []entities.Deposit
   116  	var pageInfo entities.PageInfo
   117  	var err error
   118  
   119  	query, args := getDepositsByPartyQuery(party, dateRange)
   120  	if openOnly {
   121  		query = fmt.Sprintf(`%s and status = %s`, query, nextBindVar(&args, entities.DepositStatusOpen))
   122  	}
   123  	query, args, err = PaginateQuery[entities.DepositCursor](query, args, depositOrdering, pagination)
   124  	if err != nil {
   125  		return nil, pageInfo, err
   126  	}
   127  
   128  	defer metrics.StartSQLQuery("Deposits", "GetByParty")()
   129  	if err = pgxscan.Select(ctx, d.ConnectionSource, &deposits, query, args...); err != nil {
   130  		return nil, pageInfo, fmt.Errorf("could not get deposits by party: %w", err)
   131  	}
   132  
   133  	deposits, pageInfo = entities.PageEntities[*v2.DepositEdge](deposits, pagination)
   134  
   135  	return deposits, pageInfo, nil
   136  }
   137  
   138  func getDepositsByPartyQuery(party string, dateRange entities.DateRange) (string, []interface{}) {
   139  	var args []interface{}
   140  
   141  	query := `select id, status, party_id, asset, amount, foreign_tx_hash, credited_timestamp, created_timestamp, tx_hash, vega_time
   142  		from deposits_current`
   143  
   144  	first := true
   145  	if party != "" {
   146  		query = fmt.Sprintf(`%s where party_id = %s`, query, nextBindVar(&args, entities.PartyID(party)))
   147  		first = false
   148  	}
   149  
   150  	return filterDateRange(query, depositsFilterDateColumn, dateRange, first, args...)
   151  }