Skip to content

Commit d2e136f

Browse files
ash-burnt2xburntPeartesedjroz
authored
Contract Event Emission (#283)
Signed-off-by: TwiceBurnt <169301814+2xburnt@users.noreply.github.com> Co-authored-by: TwiceBurnt <169301814+2xburnt@users.noreply.github.com> Co-authored-by: peartes <kenny.fale.kf@gmail.com> Co-authored-by: Eduardo Diaz <eduardo.j.diaz.rodriguez@gmail.com>
1 parent 754ea4d commit d2e136f

8 files changed

Lines changed: 356 additions & 7 deletions

File tree

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,12 @@ test-integration-xion-send-platform-fee: compile-integration-tests
237237
test-integration-xion-abstract-account: compile-integration-tests
238238
$(MAKE) run-integration-test TEST_NAME=XionAbstractAccount
239239

240+
test-integration-xion-abstract-account-event: compile_integration_tests
241+
$(MAKE) run-integration-test TEST_NAME=XionClientEvent
242+
243+
test-integration-xion-min-default: compile_integration_tests
244+
$(MAKE) run-integration-test TEST_NAME=TestXionMinimumFeeDefault
245+
240246
test-integration-xion-min-default: compile-integration-tests
241247
$(MAKE) run-integration-test TEST_NAME=TestXionMinimumFeeDefault
242248

app/app.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,8 @@ func NewWasmApp(
563563
// See: https://docs.cosmos.network/main/modules/gov#proposal-messages
564564
govRouter := govv1beta1.NewRouter()
565565
govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
566-
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper))
566+
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
567+
AddRoute(feeabstypes.ModuleName, feeabs.NewHostZoneProposal(app.FeeAbsKeeper))
567568
govConfig := govtypes.DefaultConfig()
568569
/*
569570
Example of setting gov params:

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ require (
5959
github.com/hashicorp/go-metrics v0.5.3
6060
github.com/larry0x/abstract-account v0.0.0-20240202022305-255071ed91ee
6161
github.com/lestrrat-go/jwx/v2 v2.0.21
62-
github.com/osmosis-labs/fee-abstraction/v8 v8.0.1
62+
github.com/osmosis-labs/fee-abstraction/v8 v8.0.2
6363
github.com/prometheus/client_golang v1.20.5
6464
github.com/spf13/cast v1.7.1
6565
github.com/spf13/cobra v1.8.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -913,8 +913,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
913913
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
914914
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
915915
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
916-
github.com/osmosis-labs/fee-abstraction/v8 v8.0.1 h1:WTmn5ddKtWZc4Ppz5XRdIUhlI0bQJsN0Yd8ybYpCUiU=
917-
github.com/osmosis-labs/fee-abstraction/v8 v8.0.1/go.mod h1:oixKpyWv08ZeFgZthXSNjiGz1wOhhJDUlSBXR3zQn+k=
916+
github.com/osmosis-labs/fee-abstraction/v8 v8.0.2 h1:z8GfKxGqkEB66rO2iDNJ6/IA62ZZlyitOeOvzE11LiY=
917+
github.com/osmosis-labs/fee-abstraction/v8 v8.0.2/go.mod h1:nNhh1fdDIXVK7xY/ji4qRNCkPEzgPrlJ1FD/ox3U+Oo=
918918
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
919919
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
920920
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=

integration_tests/abstract_account_test.go

Lines changed: 289 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package integration_tests
22

33
import (
4+
"context"
45
"crypto/sha256"
56
"encoding/base64"
67
"encoding/hex"
@@ -29,6 +30,9 @@ import (
2930
"github.com/stretchr/testify/require"
3031

3132
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
33+
cometClient "github.com/cometbft/cometbft/rpc/client"
34+
rpchttp "github.com/cometbft/cometbft/rpc/client/http"
35+
cometRpcCoreTypes "github.com/cometbft/cometbft/rpc/core/types"
3236
"github.com/cosmos/cosmos-sdk/crypto/keyring"
3337
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
3438
aatypes "github.com/larry0x/abstract-account/x/abstractaccount/types"
@@ -580,7 +584,7 @@ func TestXionAbstractAccount(t *testing.T) {
580584
aaContractAddr,
581585
path.Join(xion.GetNode().HomeDir(), removeFilePath[len(removeFilePath)-1]),
582586
"--chain-id", xion.Config().ChainID,
583-
"--authenticator-id", "1",
587+
"--nuthenticator-id", "1",
584588
)
585589
require.NoError(t, err)
586590

@@ -617,3 +621,287 @@ func GetAAContractAddress(t *testing.T, txDetails map[string]interface{}) string
617621

618622
return addr
619623
}
624+
625+
func TestXionClientEvent(t *testing.T) {
626+
if testing.Short() {
627+
t.Skip("skipping in short mode")
628+
}
629+
630+
t.Parallel()
631+
td := BuildXionChain(t, "0.0uxion", ModifyInterChainGenesis(ModifyInterChainGenesisFn{ModifyGenesisShortProposals}, [][]string{{votingPeriod, maxDepositPeriod}}))
632+
xion, ctx := td.xionChain, td.ctx
633+
634+
config := types.GetConfig()
635+
config.SetBech32PrefixForAccount("xion", "xionpub")
636+
637+
// Create and Fund User Wallets
638+
t.Log("creating and funding user accounts")
639+
fundAmount := math.NewInt(10_000_000)
640+
xionUser, err := ibctest.GetAndFundTestUserWithMnemonic(ctx, "default", deployerMnemonic, fundAmount, xion)
641+
require.NoError(t, err)
642+
currentHeight, _ := xion.Height(ctx)
643+
err = testutil.WaitForBlocks(ctx, int(currentHeight)+8, xion)
644+
require.NoError(t, err)
645+
t.Logf("created xion user %s", xionUser.FormattedAddress())
646+
647+
xionUserBalInitial, err := xion.GetBalance(ctx, xionUser.FormattedAddress(), xion.Config().Denom)
648+
require.NoError(t, err)
649+
require.Equal(t, fundAmount, xionUserBalInitial)
650+
651+
// Create a Secondary Key For Rotation
652+
recipientKeyName := "recipient-key"
653+
err = xion.CreateKey(ctx, recipientKeyName)
654+
require.NoError(t, err)
655+
receipientKeyAddressBytes, err := xion.GetAddress(ctx, recipientKeyName)
656+
require.NoError(t, err)
657+
recipientKeyAddress, err := types.Bech32ifyAddressBytes(xion.Config().Bech32Prefix, receipientKeyAddressBytes)
658+
require.NoError(t, err)
659+
660+
// Get Public Key For Funded Account
661+
account, err := ExecBin(t, ctx, xion.GetNode(),
662+
"keys", "show",
663+
xionUser.KeyName(),
664+
"--keyring-backend", keyring.BackendTest,
665+
"-p",
666+
)
667+
require.NoError(t, err)
668+
t.Log("Funded Account:")
669+
for k, v := range account {
670+
t.Logf("[%s]: %v", k, v)
671+
}
672+
673+
fp, err := os.Getwd()
674+
require.NoError(t, err)
675+
676+
// Store Wasm Contract
677+
codeID, err := xion.StoreContract(ctx, xionUser.FormattedAddress(), path.Join(fp,
678+
"integration_tests", "testdata", "contracts", "account-wasm-updatable-event-aarch64.wasm"))
679+
require.NoError(t, err)
680+
681+
// retrieve the hash
682+
codeResp, err := ExecQuery(t, ctx, xion.GetNode(),
683+
"wasm", "code-info", codeID)
684+
require.NoError(t, err)
685+
t.Logf("code response: %s", codeResp)
686+
687+
depositedFunds := fmt.Sprintf("%d%s", 100000, xion.Config().Denom)
688+
689+
registeredTxHash, err := ExecTx(t, ctx, xion.GetNode(),
690+
xionUser.KeyName(),
691+
"xion", "register",
692+
codeID,
693+
xionUser.KeyName(),
694+
"--funds", depositedFunds,
695+
"--salt", "0",
696+
"--authenticator", "Secp256K1",
697+
"--chain-id", xion.Config().ChainID,
698+
)
699+
require.NoError(t, err)
700+
t.Logf("tx hash: %s", registeredTxHash)
701+
702+
txDetails, err := ExecQuery(t, ctx, xion.GetNode(), "tx", registeredTxHash)
703+
require.NoError(t, err)
704+
t.Logf("TxDetails: %s", txDetails)
705+
aaContractAddr := GetAAContractAddress(t, txDetails)
706+
707+
contractBalance, err := xion.GetBalance(ctx, aaContractAddr, xion.Config().Denom)
708+
require.NoError(t, err)
709+
require.Equal(t, math.NewInt(100000), contractBalance)
710+
711+
contractState, err := ExecQuery(t, ctx, xion.GetNode(), "wasm", "contract-state", "smart", aaContractAddr, `{"authenticator_by_i_d":{ "id": 0 }}`)
712+
require.NoError(t, err)
713+
714+
pubkey64, ok := contractState["data"].(string)
715+
require.True(t, ok)
716+
pubkeyRawJSON, err := base64.StdEncoding.DecodeString(pubkey64)
717+
require.NoError(t, err)
718+
var pubKeyMap jsonAuthenticator
719+
json.Unmarshal(pubkeyRawJSON, &pubKeyMap)
720+
require.Equal(t, account["key"], pubKeyMap["Secp256K1"]["pubkey"])
721+
722+
// Generate Msg Send without signatures
723+
jsonMsg := RawJSONMsgSend(t, aaContractAddr, recipientKeyAddress, xion.Config().Denom)
724+
require.NoError(t, err)
725+
require.True(t, json.Valid(jsonMsg))
726+
727+
sendFile, err := os.CreateTemp("", "*-msg-bank-send.json")
728+
require.NoError(t, err)
729+
defer os.Remove(sendFile.Name())
730+
731+
_, err = sendFile.Write(jsonMsg)
732+
require.NoError(t, err)
733+
734+
err = UploadFileToContainer(t, ctx, xion.GetNode(), sendFile)
735+
require.NoError(t, err)
736+
737+
// Sign and broadcast a transaction
738+
sendFilePath := strings.Split(sendFile.Name(), "/")
739+
_, err = ExecTx(t, ctx, xion.GetNode(),
740+
xionUser.KeyName(),
741+
"xion", "sign",
742+
xionUser.KeyName(),
743+
aaContractAddr,
744+
path.Join(xion.GetNode().HomeDir(), sendFilePath[len(sendFilePath)-1]),
745+
"--chain-id", xion.Config().ChainID,
746+
)
747+
require.NoError(t, err)
748+
749+
err = testutil.WaitForBlocks(ctx, 1, xion)
750+
require.NoError(t, err)
751+
752+
// Confirm the updated balance
753+
balance, err := xion.GetBalance(ctx, recipientKeyAddress, xion.Config().Denom)
754+
require.NoError(t, err)
755+
require.Equal(t, math.NewInt(100000).Uint64(), balance.Uint64())
756+
757+
// Generate Key Rotation Msg
758+
account, err = ExecBin(t, ctx, xion.GetNode(),
759+
"keys", "show",
760+
xionUser.KeyName(),
761+
"--keyring-backend", keyring.BackendTest,
762+
"-p",
763+
)
764+
765+
// add secondary authenticator to account. in this case, the same key but in a different position
766+
jsonExecMsgStr, err := GenerateTx(t, ctx, xion.GetNode(),
767+
xionUser.KeyName(),
768+
"xion", "add-authenticator", aaContractAddr,
769+
"--authenticator-id", "1",
770+
"--chain-id", xion.Config().ChainID,
771+
)
772+
require.NoError(t, err)
773+
jsonExecMsg := []byte(jsonExecMsgStr)
774+
require.True(t, json.Valid(jsonExecMsg))
775+
776+
rotateFile, err := os.CreateTemp("", "*-msg-exec-rotate-key.json")
777+
require.NoError(t, err)
778+
defer os.Remove(rotateFile.Name())
779+
780+
_, err = rotateFile.Write(jsonExecMsg)
781+
require.NoError(t, err)
782+
783+
err = UploadFileToContainer(t, ctx, xion.GetNode(), rotateFile)
784+
require.NoError(t, err)
785+
786+
rotateFilePath := strings.Split(rotateFile.Name(), "/")
787+
788+
_, err = ExecTx(t, ctx, xion.GetNode(),
789+
xionUser.KeyName(),
790+
"xion", "sign",
791+
xionUser.KeyName(),
792+
aaContractAddr,
793+
path.Join(xion.GetNode().HomeDir(), rotateFilePath[len(rotateFilePath)-1]),
794+
"--chain-id", xion.Config().ChainID,
795+
)
796+
require.NoError(t, err)
797+
updatedContractState, err := ExecQuery(t, ctx, xion.GetNode(), "wasm", "contract-state", "smart", aaContractAddr, `{"authenticator_by_i_d":{ "id": 1 }}`)
798+
require.NoError(t, err)
799+
800+
updatedPubKey, ok := updatedContractState["data"].(string)
801+
require.True(t, ok)
802+
803+
updatedPubKeyRawJSON, err := base64.StdEncoding.DecodeString(updatedPubKey)
804+
require.NoError(t, err)
805+
var updatedPubKeyMap jsonAuthenticator
806+
807+
err = json.Unmarshal(updatedPubKeyRawJSON, &updatedPubKeyMap)
808+
require.NoError(t, err)
809+
require.Equal(t, account["key"], updatedPubKeyMap["Secp256K1"]["pubkey"])
810+
811+
cometWsClient, err := getCometClient(xion.GetHostRPCAddress()) // Note: add a close function
812+
require.NoError(t, err)
813+
fmt.Printf("%+v\n", xion.GetNode())
814+
815+
err = cometWsClient.Start()
816+
require.NoError(t, err)
817+
818+
//eventStream, err := subscribeToEvent(t, ctx, cometTypes.EventTx, cometWsClient)
819+
eventStream, err := subscribeToEvent(t, ctx, cometWsClient)
820+
821+
require.NoError(t, err)
822+
823+
doneChan := make(chan struct{})
824+
go receiveEvents(t, doneChan, eventStream)
825+
826+
jsonExecMsgStr, err = GenerateTx(t, ctx, xion.GetNode(),
827+
xionUser.KeyName(),
828+
"xion", "emit", "arbitrary_data", aaContractAddr,
829+
"--authenticator-id", "0",
830+
"--chain-id", xion.Config().ChainID,
831+
)
832+
833+
require.NoError(t, err)
834+
jsonExecMsg = []byte(jsonExecMsgStr)
835+
require.True(t, json.Valid(jsonExecMsg))
836+
837+
rotateFile, err = os.CreateTemp("", "*-msg-exec-emit.json")
838+
require.NoError(t, err)
839+
defer os.Remove(rotateFile.Name())
840+
841+
_, err = rotateFile.Write(jsonExecMsg)
842+
require.NoError(t, err)
843+
844+
err = UploadFileToContainer(t, ctx, xion.GetNode(), rotateFile)
845+
require.NoError(t, err)
846+
847+
rotateFilePath = strings.Split(rotateFile.Name(), "/")
848+
849+
_, err = ExecTx(t, ctx, xion.GetNode(),
850+
xionUser.KeyName(),
851+
"xion", "sign",
852+
xionUser.KeyName(),
853+
aaContractAddr,
854+
path.Join(xion.GetNode().HomeDir(), rotateFilePath[len(rotateFilePath)-1]),
855+
"--chain-id", xion.Config().ChainID,
856+
)
857+
require.NoError(t, err) // it's returning an error and it's not throwing
858+
fmt.Println("we have thrown a transaction")
859+
860+
//wg.Wait()
861+
<-doneChan
862+
stopClient(ctx, cometWsClient)
863+
}
864+
865+
func getCometClient(hostAddr string) (cometClient.Client, error) {
866+
return rpchttp.New(hostAddr, "/websocket")
867+
}
868+
869+
func subscribeToEvent(t *testing.T, ctx context.Context, cli cometClient.Client) (<-chan cometRpcCoreTypes.ResultEvent, error) {
870+
return cli.Subscribe(ctx, "helpers", "message.module='wasm' AND message.action='/cosmwasm.wasm.v1.MsgExecuteContract'")
871+
}
872+
873+
func receiveEvents(t *testing.T, done chan<- struct{}, eventStream <-chan cometRpcCoreTypes.ResultEvent) {
874+
for {
875+
select {
876+
case event := <-eventStream:
877+
fmt.Println("event intercepted")
878+
contractAddress, ok := event.Events["wasm-account_emit._contract_address"]
879+
if !ok {
880+
fmt.Println("not desired event")
881+
continue
882+
}
883+
arbData, ok := event.Events["wasm-account_emit.data"]
884+
if !ok {
885+
fmt.Println("not desired event")
886+
continue
887+
}
888+
fmt.Println(contractAddress)
889+
fmt.Println(arbData)
890+
done <- struct{}{}
891+
return
892+
default:
893+
continue
894+
}
895+
}
896+
}
897+
898+
func stopClient(ctx context.Context, cli cometClient.Client) error {
899+
if err := cli.UnsubscribeAll(ctx, "helpers"); err != nil {
900+
return err
901+
}
902+
903+
if err := cli.Stop(); err != nil {
904+
return err
905+
}
906+
return nil
907+
}

integration_tests/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
10361036
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
10371037
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
10381038
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
1039-
github.com/osmosis-labs/fee-abstraction/v8 v8.0.1 h1:WTmn5ddKtWZc4Ppz5XRdIUhlI0bQJsN0Yd8ybYpCUiU=
1040-
github.com/osmosis-labs/fee-abstraction/v8 v8.0.1/go.mod h1:oixKpyWv08ZeFgZthXSNjiGz1wOhhJDUlSBXR3zQn+k=
1039+
github.com/osmosis-labs/fee-abstraction/v8 v8.0.2 h1:z8GfKxGqkEB66rO2iDNJ6/IA62ZZlyitOeOvzE11LiY=
1040+
github.com/osmosis-labs/fee-abstraction/v8 v8.0.2/go.mod h1:nNhh1fdDIXVK7xY/ji4qRNCkPEzgPrlJ1FD/ox3U+Oo=
10411041
github.com/oxyno-zeta/gomock-extra-matcher v1.2.0 h1:WPEclU0y0PMwUzdDcaKZvld4aXpa3fkzjiUMQdcBEHg=
10421042
github.com/oxyno-zeta/gomock-extra-matcher v1.2.0/go.mod h1:S0r7HmKeCGsHmvIVFMjKWwswb4+30nCNWbXRMBVPkaU=
10431043
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
Binary file not shown.

0 commit comments

Comments
 (0)