github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/evm/watcher/watcher_encoder_test.go (about)

     1  package watcher
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math"
     7  	"testing"
     8  
     9  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    10  	"github.com/fibonacci-chain/fbc/x/evm/types"
    11  	jsoniter "github.com/json-iterator/go"
    12  	"github.com/stretchr/testify/require"
    13  	"github.com/tendermint/go-amino"
    14  )
    15  
    16  var (
    17  	testAccAddr1 = sdk.AccAddress("0x01")
    18  	testAccAddr2 = sdk.AccAddress("0x02")
    19  )
    20  var (
    21  	jsonEnc = jsoniter.ConfigCompatibleWithStandardLibrary
    22  	cdc     = amino.NewCodec()
    23  )
    24  
    25  var testWatchData = []*WatchData{
    26  	{},
    27  	{
    28  		DirtyAccount:  []*sdk.AccAddress{},
    29  		Batches:       []*Batch{},
    30  		DelayEraseKey: [][]byte{},
    31  		BloomData:     []*types.KV{},
    32  		DirtyList:     [][]byte{},
    33  	},
    34  	{
    35  		DirtyAccount: []*sdk.AccAddress{&testAccAddr1, &testAccAddr2},
    36  	},
    37  	{
    38  		Batches: []*Batch{{Key: []byte("0x01")}, {Value: []byte("0x01")}, {TypeValue: 1}},
    39  	},
    40  	{
    41  		DelayEraseKey: [][]byte{[]byte("0x01"), []byte("0x02")},
    42  	},
    43  	{
    44  		BloomData: []*types.KV{{Key: []byte("0x01")}, {Value: []byte("0x01")}},
    45  	},
    46  	{
    47  		DirtyList: [][]byte{[]byte("0x01"), []byte("0x02")},
    48  	},
    49  	{
    50  		DirtyAccount:  []*sdk.AccAddress{&testAccAddr1, {}, nil, &testAccAddr2},
    51  		Batches:       []*Batch{{Key: []byte("0x01")}, {}, nil, {TypeValue: 1}},
    52  		DelayEraseKey: [][]byte{[]byte("0x01"), {}, nil, []byte("0x02")},
    53  		BloomData:     []*types.KV{{Key: []byte("0x01")}, {}, nil, {Value: []byte("0x01")}},
    54  		DirtyList:     [][]byte{[]byte("0x01"), {}, nil, []byte("0x02")},
    55  	},
    56  	{
    57  		DirtyAccount:  []*sdk.AccAddress{&testAccAddr1, &testAccAddr2},
    58  		Batches:       []*Batch{{Key: []byte("0x01")}, {Value: []byte("0x02")}, {TypeValue: 1}},
    59  		DelayEraseKey: [][]byte{[]byte("0x01"), []byte("0x02")},
    60  		BloomData:     []*types.KV{{Key: []byte("0x01")}, {Value: []byte("0x01")}},
    61  		DirtyList:     [][]byte{[]byte("0x01"), []byte("0x02")},
    62  	},
    63  }
    64  
    65  func newTestWatchData() *WatchData {
    66  	return testWatchData[len(testWatchData)-1]
    67  }
    68  
    69  // TestWatchDataAmino test WatchData amino
    70  func TestWatchDataAmino(t *testing.T) { testWatchDataAmino(t) }
    71  func testWatchDataAmino(t *testing.T) {
    72  	for i, wd := range testWatchData {
    73  		expect, err := cdc.MarshalBinaryBare(wd)
    74  		require.NoError(t, err, fmt.Sprintf("num %v", i))
    75  
    76  		actual, err := wd.MarshalToAmino(cdc)
    77  		require.NoError(t, err, fmt.Sprintf("num %v", i))
    78  		require.EqualValues(t, expect, actual, fmt.Sprintf("num %v", i))
    79  
    80  		var expectValue WatchData
    81  		err = cdc.UnmarshalBinaryBare(expect, &expectValue)
    82  		require.NoError(t, err, fmt.Sprintf("num %v", i))
    83  
    84  		var actualValue WatchData
    85  		err = actualValue.UnmarshalFromAmino(cdc, expect)
    86  		require.NoError(t, err, fmt.Sprintf("num %v", i))
    87  		require.EqualValues(t, expectValue, actualValue, fmt.Sprintf("num %v", i))
    88  	}
    89  }
    90  
    91  // TestBatchAmino test Batch Amino
    92  func TestBatchAmino(t *testing.T) { testBatchAmino(t) }
    93  func testBatchAmino(t *testing.T) {
    94  	testBatchs := []*Batch{
    95  		{},
    96  		{Key: []byte("0x01"), Value: []byte("")},
    97  		{TypeValue: 1},
    98  		{TypeValue: math.MaxUint32},
    99  		{Key: []byte("0x01"), Value: []byte("0x02"), TypeValue: 32},
   100  	}
   101  
   102  	for i, bat := range testBatchs {
   103  		expect, err := cdc.MarshalBinaryBare(bat)
   104  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   105  
   106  		actual, err := bat.MarshalToAmino(cdc)
   107  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   108  		require.EqualValues(t, expect, actual, fmt.Sprintf("num %v", i))
   109  
   110  		var expectValue Batch
   111  		err = cdc.UnmarshalBinaryBare(expect, &expectValue)
   112  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   113  
   114  		var actualValue Batch
   115  		err = actualValue.UnmarshalFromAmino(cdc, expect)
   116  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   117  		require.EqualValues(t, expectValue, actualValue, fmt.Sprintf("num %v", i))
   118  	}
   119  }
   120  
   121  // TestKVAmino test KV amino
   122  func TestKVAmino(t *testing.T) { testKVAmino(t) }
   123  func testKVAmino(t *testing.T) {
   124  	testKVs := []*types.KV{
   125  		{},
   126  		{Key: []byte("0x01"), Value: []byte("")},
   127  		{Key: []byte("0x01"), Value: []byte("0x02")},
   128  	}
   129  
   130  	for i, kv := range testKVs {
   131  		expect, err := cdc.MarshalBinaryBare(kv)
   132  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   133  
   134  		actual, err := kv.MarshalToAmino(cdc)
   135  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   136  		require.EqualValues(t, expect, actual, fmt.Sprintf("num %v", i))
   137  
   138  		var expectValue types.KV
   139  		err = cdc.UnmarshalBinaryBare(expect, &expectValue)
   140  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   141  
   142  		var actualValue types.KV
   143  		err = actualValue.UnmarshalFromAmino(cdc, expect)
   144  		require.NoError(t, err, fmt.Sprintf("num %v", i))
   145  		require.EqualValues(t, expectValue, actualValue, fmt.Sprintf("num %v", i))
   146  	}
   147  
   148  }
   149  
   150  // benchmark encode performance
   151  func BenchmarkAminoEncodeDelta(b *testing.B) { benchmarkEncodeDelta(b, newEncoder("amino")) }
   152  func BenchmarkJsonEncodeDelta(b *testing.B)  { benchmarkEncodeDelta(b, newEncoder("json")) }
   153  func benchmarkEncodeDelta(b *testing.B, enc encoder) {
   154  	// produce WatchData
   155  	wd := newTestWatchData()
   156  	b.ReportAllocs()
   157  	b.ResetTimer()
   158  	for i := 0; i < b.N; i++ {
   159  		enc.encodeFunc(wd)
   160  	}
   161  
   162  }
   163  
   164  // benchmark decode performance
   165  func BenchmarkAminoDecodeDelta(b *testing.B) { benchmarkDecodeDelta(b, newEncoder("amino")) }
   166  func BenchmarkJsonDecodeDelta(b *testing.B)  { benchmarkDecodeDelta(b, newEncoder("json")) }
   167  func benchmarkDecodeDelta(b *testing.B, enc encoder) {
   168  	wd := newTestWatchData()
   169  	data, _ := enc.encodeFunc(wd)
   170  
   171  	b.ReportAllocs()
   172  	b.ResetTimer()
   173  	for i := 0; i < b.N; i++ {
   174  		enc.decodeFunc(data)
   175  	}
   176  }
   177  
   178  type encoder interface {
   179  	name() string
   180  	encodeFunc(*WatchData) ([]byte, error)
   181  	decodeFunc([]byte) (*WatchData, error)
   182  }
   183  
   184  func newEncoder(encType string) encoder {
   185  	switch encType {
   186  	case "amino":
   187  		return &aminoEncoder{}
   188  	case "json":
   189  		return &jsonEncoder{}
   190  	default:
   191  	}
   192  	panic("unsupport encoder")
   193  }
   194  
   195  // amino encoder
   196  type aminoEncoder struct{}
   197  
   198  func (ae *aminoEncoder) name() string { return "amino" }
   199  func (ae *aminoEncoder) encodeFunc(data *WatchData) ([]byte, error) {
   200  	return data.MarshalToAmino(nil)
   201  }
   202  func (ae *aminoEncoder) decodeFunc(data []byte) (*WatchData, error) {
   203  	wd := &WatchData{}
   204  	err := wd.UnmarshalFromAmino(nil, data)
   205  	return wd, err
   206  }
   207  
   208  // json encoder
   209  type jsonEncoder struct{}
   210  
   211  func (je *jsonEncoder) name() string { return "json" }
   212  func (je *jsonEncoder) encodeFunc(data *WatchData) ([]byte, error) {
   213  	return json.Marshal(data)
   214  }
   215  func (je *jsonEncoder) decodeFunc(data []byte) (*WatchData, error) {
   216  	wd := &WatchData{}
   217  	err := json.Unmarshal(data, wd)
   218  	return wd, err
   219  }