Skip to content
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

updated contracts for dlmalloc issue #216

Merged
merged 3 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ jobs:
- "XionTokenFactory"
- "XionAbstractAccountJWTCLI"
- "TreasuryContract"
- "SingleAbstractAccountMigration"

steps:
- name: Set up Go 1.21
Expand Down
305 changes: 305 additions & 0 deletions integration_tests/account_migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/cosmos/cosmos-sdk/types/tx/signing"
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
"os"
"path"
"testing"
Expand Down Expand Up @@ -229,3 +231,306 @@ func addAccounts(t *testing.T, ctx context.Context, xion *cosmos.CosmosChain, no
}
return predictedAddrs
}

func TestSingleAbstractAccountMigration(t *testing.T) {
if testing.Short() {
t.Skip("skipping in short mode")
}

t.Parallel()
td := BuildXionChain(t, "0.0uxion", ModifyInterChainGenesis(ModifyInterChainGenesisFn{ModifyGenesisShortProposals}, [][]string{{votingPeriod, maxDepositPeriod}}))
xion, ctx := td.xionChain, td.ctx

config := types.GetConfig()
config.SetBech32PrefixForAccount("xion", "xionpub")

// Register All messages we are interacting.
xion.Config().EncodingConfig.InterfaceRegistry.RegisterImplementations(
(*types.Msg)(nil),
&xiontypes.MsgSetPlatformPercentage{},
&xiontypes.MsgSend{},
&wasmtypes.MsgInstantiateContract{},
&wasmtypes.MsgExecuteContract{},
&wasmtypes.MsgStoreCode{},
&aatypes.MsgUpdateParams{},
&aatypes.MsgRegisterAccount{},
)

xion.Config().EncodingConfig.InterfaceRegistry.RegisterImplementations((*authtypes.AccountI)(nil), &aatypes.AbstractAccount{})
xion.Config().EncodingConfig.InterfaceRegistry.RegisterImplementations((*cryptotypes.PubKey)(nil), &aatypes.NilPubKey{})

// Create and Fund User Wallets
t.Log("creating and funding user accounts")
fundAmount := int64(10_000_000)
xionUser, err := ibctest.GetAndFundTestUserWithMnemonic(ctx, "default", deployerMnemonic, fundAmount, xion)
require.NoError(t, err)
currentHeight, _ := xion.Height(ctx)
err = testutil.WaitForBlocks(ctx, int(currentHeight)+8, xion)
require.NoError(t, err)
t.Logf("created xion user %s", xionUser.FormattedAddress())

xionUserBalInitial, err := xion.GetBalance(ctx, xionUser.FormattedAddress(), xion.Config().Denom)
require.NoError(t, err)
require.Equal(t, fundAmount, xionUserBalInitial)

// load the test private key
privateKeyBz, err := os.ReadFile("./integration_tests/testdata/keys/jwtRS256.key")
require.NoError(t, err)
privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyBz)
require.NoError(t, err)
t.Logf("private key: %v", privateKey)

// log the test public key
publicKey, err := jwk.New(privateKey)
require.NoError(t, err)
publicKey, err = publicKey.PublicKey()
require.NoError(t, err)
publicKeyJSON, err := json.Marshal(publicKey)
require.NoError(t, err)
t.Logf("public key: %s", publicKeyJSON)

// build the jwk key
testKey, err := jwk.ParseKey(privateKeyBz, jwk.WithPEM(true))
require.NoError(t, err)
err = testKey.Set("alg", "RS256")
require.NoError(t, err)
testKeyPublic, err := testKey.PublicKey()
require.NoError(t, err)
testPublicKeyJSON, err := json.Marshal(testKeyPublic)
require.NoError(t, err)

// deploy the key to the jwk module
aud := "integration-test-project"

createAudienceClaimHash, err := ExecTx(t, ctx, xion.FullNodes[0],
xionUser.KeyName(),
"jwk", "create-audience-claim",
aud,
"--chain-id", xion.Config().ChainID,
)
require.NoError(t, err)
t.Logf("create audience claim hash: %s", createAudienceClaimHash)

txDetails, err := ExecQuery(t, ctx, xion.FullNodes[0], "tx", createAudienceClaimHash)
require.NoError(t, err)
t.Logf("TxDetails: %s", txDetails)

createAudienceHash, err := ExecTx(t, ctx, xion.FullNodes[0],
xionUser.KeyName(),
"jwk", "create-audience",
aud,
string(testPublicKeyJSON),
"--chain-id", xion.Config().ChainID,
)
require.NoError(t, err)
t.Logf("create audience hash: %s", createAudienceHash)

