@@ -29,7 +29,9 @@ func (v *ZkgmV1) executeCall(packet core.Packet, relayer address, relayerMsg []b
2929 return callErrAck(errEurekaUnsupported), nil
3030 }
3131
32- receiverPath := string(call.ContractAddress)
32+ sender := cloneBytes(call.Sender)
33+ calldata := cloneBytes(call.ContractCalldata)
34+ receiverPath := string(cloneBytes(call.ContractAddress))
3335 receiver := zkgm.GetReceiver(receiverPath)
3436 if receiver == nil {
3537 return callErrAck(errors.New("zkgm/v1: receiver not registered: " + receiverPath)), nil
@@ -38,14 +40,14 @@ func (v *ZkgmV1) executeCall(packet core.Packet, relayer address, relayerMsg []b
3840 relayerStr := string(relayer)
3941 env := z.CallEnv{
4042 Caller: relayerStr,
41- ProxyAccount: PredictCallProxyAccount(path, packet.DestinationChannelId, call.Sender ),
43+ ProxyAccount: PredictCallProxyAccount(path, packet.DestinationChannelId, sender ),
4244 Path: path,
4345 SourceChannel: packet.SourceChannelId.String(),
4446 DestinationChannel: packet.DestinationChannelId.String(),
45- Sender: call.Sender ,
46- Calldata: call.ContractCalldata ,
47+ Sender: sender ,
48+ Calldata: calldata ,
4749 Relayer: []byte(relayerStr),
48- RelayerMsg: []byte (relayerMsg),
50+ RelayerMsg: cloneBytes (relayerMsg),
4951 }
5052
5153 err, panicked := safeCallOnZkgm(receiver, env)
@@ -77,11 +79,38 @@ func (v *ZkgmV1) timeoutCall(packet core.Packet, path *u256.Uint, call z.Call) e
7779 return nil
7880}
7981
82+ // safeCallOnZkgm runs the receiver and reports a failure as panicked=true.
83+ // revive is preferred since it also catches cross-realm aborts; the recover
84+ // fallback, used only when revive is unsupported, catches ordinary panics.
8085func safeCallOnZkgm(receiver z.Zkgmable, env z.CallEnv) (err error, panicked bool) {
81- p := revive(func() {
82- err = receiver.OnZkgm(cross, env)
83- })
84- return err, p != nil
86+ if canRevive() {
87+ p := revive(func() {
88+ err = receiver.OnZkgm(cross, env)
89+ })
90+ return err, p != nil
91+ }
92+
93+ defer func() {
94+ if recover() != nil {
95+ err = nil
96+ panicked = true
97+ }
98+ }()
99+ err = receiver.OnZkgm(cross, env)
100+ return err, false
101+ }
102+
103+ // canRevive reports whether revive works in the current runtime. revive panics
104+ // rather than returning when the interpreter lacks support for it.
105+ func canRevive() (ok bool) {
106+ ok = true
107+ defer func() {
108+ if recover() != nil {
109+ ok = false
110+ }
111+ }()
112+ revive(func() {})
113+ return ok
85114}
86115
87116func callErrAck(err error) core.RecvPacketResult {
0 commit comments