code.vegaprotocol.io/vega@v0.79.0/datanode/sqlstore/key_rotations.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 KeyRotations struct {
    30  	*ConnectionSource
    31  }
    32  
    33  var keyRotationsOrdering = TableOrdering{
    34  	ColumnOrdering{Name: "vega_time", Sorting: ASC},
    35  	ColumnOrdering{Name: "node_id", Sorting: ASC},
    36  	ColumnOrdering{Name: "old_pub_key", Sorting: ASC},
    37  	ColumnOrdering{Name: "new_pub_key", Sorting: ASC},
    38  }
    39  
    40  func NewKeyRotations(connectionSource *ConnectionSource) *KeyRotations {
    41  	return &KeyRotations{
    42  		ConnectionSource: connectionSource,
    43  	}
    44  }
    45  
    46  func (store *KeyRotations) Upsert(ctx context.Context, kr *entities.KeyRotation) error {
    47  	defer metrics.StartSQLQuery("KeyRotations", "Upsert")()
    48  	_, err := store.Exec(ctx, `
    49  		INSERT INTO key_rotations(node_id, old_pub_key, new_pub_key, block_height, tx_hash, vega_time)
    50  		VALUES ($1, $2, $3, $4, $5, $6)
    51  		ON CONFLICT (node_id, vega_time) DO UPDATE SET
    52  			old_pub_key = EXCLUDED.old_pub_key,
    53  			new_pub_key = EXCLUDED.new_pub_key,
    54  			block_height = EXCLUDED.block_height,
    55  			tx_hash = EXCLUDED.tx_hash
    56  	`, kr.NodeID, kr.OldPubKey, kr.NewPubKey, kr.BlockHeight, kr.TxHash, kr.VegaTime)
    57  
    58  	// TODO Update node table with new pubkey here?
    59  
    60  	return err
    61  }
    62  
    63  func (store *KeyRotations) GetAllPubKeyRotations(ctx context.Context, pagination entities.CursorPagination) ([]entities.KeyRotation, entities.PageInfo, error) {
    64  	defer metrics.StartSQLQuery("KeyRotations", "GetAll")()
    65  	var pageInfo entities.PageInfo
    66  	keyRotations := []entities.KeyRotation{}
    67  
    68  	var args []interface{}
    69  	var err error
    70  	query := `SELECT * FROM key_rotations`
    71  	query, args, err = PaginateQuery[entities.KeyRotationCursor](query, args, keyRotationsOrdering, pagination)
    72  	if err != nil {
    73  		return nil, pageInfo, err
    74  	}
    75  
    76  	if err = pgxscan.Select(ctx, store.ConnectionSource, &keyRotations, query, args...); err != nil {
    77  		return nil, pageInfo, fmt.Errorf("failed to retrieve key rotations: %w", err)
    78  	}
    79  
    80  	keyRotations, pageInfo = entities.PageEntities[*v2.KeyRotationEdge](keyRotations, pagination)
    81  
    82  	return keyRotations, pageInfo, nil
    83  }
    84  
    85  func (store *KeyRotations) GetByTxHash(ctx context.Context, txHash entities.TxHash) ([]entities.KeyRotation, error) {
    86  	defer metrics.StartSQLQuery("KeyRotations", "GetByTxHash")()
    87  
    88  	var keyRotations []entities.KeyRotation
    89  	query := `SELECT * FROM key_rotations WHERE tx_hash = $1`
    90  
    91  	if err := pgxscan.Select(ctx, store.ConnectionSource, &keyRotations, query, txHash); err != nil {
    92  		return nil, fmt.Errorf("failed to retrieve key rotations: %w", err)
    93  	}
    94  
    95  	return keyRotations, nil
    96  }
    97  
    98  func (store *KeyRotations) GetPubKeyRotationsPerNode(ctx context.Context, nodeID string, pagination entities.CursorPagination) ([]entities.KeyRotation, entities.PageInfo, error) {
    99  	defer metrics.StartSQLQuery("KeyRotations", "GetPubKeyRotationsPerNode")()
   100  	var pageInfo entities.PageInfo
   101  	id := entities.NodeID(nodeID)
   102  	keyRotations := []entities.KeyRotation{}
   103  
   104  	sorting, cmp, cursor := extractPaginationInfo(pagination)
   105  
   106  	kc := &entities.KeyRotationCursor{}
   107  	if err := kc.Parse(cursor); err != nil {
   108  		return nil, pageInfo, fmt.Errorf("could not parse key rotation cursor: %w", err)
   109  	}
   110  
   111  	cursorParams := []CursorQueryParameter{
   112  		NewCursorQueryParameter("vega_time", sorting, cmp, kc.VegaTime),
   113  	}
   114  
   115  	var args []interface{}
   116  	query := fmt.Sprintf(`SELECT * FROM key_rotations WHERE node_id = %s`, nextBindVar(&args, id))
   117  	query, args = orderAndPaginateWithCursor(query, pagination, cursorParams, args...)
   118  
   119  	if err := pgxscan.Select(ctx, store.ConnectionSource, &keyRotations, query, args...); err != nil {
   120  		return nil, pageInfo, fmt.Errorf("failed to retrieve key rotations: %w", err)
   121  	}
   122  
   123  	keyRotations, pageInfo = entities.PageEntities[*v2.KeyRotationEdge](keyRotations, pagination)
   124  
   125  	return keyRotations, pageInfo, nil
   126  }