Skip to content

Commit

Permalink
Add TestWasmRecreateWithDelegatecall
Browse files Browse the repository at this point in the history
Test that the given Stylus program will be lazily recreated after being
called by a Solidity contract with a delegate call. This change modifies
the existing recreation test so both tests can share most of the code.
  • Loading branch information
gligneul committed Jul 11, 2024
1 parent 1fcaf60 commit 9b1faa2
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 15 deletions.
2 changes: 1 addition & 1 deletion contracts
70 changes: 56 additions & 14 deletions system_tests/program_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1668,20 +1668,12 @@ func formatTime(duration time.Duration) string {
return fmt.Sprintf("%.2f%s", span, units[unit])
}

func TestWasmRecreate(t *testing.T) {
builder, auth, cleanup := setupProgramTest(t, true)
func testWasmRecreate(t *testing.T, builder *NodeBuilder, storeTx *types.Transaction, loadTx *types.Transaction, want []byte) {
ctx := builder.ctx
l2info := builder.L2Info
l2client := builder.L2.Client
defer cleanup()

storage := deployWasm(t, ctx, auth, l2client, rustFile("storage"))

zero := common.Hash{}
val := common.HexToHash("0x121233445566")

// do an onchain call - store value
storeTx := l2info.PrepareTxTo("Owner", &storage, l2info.TransferGas, nil, argsForStorageWrite(zero, val))
Require(t, l2client.SendTransaction(ctx, storeTx))
_, err := EnsureTxSucceeded(ctx, l2client, storeTx)
Require(t, err)
Expand All @@ -1694,11 +1686,10 @@ func TestWasmRecreate(t *testing.T) {
Require(t, err)

// make sure reading 2nd value succeeds from 2nd node
loadTx := l2info.PrepareTxTo("Owner", &storage, l2info.TransferGas, nil, argsForStorageRead(zero))
result, err := arbutil.SendTxAsCall(ctx, nodeB.Client, loadTx, l2info.GetAddress("Owner"), nil, true)
Require(t, err)
if common.BytesToHash(result) != val {
Fatal(t, "got wrong value")
if !bytes.Equal(result, want) {
t.Fatalf("got wrong value, got %x, want %x", result, want)
}
// close nodeB
cleanupB()
Expand All @@ -1723,8 +1714,8 @@ func TestWasmRecreate(t *testing.T) {
// test nodeB - answers eth_call (requires reloading wasm)
result, err = arbutil.SendTxAsCall(ctx, nodeB.Client, loadTx, l2info.GetAddress("Owner"), nil, true)
Require(t, err)
if common.BytesToHash(result) != val {
Fatal(t, "got wrong value")
if !bytes.Equal(result, want) {
t.Fatalf("got wrong value, got %x, want %x", result, want)
}

// send new tx (requires wasm) and check nodeB sees it as well
Expand All @@ -1743,7 +1734,58 @@ func TestWasmRecreate(t *testing.T) {
Fatal(t, "not contents found before delete")
}
os.RemoveAll(wasmPath)
}

func TestWasmRecreate(t *testing.T) {
builder, auth, cleanup := setupProgramTest(t, true)
ctx := builder.ctx
l2info := builder.L2Info
l2client := builder.L2.Client
defer cleanup()

storage := deployWasm(t, ctx, auth, l2client, rustFile("storage"))

zero := common.Hash{}
val := common.HexToHash("0x121233445566")

storeTx := l2info.PrepareTxTo("Owner", &storage, l2info.TransferGas, nil, argsForStorageWrite(zero, val))
loadTx := l2info.PrepareTxTo("Owner", &storage, l2info.TransferGas, nil, argsForStorageRead(zero))

testWasmRecreate(t, builder, storeTx, loadTx, val[:])
}

func TestWasmRecreateWithDelegatecall(t *testing.T) {
builder, auth, cleanup := setupProgramTest(t, true)
ctx := builder.ctx
l2info := builder.L2Info
l2client := builder.L2.Client
defer cleanup()

storage := deployWasm(t, ctx, auth, l2client, rustFile("storage"))

zero := common.Hash{}
val := common.HexToHash("0x121233445566")

// deploy mock that contains the delegatecall method
mock, tx, _, err := mocksgen.DeployProgramTest(&auth, l2client)
Require(t, err)
_, err = EnsureTxSucceeded(ctx, l2client, tx)
Require(t, err)
mockAbi, err := mocksgen.ProgramTestMetaData.GetAbi()
Require(t, err)

data, err := mockAbi.Pack("delegatecallProgram", storage, argsForStorageWrite(zero, val))
Require(t, err)
storeTx := l2info.PrepareTxTo("Owner", &mock, l2info.TransferGas, nil, data)

data, err = mockAbi.Pack("delegatecallProgram", storage, argsForStorageRead(zero))
Require(t, err)
loadTx := l2info.PrepareTxTo("Owner", &mock, l2info.TransferGas, nil, data)

want, err := mockAbi.Methods["delegatecallProgram"].Outputs.Pack(val[:])
Require(t, err)

testWasmRecreate(t, builder, storeTx, loadTx, want)
}

// createMapFromDb is used in verifying if wasm store rebuilding works
Expand Down

0 comments on commit 9b1faa2

Please sign in to comment.