// Store Wasm Contracts
fp, err := os.Getwd()
require.NoError(t, err)
codeIDStr, err := xion.StoreContract(ctx, xionUser.FormattedAddress(), path.Join(fp,
"integration_tests", "testdata", "contracts", "account_updatable-aarch64-previous.wasm"))
require.NoError(t, err)

migrateTargetCodeIDStr, err := xion.StoreContract(ctx, xionUser.FormattedAddress(), path.Join(fp,
"integration_tests", "testdata", "contracts", "account_updatable-aarch64.wasm"))
require.NoError(t, err)

// retrieve the hash
codeResp, err := ExecQuery(t, ctx, xion.FullNodes[0],
"wasm", "code-info", codeIDStr)
require.NoError(t, err)
t.Logf("code response: %s", codeResp)

sub := "integration-test-user"

authenticatorDetails := map[string]interface{}{}
authenticatorDetails["sub"] = sub
authenticatorDetails["aud"] = aud
//authenticatorDetails["id"] = 0

authenticator := map[string]interface{}{}
authenticator["Jwt"] = authenticatorDetails

instantiateMsg := map[string]interface{}{}
instantiateMsg["id"] = 0
instantiateMsg["authenticator"] = authenticator

// predict the contract address so it can be verified
salt := "0"
creatorAddr := types.AccAddress(xionUser.Address())
codeHash, err := hex.DecodeString(codeResp["data_hash"].(string))
require.NoError(t, err)
predictedAddr := wasmkeeper.BuildContractAddressPredictable(codeHash, creatorAddr, []byte(salt), []byte{})
t.Logf("predicted address: %s", predictedAddr.String())

// b64 the contract address to use as the transaction hash
signatureBz := sha256.Sum256([]byte(predictedAddr.String()))
signature := base64.StdEncoding.EncodeToString(signatureBz[:])

now := time.Now()
fiveAgo := now.Add(-time.Second * 5)
inFive := now.Add(time.Minute * 5)

auds := jwt.ClaimStrings{aud}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"iss": aud,
"sub": sub,
"aud": auds,
"exp": inFive.Unix(),
"nbf": fiveAgo.Unix(),
"iat": fiveAgo.Unix(),
"transaction_hash": signature,
})
t.Logf("jwt claims: %v", token)

// sign the JWT with the predefined key
output, err := token.SignedString(privateKey)
require.NoError(t, err)
t.Logf("signed token: %s", output)

instantiateMsg["signature"] = []byte(output)
instantiateMsgStr, err := json.Marshal(instantiateMsg)
require.NoError(t, err)
t.Logf("inst msg: %s", string(instantiateMsgStr))

// register the account
t.Logf("registering account: %s", instantiateMsgStr)
registerCmd := []string{
"abstract-account", "register",
codeIDStr, string(instantiateMsgStr),
"--salt", salt,
"--funds", "10000uxion",
"--chain-id", xion.Config().ChainID,
}
t.Logf("sender: %s", xionUser.FormattedAddress())
t.Logf("register cmd: %s", registerCmd)

txHash, err := ExecTx(t, ctx, xion.FullNodes[0], xionUser.KeyName(), registerCmd...)
require.NoError(t, err)
t.Logf("tx hash: %s", txHash)

contractsResponse, err := ExecQuery(t, ctx, xion.FullNodes[0], "wasm", "contracts", codeIDStr)
require.NoError(t, err)

contract := contractsResponse["contracts"].([]interface{})[0].(string)

err = testutil.WaitForBlocks(ctx, 1, xion)
require.NoError(t, err)
newBalance, err := xion.GetBalance(ctx, contract, xion.Config().Denom)
require.NoError(t, err)
require.Equal(t, int64(10_000), newBalance)

// get the account from the chain. there might be a better way to do this
accountResponse, err := ExecQuery(t, ctx, xion.FullNodes[0],
"account", contract)
require.NoError(t, err)
t.Logf("account response: %s", accountResponse)

delete(accountResponse, "@type")
var account aatypes.AbstractAccount
accountJSON, err := json.Marshal(accountResponse)
require.NoError(t, err)

encodingConfig := xionapp.MakeEncodingConfig()
err = encodingConfig.Marshaler.UnmarshalJSON(accountJSON, &account)
require.NoError(t, err)

// Generate Msg Send without signatures
jsonMsg := RawJSONMsgMigrateContract(account.GetAddress().String(), migrateTargetCodeIDStr)
require.NoError(t, err)
require.True(t, json.Valid(jsonMsg))

