github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/spanlatch/manager_test.go (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package spanlatch
    12  
    13  import (
    14  	"bytes"
    15  	"context"
    16  	"fmt"
    17  	"math/rand"
    18  	"strings"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/cockroachdb/cockroach/pkg/keys"
    23  	"github.com/cockroachdb/cockroach/pkg/kv/kvserver/spanset"
    24  	"github.com/cockroachdb/cockroach/pkg/roachpb"
    25  	"github.com/cockroachdb/cockroach/pkg/testutils"
    26  	"github.com/cockroachdb/cockroach/pkg/util/hlc"
    27  	"github.com/cockroachdb/cockroach/pkg/util/leaktest"
    28  	"github.com/stretchr/testify/require"
    29  )
    30  
    31  var read = false
    32  var write = true
    33  var zeroTS = hlc.Timestamp{}
    34  
    35  func spans(from, to string, write bool, ts hlc.Timestamp) *spanset.SpanSet {
    36  	var spanSet spanset.SpanSet
    37  	add(&spanSet, from, to, write, ts)
    38  	return &spanSet
    39  }
    40  
    41  func add(spanSet *spanset.SpanSet, from, to string, write bool, ts hlc.Timestamp) {
    42  	var start, end roachpb.Key
    43  	if to == "" {
    44  		start = roachpb.Key(from)
    45  	} else {
    46  		start = roachpb.Key(from)
    47  		end = roachpb.Key(to)
    48  	}
    49  	if strings.HasPrefix(from, "local") {
    50  		start = append(keys.LocalRangePrefix, start...)
    51  		if end != nil {
    52  			end = append(keys.LocalRangePrefix, end...)
    53  		}
    54  	}
    55  	access := spanset.SpanReadOnly
    56  	if write {
    57  		access = spanset.SpanReadWrite
    58  	}
    59  
    60  	if strings.HasPrefix(from, "local") {
    61  		spanSet.AddNonMVCC(access, roachpb.Span{Key: start, EndKey: end})
    62  	} else {
    63  		spanSet.AddMVCC(access, roachpb.Span{Key: start, EndKey: end}, ts)
    64  	}
    65  }
    66  
    67  func testLatchSucceeds(t *testing.T, lgC <-chan *Guard) *Guard {
    68  	t.Helper()
    69  	select {
    70  	case lg := <-lgC:
    71  		return lg
    72  	case <-time.After(testutils.DefaultSucceedsSoonDuration):
    73  		// False positives are not ok, so we use a more
    74  		// conservative timeout than in testLatchBlocks.
    75  		t.Fatal("latch acquisition should succeed")
    76  	}
    77  	return nil
    78  }
    79  
    80  func testLatchBlocks(t *testing.T, lgC <-chan *Guard) {
    81  	t.Helper()
    82  	select {
    83  	case <-lgC:
    84  		t.Fatal("latch acquisition should block")
    85  	case <-time.After(3 * time.Millisecond):
    86  		// False positives are ok as long as they are rare, so we
    87  		// use an aggressive timeout to avoid slowing down tests.
    88  	}
    89  }
    90  
    91  // MustAcquire is like Acquire, except it can't return context cancellation
    92  // errors.
    93  func (m *Manager) MustAcquire(spans *spanset.SpanSet) *Guard {
    94  	lg, err := m.Acquire(context.Background(), spans)
    95  	if err != nil {
    96  		panic(err)
    97  	}
    98  	return lg
    99  }
   100  
   101  // MustAcquireCh is like Acquire, except it only sequences the latch latch
   102  // attempt synchronously and waits on dependent latches asynchronously. It
   103  // returns a channel that provides the Guard when the latches are acquired (i.e.
   104  // after waiting). If the context expires, a nil Guard will be delivered on the
   105  // channel.
   106  func (m *Manager) MustAcquireCh(spans *spanset.SpanSet) <-chan *Guard {
   107  	return m.MustAcquireChCtx(context.Background(), spans)
   108  }
   109  
   110  // MustAcquireChCtx is like MustAcquireCh, except it accepts a context.
   111  func (m *Manager) MustAcquireChCtx(ctx context.Context, spans *spanset.SpanSet) <-chan *Guard {
   112  	ch := make(chan *Guard)
   113  	lg, snap := m.sequence(spans)
   114  	go func() {
   115  		err := m.wait(ctx, lg, snap)
   116  		if err != nil {
   117  			m.Release(lg)
   118  			lg = nil
   119  		}
   120  		ch <- lg
   121  	}()
   122  	return ch
   123  }
   124  
   125  func TestLatchManager(t *testing.T) {
   126  	defer leaktest.AfterTest(t)()
   127  	var m Manager
   128  
   129  	// Try latches with no overlapping already-acquired latches.
   130  	lg1 := m.MustAcquire(spans("a", "", write, zeroTS))
   131  	m.Release(lg1)
   132  
   133  	lg2 := m.MustAcquire(spans("a", "b", write, zeroTS))
   134  	m.Release(lg2)
   135  
   136  	// Add a latch and verify overlapping latches wait on it.
   137  	lg3 := m.MustAcquire(spans("a", "b", write, zeroTS))
   138  	lg4C := m.MustAcquireCh(spans("a", "b", write, zeroTS))
   139  
   140  	// Second write should block.
   141  	testLatchBlocks(t, lg4C)
   142  
   143  	// First write completes, second grabs latch.
   144  	m.Release(lg3)
   145  	testLatchSucceeds(t, lg4C)
   146  }
   147  
   148  func TestLatchManagerAcquireOverlappingSpans(t *testing.T) {
   149  	defer leaktest.AfterTest(t)()
   150  	var m Manager
   151  
   152  	// Acquire overlapping latches with different access patterns.
   153  	//    |----------|        <- Read latch [a-c)@t1
   154  	//        |----------|    <- Write latch [b-d)@t1
   155  	//
   156  	//    ^   ^      ^   ^
   157  	//    |   |      |   |
   158  	//    a   b      c   d
   159  	//
   160  	var ts0, ts1 = hlc.Timestamp{WallTime: 0}, hlc.Timestamp{WallTime: 1}
   161  	var spanSet spanset.SpanSet
   162  	add(&spanSet, "a", "c", read, ts1)
   163  	add(&spanSet, "b", "d", write, ts1)
   164  	lg1 := m.MustAcquire(&spanSet)
   165  
   166  	lg2C := m.MustAcquireCh(spans("a", "b", read, ts0))
   167  	lg2 := testLatchSucceeds(t, lg2C)
   168  	m.Release(lg2)
   169  
   170  	// We acquire reads at lower timestamps than writes to check for blocked
   171  	// acquisitions based on the original latch, not the latches declared in
   172  	// earlier test cases.
   173  	var latchCs []<-chan *Guard
   174  	latchCs = append(latchCs, m.MustAcquireCh(spans("a", "b", write, ts1)))
   175  	latchCs = append(latchCs, m.MustAcquireCh(spans("b", "c", read, ts0)))
   176  	latchCs = append(latchCs, m.MustAcquireCh(spans("b", "c", write, ts1)))
   177  	latchCs = append(latchCs, m.MustAcquireCh(spans("c", "d", write, ts1)))
   178  	latchCs = append(latchCs, m.MustAcquireCh(spans("c", "d", read, ts0)))
   179  
   180  	for _, lgC := range latchCs {
   181  		testLatchBlocks(t, lgC)
   182  	}
   183  
   184  	m.Release(lg1)
   185  
   186  	for _, lgC := range latchCs {
   187  		lg := testLatchSucceeds(t, lgC)
   188  		m.Release(lg)
   189  	}
   190  }
   191  
   192  func TestLatchManagerAcquiringReadsVaryingTimestamps(t *testing.T) {
   193  	defer leaktest.AfterTest(t)()
   194  	var m Manager
   195  
   196  	var ts0, ts1 = hlc.Timestamp{WallTime: 0}, hlc.Timestamp{WallTime: 1}
   197  	var spanSet spanset.SpanSet
   198  	add(&spanSet, "a", "", read, ts0)
   199  	add(&spanSet, "a", "", read, ts1)
   200  	lg1 := m.MustAcquire(&spanSet)
   201  
   202  	for _, walltime := range []int64{0, 1, 2} {
   203  		ts := hlc.Timestamp{WallTime: walltime}
   204  		lg := testLatchSucceeds(t, m.MustAcquireCh(spans("a", "", read, ts)))
   205  		m.Release(lg)
   206  	}
   207  
   208  	var latchCs []<-chan *Guard
   209  	for _, walltime := range []int64{0, 1, 2} {
   210  		ts := hlc.Timestamp{WallTime: walltime}
   211  		latchCs = append(latchCs, m.MustAcquireCh(spans("a", "", write, ts)))
   212  	}
   213  
   214  	for _, lgC := range latchCs {
   215  		testLatchBlocks(t, lgC)
   216  	}
   217  
   218  	m.Release(lg1)
   219  
   220  	for _, lgC := range latchCs {
   221  		lg := testLatchSucceeds(t, lgC)
   222  		m.Release(lg)
   223  	}
   224  }
   225  
   226  func TestLatchManagerNoWaitOnReadOnly(t *testing.T) {
   227  	defer leaktest.AfterTest(t)()
   228  	var m Manager
   229  
   230  	// Acquire latch for read-only span.
   231  	m.MustAcquire(spans("a", "", read, zeroTS))
   232  
   233  	// Verify no wait with another read-only span.
   234  	m.MustAcquire(spans("a", "", read, zeroTS))
   235  }
   236  
   237  func TestLatchManagerWriteWaitForMultipleReads(t *testing.T) {
   238  	defer leaktest.AfterTest(t)()
   239  	var m Manager
   240  
   241  	// Acquire latch for read-only span.
   242  	lg1 := m.MustAcquire(spans("a", "", read, zeroTS))
   243  	// Acquire another one on top.
   244  	lg2 := m.MustAcquire(spans("a", "", read, zeroTS))
   245  
   246  	// A write span should have to wait for **both** reads.
   247  	lg3C := m.MustAcquireCh(spans("a", "", write, zeroTS))
   248  
   249  	// Certainly blocks now.
   250  	testLatchBlocks(t, lg3C)
   251  
   252  	// The second read releases latch, but the first one remains.
   253  	m.Release(lg2)
   254  
   255  	// Should still block.
   256  	testLatchBlocks(t, lg3C)
   257  
   258  	// First read releases latch.
   259  	m.Release(lg1)
   260  
   261  	// Now it goes through.
   262  	testLatchSucceeds(t, lg3C)
   263  }
   264  
   265  func TestLatchManagerMultipleOverlappingLatches(t *testing.T) {
   266  	defer leaktest.AfterTest(t)()
   267  	var m Manager
   268  
   269  	// Acquire multiple latches.
   270  	lg1C := m.MustAcquireCh(spans("a", "", write, zeroTS))
   271  	lg2C := m.MustAcquireCh(spans("b", "c", write, zeroTS))
   272  	lg3C := m.MustAcquireCh(spans("a", "d", write, zeroTS))
   273  
   274  	// Attempt to acquire latch which overlaps them all.
   275  	lg4C := m.MustAcquireCh(spans("0", "z", write, zeroTS))
   276  	testLatchBlocks(t, lg4C)
   277  	m.Release(<-lg1C)
   278  	testLatchBlocks(t, lg4C)
   279  	m.Release(<-lg2C)
   280  	testLatchBlocks(t, lg4C)
   281  	m.Release(<-lg3C)
   282  	testLatchSucceeds(t, lg4C)
   283  }
   284  
   285  func TestLatchManagerMultipleOverlappingSpans(t *testing.T) {
   286  	defer leaktest.AfterTest(t)()
   287  	var m Manager
   288  
   289  	// Acquire multiple latches.
   290  	lg1 := m.MustAcquire(spans("a", "", write, zeroTS))
   291  	lg2 := m.MustAcquire(spans("b", "c", read, zeroTS))
   292  	lg3 := m.MustAcquire(spans("d", "f", write, zeroTS))
   293  	lg4 := m.MustAcquire(spans("g", "", write, zeroTS))
   294  
   295  	// Attempt to acquire latches overlapping each of them.
   296  	var spans spanset.SpanSet
   297  	spans.AddNonMVCC(spanset.SpanReadWrite, roachpb.Span{Key: roachpb.Key("a")})
   298  	spans.AddNonMVCC(spanset.SpanReadWrite, roachpb.Span{Key: roachpb.Key("b")})
   299  	spans.AddNonMVCC(spanset.SpanReadWrite, roachpb.Span{Key: roachpb.Key("e")})
   300  	lg5C := m.MustAcquireCh(&spans)
   301  
   302  	// Blocks until the first three prerequisite latches release.
   303  	testLatchBlocks(t, lg5C)
   304  	m.Release(lg2)
   305  	testLatchBlocks(t, lg5C)
   306  	m.Release(lg3)
   307  	testLatchBlocks(t, lg5C)
   308  	m.Release(lg1)
   309  	lg5 := testLatchSucceeds(t, lg5C)
   310  	m.Release(lg4)
   311  	m.Release(lg5)
   312  }
   313  
   314  func TestLatchManagerDependentLatches(t *testing.T) {
   315  	defer leaktest.AfterTest(t)()
   316  
   317  	cases := []struct {
   318  		name      string
   319  		sp1       *spanset.SpanSet
   320  		sp2       *spanset.SpanSet
   321  		dependent bool
   322  	}{
   323  		{
   324  			name:      "point writes, same key",
   325  			sp1:       spans("a", "", write, zeroTS),
   326  			sp2:       spans("a", "", write, zeroTS),
   327  			dependent: true,
   328  		},
   329  		{
   330  			name:      "point writes, different key",
   331  			sp1:       spans("a", "", write, zeroTS),
   332  			sp2:       spans("b", "", write, zeroTS),
   333  			dependent: false,
   334  		},
   335  		{
   336  			name:      "range writes, overlapping span",
   337  			sp1:       spans("a", "c", write, zeroTS),
   338  			sp2:       spans("b", "d", write, zeroTS),
   339  			dependent: true,
   340  		},
   341  		{
   342  			name:      "range writes, non-overlapping span",
   343  			sp1:       spans("a", "b", write, zeroTS),
   344  			sp2:       spans("b", "c", write, zeroTS),
   345  			dependent: false,
   346  		},
   347  		{
   348  			name:      "point reads, same key",
   349  			sp1:       spans("a", "", read, zeroTS),
   350  			sp2:       spans("a", "", read, zeroTS),
   351  			dependent: false,
   352  		},
   353  		{
   354  			name:      "point reads, different key",
   355  			sp1:       spans("a", "", read, zeroTS),
   356  			sp2:       spans("b", "", read, zeroTS),
   357  			dependent: false,
   358  		},
   359  		{
   360  			name:      "range reads, overlapping span",
   361  			sp1:       spans("a", "c", read, zeroTS),
   362  			sp2:       spans("b", "d", read, zeroTS),
   363  			dependent: false,
   364  		},
   365  		{
   366  			name:      "range reads, non-overlapping span",
   367  			sp1:       spans("a", "b", read, zeroTS),
   368  			sp2:       spans("b", "c", read, zeroTS),
   369  			dependent: false,
   370  		},
   371  		{
   372  			name:      "read and write, same ts",
   373  			sp1:       spans("a", "", write, hlc.Timestamp{WallTime: 1}),
   374  			sp2:       spans("a", "", read, hlc.Timestamp{WallTime: 1}),
   375  			dependent: true,
   376  		},
   377  		{
   378  			name:      "read and write, causal ts",
   379  			sp1:       spans("a", "", write, hlc.Timestamp{WallTime: 1}),
   380  			sp2:       spans("a", "", read, hlc.Timestamp{WallTime: 2}),
   381  			dependent: true,
   382  		},
   383  		{
   384  			name:      "read and write, non-causal ts",
   385  			sp1:       spans("a", "", write, hlc.Timestamp{WallTime: 2}),
   386  			sp2:       spans("a", "", read, hlc.Timestamp{WallTime: 1}),
   387  			dependent: false,
   388  		},
   389  		{
   390  			name:      "read and write, zero ts read",
   391  			sp1:       spans("a", "", write, hlc.Timestamp{WallTime: 1}),
   392  			sp2:       spans("a", "", read, hlc.Timestamp{WallTime: 0}),
   393  			dependent: true,
   394  		},
   395  		{
   396  			name:      "point reads, different ts",
   397  			sp1:       spans("a", "", read, hlc.Timestamp{WallTime: 1}),
   398  			sp2:       spans("a", "", read, hlc.Timestamp{WallTime: 0}),
   399  			dependent: false,
   400  		},
   401  		{
   402  			name:      "read and write, zero ts write",
   403  			sp1:       spans("a", "", write, hlc.Timestamp{WallTime: 0}),
   404  			sp2:       spans("a", "", read, hlc.Timestamp{WallTime: 1}),
   405  			dependent: true,
   406  		},
   407  		{
   408  			name:      "read and write, non-overlapping",
   409  			sp1:       spans("a", "b", write, zeroTS),
   410  			sp2:       spans("b", "", read, zeroTS),
   411  			dependent: false,
   412  		},
   413  		{
   414  			name:      "local range writes, overlapping span",
   415  			sp1:       spans("local a", "local c", write, zeroTS),
   416  			sp2:       spans("local b", "local d", write, zeroTS),
   417  			dependent: true,
   418  		},
   419  		{
   420  			name:      "local range writes, non-overlapping span",
   421  			sp1:       spans("local a", "local b", write, zeroTS),
   422  			sp2:       spans("local b", "local c", write, zeroTS),
   423  			dependent: false,
   424  		},
   425  		{
   426  			name:      "local range reads, overlapping span",
   427  			sp1:       spans("local a", "local c", read, zeroTS),
   428  			sp2:       spans("local b", "local d", read, zeroTS),
   429  			dependent: false,
   430  		},
   431  		{
   432  			name:      "local range reads, non-overlapping span",
   433  			sp1:       spans("local a", "local b", read, zeroTS),
   434  			sp2:       spans("local b", "local c", read, zeroTS),
   435  			dependent: false,
   436  		},
   437  		{
   438  			name:      "local read and write, same ts",
   439  			sp1:       spans("local a", "", write, hlc.Timestamp{WallTime: 1}),
   440  			sp2:       spans("local a", "", read, hlc.Timestamp{WallTime: 1}),
   441  			dependent: true,
   442  		},
   443  		{
   444  			name:      "local read and write, causal ts",
   445  			sp1:       spans("local a", "", write, hlc.Timestamp{WallTime: 1}),
   446  			sp2:       spans("local a", "", read, hlc.Timestamp{WallTime: 2}),
   447  			dependent: true,
   448  		},
   449  		{
   450  			name:      "local read and write, non-causal ts",
   451  			sp1:       spans("local a", "", write, hlc.Timestamp{WallTime: 2}),
   452  			sp2:       spans("local a", "", read, hlc.Timestamp{WallTime: 1}),
   453  			dependent: true,
   454  		},
   455  		{
   456  			name:      "local read and write, zero ts read",
   457  			sp1:       spans("local a", "", write, hlc.Timestamp{WallTime: 1}),
   458  			sp2:       spans("local a", "", read, hlc.Timestamp{WallTime: 0}),
   459  			dependent: true,
   460  		},
   461  		{
   462  			name:      "local read and write, zero ts write",
   463  			sp1:       spans("local a", "", write, hlc.Timestamp{WallTime: 0}),
   464  			sp2:       spans("local a", "", read, hlc.Timestamp{WallTime: 1}),
   465  			dependent: true,
   466  		},
   467  		{
   468  			name:      "local read and write, non-overlapping",
   469  			sp1:       spans("a", "b", write, zeroTS),
   470  			sp2:       spans("b", "", read, zeroTS),
   471  			dependent: false,
   472  		},
   473  		{
   474  			name:      "local read and global write, overlapping",
   475  			sp1:       spans("a", "b", write, zeroTS),
   476  			sp2:       spans("local b", "", read, zeroTS),
   477  			dependent: false,
   478  		},
   479  		{
   480  			name:      "local write and global read, overlapping",
   481  			sp1:       spans("local a", "local b", write, zeroTS),
   482  			sp2:       spans("b", "", read, zeroTS),
   483  			dependent: false,
   484  		},
   485  	}
   486  	for _, c := range cases {
   487  		t.Run(c.name, func(t *testing.T) {
   488  			testutils.RunTrueAndFalse(t, "inv", func(t *testing.T, inv bool) {
   489  				c := c
   490  				if inv {
   491  					c.sp1, c.sp2 = c.sp2, c.sp1
   492  				}
   493  
   494  				var m Manager
   495  				lg1 := m.MustAcquire(c.sp1)
   496  				lg2C := m.MustAcquireCh(c.sp2)
   497  				if c.dependent {
   498  					testLatchBlocks(t, lg2C)
   499  					m.Release(lg1)
   500  					lg2 := testLatchSucceeds(t, lg2C)
   501  					m.Release(lg2)
   502  				} else {
   503  					lg2 := testLatchSucceeds(t, lg2C)
   504  					m.Release(lg1)
   505  					m.Release(lg2)
   506  				}
   507  			})
   508  		})
   509  	}
   510  }
   511  
   512  func TestLatchManagerContextCancellation(t *testing.T) {
   513  	defer leaktest.AfterTest(t)()
   514  	var m Manager
   515  
   516  	// Attempt to acquire three latches that all block on each other.
   517  	lg1 := m.MustAcquire(spans("a", "", write, zeroTS))
   518  	// The second one is given a cancelable context.
   519  	ctx2, cancel2 := context.WithCancel(context.Background())
   520  	lg2C := m.MustAcquireChCtx(ctx2, spans("a", "", write, zeroTS))
   521  	lg3C := m.MustAcquireCh(spans("a", "", write, zeroTS))
   522  
   523  	// The second and third latch attempt block on the first.
   524  	testLatchBlocks(t, lg2C)
   525  	testLatchBlocks(t, lg3C)
   526  
   527  	// Cancel the second acquisition's context. It should stop waiting.
   528  	cancel2()
   529  	require.Nil(t, <-lg2C)
   530  
   531  	// The third latch attempt still blocks.
   532  	testLatchBlocks(t, lg3C)
   533  
   534  	// Release the first latch. The third succeeds in acquiring the latch.
   535  	m.Release(lg1)
   536  	testLatchSucceeds(t, lg3C)
   537  }
   538  
   539  func BenchmarkLatchManagerReadOnlyMix(b *testing.B) {
   540  	for _, size := range []int{1, 4, 16, 64, 128, 256} {
   541  		b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) {
   542  			var m Manager
   543  			ss := spans("a", "b", read, zeroTS)
   544  			for i := 0; i < size; i++ {
   545  				_ = m.MustAcquire(ss)
   546  			}
   547  
   548  			b.ResetTimer()
   549  			for i := 0; i < b.N; i++ {
   550  				_ = m.MustAcquire(ss)
   551  			}
   552  		})
   553  	}
   554  }
   555  
   556  func BenchmarkLatchManagerReadWriteMix(b *testing.B) {
   557  	for _, readsPerWrite := range []int{0, 1, 4, 16, 64, 128, 256} {
   558  		b.Run(fmt.Sprintf("readsPerWrite=%d", readsPerWrite), func(b *testing.B) {
   559  			var m Manager
   560  			lgBuf := make(chan *Guard, 16)
   561  
   562  			spans := make([]spanset.SpanSet, b.N)
   563  			for i := range spans {
   564  				a, b := randBytes(100), randBytes(100)
   565  				// Overwrite first byte so that we do not mix local and global ranges
   566  				a[0], b[0] = 'a', 'a'
   567  				if bytes.Compare(a, b) > 0 {
   568  					a, b = b, a
   569  				}
   570  				span := roachpb.Span{Key: a, EndKey: b}
   571  				access := spanset.SpanReadOnly
   572  				if i%(readsPerWrite+1) == 0 {
   573  					access = spanset.SpanReadWrite
   574  				}
   575  				spans[i].AddNonMVCC(access, span)
   576  			}
   577  
   578  			b.ResetTimer()
   579  			for i := range spans {
   580  				lg, snap := m.sequence(&spans[i])
   581  				snap.close()
   582  				if len(lgBuf) == cap(lgBuf) {
   583  					m.Release(<-lgBuf)
   584  				}
   585  				lgBuf <- lg
   586  			}
   587  		})
   588  	}
   589  }
   590  
   591  func randBytes(n int) []byte {
   592  	b := make([]byte, n)
   593  	_, err := rand.Read(b)
   594  	if err != nil {
   595  		panic(err)
   596  	}
   597  	return b
   598  }