code.vegaprotocol.io/vega@v0.79.0/core/validators/topology_checkpoint_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 validators_test
    17  
    18  import (
    19  	"context"
    20  	"encoding/hex"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"testing"
    24  
    25  	"code.vegaprotocol.io/vega/core/validators"
    26  	"code.vegaprotocol.io/vega/libs/proto"
    27  	checkpoint "code.vegaprotocol.io/vega/protos/vega/checkpoint/v1"
    28  	commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func addTwoNodes(top *testTop) {
    35  	number := 2
    36  	tmPubKeys := make([]string, 0, number)
    37  
    38  	for i := 0; i < number; i++ {
    39  		tmPubKeys = append(tmPubKeys, fmt.Sprintf("tm-pub-key-%d", i))
    40  	}
    41  
    42  	ctx := context.Background()
    43  
    44  	for i := 0; i < number; i++ {
    45  		top.AddNewNode(ctx, &commandspb.AnnounceNode{
    46  			Id:              fmt.Sprintf("vega-master-pubkey-%d", i),
    47  			ChainPubKey:     tmPubKeys[0],
    48  			VegaPubKey:      hexEncode(fmt.Sprintf("vega-key-%d", i)),
    49  			EthereumAddress: fmt.Sprintf("eth-address-%d", i),
    50  		}, validators.ValidatorStatusTendermint)
    51  	}
    52  }
    53  
    54  func hexEncode(str string) string {
    55  	return hex.EncodeToString([]byte(str))
    56  }
    57  
    58  func TestTopologyCheckpoint(t *testing.T) {
    59  	t.Run("test checkpoint success", testTopologyCheckpointSuccess)
    60  	t.Run("test checkpoint uses relative block height", testTopologyCheckpointUsesRelativeBlockHeight)
    61  }
    62  
    63  func TestCheckPointLoading(t *testing.T) {
    64  	newTop := getTestTopWithDefaultValidator(t)
    65  	defer newTop.ctrl.Finish()
    66  	newTop.timeService.EXPECT().GetTimeNow().AnyTimes()
    67  
    68  	inFile := "testcp/20220411202622-135-812dab0eb11196b49fd716329feb50c243f645226460df760168215d73acf0dd.cp"
    69  	data, _ := ioutil.ReadFile(inFile)
    70  	cp := &checkpoint.Checkpoint{}
    71  	if err := proto.Unmarshal(data, cp); err != nil {
    72  		t.Fatal(err)
    73  	}
    74  	require.Equal(t, 1, len(newTop.AllNodeIDs()))
    75  	newTop.Load(context.Background(), cp.Validators)
    76  	require.Equal(t, 2, len(newTop.AllNodeIDs()))
    77  }
    78  
    79  func testTopologyCheckpointSuccess(t *testing.T) {
    80  	top := getTestTopWithDefaultValidator(t)
    81  	defer top.ctrl.Finish()
    82  	top.timeService.EXPECT().GetTimeNow().AnyTimes()
    83  
    84  	ctx := context.Background()
    85  	addTwoNodes(top)
    86  
    87  	kr1 := &commandspb.KeyRotateSubmission{
    88  		NewPubKeyIndex:    1,
    89  		TargetBlock:       10,
    90  		NewPubKey:         "new-vega-key",
    91  		CurrentPubKeyHash: hashKey("vega-key-0"),
    92  	}
    93  	err := top.AddKeyRotate(ctx, "vega-master-pubkey-0", 5, kr1)
    94  	assert.NoError(t, err)
    95  
    96  	kr2 := &commandspb.KeyRotateSubmission{
    97  		NewPubKeyIndex:    1,
    98  		TargetBlock:       11,
    99  		NewPubKey:         "new-vega-key-1",
   100  		CurrentPubKeyHash: hashKey("vega-key-1"),
   101  	}
   102  	err = top.AddKeyRotate(ctx, "vega-master-pubkey-1", 5, kr2)
   103  	assert.NoError(t, err)
   104  
   105  	ekr1 := newEthereumKeyRotationSubmission("eth-address-0", "new-eth-address-0", 10, "")
   106  	err = top.ProcessEthereumKeyRotation(ctx, hexEncode("vega-key-0"), ekr1, MockVerify)
   107  	assert.NoError(t, err)
   108  
   109  	ekr2 := newEthereumKeyRotationSubmission("eth-address-1", "new-eth-address-1", 11, "")
   110  	err = top.ProcessEthereumKeyRotation(ctx, hexEncode("vega-key-1"), ekr2, MockVerify)
   111  	assert.NoError(t, err)
   112  
   113  	pkrs := top.GetAllPendingKeyRotations()
   114  	assert.Len(t, pkrs, 2)
   115  
   116  	ckp, err := top.Checkpoint()
   117  	assert.NotEmpty(t, ckp)
   118  	assert.NoError(t, err)
   119  
   120  	newTop := getTestTopWithDefaultValidator(t)
   121  	defer newTop.ctrl.Finish()
   122  
   123  	addTwoNodes(newTop)
   124  	newTop.Load(ctx, ckp)
   125  
   126  	newPkrs := newTop.GetAllPendingKeyRotations()
   127  	assert.Len(t, newPkrs, 2)
   128  	assert.Equal(t, pkrs, newPkrs)
   129  
   130  	assert.Equal(t, top.GetPendingEthereumKeyRotation(ekr1.TargetBlock, "vega-master-pubkey-0"), newTop.GetPendingEthereumKeyRotation(ekr1.TargetBlock, "vega-master-pubkey-0"))
   131  	assert.Equal(t, top.GetPendingEthereumKeyRotation(ekr2.TargetBlock, "vega-master-pubkey-1"), newTop.GetPendingEthereumKeyRotation(ekr2.TargetBlock, "vega-master-pubkey-1"))
   132  }
   133  
   134  func testTopologyCheckpointUsesRelativeBlockHeight(t *testing.T) {
   135  	top := getTestTopWithDefaultValidator(t)
   136  	defer top.ctrl.Finish()
   137  	top.timeService.EXPECT().GetTimeNow().AnyTimes()
   138  
   139  	ctx := context.Background()
   140  	addTwoNodes(top)
   141  
   142  	kr1 := &commandspb.KeyRotateSubmission{
   143  		NewPubKeyIndex:    1,
   144  		TargetBlock:       105,
   145  		NewPubKey:         "new-vega-key",
   146  		CurrentPubKeyHash: hashKey("vega-key-0"),
   147  	}
   148  	err := top.AddKeyRotate(ctx, "vega-master-pubkey-0", 5, kr1)
   149  	assert.NoError(t, err)
   150  
   151  	kr2 := &commandspb.KeyRotateSubmission{
   152  		NewPubKeyIndex:    1,
   153  		TargetBlock:       115,
   154  		NewPubKey:         "new-vega-key-1",
   155  		CurrentPubKeyHash: hashKey("vega-key-1"),
   156  	}
   157  	err = top.AddKeyRotate(ctx, "vega-master-pubkey-1", 5, kr2)
   158  	assert.NoError(t, err)
   159  
   160  	ekr1 := newEthereumKeyRotationSubmission("eth-address-0", "new-eth-address-0", 105, "")
   161  	err = top.ProcessEthereumKeyRotation(ctx, hexEncode("vega-key-0"), ekr1, MockVerify)
   162  	assert.NoError(t, err)
   163  
   164  	ekr2 := newEthereumKeyRotationSubmission("eth-address-1", "new-eth-address-1", 115, "")
   165  	err = top.ProcessEthereumKeyRotation(ctx, hexEncode("vega-key-1"), ekr2, MockVerify)
   166  	assert.NoError(t, err)
   167  
   168  	pkrs := top.GetAllPendingKeyRotations()
   169  	assert.Len(t, pkrs, 2)
   170  
   171  	ckp, err := top.Checkpoint()
   172  	assert.NotEmpty(t, ckp)
   173  	assert.NoError(t, err)
   174  
   175  	newTop := getTestTopWithDefaultValidator(t)
   176  	defer newTop.ctrl.Finish()
   177  	newTop.timeService.EXPECT().GetTimeNow().AnyTimes()
   178  
   179  	addTwoNodes(newTop)
   180  
   181  	var newNetworkBlockHeight uint64 = 100
   182  
   183  	// set current block height to newNetworkBlockHeight
   184  	newTop.BeginBlock(ctx, newNetworkBlockHeight, "")
   185  
   186  	newTop.Load(ctx, ckp)
   187  
   188  	newPkrs := newTop.GetAllPendingKeyRotations()
   189  	assert.Len(t, newPkrs, 2)
   190  
   191  	assert.Equal(t, pkrs[0].BlockHeight+newNetworkBlockHeight, newPkrs[0].BlockHeight)
   192  	assert.Equal(t, pkrs[1].BlockHeight+newNetworkBlockHeight, newPkrs[1].BlockHeight)
   193  }