code.vegaprotocol.io/vega@v0.79.0/core/staking/accounting_snapshot_test.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 staking_test
    17  
    18  import (
    19  	"bytes"
    20  	"context"
    21  	"testing"
    22  
    23  	"code.vegaprotocol.io/vega/core/types"
    24  	"code.vegaprotocol.io/vega/libs/crypto"
    25  	"code.vegaprotocol.io/vega/libs/num"
    26  	"code.vegaprotocol.io/vega/libs/proto"
    27  	snapshot "code.vegaprotocol.io/vega/protos/vega/snapshot/v1"
    28  
    29  	"github.com/golang/mock/gomock"
    30  	"github.com/stretchr/testify/require"
    31  )
    32  
    33  var allKey = (&types.PayloadStakingAccounts{}).Key()
    34  
    35  func TestAccountsSnapshotEmpty(t *testing.T) {
    36  	acc := getAccountingTest(t)
    37  	defer acc.ctrl.Finish()
    38  
    39  	s, _, err := acc.GetState(allKey)
    40  	require.Nil(t, err)
    41  	require.NotNil(t, s)
    42  }
    43  
    44  func TestAccountsSnapshotRoundTrip(t *testing.T) {
    45  	ctx := context.Background()
    46  	acc := getAccountingTest(t)
    47  	defer acc.ctrl.Finish()
    48  	acc.broker.EXPECT().Send(gomock.Any()).Times(1)
    49  
    50  	s1, _, err := acc.GetState(allKey)
    51  	require.Nil(t, err)
    52  
    53  	evt := &types.StakeLinking{
    54  		ID:              "someid1",
    55  		Type:            types.StakeLinkingTypeDeposited,
    56  		TS:              100,
    57  		Party:           testParty,
    58  		Amount:          num.NewUint(10),
    59  		BlockHeight:     12,
    60  		BlockTime:       1000002000,
    61  		LogIndex:        100022,
    62  		EthereumAddress: "0xe82EfC4187705655C9b484dFFA25f240e8A6B0BA",
    63  		TxHash:          crypto.RandomHash(),
    64  	}
    65  	acc.AddEvent(ctx, evt)
    66  	acc.tsvc.EXPECT().GetTimeNow().AnyTimes()
    67  	acc.witness.EXPECT().StartCheck(gomock.Any(), gomock.Any(), gomock.Any()).Times(1)
    68  	acc.Accounting.ProcessStakeTotalSupply(context.Background(), &types.StakeTotalSupply{
    69  		TokenAddress: crypto.RandomHash(),
    70  		TotalSupply:  num.NewUint(100),
    71  	})
    72  
    73  	evt = &types.StakeLinking{
    74  		ID:              "someid2",
    75  		Type:            types.StakeLinkingTypeDeposited,
    76  		TS:              100,
    77  		Party:           testParty,
    78  		Amount:          num.NewUint(10),
    79  		BlockHeight:     13,
    80  		BlockTime:       1000003000,
    81  		LogIndex:        100022,
    82  		EthereumAddress: "0xe82EfC4187705655C9b484dFFA25f240e8A6B0BA",
    83  		TxHash:          evt.TxHash,
    84  	}
    85  
    86  	acc.AddEvent(ctx, evt)
    87  
    88  	balance, err := acc.GetAvailableBalance(testParty)
    89  	require.NoError(t, err)
    90  	require.Equal(t, "20", balance.String())
    91  
    92  	// Check state has change now an event as been added
    93  	s2, _, err := acc.GetState(allKey)
    94  	require.Nil(t, err)
    95  	require.False(t, bytes.Equal(s1, s2))
    96  
    97  	// taking the snapshot has corrected the duplicate balance
    98  	balance, err = acc.GetAvailableBalance(testParty)
    99  	require.NoError(t, err)
   100  	require.Equal(t, "10", balance.String())
   101  
   102  	// Get state ready to load in a new instance of the engine
   103  	state, _, err := acc.GetState(allKey)
   104  	require.Nil(t, err)
   105  
   106  	snap := &snapshot.Payload{}
   107  	err = proto.Unmarshal(state, snap)
   108  	require.Nil(t, err)
   109  
   110  	snapAcc := getAccountingTest(t)
   111  	defer snapAcc.ctrl.Finish()
   112  
   113  	// Load it in anc check that the accounts and their balances have returned
   114  	snapAcc.broker.EXPECT().SendBatch(gomock.Any()).Times(2)
   115  	snapAcc.witness.EXPECT().RestoreResource(gomock.Any(), gomock.Any()).AnyTimes()
   116  	provs, err := snapAcc.LoadState(ctx, types.PayloadFromProto(snap))
   117  	require.Nil(t, err)
   118  	require.Nil(t, provs)
   119  	require.Equal(t, acc.GetAllAvailableBalances(), snapAcc.GetAllAvailableBalances())
   120  	accBalance := acc.GetAllAvailableBalances()
   121  	snapAccBalance := snapAcc.GetAllAvailableBalances()
   122  	require.Equal(t, accBalance["bob"].String(), snapAccBalance["bob"].String())
   123  	s3, _, err := snapAcc.GetState(allKey)
   124  	require.Nil(t, err)
   125  	require.True(t, bytes.Equal(s2, s3))
   126  }