github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/lite/dynamic_verifier_test.go (about)

     1  package lite
     2  
     3  import (
     4  	"fmt"
     5  	"sync"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	dbm "github.com/tendermint/tm-db"
    12  
    13  	"github.com/tendermint/tendermint/crypto/tmhash"
    14  	log "github.com/tendermint/tendermint/libs/log"
    15  	"github.com/tendermint/tendermint/types"
    16  )
    17  
    18  const testChainID = "inquiry-test"
    19  
    20  func TestInquirerValidPath(t *testing.T) {
    21  	assert, require := assert.New(t), require.New(t)
    22  	trust := NewDBProvider("trust", dbm.NewMemDB())
    23  	source := NewDBProvider("source", dbm.NewMemDB())
    24  
    25  	// Set up the validators to generate test blocks.
    26  	var vote int64 = 10
    27  	keys := genPrivKeys(5)
    28  	nkeys := keys.Extend(1)
    29  
    30  	// Construct a bunch of commits, each with one more height than the last.
    31  	chainID := testChainID
    32  	consHash := []byte("params")
    33  	resHash := []byte("results")
    34  	count := 50
    35  	fcz := make([]FullCommit, count)
    36  	for i := 0; i < count; i++ {
    37  		vals := keys.ToValidators(vote, 0)
    38  		nextVals := nkeys.ToValidators(vote, 0)
    39  		h := int64(1 + i)
    40  		appHash := []byte(fmt.Sprintf("h=%d", h))
    41  		fcz[i] = keys.GenFullCommit(
    42  			chainID, h, nil,
    43  			vals, nextVals,
    44  			appHash, consHash, resHash, 0, len(keys))
    45  		// Extend the keys by 1 each time.
    46  		keys = nkeys
    47  		nkeys = nkeys.Extend(1)
    48  	}
    49  
    50  	// Initialize a Verifier with the initial state.
    51  	err := trust.SaveFullCommit(fcz[0])
    52  	require.Nil(err)
    53  	cert := NewDynamicVerifier(chainID, trust, source)
    54  	cert.SetLogger(log.TestingLogger())
    55  
    56  	// This should fail validation:
    57  	sh := fcz[count-1].SignedHeader
    58  	err = cert.Verify(sh)
    59  	require.NotNil(err)
    60  
    61  	// Adding a few commits in the middle should be insufficient.
    62  	for i := 10; i < 13; i++ {
    63  		err := source.SaveFullCommit(fcz[i])
    64  		require.Nil(err)
    65  	}
    66  	err = cert.Verify(sh)
    67  	assert.NotNil(err)
    68  
    69  	// With more info, we succeed.
    70  	for i := 0; i < count; i++ {
    71  		err := source.SaveFullCommit(fcz[i])
    72  		require.Nil(err)
    73  	}
    74  
    75  	// TODO: Requires proposer address to be set in header.
    76  	// err = cert.Verify(sh)
    77  	// assert.Nil(err, "%+v", err)
    78  }
    79  
    80  func TestDynamicVerify(t *testing.T) {
    81  	trust := NewDBProvider("trust", dbm.NewMemDB())
    82  	source := NewDBProvider("source", dbm.NewMemDB())
    83  
    84  	// 10 commits with one valset, 1 to change,
    85  	// 10 commits with the next one
    86  	n1, n2 := 10, 10
    87  	nCommits := n1 + n2 + 1
    88  	maxHeight := int64(nCommits)
    89  	fcz := make([]FullCommit, nCommits)
    90  
    91  	// gen the 2 val sets
    92  	chainID := "dynamic-verifier"
    93  	power := int64(10)
    94  	keys1 := genPrivKeys(5)
    95  	vals1 := keys1.ToValidators(power, 0)
    96  	keys2 := genPrivKeys(5)
    97  	vals2 := keys2.ToValidators(power, 0)
    98  
    99  	// make some commits with the first
   100  	for i := 0; i < n1; i++ {
   101  		fcz[i] = makeFullCommit(int64(i), keys1, vals1, vals1, chainID)
   102  	}
   103  
   104  	// update the val set
   105  	fcz[n1] = makeFullCommit(int64(n1), keys1, vals1, vals2, chainID)
   106  
   107  	// make some commits with the new one
   108  	for i := n1 + 1; i < nCommits; i++ {
   109  		fcz[i] = makeFullCommit(int64(i), keys2, vals2, vals2, chainID)
   110  	}
   111  
   112  	// Save everything in the source
   113  	for _, fc := range fcz {
   114  		source.SaveFullCommit(fc)
   115  	}
   116  
   117  	// Initialize a Verifier with the initial state.
   118  	err := trust.SaveFullCommit(fcz[0])
   119  	require.Nil(t, err)
   120  	ver := NewDynamicVerifier(chainID, trust, source)
   121  	ver.SetLogger(log.TestingLogger())
   122  
   123  	// fetch the latest from the source
   124  	_, err = source.LatestFullCommit(chainID, 1, maxHeight)
   125  	require.NoError(t, err)
   126  
   127  	// TODO: Requires proposer address to be set in header.
   128  	// try to update to the latest
   129  	// err = ver.Verify(latestFC.SignedHeader)
   130  	// require.NoError(t, err)
   131  }
   132  
   133  func makeFullCommit(height int64, keys privKeys, vals, nextVals *types.ValidatorSet, chainID string) FullCommit {
   134  	height++
   135  
   136  	consHash := tmhash.Sum([]byte("special-params"))
   137  	appHash := tmhash.Sum([]byte(fmt.Sprintf("h=%d", height)))
   138  	resHash := tmhash.Sum([]byte(fmt.Sprintf("res=%d", height)))
   139  
   140  	return keys.GenFullCommit(
   141  		chainID, height, nil,
   142  		vals, nextVals,
   143  		appHash, consHash, resHash, 0, len(keys),
   144  	)
   145  }
   146  
   147  func TestInquirerVerifyHistorical(t *testing.T) {
   148  	assert, require := assert.New(t), require.New(t)
   149  	trust := NewDBProvider("trust", dbm.NewMemDB())
   150  	source := NewDBProvider("source", dbm.NewMemDB())
   151  
   152  	// Set up the validators to generate test blocks.
   153  	var vote int64 = 10
   154  	keys := genPrivKeys(5)
   155  	nkeys := keys.Extend(1)
   156  
   157  	// Construct a bunch of commits, each with one more height than the last.
   158  	chainID := testChainID
   159  	count := 10
   160  	consHash := []byte("special-params")
   161  	fcz := make([]FullCommit, count)
   162  	for i := 0; i < count; i++ {
   163  		vals := keys.ToValidators(vote, 0)
   164  		nextVals := nkeys.ToValidators(vote, 0)
   165  		h := int64(1 + i)
   166  		appHash := []byte(fmt.Sprintf("h=%d", h))
   167  		resHash := []byte(fmt.Sprintf("res=%d", h))
   168  		fcz[i] = keys.GenFullCommit(
   169  			chainID, h, nil,
   170  			vals, nextVals,
   171  			appHash, consHash, resHash, 0, len(keys))
   172  		// Extend the keys by 1 each time.
   173  		keys = nkeys
   174  		nkeys = nkeys.Extend(1)
   175  	}
   176  
   177  	// Initialize a Verifier with the initial state.
   178  	err := trust.SaveFullCommit(fcz[0])
   179  	require.Nil(err)
   180  	cert := NewDynamicVerifier(chainID, trust, source)
   181  	cert.SetLogger(log.TestingLogger())
   182  
   183  	// Store a few full commits as trust.
   184  	for _, i := range []int{2, 5} {
   185  		trust.SaveFullCommit(fcz[i])
   186  	}
   187  
   188  	// See if we can jump forward using trusted full commits.
   189  	// Souce doesn't have fcz[9] so cert.LastTrustedHeight wont' change.
   190  	err = source.SaveFullCommit(fcz[7])
   191  	require.Nil(err, "%+v", err)
   192  
   193  	// TODO: Requires proposer address to be set in header.
   194  	// sh := fcz[8].SignedHeader
   195  	// err = cert.Verify(sh)
   196  	// require.Nil(err, "%+v", err)
   197  	// assert.Equal(fcz[7].Height(), cert.LastTrustedHeight())
   198  
   199  	commit, err := trust.LatestFullCommit(chainID, fcz[8].Height(), fcz[8].Height())
   200  	require.NotNil(err, "%+v", err)
   201  	assert.Equal(commit, (FullCommit{}))
   202  
   203  	// With fcz[9] Verify will update last trusted height.
   204  	err = source.SaveFullCommit(fcz[9])
   205  	require.Nil(err, "%+v", err)
   206  
   207  	// TODO: Requires proposer address to be set in header.
   208  	// sh = fcz[8].SignedHeader
   209  	// err = cert.Verify(sh)
   210  	// require.Nil(err, "%+v", err)
   211  	// assert.Equal(fcz[8].Height(), cert.LastTrustedHeight())
   212  
   213  	// TODO: Requires proposer address to be set in header.
   214  	// commit, err = trust.LatestFullCommit(chainID, fcz[8].Height(), fcz[8].Height())
   215  	// require.Nil(err, "%+v", err)
   216  	// assert.Equal(commit.Height(), fcz[8].Height())
   217  
   218  	// Add access to all full commits via untrusted source.
   219  	for i := 0; i < count; i++ {
   220  		err := source.SaveFullCommit(fcz[i])
   221  		require.Nil(err)
   222  	}
   223  
   224  	// TODO: Requires proposer address to be set in header.
   225  	// Try to check an unknown seed in the past.
   226  	// sh = fcz[3].SignedHeader
   227  	// err = cert.Verify(sh)
   228  	// require.Nil(err, "%+v", err)
   229  	// assert.Equal(fcz[8].Height(), cert.LastTrustedHeight())
   230  
   231  	// TODO: Requires proposer address to be set in header.
   232  	// Jump all the way forward again.
   233  	// sh = fcz[count-1].SignedHeader
   234  	// err = cert.Verify(sh)
   235  	// require.Nil(err, "%+v", err)
   236  	// assert.Equal(fcz[9].Height(), cert.LastTrustedHeight())
   237  }
   238  
   239  func TestConcurrencyInquirerVerify(t *testing.T) {
   240  	_, require := assert.New(t), require.New(t)
   241  	trust := NewDBProvider("trust", dbm.NewMemDB()).SetLimit(10)
   242  	source := NewDBProvider("source", dbm.NewMemDB())
   243  
   244  	// Set up the validators to generate test blocks.
   245  	var vote int64 = 10
   246  	keys := genPrivKeys(5)
   247  	nkeys := keys.Extend(1)
   248  
   249  	// Construct a bunch of commits, each with one more height than the last.
   250  	chainID := testChainID
   251  	count := 10
   252  	consHash := []byte("special-params")
   253  	fcz := make([]FullCommit, count)
   254  	for i := 0; i < count; i++ {
   255  		vals := keys.ToValidators(vote, 0)
   256  		nextVals := nkeys.ToValidators(vote, 0)
   257  		h := int64(1 + i)
   258  		appHash := []byte(fmt.Sprintf("h=%d", h))
   259  		resHash := []byte(fmt.Sprintf("res=%d", h))
   260  		fcz[i] = keys.GenFullCommit(
   261  			chainID, h, nil,
   262  			vals, nextVals,
   263  			appHash, consHash, resHash, 0, len(keys))
   264  		// Extend the keys by 1 each time.
   265  		keys = nkeys
   266  		nkeys = nkeys.Extend(1)
   267  	}
   268  
   269  	// Initialize a Verifier with the initial state.
   270  	err := trust.SaveFullCommit(fcz[0])
   271  	require.Nil(err)
   272  	cert := NewDynamicVerifier(chainID, trust, source)
   273  	cert.SetLogger(log.TestingLogger())
   274  
   275  	err = source.SaveFullCommit(fcz[7])
   276  	require.Nil(err, "%+v", err)
   277  	err = source.SaveFullCommit(fcz[8])
   278  	require.Nil(err, "%+v", err)
   279  	sh := fcz[8].SignedHeader
   280  
   281  	var wg sync.WaitGroup
   282  	count = 100
   283  	errList := make([]error, count)
   284  
   285  	for i := 0; i < count; i++ {
   286  		wg.Add(1)
   287  		go func(index int) {
   288  			errList[index] = cert.Verify(sh)
   289  			defer wg.Done()
   290  		}(i)
   291  	}
   292  
   293  	wg.Wait()
   294  
   295  	// TODO: Requires proposer address to be set in header.
   296  	// for _, err := range errList {
   297  	// 	require.Nil(err)
   298  	// }
   299  }