diff --git a/test/contracts/new-blockchain-hooks/Makefile b/test/contracts/new-blockchain-hooks/Makefile new file mode 100644 index 000000000..8ac5eed31 --- /dev/null +++ b/test/contracts/new-blockchain-hooks/Makefile @@ -0,0 +1,2 @@ +build: + rustc --target wasm32-unknown-unknown -O --crate-type=cdylib src/lib.rs -o output/new-blockchain-hooks.wasm \ No newline at end of file diff --git a/test/contracts/new-blockchain-hooks/output/new-blockchain-hooks.wasm b/test/contracts/new-blockchain-hooks/output/new-blockchain-hooks.wasm new file mode 100755 index 000000000..9fc969f4b Binary files /dev/null and b/test/contracts/new-blockchain-hooks/output/new-blockchain-hooks.wasm differ diff --git a/test/contracts/new-blockchain-hooks/src/lib.rs b/test/contracts/new-blockchain-hooks/src/lib.rs new file mode 100644 index 000000000..e980ffa6b --- /dev/null +++ b/test/contracts/new-blockchain-hooks/src/lib.rs @@ -0,0 +1,51 @@ +#![no_std] +#![no_main] + +#[panic_handler] +fn panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +#[no_mangle] +pub extern "C" fn test_round_time() { + unsafe { + let result = getRoundTime(); + let result: [u8; 1] = [(result & 0xff) as u8]; + finish(result.as_ref().as_ptr(), 1); + }; +} + +#[no_mangle] +pub extern "C" fn test_epoch_start_block_time_stamp() { + unsafe { + let result = epochStartBlockTimeStamp(); + let result: [u8; 1] = [(result & 0xff) as u8]; + finish(result.as_ref().as_ptr(), 1); + }; +} + +#[no_mangle] +pub extern "C" fn test_epoch_start_block_nonce() { + unsafe { + let result = epochStartBlockNonce(); + let result: [u8; 1] = [(result & 0xff) as u8]; + finish(result.as_ref().as_ptr(), 1); + }; +} + +#[no_mangle] +pub extern "C" fn test_epoch_start_block_round() { + unsafe { + let result = epochStartBlockRound(); + let result: [u8; 1] = [(result & 0xff) as u8]; + finish(result.as_ref().as_ptr(), 1); + }; +} + +extern { + fn finish(data: *const u8, len: i32); + fn getRoundTime() -> i64; + fn epochStartBlockTimeStamp() -> i64; + fn epochStartBlockNonce() -> i64; + fn epochStartBlockRound() -> i64; +} \ No newline at end of file diff --git a/vmhost/hosttest/newBloclchainHooks_test.go b/vmhost/hosttest/newBloclchainHooks_test.go new file mode 100644 index 000000000..aa3b21b67 --- /dev/null +++ b/vmhost/hosttest/newBloclchainHooks_test.go @@ -0,0 +1,131 @@ +package hostCoretest + +import ( + "math/big" + "testing" + + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/multiversx/mx-chain-vm-go/testcommon" + + "github.com/stretchr/testify/require" +) + +func TestNewBlockchainHooks_GetRoundTime(t *testing.T) { + code := testcommon.GetTestSCCode("new-blockchain-hooks", "../../") + + blockchainHook := testcommon.BlockchainHookStubForCall(code, nil) + blockchainHook.RoundTimeCalled = func() uint64 { + return 32 + } + + host := testcommon.NewTestHostBuilder(t). + WithBlockchainHook(blockchainHook). + Build() + defer func() { + host.Reset() + }() + + input := testcommon.DefaultTestContractCallInput() + input.GasProvided = 100000 + input.Function = "test_round_time" + input.CallValue = big.NewInt(64) + + vmOutput, err := host.RunSmartContractCall(input) + require.Nil(t, err) + + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + require.Len(t, vmOutput.ReturnData, 1) + require.Equal(t, "", vmOutput.ReturnMessage) + + require.Equal(t, []byte{32}, vmOutput.ReturnData[0]) +} + +func TestNewBlockchainHooks_EpochStartBlockTimeStamp(t *testing.T) { + code := testcommon.GetTestSCCode("new-blockchain-hooks", "../../") + + blockchainHook := testcommon.BlockchainHookStubForCall(code, nil) + blockchainHook.EpochStartBlockTimeStampCalled = func() uint64 { + return 31 + } + + host := testcommon.NewTestHostBuilder(t). + WithBlockchainHook(blockchainHook). + Build() + defer func() { + host.Reset() + }() + + input := testcommon.DefaultTestContractCallInput() + input.GasProvided = 100000 + input.Function = "test_epoch_start_block_time_stamp" + input.CallValue = big.NewInt(64) + + vmOutput, err := host.RunSmartContractCall(input) + require.Nil(t, err) + + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + require.Len(t, vmOutput.ReturnData, 1) + require.Equal(t, "", vmOutput.ReturnMessage) + + require.Equal(t, []byte{31}, vmOutput.ReturnData[0]) +} + +func TestNewBlockchainHooks_EpochStartBlockNonce(t *testing.T) { + code := testcommon.GetTestSCCode("new-blockchain-hooks", "../../") + + blockchainHook := testcommon.BlockchainHookStubForCall(code, nil) + blockchainHook.EpochStartBlockNonceCalled = func() uint64 { + return 30 + } + + host := testcommon.NewTestHostBuilder(t). + WithBlockchainHook(blockchainHook). + Build() + defer func() { + host.Reset() + }() + + input := testcommon.DefaultTestContractCallInput() + input.GasProvided = 100000 + input.Function = "test_epoch_start_block_nonce" + input.CallValue = big.NewInt(64) + + vmOutput, err := host.RunSmartContractCall(input) + require.Nil(t, err) + + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + require.Len(t, vmOutput.ReturnData, 1) + require.Equal(t, "", vmOutput.ReturnMessage) + + require.Equal(t, []byte{30}, vmOutput.ReturnData[0]) +} + +func TestNewBlockchainHooks_EpochStartBlockRound(t *testing.T) { + code := testcommon.GetTestSCCode("new-blockchain-hooks", "../../") + + blockchainHook := testcommon.BlockchainHookStubForCall(code, nil) + blockchainHook.EpochStartBlockRoundCalled = func() uint64 { + return 29 + } + + host := testcommon.NewTestHostBuilder(t). + WithBlockchainHook(blockchainHook). + Build() + defer func() { + host.Reset() + }() + + input := testcommon.DefaultTestContractCallInput() + input.GasProvided = 100000 + input.Function = "test_epoch_start_block_round" + input.CallValue = big.NewInt(64) + + vmOutput, err := host.RunSmartContractCall(input) + require.Nil(t, err) + + require.Equal(t, vmcommon.Ok, vmOutput.ReturnCode) + require.Len(t, vmOutput.ReturnData, 1) + require.Equal(t, "", vmOutput.ReturnMessage) + + require.Equal(t, []byte{29}, vmOutput.ReturnData[0]) +}