tx, err := encodingConfig.TxConfig.TxJSONDecoder()([]byte(jsonMsg))
require.NoError(t, err)

signerData := authsigning.SignerData{
Address: account.GetAddress().String(),
ChainID: xion.Config().ChainID,
AccountNumber: account.GetAccountNumber(),
Sequence: account.GetSequence(),
PubKey: account.GetPubKey(),
}

txBuilder, err := encodingConfig.TxConfig.WrapTxBuilder(tx)
require.NoError(t, err)

sigData := signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: nil,
}

sig := signing.SignatureV2{
PubKey: account.GetPubKey(),
Data: &sigData,
Sequence: account.GetSequence(),
}

err = txBuilder.SetSignatures(sig)
require.NoError(t, err)

signBytes, err := encodingConfig.TxConfig.SignModeHandler().GetSignBytes(signing.SignMode_SIGN_MODE_DIRECT, signerData, txBuilder.GetTx())
require.NoError(t, err)

// our signature is the sha256 of the signbytes
signatureBz = sha256.Sum256(signBytes)
signature = base64.StdEncoding.EncodeToString(signatureBz[:])

// we need to create a new valid token, making sure the time works
now = time.Now()
fiveAgo = now.Add(-time.Second * 5)
inFive = now.Add(time.Minute * 5)

token = jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"iss": aud,
"sub": sub,
"aud": auds,
"exp": inFive.Unix(),
"nbf": fiveAgo.Unix(),
"iat": fiveAgo.Unix(),
"transaction_hash": signature,
})
t.Logf("jwt claims: %v", token)

// sign the JWT with the predefined key
signedTokenStr, err := token.SignedString(privateKey)
require.NoError(t, err)

// add the auth index to the signature
signedTokenBz := []byte(signedTokenStr)
sigBytes := append([]byte{0}, signedTokenBz...)

sigData = signing.SingleSignatureData{
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
Signature: sigBytes,
}

sig = signing.SignatureV2{
PubKey: account.GetPubKey(),
Data: &sigData,
Sequence: account.GetSequence(),
}
err = txBuilder.SetSignatures(sig)
require.NoError(t, err)

jsonTx, err := encodingConfig.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
require.NoError(t, err)
t.Logf("json tx: %s", jsonTx)

output, err = ExecBroadcast(t, ctx, xion.FullNodes[0], jsonTx)
require.NoError(t, err)
t.Logf("output: %s", output)

err = testutil.WaitForBlocks(ctx, 2, xion)
require.NoError(t, err)

// confirm the new contract code ID
rawUpdatedContractInfo, err := ExecQuery(t, ctx, td.xionChain.FullNodes[0],
"wasm", "contract", account.GetAddress().String())
require.NoError(t, err)
t.Logf("updated contract info: %s", rawUpdatedContractInfo)

updatedContractInfo := rawUpdatedContractInfo["contract_info"].(map[string]interface{})
updatedCodeID := updatedContractInfo["code_id"].(string)
require.Equal(t, updatedCodeID, migrateTargetCodeIDStr)
}
Binary file modified integration_tests/testdata/contracts/account_updatable-aarch64.wasm
100755 → 100644
Binary file not shown.
Binary file modified integration_tests/testdata/contracts/treasury-aarch64.wasm
100755 → 100644
Binary file not shown.
36 changes: 36 additions & 0 deletions integration_tests/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,42 @@ func RawJSONMsgExecContractRemoveAuthenticator(sender string, contract string, i
return rawMsg
}

func RawJSONMsgMigrateContract(sender string, codeID string) []byte {
msg := fmt.Sprintf(`

{
"body": {
"messages": [
{
"@type": "/cosmwasm.wasm.v1.MsgMigrateContract",
"sender": "%s",
"contract": "%s",
"code_id": "%s",
"msg": {}
}
],
"memo": "",
"timeout_height": "0",
"extension_options": [],
"non_critical_extension_options": []
},
"auth_info": {
"signer_infos": [],
"fee": {
"amount": [],
"gas_limit": "200000",
"payer": "",
"granter": ""
},
"tip": null
},
"signatures": []
}
`, sender, sender, codeID)
var rawMsg json.RawMessage = []byte(msg)
return rawMsg
}

func ParamChangeProposal(t *testing.T, subspace, key, value, title, description, deposit string) paramsutils.ParamChangeProposalJSON {
changes := paramsutils.ParamChangeJSON{
Subspace: subspace,
Expand Down
Loading