From af4c7b53ade34583190961649d1922db8607497f Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Tue, 15 Oct 2024 11:31:33 +0530 Subject: [PATCH 1/2] Test precompile methods related to stylus --- system_tests/program_test.go | 128 +++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/system_tests/program_test.go b/system_tests/program_test.go index 4755096b26..61a157e5f8 100644 --- a/system_tests/program_test.go +++ b/system_tests/program_test.go @@ -1242,6 +1242,134 @@ func testSdkStorage(t *testing.T, jit bool) { check() } +func TestStylusPrecompileMethodsSimple(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, true) + cleanup := builder.Build(t) + defer cleanup() + + arbOwner, err := pgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) + Require(t, err) + arbDebug, err := pgen.NewArbDebug(types.ArbDebugAddress, builder.L2.Client) + Require(t, err) + arbWasm, err := pgen.NewArbWasm(types.ArbWasmAddress, builder.L2.Client) + Require(t, err) + + ensure := func(tx *types.Transaction, err error) *types.Receipt { + t.Helper() + Require(t, err) + receipt, err := EnsureTxSucceeded(ctx, builder.L2.Client, tx) + Require(t, err) + return receipt + } + + ownerAuth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + ensure(arbDebug.BecomeChainOwner(&ownerAuth)) + + // ArbOwner precompile methods + testConst := uint16(10) + ensure(arbOwner.SetInkPrice(&ownerAuth, uint32(testConst))) + ensure(arbOwner.SetWasmMaxStackDepth(&ownerAuth, uint32(testConst))) + ensure(arbOwner.SetWasmFreePages(&ownerAuth, testConst)) + ensure(arbOwner.SetWasmPageGas(&ownerAuth, testConst)) + ensure(arbOwner.SetWasmPageLimit(&ownerAuth, testConst)) + // Setting low values of gas and cached parameters ensures when MinInitGas is called on ArbWasm precompile, + // the returned values would be programs.MinInitGasUnits and programs.MinCachedGasUnits + ensure(arbOwner.SetWasmMinInitGas(&ownerAuth, 1, 1)) + ensure(arbOwner.SetWasmInitCostScalar(&ownerAuth, uint64(testConst))) + expectedExpiryDays := uint16(1) + ensure(arbOwner.SetWasmExpiryDays(&ownerAuth, expectedExpiryDays)) + ensure(arbOwner.SetWasmKeepaliveDays(&ownerAuth, 0)) + ensure(arbOwner.SetWasmBlockCacheSize(&ownerAuth, testConst)) + + // ArbWasm precompile methods + wasm, _ := readWasmFile(t, rustFile("keccak")) + codehash := crypto.Keccak256Hash(wasm) + programAddress := deployContract(t, ctx, ownerAuth, builder.L2.Client, wasm) + + activateAuth := ownerAuth + activateAuth.Value = oneEth + ensure(arbWasm.ActivateProgram(&activateAuth, programAddress)) + + bcs, err := arbWasm.BlockCacheSize(nil) + Require(t, err) + if bcs != testConst { + t.Errorf("BlockCacheSize from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", bcs, testConst) + } + ed, err := arbWasm.ExpiryDays(nil) + Require(t, err) + if ed != expectedExpiryDays { + t.Errorf("ExpiryDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ed, expectedExpiryDays) + } + fp, err := arbWasm.FreePages(nil) + Require(t, err) + if fp != testConst { + t.Errorf("FreePages from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", fp, testConst) + } + ics, err := arbWasm.InitCostScalar(nil) + Require(t, err) + if ics != uint64(testConst) { + t.Errorf("InitCostScalar from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ics, testConst) + } + ip, err := arbWasm.InkPrice(nil) + Require(t, err) + if ip != uint32(testConst) { + t.Errorf("InkPrice from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ip, testConst) + } + kad, err := arbWasm.KeepaliveDays(nil) + Require(t, err) + if kad != 0 { + t.Errorf("KeepaliveDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: 0", kad) + } + msd, err := arbWasm.MaxStackDepth(nil) + Require(t, err) + if msd != uint32(testConst) { + t.Errorf("MaxStackDepth from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", msd, testConst) + } + mig, err := arbWasm.MinInitGas(nil) + Require(t, err) + if mig.Gas != programs.MinInitGasUnits { + t.Errorf("MinInitGas from arbWasm precompile didnt match the Gas value set by arbowner. have: %d, want: %d", mig.Gas, programs.MinInitGasUnits) + } + if mig.Cached != programs.MinCachedGasUnits { + t.Errorf("MinInitGas from arbWasm precompile didnt match the Cached value set by arbowner. have: %d, want: %d", mig.Cached, programs.MinCachedGasUnits) + } + pg, err := arbWasm.PageGas(nil) + Require(t, err) + if pg != testConst { + t.Errorf("PageGas from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pg, testConst) + } + pl, err := arbWasm.PageLimit(nil) + Require(t, err) + if pl != testConst { + t.Errorf("PageLimit from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pl, testConst) + } + // pageramp currently is initialPageRamp = 620674314 value in programs package + _, err = arbWasm.PageRamp(nil) + Require(t, err) + + cas, err := arbWasm.CodehashAsmSize(nil, codehash) + Require(t, err) + if cas == 0 { + t.Error("CodehashAsmSize from arbWasm precompile returned 0 value") + } + ptl, err := arbWasm.ProgramTimeLeft(nil, programAddress) + Require(t, err) + expectedExpirySeconds := (uint64(expectedExpiryDays) * 24 * 3600) + // ProgramTimeLeft returns time in seconds to expiry and the current ExpiryDays is set to 1 day + // We expect the lag of 3600 seconds to exist because program.activatedAt uses hoursSinceArbitrum that + // rounds down (the current time since ArbitrumStartTime in hours)/3600 + if expectedExpirySeconds-ptl > 3600 { + t.Errorf("ProgramTimeLeft from arbWasm precompile returned value lesser than expected. %d <= want <= %d, have: %d", expectedExpirySeconds-3600, expectedExpirySeconds, ptl) + } + // Since ArbOwner has set wasm KeepaliveDays to 0, it enables us to do this, though this shouldn't have any effect + codehashKeepaliveAuth := ownerAuth + codehashKeepaliveAuth.Value = oneEth + ensure(arbWasm.CodehashKeepalive(&codehashKeepaliveAuth, codehash)) +} + func TestProgramActivationLogs(t *testing.T) { t.Parallel() builder, auth, cleanup := setupProgramTest(t, true) From 044f70bd6312d0e71fe1dff386d9325db71f02db Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Tue, 22 Oct 2024 12:52:24 +0530 Subject: [PATCH 2/2] address PR comments --- system_tests/program_test.go | 94 +++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/system_tests/program_test.go b/system_tests/program_test.go index 9c8fe949ab..c240aaad6b 100644 --- a/system_tests/program_test.go +++ b/system_tests/program_test.go @@ -1268,66 +1268,75 @@ func TestStylusPrecompileMethodsSimple(t *testing.T) { ownerAuth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) ensure(arbDebug.BecomeChainOwner(&ownerAuth)) - // ArbOwner precompile methods - testConst := uint16(10) - ensure(arbOwner.SetInkPrice(&ownerAuth, uint32(testConst))) - ensure(arbOwner.SetWasmMaxStackDepth(&ownerAuth, uint32(testConst))) - ensure(arbOwner.SetWasmFreePages(&ownerAuth, testConst)) - ensure(arbOwner.SetWasmPageGas(&ownerAuth, testConst)) - ensure(arbOwner.SetWasmPageLimit(&ownerAuth, testConst)) - // Setting low values of gas and cached parameters ensures when MinInitGas is called on ArbWasm precompile, - // the returned values would be programs.MinInitGasUnits and programs.MinCachedGasUnits - ensure(arbOwner.SetWasmMinInitGas(&ownerAuth, 1, 1)) - ensure(arbOwner.SetWasmInitCostScalar(&ownerAuth, uint64(testConst))) - expectedExpiryDays := uint16(1) - ensure(arbOwner.SetWasmExpiryDays(&ownerAuth, expectedExpiryDays)) - ensure(arbOwner.SetWasmKeepaliveDays(&ownerAuth, 0)) - ensure(arbOwner.SetWasmBlockCacheSize(&ownerAuth, testConst)) - - // ArbWasm precompile methods wasm, _ := readWasmFile(t, rustFile("keccak")) - codehash := crypto.Keccak256Hash(wasm) programAddress := deployContract(t, ctx, ownerAuth, builder.L2.Client, wasm) activateAuth := ownerAuth activateAuth.Value = oneEth ensure(arbWasm.ActivateProgram(&activateAuth, programAddress)) - bcs, err := arbWasm.BlockCacheSize(nil) - Require(t, err) - if bcs != testConst { - t.Errorf("BlockCacheSize from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", bcs, testConst) - } + expectedExpiryDays := uint16(1) + ensure(arbOwner.SetWasmExpiryDays(&ownerAuth, expectedExpiryDays)) ed, err := arbWasm.ExpiryDays(nil) Require(t, err) if ed != expectedExpiryDays { t.Errorf("ExpiryDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ed, expectedExpiryDays) } + ptl, err := arbWasm.ProgramTimeLeft(nil, programAddress) + Require(t, err) + expectedExpirySeconds := (uint64(expectedExpiryDays) * 24 * 3600) + // ProgramTimeLeft returns time in seconds to expiry and the current ExpiryDays is set to 1 day + // We expect the lag of 3600 seconds to exist because program.activatedAt uses hoursSinceArbitrum that + // rounds down (the current time since ArbitrumStartTime in hours)/3600 + if expectedExpirySeconds-ptl > 3600 { + t.Errorf("ProgramTimeLeft from arbWasm precompile returned value lesser than expected. %d <= want <= %d, have: %d", expectedExpirySeconds-3600, expectedExpirySeconds, ptl) + } + + ensure(arbOwner.SetWasmBlockCacheSize(&ownerAuth, 100)) + bcs, err := arbWasm.BlockCacheSize(nil) + Require(t, err) + if bcs != 100 { + t.Errorf("BlockCacheSize from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", bcs, 100) + } + + ensure(arbOwner.SetWasmFreePages(&ownerAuth, 3)) fp, err := arbWasm.FreePages(nil) Require(t, err) - if fp != testConst { - t.Errorf("FreePages from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", fp, testConst) + if fp != 3 { + t.Errorf("FreePages from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", fp, 3) } + + ensure(arbOwner.SetWasmInitCostScalar(&ownerAuth, uint64(4))) ics, err := arbWasm.InitCostScalar(nil) Require(t, err) - if ics != uint64(testConst) { - t.Errorf("InitCostScalar from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ics, testConst) + if ics != uint64(4) { + t.Errorf("InitCostScalar from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ics, 4) } + + ensure(arbOwner.SetInkPrice(&ownerAuth, uint32(5))) ip, err := arbWasm.InkPrice(nil) Require(t, err) - if ip != uint32(testConst) { - t.Errorf("InkPrice from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ip, testConst) + if ip != uint32(5) { + t.Errorf("InkPrice from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ip, 5) } + + ensure(arbOwner.SetWasmKeepaliveDays(&ownerAuth, 0)) kad, err := arbWasm.KeepaliveDays(nil) Require(t, err) if kad != 0 { t.Errorf("KeepaliveDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: 0", kad) } + + ensure(arbOwner.SetWasmMaxStackDepth(&ownerAuth, uint32(6))) msd, err := arbWasm.MaxStackDepth(nil) Require(t, err) - if msd != uint32(testConst) { - t.Errorf("MaxStackDepth from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", msd, testConst) + if msd != uint32(6) { + t.Errorf("MaxStackDepth from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", msd, 6) } + + // Setting low values of gas and cached parameters ensures when MinInitGas is called on ArbWasm precompile, + // the returned values would be programs.MinInitGasUnits and programs.MinCachedGasUnits + ensure(arbOwner.SetWasmMinInitGas(&ownerAuth, 1, 1)) mig, err := arbWasm.MinInitGas(nil) Require(t, err) if mig.Gas != programs.MinInitGasUnits { @@ -1336,34 +1345,31 @@ func TestStylusPrecompileMethodsSimple(t *testing.T) { if mig.Cached != programs.MinCachedGasUnits { t.Errorf("MinInitGas from arbWasm precompile didnt match the Cached value set by arbowner. have: %d, want: %d", mig.Cached, programs.MinCachedGasUnits) } + + ensure(arbOwner.SetWasmPageGas(&ownerAuth, 7)) pg, err := arbWasm.PageGas(nil) Require(t, err) - if pg != testConst { - t.Errorf("PageGas from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pg, testConst) + if pg != 7 { + t.Errorf("PageGas from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pg, 7) } + + ensure(arbOwner.SetWasmPageLimit(&ownerAuth, 8)) pl, err := arbWasm.PageLimit(nil) Require(t, err) - if pl != testConst { - t.Errorf("PageLimit from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pl, testConst) + if pl != 8 { + t.Errorf("PageLimit from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pl, 8) } + // pageramp currently is initialPageRamp = 620674314 value in programs package _, err = arbWasm.PageRamp(nil) Require(t, err) + codehash := crypto.Keccak256Hash(wasm) cas, err := arbWasm.CodehashAsmSize(nil, codehash) Require(t, err) if cas == 0 { t.Error("CodehashAsmSize from arbWasm precompile returned 0 value") } - ptl, err := arbWasm.ProgramTimeLeft(nil, programAddress) - Require(t, err) - expectedExpirySeconds := (uint64(expectedExpiryDays) * 24 * 3600) - // ProgramTimeLeft returns time in seconds to expiry and the current ExpiryDays is set to 1 day - // We expect the lag of 3600 seconds to exist because program.activatedAt uses hoursSinceArbitrum that - // rounds down (the current time since ArbitrumStartTime in hours)/3600 - if expectedExpirySeconds-ptl > 3600 { - t.Errorf("ProgramTimeLeft from arbWasm precompile returned value lesser than expected. %d <= want <= %d, have: %d", expectedExpirySeconds-3600, expectedExpirySeconds, ptl) - } // Since ArbOwner has set wasm KeepaliveDays to 0, it enables us to do this, though this shouldn't have any effect codehashKeepaliveAuth := ownerAuth codehashKeepaliveAuth.Value = oneEth