Skip to content

Commit

Permalink
test: config and remove keys
Browse files Browse the repository at this point in the history
  • Loading branch information
whalelephant committed Aug 8, 2021
1 parent 083bc30 commit 79c9c29
Show file tree
Hide file tree
Showing 10 changed files with 301 additions and 29 deletions.
14 changes: 7 additions & 7 deletions contracts/MultiSigFlowToken.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ pub contract MultiSigFlowToken: FungibleToken {
let manager = OnChainMultiSig.Manager(sigStore: self.signatureStore);
let p = manager.readyForExecution(txIndex: txIndex) ?? panic ("TX not ready for execution")
switch p.method {
case "configureKeys":
let pubKey = p.args[0].value as? [String] ?? panic ("cannot downcast public key");
let weight = p.args[1].value as? [UFix64] ?? panic ("cannot downcast weight");
let newSignatureStore = manager.configureKeys(pks: pubKey, kws: weight)
case "configureKey":
let pubKey = p.args[0].value as? String ?? panic ("cannot downcast public key");
let weight = p.args[1].value as? UFix64 ?? panic ("cannot downcast weight");
let newSignatureStore = manager.configureKeys(pks: [pubKey], kws: [weight])
self.signatureStore = newSignatureStore;
case "removeKeys":
let pubKey = p.args[0].value as? [String] ?? panic ("cannot downcast public key");
let newSignatureStore = manager.removeKeys(pks: pubKey)
case "removeKey":
let pubKey = p.args[0].value as? String ?? panic ("cannot downcast public key");
let newSignatureStore = manager.removeKeys(pks: [pubKey])
self.signatureStore = newSignatureStore;
case "withdraw":
let amount = p.args[0].value as? UFix64 ?? panic ("cannot downcast amount");
Expand Down
103 changes: 103 additions & 0 deletions lib/go/keys/keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package keys

import (
"github.com/bjartek/go-with-the-flow/gwtf"
util "github.com/flow-hydraulics/onchain-multisig"
"github.com/onflow/cadence"
)

func MultiSig_NewRemoveSignerPayload(
g *gwtf.GoWithTheFlow,
acctToRemove string,
signerAcct string,
vaultAcct string,
) (events []*gwtf.FormatedEvent, err error) {
txFilename := "../../../transactions/new_pending_remove_multisig_key.cdc"
txScript := util.ParseCadenceTemplate(txFilename)

method := "removeKey"
pkToRemove := g.Accounts[acctToRemove].PrivateKey.PublicKey().String()
signable, err := util.GetSignableDataFromScript(g, method, cadence.NewString(pkToRemove[2:]))
if err != nil {
return
}

sig, err := util.SignPayloadOffline(g, signable, signerAcct)
if err != nil {
return
}

signerPubKey := g.Accounts[signerAcct].PrivateKey.PublicKey().String()
e, err := g.TransactionFromFile(txFilename, txScript).
SignProposeAndPayAs(signerAcct).
StringArgument(signerPubKey[2:]).
StringArgument(sig).
AccountArgument(vaultAcct).
StringArgument(method).
StringArgument(pkToRemove[2:]).
Run()
events = util.ParseTestEvents(e)
return
}

func MultiSig_NewRemoveKeyPayloadSignature(
g *gwtf.GoWithTheFlow,
acctToRemove string,
txIndex uint64,
signerAcct string,
vaultAcct string,
) (events []*gwtf.FormatedEvent, err error) {
method := "removeKey"
pkToRemove := g.Accounts[acctToRemove].PrivateKey.PublicKey().String()
signable, err := util.GetSignableDataFromScript(g, method, cadence.NewString(pkToRemove[2:]))
if err != nil {
return
}

sig, err := util.SignPayloadOffline(g, signable, signerAcct)
if err != nil {
return
}

return util.MultiSigVault_NewPayloadSignature(g, txIndex, sig, signerAcct, vaultAcct)
}

func MultiSig_NewConfigSignerPayload(
g *gwtf.GoWithTheFlow,
acctToConfig string,
acctToConfigWeight string,
signerAcct string,
vaultAcct string,
) (events []*gwtf.FormatedEvent, err error) {
txFilename := "../../../transactions/new_pending_config_multisig_key.cdc"
txScript := util.ParseCadenceTemplate(txFilename)

method := "configureKey"
pkToConfig := g.Accounts[acctToConfig].PrivateKey.PublicKey().String()
weightToConfig, err := cadence.NewUFix64(acctToConfigWeight)
if err != nil {
return
}
signable, err := util.GetSignableDataFromScript(g, method, cadence.NewString(pkToConfig[2:]), weightToConfig)
if err != nil {
return
}

sig, err := util.SignPayloadOffline(g, signable, signerAcct)
if err != nil {
return
}

signerPubKey := g.Accounts[signerAcct].PrivateKey.PublicKey().String()
e, err := g.TransactionFromFile(txFilename, txScript).
SignProposeAndPayAs(signerAcct).
StringArgument(signerPubKey[2:]).
StringArgument(sig).
AccountArgument(vaultAcct).
StringArgument(method).
StringArgument(pkToConfig[2:]).
UFix64Argument(acctToConfigWeight).
Run()
events = util.ParseTestEvents(e)
return
}
84 changes: 84 additions & 0 deletions lib/go/keys/keys_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package keys

import (
"strconv"
"testing"

"github.com/bjartek/go-with-the-flow/gwtf"
util "github.com/flow-hydraulics/onchain-multisig"
"github.com/flow-hydraulics/onchain-multisig/vault"
"github.com/stretchr/testify/assert"
)

func TestAddNewPendingKeyRemoval(t *testing.T) {
g := gwtf.NewGoWithTheFlow("../../../flow.json")

vaultAcct := "vaulted-account"
payerAcct := "owner"

initTxIndex, err := util.GetTxIndex(g, vaultAcct)
assert.NoError(t, err)

events, err := MultiSig_NewRemoveSignerPayload(g, vault.Acct500_1, vault.Acct1000, vaultAcct)
assert.NoError(t, err)

postTxIndex, err := util.GetTxIndex(g, vaultAcct)
assert.NoError(t, err)
assert.Equal(t, uint64(1), postTxIndex-initTxIndex)

uuid, err := util.GetVaultUUID(g, vaultAcct)
assert.NoError(t, err)

util.NewExpectedEvent("OnChainMultiSig", "NewPayloadAdded").
AddField("resourceId", strconv.Itoa(int(uuid))).
AddField("txIndex", strconv.Itoa(int(postTxIndex))).
AssertEqual(t, events[0])

_, err = vault.MultiSig_VaultExecuteTx(g, postTxIndex, payerAcct, vaultAcct)
assert.NoError(t, err)

removedPk := g.Accounts[vault.Acct500_1].PrivateKey.PublicKey().String()[2:]
keys, err := util.GetStoreKeys(g, vaultAcct)
var removed bool = true
for _, key := range keys {
if key == removedPk {
removed = false
}
}
assert.Equal(t, removed, true)
}

func TestRemovaledKeyCannotAddSig(t *testing.T) {
g := gwtf.NewGoWithTheFlow("../../../flow.json")

vaultAcct := "vaulted-account"
removedAcct := vault.Acct500_1

_, err := MultiSig_NewRemoveKeyPayloadSignature(g, removedAcct, 1, removedAcct, vaultAcct)
assert.Error(t, err)
}

func TestAddNewPendingKeyConfig(t *testing.T) {
g := gwtf.NewGoWithTheFlow("../../../flow.json")

vaultAcct := "vaulted-account"
payerAcct := "owner"
newAcct := vault.Acct500_1
newAcctWeight := "100.00000000"

initTxIndex, err := util.GetTxIndex(g, vaultAcct)
assert.NoError(t, err)

_, err = MultiSig_NewConfigSignerPayload(g, newAcct, newAcctWeight, vault.Acct1000, vaultAcct)
assert.NoError(t, err)

postTxIndex, err := util.GetTxIndex(g, vaultAcct)
assert.NoError(t, err)
assert.Equal(t, uint64(1), postTxIndex-initTxIndex)

_, err = vault.MultiSig_VaultExecuteTx(g, postTxIndex, payerAcct, vaultAcct)
assert.NoError(t, err)

weight, err := util.GetKeyWeight(g, vaultAcct, newAcct)
assert.Equal(t, newAcctWeight, weight.String())
}
1 change: 1 addition & 0 deletions lib/go/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ go clean -testcache

go run scripts/deploy/deploy.go
go test ./vault -v
go test ./keys -v
37 changes: 37 additions & 0 deletions lib/go/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,21 @@ func GetStoreKeys(g *gwtf.GoWithTheFlow, account string) (result []string, err e
return
}

func GetKeyWeight(g *gwtf.GoWithTheFlow, resourceAcct string, signerAcct string) (result cadence.UFix64, err error) {
filename := "../../../scripts/get_key_weight.cdc"
script := ParseCadenceTemplate(filename)
signerPubKey := g.Accounts[signerAcct].PrivateKey.PublicKey().String()[2:]
value, err := g.ScriptFromFile(filename, script).
AccountArgument(resourceAcct).
StringArgument(signerPubKey).
RunReturns()
if err != nil {
return
}
result = value.(cadence.UFix64)
return
}

func GetTxIndex(g *gwtf.GoWithTheFlow, account string) (result uint64, err error) {
filename := "../../../scripts/get_store_tx_index.cdc"
script := ParseCadenceTemplate(filename)
Expand Down Expand Up @@ -213,3 +228,25 @@ func GetSignableDataFromScript(
}
return
}

func MultiSigVault_NewPayloadSignature(
g *gwtf.GoWithTheFlow,
txIndex uint64,
sig string,
signerAcct string,
resourceAcct string,
) (events []*gwtf.FormatedEvent, err error) {
txFilename := "../../../transactions/add_payload_signature.cdc"
txScript := ParseCadenceTemplate(txFilename)

signerPubKey := g.Accounts[signerAcct].PrivateKey.PublicKey().String()
e, err := g.TransactionFromFile(txFilename, txScript).
SignProposeAndPayAs(signerAcct).
UInt64Argument(txIndex).
StringArgument(signerPubKey[2:]).
StringArgument(sig).
AccountArgument(resourceAcct).
Run()
events = ParseTestEvents(e)
return
}
22 changes: 5 additions & 17 deletions lib/go/vault/vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,10 @@ func MultiSig_NewPendingTransferPayload(
return
}

pubKey := g.Accounts[signerAcct].PrivateKey.PublicKey().String()

signerPubKey := g.Accounts[signerAcct].PrivateKey.PublicKey().String()
e, err := g.TransactionFromFile(txFilename, txScript).
SignProposeAndPayAs(signerAcct).
StringArgument(pubKey).
StringArgument(signerPubKey[2:]).
StringArgument(sig).
AccountArgument(vaultAcct).
StringArgument(method).
Expand All @@ -114,9 +113,6 @@ func MultiSig_NewPayloadSignature(
signerAcct string,
vaultAcct string,
) (events []*gwtf.FormatedEvent, err error) {
txFilename := "../../../transactions/add_payload_signature.cdc"
txScript := util.ParseCadenceTemplate(txFilename)

method := "transfer"
ufix64, err := cadence.NewUFix64(amount)
if err != nil {
Expand All @@ -133,29 +129,21 @@ func MultiSig_NewPayloadSignature(
return
}

pubKey := g.Accounts[signerAcct].PrivateKey.PublicKey().String()
e, err := g.TransactionFromFile(txFilename, txScript).
SignProposeAndPayAs(signerAcct).
UInt64Argument(txIndex).
StringArgument(pubKey).
StringArgument(sig).
AccountArgument(vaultAcct).
Run()
events = util.ParseTestEvents(e)
return
return util.MultiSigVault_NewPayloadSignature(g, txIndex, sig, signerAcct, vaultAcct)
}

func MultiSig_VaultExecuteTx(
g *gwtf.GoWithTheFlow,
index uint64,
payerAcct string,
vaultAcct string,
) (events []*gwtf.FormatedEvent, err error) {
txFilename := "../../../transactions/executeTx.cdc"
txScript := util.ParseCadenceTemplate(txFilename)

e, err := g.TransactionFromFile(txFilename, txScript).
SignProposeAndPayAs(payerAcct).
AccountArgument("vaulted-account").
AccountArgument(vaultAcct).
UInt64Argument(index).
Run()
events = util.ParseTestEvents(e)
Expand Down
11 changes: 6 additions & 5 deletions lib/go/vault/vault_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,16 @@ func TestExecutePendingTransnferFromFullAcct(t *testing.T) {
g := gwtf.NewGoWithTheFlow("../../../flow.json")
transferAmount := "15.50000000"
payerAcct := "owner"
vaultAcct := "vaulted-account"
txIndex := uint64(1)

initFromBalance, err := util.GetBalance(g, "vaulted-account")
initFromBalance, err := util.GetBalance(g, vaultAcct)
assert.NoError(t, err)

_, err = MultiSig_VaultExecuteTx(g, txIndex, payerAcct)
_, err = MultiSig_VaultExecuteTx(g, txIndex, payerAcct, vaultAcct)
assert.NoError(t, err)

postFromBalance, err := util.GetBalance(g, "vaulted-account")
postFromBalance, err := util.GetBalance(g, vaultAcct)
assert.NoError(t, err)

assert.Equal(t, transferAmount, (initFromBalance - postFromBalance).String())
Expand Down Expand Up @@ -134,7 +135,7 @@ func TestExecutePayloadWithMultipleSig(t *testing.T) {
AssertEqual(t, events[0])

// This should fail because the weight is less than 1000
_, err = MultiSig_VaultExecuteTx(g, postTxIndex, payerAcct)
_, err = MultiSig_VaultExecuteTx(g, postTxIndex, payerAcct, vaultAcct)
assert.Error(t, err)

//
Expand All @@ -146,7 +147,7 @@ func TestExecutePayloadWithMultipleSig(t *testing.T) {
initFromBalance, err := util.GetBalance(g, "vaulted-account")
assert.NoError(t, err)

_, err = MultiSig_VaultExecuteTx(g, postTxIndex, payerAcct)
_, err = MultiSig_VaultExecuteTx(g, postTxIndex, payerAcct, vaultAcct)
assert.NoError(t, err)

postFromBalance, err := util.GetBalance(g, "vaulted-account")
Expand Down
15 changes: 15 additions & 0 deletions scripts/get_key_weight.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This script reads the balance field of an account's Balance
import FungibleToken from 0x{{.FungibleToken}}
import OnChainMultiSig from 0x{{.OnChainMultiSig}}
import MultiSigFlowToken from 0x{{.MultiSigFlowToken}}

pub fun main(account: Address, key: String): UFix64 {
let acct = getAccount(account)
let vaultRef = acct.getCapability(MultiSigFlowToken.VaultPubSigner)
.borrow<&MultiSigFlowToken.Vault{OnChainMultiSig.PublicSigner}>()
?? panic("Could not borrow Pub Signer reference to the Vault")

let attr = vaultRef.signatureStore!.keyList[key]!
return attr.weight
}
22 changes: 22 additions & 0 deletions transactions/new_pending_config_multisig_key.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Masterminter uses this to configure which minter the minter controller manages
import MultiSigFlowToken from 0x{{.MultiSigFlowToken}}
import OnChainMultiSig from 0x{{.OnChainMultiSig}}

transaction (publicKey: String, sig: String, addr: Address, method: String, pubKeyToConfig: String, weight: UFix64) {
prepare(oneOfMultiSig: AuthAccount) {
}

execute {
let vaultedAcct = getAccount(addr)

let pubSigRef = vaultedAcct.getCapability(MultiSigFlowToken.VaultPubSigner)
.borrow<&MultiSigFlowToken.Vault{OnChainMultiSig.PublicSigner}>()
?? panic("Could not borrow vault pub sig reference")

let pk = OnChainMultiSig.PayloadArg(t: Type<String>(), v: pubKeyToConfig);
let w = OnChainMultiSig.PayloadArg(t: Type<UFix64>(), v: weight);
let p = OnChainMultiSig.PayloadDetails(method: method, args: [pk, w]);
return pubSigRef.addNewPayload(payload: p, publicKey: publicKey, sig: sig.decodeHex())
}
}
Loading

0 comments on commit 79c9c29

Please sign in to comment.