Contract-to-contract send works
This commit is contained in:
2
go.mod
2
go.mod
@@ -4,7 +4,7 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcd v0.0.0-20190807005414-4063feeff79a // indirect
|
||||
github.com/confio/go-cosmwasm v0.6.1
|
||||
github.com/confio/go-cosmwasm v0.6.2
|
||||
github.com/cosmos/cosmos-sdk v0.34.4-0.20191114141721-d4c831e63ad3
|
||||
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect
|
||||
github.com/golang/mock v1.3.1 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@@ -38,6 +38,8 @@ github.com/confio/go-cosmwasm v0.6.0 h1:6MsfozR4IWb+V9TgVhDoGvcEs0ItBCqHg4pGbMaf
|
||||
github.com/confio/go-cosmwasm v0.6.0/go.mod h1:pHipRby+f3cv97QPLELkzOAlNs/s87uDyhc+SnMn7L4=
|
||||
github.com/confio/go-cosmwasm v0.6.1 h1:ifjLWE4T0mKngoq+ubZdtfGJFNWyOeQpfJWNO9y6WKI=
|
||||
github.com/confio/go-cosmwasm v0.6.1/go.mod h1:pHipRby+f3cv97QPLELkzOAlNs/s87uDyhc+SnMn7L4=
|
||||
github.com/confio/go-cosmwasm v0.6.2 h1:UMi8mP6VjID1QMPnLMW6xP6zdn7hXmgQTOYSwQgCN0k=
|
||||
github.com/confio/go-cosmwasm v0.6.2/go.mod h1:pHipRby+f3cv97QPLELkzOAlNs/s87uDyhc+SnMn7L4=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
|
||||
@@ -296,43 +296,55 @@ func (k Keeper) dispatchMessages(ctx sdk.Context, contract exported.Account, msg
|
||||
}
|
||||
|
||||
func (k Keeper) dispatchMessage(ctx sdk.Context, contract exported.Account, msg wasmTypes.CosmosMsg) error {
|
||||
// we check each type (pointers would make it easier to test if set)
|
||||
// maybe use this instead for the arg?
|
||||
contractAddr := contract.GetAddress()
|
||||
if msg.Send != nil {
|
||||
sendMsg, err := convertCosmosSendMsg(msg.Send)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return k.handleSdkMessage(ctx, contract, sendMsg)
|
||||
return k.sendTokens(ctx, contractAddr, msg.Send.FromAddress, msg.Send.ToAddress, msg.Send.Amount)
|
||||
} else if msg.Contract != nil {
|
||||
targetAddr, stderr := sdk.AccAddressFromBech32(msg.Contract.ContractAddr)
|
||||
if stderr != nil {
|
||||
return sdk.ErrInvalidAddress(msg.Contract.ContractAddr)
|
||||
}
|
||||
_, err := k.Execute(ctx, targetAddr, contract.GetAddress(), []byte(msg.Contract.Msg), nil)
|
||||
err := k.sendTokens(ctx, contractAddr, contractAddr.String(), targetAddr.String(), msg.Contract.Send)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = k.Execute(ctx, targetAddr, contractAddr, []byte(msg.Contract.Msg), nil)
|
||||
return err // may be nil
|
||||
} else if msg.Opaque != nil {
|
||||
msg, err := ParseOpaqueMsg(k.cdc, msg.Opaque)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return k.handleSdkMessage(ctx, contract, msg)
|
||||
return k.handleSdkMessage(ctx, contractAddr, msg)
|
||||
}
|
||||
// what is it?
|
||||
panic(fmt.Sprintf("Unknown CosmosMsg: %#v", msg))
|
||||
}
|
||||
|
||||
func convertCosmosSendMsg(msg *wasmTypes.SendMsg) (bank.MsgSend, sdk.Error) {
|
||||
fromAddr, stderr := sdk.AccAddressFromBech32(msg.FromAddress)
|
||||
if stderr != nil {
|
||||
return bank.MsgSend{}, sdk.ErrInvalidAddress(msg.FromAddress)
|
||||
func (k Keeper) sendTokens(ctx sdk.Context, signer sdk.AccAddress, origin string, target string, tokens []wasmTypes.Coin) error {
|
||||
if len(tokens) == 0 {
|
||||
return nil
|
||||
}
|
||||
toAddr, stderr := sdk.AccAddressFromBech32(msg.ToAddress)
|
||||
msg, err := convertCosmosSendMsg(origin, target, tokens)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return k.handleSdkMessage(ctx, signer, msg)
|
||||
}
|
||||
|
||||
func convertCosmosSendMsg(from string, to string, coins []wasmTypes.Coin) (bank.MsgSend, sdk.Error) {
|
||||
fromAddr, stderr := sdk.AccAddressFromBech32(from)
|
||||
if stderr != nil {
|
||||
return bank.MsgSend{}, sdk.ErrInvalidAddress(msg.ToAddress)
|
||||
return bank.MsgSend{}, sdk.ErrInvalidAddress(from)
|
||||
}
|
||||
toAddr, stderr := sdk.AccAddressFromBech32(to)
|
||||
if stderr != nil {
|
||||
return bank.MsgSend{}, sdk.ErrInvalidAddress(to)
|
||||
}
|
||||
|
||||
var coins sdk.Coins
|
||||
for _, coin := range msg.Amount {
|
||||
var toSend sdk.Coins
|
||||
for _, coin := range coins {
|
||||
amount, ok := sdk.NewIntFromString(coin.Amount)
|
||||
if !ok {
|
||||
return bank.MsgSend{}, sdk.ErrInvalidCoins(coin.Amount + coin.Denom)
|
||||
@@ -341,19 +353,18 @@ func convertCosmosSendMsg(msg *wasmTypes.SendMsg) (bank.MsgSend, sdk.Error) {
|
||||
Denom: coin.Denom,
|
||||
Amount: amount,
|
||||
}
|
||||
coins = append(coins, c)
|
||||
toSend = append(toSend, c)
|
||||
}
|
||||
sendMsg := bank.MsgSend{
|
||||
FromAddress: fromAddr,
|
||||
ToAddress: toAddr,
|
||||
Amount: coins,
|
||||
Amount: toSend,
|
||||
}
|
||||
return sendMsg, nil
|
||||
}
|
||||
|
||||
func (k Keeper) handleSdkMessage(ctx sdk.Context, contract exported.Account, msg sdk.Msg) error {
|
||||
func (k Keeper) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Address, msg sdk.Msg) error {
|
||||
// make sure this account can send it
|
||||
contractAddr := contract.GetAddress()
|
||||
for _, acct := range msg.GetSigners() {
|
||||
if !acct.Equals(contractAddr) {
|
||||
return sdkErrors.Wrap(sdkErrors.ErrUnauthorized, "contract doesn't have permission")
|
||||
|
||||
@@ -212,6 +212,11 @@ func checkAccount(t *testing.T, ctx sdk.Context, accKeeper auth.AccountKeeper, a
|
||||
assert.Nil(t, acct)
|
||||
} else {
|
||||
assert.NotNil(t, acct)
|
||||
assert.Equal(t, acct.GetCoins(), expected)
|
||||
if expected.Empty() {
|
||||
// there is confusion between nil and empty slice... let's just treat them the same
|
||||
assert.True(t, acct.GetCoins().Empty())
|
||||
} else {
|
||||
assert.Equal(t, acct.GetCoins(), expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user