-
Notifications
You must be signed in to change notification settings - Fork 587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adr 8 callback packet data impl followups #3325
Changes from 6 commits
1bdb0e9
be4c2d0
036565a
80bab81
2cb28d7
02d8975
796c7bc
71e8bf4
94d74f9
b502f47
6be595a
85faf55
b4a386a
b3f1b4d
cbb6859
89ecf25
88f3c3c
5a67efc
7d23e0f
8c16ce0
2818a57
8e8c64a
3cdc8b3
be5a766
767c5af
12c00ec
4961826
a02ec51
6f25b8e
f4c20e4
8971ffc
1c6164b
9435525
7f88419
935c5f0
a1252f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,7 @@ var ( | |
DefaultRelativePacketTimeoutTimestamp = uint64((time.Duration(10) * time.Minute).Nanoseconds()) | ||
) | ||
|
||
var _ exported.CallbackPacketDataI = (*InterchainAccountPacketData)(nil) | ||
var _ exported.CallbackPacketData = (*InterchainAccountPacketData)(nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this change 👍 |
||
|
||
// ValidateBasic performs basic validation of the interchain account packet data. | ||
// The memo may be empty. | ||
|
@@ -55,7 +55,7 @@ func (iapd InterchainAccountPacketData) GetBytes() []byte { | |
|
||
ADR-8 CallbackPacketData implementation | ||
|
||
InterchainAccountPacketData implements CallbackPacketDataI interface. This will allow middlewares targetting specific VMs | ||
InterchainAccountPacketData implements CallbackPacketDataI interface. This will allow middlewares targeting specific VMs | ||
to retrieve the desired callback addresses for the ICA packet on the source and destination chains. | ||
|
||
The Memo is used to set the desired callback addresses. | ||
|
@@ -66,27 +66,32 @@ The Memo format is defined like so: | |
{ | ||
// ... other memo fields we don't care about | ||
"callbacks": { | ||
"src_callback_address": {contractAddrOnSrcChain}, | ||
"src_callback_address": {contractAddrOnSourceChain}, | ||
"dest_callback_address": {contractAddrOnDestChain}, | ||
crodriguezvega marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"src_callback_msg": {jsonObjectForSrcChainCallback}, // optional field | ||
"dest_callback_msg": {jsonObjectForDestChainCallback}, // optional field | ||
} | ||
|
||
// optional fields | ||
"src_callback_msg": {jsonObjectForSourceChainCallback}, | ||
"dest_callback_msg": {jsonObjectForDestChainCallback}, | ||
} | ||
} | ||
``` | ||
|
||
*/ | ||
|
||
// GetSrcCallbackAddress returns the callback address on the source chain. | ||
// ADR-8 middleware should callback on the sender address on the source chain | ||
// if the sender address is an IBC Actor (i.e. smart contract that accepts IBC callbacks) | ||
func (iapd InterchainAccountPacketData) GetSrcCallbackAddress() string { | ||
// GetSourceCallbackAddress returns the source callback address provided in the packet data memo. | ||
// If no callback address is specified, an empty string is returned. | ||
// | ||
// The memo is expected to specify the callback address in the following format: | ||
// { "callbacks": { "src_callback_address": {contractAddrOnSourceChain}} | ||
// | ||
// ADR-8 middleware should callback on the returned address if it is a PacketActor | ||
// (i.e. smart contract that accepts IBC callbacks). | ||
func (iapd InterchainAccountPacketData) GetSourceCallbackAddress() string { | ||
crodriguezvega marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if len(iapd.Memo) == 0 { | ||
return "" | ||
} | ||
|
||
jsonObject := make(map[string]interface{}) | ||
// the jsonObject must be a valid JSON object | ||
err := json.Unmarshal([]byte(iapd.Memo), &jsonObject) | ||
if err != nil { | ||
return "" | ||
|
@@ -101,17 +106,19 @@ func (iapd InterchainAccountPacketData) GetSrcCallbackAddress() string { | |
if !ok { | ||
return "" | ||
} | ||
|
||
return callbackAddr | ||
} | ||
|
||
// GetDestCallbackAddress returns the callback address on the destination chain. | ||
// ADR-8 middleware should callback on the receiver address on the destination chain | ||
// if the receiver address is an IBC Actor (i.e. smart contract that accepts IBC callbacks) | ||
// GetDestCallbackAddress returns an empty string. Destination callback addresses | ||
// are not supported for ICS 27 since this feature is natively supported by | ||
// interchain accounts host submodule transaction execution. | ||
func (iapd InterchainAccountPacketData) GetDestCallbackAddress() string { | ||
return "" | ||
} | ||
|
||
// UserDefinedGasLimit no-ops on this method to use relayer passed in gas | ||
// UserDefinedGasLimit returns 0 (no-op). The gas limit of the executing | ||
// transaction will be used. | ||
func (fptd InterchainAccountPacketData) UserDefinedGasLimit() uint64 { | ||
return 0 | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
package types_test | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/types" | ||
) | ||
|
||
|
@@ -83,11 +85,13 @@ func (suite *TypesTestSuite) TestValidateBasic() { | |
} | ||
} | ||
|
||
func (suite *TypesTestSuite) TestGetCallbackAddresses() { | ||
func (suite *TypesTestSuite) TestGetSourceCallbackAddress() { | ||
expSrcCbAddr := "srcCbAddr" | ||
colin-axner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
testCases := []struct { | ||
name string | ||
packetData types.InterchainAccountPacketData | ||
expSrcCallbackAddr string | ||
name string | ||
packetData types.InterchainAccountPacketData | ||
expPass bool | ||
}{ | ||
{ | ||
"memo is empty", | ||
|
@@ -96,7 +100,7 @@ func (suite *TypesTestSuite) TestGetCallbackAddresses() { | |
Data: []byte("data"), | ||
Memo: "", | ||
}, | ||
"", | ||
false, | ||
}, | ||
{ | ||
"memo is not json string", | ||
|
@@ -105,7 +109,7 @@ func (suite *TypesTestSuite) TestGetCallbackAddresses() { | |
Data: []byte("data"), | ||
Memo: "memo", | ||
}, | ||
"", | ||
false, | ||
}, | ||
{ | ||
"memo is does not have callbacks in json struct", | ||
colin-axner marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
@@ -114,7 +118,7 @@ func (suite *TypesTestSuite) TestGetCallbackAddresses() { | |
Data: []byte("data"), | ||
Memo: "{\"Key\": 10}", | ||
}, | ||
"", | ||
false, | ||
}, | ||
{ | ||
"memo has callbacks in json struct but does not have src_callback_address key", | ||
|
@@ -123,7 +127,7 @@ func (suite *TypesTestSuite) TestGetCallbackAddresses() { | |
Data: []byte("data"), | ||
Memo: "{\"callbacks\": {\"Key\": 10}}", | ||
}, | ||
"", | ||
false, | ||
}, | ||
{ | ||
"memo has callbacks in json struct but does not have string value for src_callback_address key", | ||
|
@@ -132,21 +136,71 @@ func (suite *TypesTestSuite) TestGetCallbackAddresses() { | |
Data: []byte("data"), | ||
Memo: "{\"callbacks\": {\"src_callback_address\": 10}}", | ||
}, | ||
"", | ||
false, | ||
}, | ||
{ | ||
"memo has callbacks in json struct but does not have string value for src_callback_address key", | ||
"memo has callbacks in json struct and properly formatted src_callback_address", | ||
types.InterchainAccountPacketData{ | ||
Type: types.EXECUTE_TX, | ||
Data: []byte("data"), | ||
Memo: fmt.Sprintf("{\"callbacks\": {\"src_callback_address\": \"%s\"}}", expSrcCbAddr), | ||
}, | ||
true, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
tc := tc | ||
suite.Run(tc.name, func() { | ||
srcCbAddr := tc.packetData.GetSourceCallbackAddress() | ||
|
||
if tc.expPass { | ||
suite.Require().Equal(expSrcCbAddr, srcCbAddr) | ||
} else { | ||
suite.Require().Equal("", srcCbAddr) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
func (suite *TypesTestSuite) TestGetDestCallbackAddress() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like an odd test to have for a no-op function There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If unresolved merge conflicts cause this to return a non empty string, I'd prefer the tests to catch the issue. It's quite easy for merge conflicts to slip through |
||
testCases := []struct { | ||
name string | ||
packetData types.InterchainAccountPacketData | ||
}{ | ||
{ | ||
"memo is empty", | ||
types.InterchainAccountPacketData{ | ||
Type: types.EXECUTE_TX, | ||
Data: []byte("data"), | ||
Memo: "{\"callbacks\": {\"src_callback_address\": \"testAddress\"}}", | ||
Memo: "", | ||
}, | ||
}, | ||
{ | ||
"memo has dest callback address specified in json struct", | ||
types.InterchainAccountPacketData{ | ||
Type: types.EXECUTE_TX, | ||
Data: []byte("data"), | ||
Memo: "{\"callbacks\": {\"dest_callback_address\": \"testAddress\"}}", | ||
}, | ||
"testAddress", | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
srcCbAddr := tc.packetData.GetSrcCallbackAddress() | ||
suite.Require().Equal(tc.expSrcCallbackAddr, srcCbAddr, "%s testcase does not have expected src_callback_address", tc.name) | ||
tc := tc | ||
suite.Run(tc.name, func() { | ||
destCbAddr := tc.packetData.GetDestCallbackAddress() | ||
suite.Require().Equal("", destCbAddr) | ||
}) | ||
} | ||
} | ||
|
||
func (suite *TypesTestSuite) TestUserDefinedGasLimit() { | ||
packetData := types.InterchainAccountPacketData{ | ||
Type: types.EXECUTE_TX, | ||
Data: []byte("data"), | ||
Memo: "{\"callbacks\": {\"user_defined_gas_limit\": 100}}", | ||
} | ||
|
||
suite.Require().Equal(uint64(0), packetData.UserDefinedGasLimit(), "user defined gas limit does not return 0") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately to unmarshal into an interface, you need to marshal into an interface (ie, an any). Using
packet.GetData()
will cause this to failThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update ADR 8 if we go with the hardcoded supported packet data type approach. That is, require the ADR to have a list of supported packet data types. This could also be defined at the app.go layer when creating ibc stacks since there is only one packet data type per stack, so you could specify that the transfer stack should unmarshal into fungible token packet data
This change would essentially mean the
CallbackPacketData
is just used for compliance purposesThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, I think we should just remove all the codec related code here