-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9939559
commit 6e6441d
Showing
6 changed files
with
161 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package ccipevm | ||
|
||
import ( | ||
"fmt" | ||
|
||
cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" | ||
) | ||
|
||
func DecodeDestExecDataToMap(DestExecData cciptypes.Bytes) (map[string]interface{}, error) { | ||
destGasAmount, err := abiDecodeUint32(DestExecData) | ||
if err != nil { | ||
return nil, fmt.Errorf("decode dest gas amount: %w", err) | ||
} | ||
|
||
return map[string]interface{}{ | ||
evmDestExecDataKey: destGasAmount, | ||
}, nil | ||
} | ||
|
||
func DecodeExtraArgsToMap(extraArgs []byte) (map[string]any, error) { | ||
if len(extraArgs) < 4 { | ||
return nil, fmt.Errorf("extra args too short: %d, should be at least 4 (i.e the extraArgs tag)", len(extraArgs)) | ||
} | ||
|
||
var method string | ||
var extraByteOffset int | ||
switch string(extraArgs[:4]) { | ||
case string(evmExtraArgsV1Tag): | ||
// for EVMExtraArgs, the first four bytes is the method name | ||
method = evmV1DecodeName | ||
extraByteOffset = 4 | ||
case string(evmExtraArgsV2Tag): | ||
method = evmV2DecodeName | ||
extraByteOffset = 4 | ||
case string(svmExtraArgsV1Tag): | ||
// for SVMExtraArgs there's the four bytes plus another 32 bytes padding for the dynamic array | ||
// https://github.com/smartcontractkit/chainlink/blob/33c0bda696b0ed97f587a46eacd5c65bed9fb2c1/contracts/src/v0.8/ccip/libraries/Client.sol#L57 | ||
// this is a temporary solution, the evm on-chain side will fix it, so the offset should just be 4 instead of 36 | ||
method = svmV1DecodeName | ||
extraByteOffset = 36 | ||
default: | ||
return nil, fmt.Errorf("unknown extra args tag: %x", extraArgs) | ||
} | ||
|
||
output := make(map[string]any) | ||
args := make(map[string]interface{}) | ||
err := messageHasherABI.Methods[method].Inputs.UnpackIntoMap(args, extraArgs[extraByteOffset:]) | ||
if err != nil { | ||
return nil, fmt.Errorf("abi decode extra args %v: %w", method, err) | ||
} | ||
|
||
for k, val := range args { | ||
output[k] = val | ||
} | ||
return output, nil | ||
} |
105 changes: 105 additions & 0 deletions
105
core/capabilities/ccip/ccipevm/extradatadecoder_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package ccipevm | ||
|
||
import ( | ||
"math/big" | ||
"math/rand" | ||
"testing" | ||
|
||
"github.com/gagliardetto/solana-go" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/message_hasher" | ||
) | ||
|
||
func Test_decodeExtraData(t *testing.T) { | ||
d := testSetup(t) | ||
gasLimit := big.NewInt(rand.Int63()) | ||
|
||
t.Run("decode extra args into map evm v1", func(t *testing.T) { | ||
encoded, err := d.contract.EncodeEVMExtraArgsV1(nil, message_hasher.ClientEVMExtraArgsV1{ | ||
GasLimit: gasLimit, | ||
}) | ||
require.NoError(t, err) | ||
|
||
m, err := DecodeExtraArgsToMap(encoded) | ||
require.NoError(t, err) | ||
require.Len(t, m, 1) | ||
|
||
gl, exist := m["gasLimit"] | ||
require.True(t, exist) | ||
require.Equal(t, gl, gasLimit) | ||
}) | ||
|
||
t.Run("decode extra args into map evm v2", func(t *testing.T) { | ||
encoded, err := d.contract.EncodeEVMExtraArgsV2(nil, message_hasher.ClientEVMExtraArgsV2{ | ||
GasLimit: gasLimit, | ||
AllowOutOfOrderExecution: true, | ||
}) | ||
require.NoError(t, err) | ||
|
||
m, err := DecodeExtraArgsToMap(encoded) | ||
require.NoError(t, err) | ||
require.Len(t, m, 2) | ||
|
||
gl, exist := m["gasLimit"] | ||
require.True(t, exist) | ||
require.Equal(t, gl, gasLimit) | ||
|
||
ooe, exist := m["allowOutOfOrderExecution"] | ||
require.True(t, exist) | ||
require.Equal(t, true, ooe) | ||
}) | ||
|
||
t.Run("decode extra args into map svm", func(t *testing.T) { | ||
key, err := solana.NewRandomPrivateKey() | ||
require.NoError(t, err) | ||
cu := uint32(10000) | ||
bitmap := uint64(4) | ||
ooe := false | ||
tokenReceiver := [32]byte(key.PublicKey().Bytes()) | ||
accounts := [][32]byte{[32]byte(key.PublicKey().Bytes())} | ||
decoded, err := d.contract.DecodeSVMExtraArgsV1(nil, cu, bitmap, ooe, tokenReceiver, accounts) | ||
if err != nil { | ||
return | ||
} | ||
encoded, err := d.contract.EncodeSVMExtraArgsV1(nil, decoded) | ||
require.NoError(t, err) | ||
|
||
m, err := DecodeExtraArgsToMap(encoded) | ||
require.NoError(t, err) | ||
require.Len(t, m, 5) | ||
|
||
cuDecoded, exist := m["computeUnits"] | ||
require.True(t, exist) | ||
require.Equal(t, cuDecoded, cu) | ||
|
||
bitmapDecoded, exist := m["accountIsWritableBitmap"] | ||
require.True(t, exist) | ||
require.Equal(t, bitmapDecoded, bitmap) | ||
|
||
ooeDecoded, exist := m["allowOutOfOrderExecution"] | ||
require.True(t, exist) | ||
require.Equal(t, ooeDecoded, ooe) | ||
|
||
tokenReceiverDecoded, exist := m["tokenReceiver"] | ||
require.True(t, exist) | ||
require.Equal(t, tokenReceiverDecoded, tokenReceiver) | ||
|
||
accountsDecoded, exist := m["accounts"] | ||
require.True(t, exist) | ||
require.Equal(t, accountsDecoded, accounts) | ||
}) | ||
|
||
t.Run("decode dest exec data into map", func(t *testing.T) { | ||
destGasAmount := uint32(10000) | ||
encoded, err := abiEncodeUint32(destGasAmount) | ||
require.NoError(t, err) | ||
m, err := DecodeDestExecDataToMap(encoded) | ||
require.NoError(t, err) | ||
require.Len(t, m, 1) | ||
|
||
decoded, exist := m[evmDestExecDataKey] | ||
require.True(t, exist) | ||
require.Equal(t, destGasAmount, decoded) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.