github.com/consideritdone/landslidecore@v0.0.0-20230718131026-a8b21c5cf8a7/vm/vm_test.go (about)

     1  package vm
     2  
     3  import (
     4  	"context"
     5  	_ "embed"
     6  	"fmt"
     7  	"os"
     8  	"testing"
     9  
    10  	"github.com/consideritdone/landslidecore/abci/example/kvstore"
    11  
    12  	"github.com/ava-labs/avalanchego/database/manager"
    13  	"github.com/ava-labs/avalanchego/ids"
    14  	"github.com/ava-labs/avalanchego/snow"
    15  	"github.com/ava-labs/avalanchego/snow/engine/common"
    16  	"github.com/ava-labs/avalanchego/utils/logging"
    17  	"github.com/ava-labs/avalanchego/version"
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  
    21  	"github.com/consideritdone/landslidecore/abci/example/counter"
    22  	atypes "github.com/consideritdone/landslidecore/abci/types"
    23  	tmrand "github.com/consideritdone/landslidecore/libs/rand"
    24  )
    25  
    26  var (
    27  	blockchainID = ids.ID{1, 2, 3}
    28  
    29  	//go:embed data/vm_test_genesis.json
    30  	genesis string
    31  )
    32  
    33  func newCounterTestVM() (*VM, *snow.Context, chan common.Message, error) {
    34  	app := counter.NewApplication(true)
    35  
    36  	return newTestVM(app)
    37  }
    38  
    39  func newKVTestVM() (*VM, *snow.Context, chan common.Message, error) {
    40  	app := kvstore.NewApplication()
    41  
    42  	return newTestVM(app)
    43  }
    44  
    45  func newTestVM(app atypes.Application) (*VM, *snow.Context, chan common.Message, error) {
    46  	dbManager := manager.NewMemDB(&version.Semantic{
    47  		Major: 1,
    48  		Minor: 0,
    49  		Patch: 0,
    50  	})
    51  	msgChan := make(chan common.Message, 1)
    52  	vm := New(LocalAppCreator(app))
    53  	snowCtx := snow.DefaultContextTest()
    54  	snowCtx.Log = logging.NewLogger(
    55  		fmt.Sprintf("<%s Chain>", blockchainID),
    56  		logging.NewWrappedCore(
    57  			logging.Info,
    58  			os.Stderr,
    59  			logging.Colors.ConsoleEncoder(),
    60  		),
    61  	)
    62  	snowCtx.ChainID = blockchainID
    63  	err := vm.Initialize(context.TODO(), snowCtx, dbManager, []byte(genesis), nil, nil, msgChan, nil, nil)
    64  
    65  	return vm, snowCtx, msgChan, err
    66  }
    67  
    68  func mustNewCounterTestVm(t *testing.T) (*VM, Service, chan common.Message) {
    69  	vm, _, msgChan, err := newCounterTestVM()
    70  	require.NoError(t, err)
    71  	require.NotNil(t, vm)
    72  
    73  	service := NewService(vm)
    74  	return vm, service, msgChan
    75  }
    76  
    77  func mustNewKVTestVm(t *testing.T) (*VM, Service, chan common.Message) {
    78  	vm, _, msgChan, err := newKVTestVM()
    79  	require.NoError(t, err)
    80  	require.NotNil(t, vm)
    81  
    82  	service := NewService(vm)
    83  	return vm, service, msgChan
    84  }
    85  
    86  // MakeTxKV returns a text transaction, allong with expected key, value pair
    87  func MakeTxKV() ([]byte, []byte, []byte) {
    88  	k := []byte(tmrand.Str(2))
    89  	v := []byte(tmrand.Str(2))
    90  	return k, v, append(k, append([]byte("="), v...)...)
    91  }
    92  
    93  func TestInitVm(t *testing.T) {
    94  	vm, service, msgChan := mustNewCounterTestVm(t)
    95  
    96  	blk0, err := vm.BuildBlock(context.Background())
    97  	assert.ErrorIs(t, err, errNoPendingTxs, "expecting error no txs")
    98  	assert.Nil(t, blk0)
    99  
   100  	// submit first tx (0x00)
   101  	reply, err := service.BroadcastTxSync(nil, []byte{0x00})
   102  	assert.NoError(t, err)
   103  	assert.Equal(t, atypes.CodeTypeOK, reply.Code)
   104  
   105  	select { // require there is a pending tx message to the engine
   106  	case msg := <-msgChan:
   107  		require.Equal(t, common.PendingTxs, msg)
   108  	default:
   109  		require.FailNow(t, "should have been pendingTxs message on channel")
   110  	}
   111  
   112  	// build 1st block
   113  	blk1, err := vm.BuildBlock(context.Background())
   114  	assert.NoError(t, err)
   115  	assert.NotNil(t, blk1)
   116  
   117  	err = blk1.Accept(context.Background())
   118  	assert.NoError(t, err)
   119  
   120  	tmBlk1 := blk1.(*Block).Block
   121  
   122  	t.Logf("Block: %d", blk1.Height())
   123  	t.Logf("TM Block Tx count: %d", len(tmBlk1.Data.Txs))
   124  
   125  	// submit second tx (0x01)
   126  	reply, err = service.BroadcastTxSync(nil, []byte{0x01})
   127  	assert.NoError(t, err)
   128  	assert.Equal(t, atypes.CodeTypeOK, reply.Code)
   129  
   130  	// submit 3rd tx (0x02)
   131  	reply, err = service.BroadcastTxSync(nil, []byte{0x02})
   132  	assert.NoError(t, err)
   133  	assert.Equal(t, atypes.CodeTypeOK, reply.Code)
   134  
   135  	select { // require there is a pending tx message to the engine
   136  	case msg := <-msgChan:
   137  		require.Equal(t, common.PendingTxs, msg)
   138  	default:
   139  		require.FailNow(t, "should have been pendingTxs message on channel")
   140  	}
   141  
   142  	// build second block with 2 TX together
   143  	blk2, err := vm.BuildBlock(context.Background())
   144  	assert.NoError(t, err)
   145  	assert.NotNil(t, blk2)
   146  
   147  	err = blk2.Accept(context.Background())
   148  	assert.NoError(t, err)
   149  
   150  	tmBlk2 := blk2.(*Block).Block
   151  
   152  	t.Logf("Block: %d", blk2.Height())
   153  	t.Logf("TM Block Tx count: %d", len(tmBlk2.Data.Txs))
   154  }