github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/protocol/orphan_manage_test.go (about)

     1  package protocol
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/bytom/bytom/protocol/bc"
     8  	"github.com/bytom/bytom/protocol/bc/types"
     9  	"github.com/bytom/bytom/testutil"
    10  )
    11  
    12  var testBlocks = []*types.Block{
    13  	{BlockHeader: types.BlockHeader{
    14  		PreviousBlockHash: bc.Hash{V0: 1},
    15  		Timestamp: 0,
    16  	}},
    17  	{BlockHeader: types.BlockHeader{
    18  		PreviousBlockHash: bc.Hash{V0: 1},
    19  		Timestamp: 1,
    20  	}},
    21  	{BlockHeader: types.BlockHeader{
    22  		PreviousBlockHash: bc.Hash{V0: 2},
    23  		Timestamp: 3,
    24  	}},
    25  }
    26  
    27  var blockHashes = []bc.Hash{}
    28  
    29  func init() {
    30  	for _, block := range testBlocks {
    31  		blockHashes = append(blockHashes, block.Hash())
    32  	}
    33  }
    34  
    35  func TestDeleteLRU(t *testing.T) {
    36  	now := time.Now()
    37  	cases := []struct {
    38  		before *OrphanManage
    39  		after  *OrphanManage
    40  	}{
    41  		{
    42  			before: &OrphanManage{
    43  				orphan: map[bc.Hash]*OrphanBlock{
    44  					blockHashes[0]: {testBlocks[0], now},
    45  				},
    46  				prevOrphans: map[bc.Hash][]*bc.Hash{
    47  					{V0: 1}: {&blockHashes[0]},
    48  				},
    49  			},
    50  			after: &OrphanManage{
    51  				orphan:      map[bc.Hash]*OrphanBlock{},
    52  				prevOrphans: map[bc.Hash][]*bc.Hash{},
    53  			},
    54  		},
    55  		{
    56  			before: &OrphanManage{
    57  				orphan:      map[bc.Hash]*OrphanBlock{},
    58  				prevOrphans: map[bc.Hash][]*bc.Hash{},
    59  			},
    60  			after: &OrphanManage{
    61  				orphan:      map[bc.Hash]*OrphanBlock{},
    62  				prevOrphans: map[bc.Hash][]*bc.Hash{},
    63  			},
    64  		},
    65  		{
    66  			before: &OrphanManage{
    67  				orphan: map[bc.Hash]*OrphanBlock{
    68  					blockHashes[0]: {testBlocks[0], now.Add(2)},
    69  					blockHashes[1]: {testBlocks[1], now.Add(1)},
    70  				},
    71  				prevOrphans: map[bc.Hash][]*bc.Hash{
    72  					{V0: 1}: {&blockHashes[0], &blockHashes[1]},
    73  				},
    74  			},
    75  			after: &OrphanManage{
    76  				orphan: map[bc.Hash]*OrphanBlock{
    77  					blockHashes[0]: {testBlocks[0], now.Add(2)},
    78  				},
    79  				prevOrphans: map[bc.Hash][]*bc.Hash{
    80  					{V0: 1}: {&blockHashes[0]},
    81  				},
    82  			},
    83  		},
    84  	}
    85  
    86  	for i, c := range cases {
    87  		c.before.deleteLRU()
    88  		if !testutil.DeepEqual(c.before, c.after) {
    89  			t.Errorf("case %d:\n got %v\n want %v", i, c.before, c.after)
    90  		}
    91  	}
    92  }
    93  
    94  func TestOrphanManageAdd(t *testing.T) {
    95  	cases := []struct {
    96  		before    *OrphanManage
    97  		after     *OrphanManage
    98  		addOrphan *types.Block
    99  	}{
   100  		{
   101  			before: &OrphanManage{
   102  				orphan:      map[bc.Hash]*OrphanBlock{},
   103  				prevOrphans: map[bc.Hash][]*bc.Hash{},
   104  			},
   105  			after: &OrphanManage{
   106  				orphan: map[bc.Hash]*OrphanBlock{
   107  					blockHashes[0]: {testBlocks[0], time.Time{}},
   108  				},
   109  				prevOrphans: map[bc.Hash][]*bc.Hash{
   110  					{V0: 1}: {&blockHashes[0]},
   111  				},
   112  			},
   113  			addOrphan: testBlocks[0],
   114  		},
   115  		{
   116  			before: &OrphanManage{
   117  				orphan: map[bc.Hash]*OrphanBlock{
   118  					blockHashes[0]: {testBlocks[0], time.Time{}},
   119  				},
   120  				prevOrphans: map[bc.Hash][]*bc.Hash{
   121  					{V0: 1}: {&blockHashes[0]},
   122  				},
   123  			},
   124  			after: &OrphanManage{
   125  				orphan: map[bc.Hash]*OrphanBlock{
   126  					blockHashes[0]: {testBlocks[0], time.Time{}},
   127  				},
   128  				prevOrphans: map[bc.Hash][]*bc.Hash{
   129  					{V0: 1}: {&blockHashes[0]},
   130  				},
   131  			},
   132  			addOrphan: testBlocks[0],
   133  		},
   134  		{
   135  			before: &OrphanManage{
   136  				orphan: map[bc.Hash]*OrphanBlock{
   137  					blockHashes[0]: {testBlocks[0], time.Time{}},
   138  				},
   139  				prevOrphans: map[bc.Hash][]*bc.Hash{
   140  					{V0: 1}: {&blockHashes[0]},
   141  				},
   142  			},
   143  			after: &OrphanManage{
   144  				orphan: map[bc.Hash]*OrphanBlock{
   145  					blockHashes[0]: {testBlocks[0], time.Time{}},
   146  					blockHashes[1]: {testBlocks[1], time.Time{}},
   147  				},
   148  				prevOrphans: map[bc.Hash][]*bc.Hash{
   149  					{V0: 1}: {&blockHashes[0], &blockHashes[1]},
   150  				},
   151  			},
   152  			addOrphan: testBlocks[1],
   153  		},
   154  		{
   155  			before: &OrphanManage{
   156  				orphan: map[bc.Hash]*OrphanBlock{
   157  					blockHashes[0]: {testBlocks[0], time.Time{}},
   158  				},
   159  				prevOrphans: map[bc.Hash][]*bc.Hash{
   160  					{V0: 1}: {&blockHashes[0]},
   161  				},
   162  			},
   163  			after: &OrphanManage{
   164  				orphan: map[bc.Hash]*OrphanBlock{
   165  					blockHashes[0]: {testBlocks[0], time.Time{}},
   166  					blockHashes[2]: {testBlocks[2], time.Time{}},
   167  				},
   168  				prevOrphans: map[bc.Hash][]*bc.Hash{
   169  					{V0: 1}: {&blockHashes[0]},
   170  					{V0: 2}: {&blockHashes[2]},
   171  				},
   172  			},
   173  			addOrphan: testBlocks[2],
   174  		},
   175  	}
   176  
   177  	for i, c := range cases {
   178  		c.before.Add(c.addOrphan)
   179  		for _, orphan := range c.before.orphan {
   180  			orphan.expiration = time.Time{}
   181  		}
   182  		if !testutil.DeepEqual(c.before, c.after) {
   183  			t.Errorf("case %d: got %v want %v", i, c.before, c.after)
   184  		}
   185  	}
   186  }
   187  
   188  func TestOrphanManageDelete(t *testing.T) {
   189  	cases := []struct {
   190  		before *OrphanManage
   191  		after  *OrphanManage
   192  		remove *bc.Hash
   193  	}{
   194  		{
   195  			before: &OrphanManage{
   196  				orphan: map[bc.Hash]*OrphanBlock{
   197  					blockHashes[0]: {testBlocks[0], time.Time{}},
   198  				},
   199  				prevOrphans: map[bc.Hash][]*bc.Hash{
   200  					{V0: 1}: {&blockHashes[0]},
   201  				},
   202  			},
   203  			after: &OrphanManage{
   204  				orphan: map[bc.Hash]*OrphanBlock{
   205  					blockHashes[0]: {testBlocks[0], time.Time{}},
   206  				},
   207  				prevOrphans: map[bc.Hash][]*bc.Hash{
   208  					{V0: 1}: {&blockHashes[0]},
   209  				},
   210  			},
   211  			remove: &blockHashes[1],
   212  		},
   213  		{
   214  			before: &OrphanManage{
   215  				orphan: map[bc.Hash]*OrphanBlock{
   216  					blockHashes[0]: {testBlocks[0], time.Time{}},
   217  				},
   218  				prevOrphans: map[bc.Hash][]*bc.Hash{
   219  					{V0: 1}: {&blockHashes[0]},
   220  				},
   221  			},
   222  			after: &OrphanManage{
   223  				orphan:      map[bc.Hash]*OrphanBlock{},
   224  				prevOrphans: map[bc.Hash][]*bc.Hash{},
   225  			},
   226  			remove: &blockHashes[0],
   227  		},
   228  		{
   229  			before: &OrphanManage{
   230  				orphan: map[bc.Hash]*OrphanBlock{
   231  					blockHashes[0]: {testBlocks[0], time.Time{}},
   232  					blockHashes[1]: {testBlocks[1], time.Time{}},
   233  				},
   234  				prevOrphans: map[bc.Hash][]*bc.Hash{
   235  					{V0: 1}: {&blockHashes[0], &blockHashes[1]},
   236  				},
   237  			},
   238  			after: &OrphanManage{
   239  				orphan: map[bc.Hash]*OrphanBlock{
   240  					blockHashes[0]: {testBlocks[0], time.Time{}},
   241  				},
   242  				prevOrphans: map[bc.Hash][]*bc.Hash{
   243  					{V0: 1}: {&blockHashes[0]},
   244  				},
   245  			},
   246  			remove: &blockHashes[1],
   247  		},
   248  	}
   249  
   250  	for i, c := range cases {
   251  		c.before.delete(c.remove)
   252  		if !testutil.DeepEqual(c.before, c.after) {
   253  			t.Errorf("case %d: got %v want %v", i, c.before, c.after)
   254  		}
   255  	}
   256  }
   257  
   258  func TestOrphanManageExpire(t *testing.T) {
   259  	cases := []struct {
   260  		before *OrphanManage
   261  		after  *OrphanManage
   262  	}{
   263  		{
   264  			before: &OrphanManage{
   265  				orphan: map[bc.Hash]*OrphanBlock{
   266  					blockHashes[0]: {
   267  						testBlocks[0],
   268  						time.Unix(1633479700, 0),
   269  					},
   270  				},
   271  				prevOrphans: map[bc.Hash][]*bc.Hash{
   272  					{V0: 1}: {&blockHashes[0]},
   273  				},
   274  			},
   275  			after: &OrphanManage{
   276  				orphan:      map[bc.Hash]*OrphanBlock{},
   277  				prevOrphans: map[bc.Hash][]*bc.Hash{},
   278  			},
   279  		},
   280  		{
   281  			before: &OrphanManage{
   282  				orphan: map[bc.Hash]*OrphanBlock{
   283  					blockHashes[0]: {
   284  						testBlocks[0],
   285  						time.Unix(1633479702, 0),
   286  					},
   287  				},
   288  				prevOrphans: map[bc.Hash][]*bc.Hash{
   289  					{V0: 1}: {&blockHashes[0]},
   290  				},
   291  			},
   292  			after: &OrphanManage{
   293  				orphan: map[bc.Hash]*OrphanBlock{
   294  					blockHashes[0]: {
   295  						testBlocks[0],
   296  						time.Unix(1633479702, 0),
   297  					},
   298  				},
   299  				prevOrphans: map[bc.Hash][]*bc.Hash{
   300  					{V0: 1}: {&blockHashes[0]},
   301  				},
   302  			},
   303  		},
   304  	}
   305  
   306  	for i, c := range cases {
   307  		c.before.orphanExpire(time.Unix(1633479701, 0))
   308  		if !testutil.DeepEqual(c.before, c.after) {
   309  			t.Errorf("case %d: got %v want %v", i, c.before, c.after)
   310  		}
   311  	}
   312  }
   313  
   314  func TestOrphanManageNumLimit(t *testing.T) {
   315  	cases := []struct {
   316  		addOrphanBlockNum    int
   317  		expectOrphanBlockNum int
   318  	}{
   319  		{
   320  			addOrphanBlockNum:    10,
   321  			expectOrphanBlockNum: 10,
   322  		},
   323  		{
   324  			addOrphanBlockNum:    numOrphanBlockLimit,
   325  			expectOrphanBlockNum: numOrphanBlockLimit,
   326  		},
   327  		{
   328  			addOrphanBlockNum:    numOrphanBlockLimit + 1,
   329  			expectOrphanBlockNum: numOrphanBlockLimit,
   330  		},
   331  		{
   332  			addOrphanBlockNum:    numOrphanBlockLimit + 10,
   333  			expectOrphanBlockNum: numOrphanBlockLimit,
   334  		},
   335  	}
   336  
   337  	for i, c := range cases {
   338  		orphanManage := &OrphanManage{
   339  			orphan:      map[bc.Hash]*OrphanBlock{},
   340  			prevOrphans: map[bc.Hash][]*bc.Hash{},
   341  		}
   342  		for num := 0; num < c.addOrphanBlockNum; num++ {
   343  			orphanManage.Add(&types.Block{BlockHeader: types.BlockHeader{Height: uint64(num)}})
   344  		}
   345  		if len(orphanManage.orphan) != c.expectOrphanBlockNum {
   346  			t.Errorf("case %d: got %d want %d", i, len(orphanManage.orphan), c.expectOrphanBlockNum)
   347  		}
   348  	}
   349  }