diff --git a/client/client.go b/client/client.go index ad4fe7dc54c557e31439fb3fc21aa0454757d117..d131f510b8af05ee34f0566500bf377e97b1cceb 100644 --- a/client/client.go +++ b/client/client.go @@ -26,7 +26,7 @@ import ( "github.com/eris-ltd/eris-db/txs" ) -type NodeClient interface{ +type NodeClient interface { Broadcast(transaction txs.Tx) (*txs.Receipt, error) GetAccount(address []byte) (*account.Account, error) @@ -36,7 +36,7 @@ type NodeClient interface{ // eris-db/client.NodeClient var _ NodeClient = (*ErisNodeClient)(nil) -// Eris-Client is a simple struct exposing the client rpc methods +// Eris-Client is a simple struct exposing the client rpc methods type ErisNodeClient struct { broadcastRPC string @@ -44,7 +44,7 @@ type ErisNodeClient struct { // ErisKeyClient.New returns a new eris-keys client for provided rpc location // Eris-keys connects over http request-responses -func NewErisNodeClient(rpcString string) *ErisNodeClient{ +func NewErisNodeClient(rpcString string) *ErisNodeClient { return &ErisNodeClient{ broadcastRPC: rpcString, } @@ -53,7 +53,7 @@ func NewErisNodeClient(rpcString string) *ErisNodeClient{ //------------------------------------------------------------------------------------ // broadcast to blockchain node // NOTE: [ben] Eris Client first continues from tendermint rpc, but will have handshake to negotiate -// protocol version for moving towards rpc/v1 +// protocol version for moving towards rpc/v1 func (erisClient *ErisNodeClient) Broadcast(tx txs.Tx) (*txs.Receipt, error) { client := rpcclient.NewClientURI(erisClient.broadcastRPC) @@ -80,5 +80,3 @@ func (erisClient *ErisNodeClient) GetAccount(address []byte) (*account.Account, return account.Copy(), nil } - - diff --git a/client/cmd/transaction.go b/client/cmd/transaction.go index 2003ecc4478fc3cf4dc8e43540be6cd1f92a7c47..13076b0ec366a21a1e06082de52ff2dbf99f8e17 100644 --- a/client/cmd/transaction.go +++ b/client/cmd/transaction.go @@ -135,8 +135,6 @@ func buildTransactionCommand() { }, PreRun: assertParameters, } - permissionsCmd.Flags().StringVarP(&clientDo.AddrFlag, "addr", "a", "", "specify an address") - permissionsCmd.Flags().StringVarP(&clientDo.HeightFlag, "height", "n", "", "specify a height to unbond at") TransactionCmd.AddCommand(sendCmd, nameCmd, callCmd, bondCmd, unbondCmd, rebondCmd, permissionsCmd) } diff --git a/client/core/transaction_factory.go b/client/core/transaction_factory.go index 7ab278bd2c1b2d8c8f9a8723670cafa9d2af9568..73c6f5c2814b182a9588f960b2504acab1a9d910 100644 --- a/client/core/transaction_factory.go +++ b/client/core/transaction_factory.go @@ -23,7 +23,7 @@ import ( // "strings" // "time" - // ptypes "github.com/eris-ltd/permission/types" + ptypes "github.com/eris-ltd/eris-db/permission/types" // log "github.com/eris-ltd/eris-logger" @@ -120,79 +120,69 @@ var PermsFuncs = []PermFunc{ {"rm_role", "address, role"}, } -// func Permissions(nodeAddr, signAddr, pubkey, addrS, nonceS, permFunc string, argsS []string) (*txs.PermissionsTx, error) { -// pub, _, nonce, err := checkCommon(nodeAddr, signAddr, pubkey, addrS, "0", nonceS) -// if err != nil { -// return nil, err -// } -// var args ptypes.PermArgs -// switch permFunc { -// case "set_base": -// addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1]) -// if err != nil { -// return nil, err -// } -// if len(argsS) != 3 { -// return nil, fmt.Errorf("set_base also takes a value (true or false)") -// } -// var value bool -// if argsS[2] == "true" { -// value = true -// } else if argsS[2] == "false" { -// value = false -// } else { -// return nil, fmt.Errorf("Unknown value %s", argsS[2]) -// } -// args = &ptypes.SetBaseArgs{addr, pF, value} -// case "unset_base": -// addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1]) -// if err != nil { -// return nil, err -// } -// args = &ptypes.UnsetBaseArgs{addr, pF} -// case "set_global": -// pF, err := ptypes.PermStringToFlag(argsS[0]) -// if err != nil { -// return nil, err -// } -// var value bool -// if argsS[1] == "true" { -// value = true -// } else if argsS[1] == "false" { -// value = false -// } else { -// return nil, fmt.Errorf("Unknown value %s", argsS[1]) -// } -// args = &ptypes.SetGlobalArgs{pF, value} -// case "add_role": -// addr, err := hex.DecodeString(argsS[0]) -// if err != nil { -// return nil, err -// } -// args = &ptypes.AddRoleArgs{addr, argsS[1]} -// case "rm_role": -// addr, err := hex.DecodeString(argsS[0]) -// if err != nil { -// return nil, err -// } -// args = &ptypes.RmRoleArgs{addr, argsS[1]} -// default: -// return nil, fmt.Errorf("Invalid permission function for use in PermissionsTx: %s", permFunc) -// } -// // args := snativeArgs( -// tx := types.NewPermissionsTxWithNonce(pub, args, int(nonce)) -// return tx, nil -// } - -// func decodeAddressPermFlag(addrS, permFlagS string) (addr []byte, pFlag ptypes.PermFlag, err error) { -// if addr, err = hex.DecodeString(addrS); err != nil { -// return -// } -// if pFlag, err = ptypes.PermStringToFlag(permFlagS); err != nil { -// return -// } -// return -// } +func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addrS, nonceS, permFunc string, argsS []string) (*txs.PermissionsTx, error) { + pub, _, nonce, err := checkCommon(nodeClient, keyClient, pubkey, addrS, "0", nonceS) + if err != nil { + return nil, err + } + var args ptypes.PermArgs + switch permFunc { + case "set_base": + addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1]) + if err != nil { + return nil, err + } + if len(argsS) != 3 { + return nil, fmt.Errorf("set_base also takes a value (true or false)") + } + var value bool + if argsS[2] == "true" { + value = true + } else if argsS[2] == "false" { + value = false + } else { + return nil, fmt.Errorf("Unknown value %s", argsS[2]) + } + args = &ptypes.SetBaseArgs{addr, pF, value} + case "unset_base": + addr, pF, err := decodeAddressPermFlag(argsS[0], argsS[1]) + if err != nil { + return nil, err + } + args = &ptypes.UnsetBaseArgs{addr, pF} + case "set_global": + pF, err := ptypes.PermStringToFlag(argsS[0]) + if err != nil { + return nil, err + } + var value bool + if argsS[1] == "true" { + value = true + } else if argsS[1] == "false" { + value = false + } else { + return nil, fmt.Errorf("Unknown value %s", argsS[1]) + } + args = &ptypes.SetGlobalArgs{pF, value} + case "add_role": + addr, err := hex.DecodeString(argsS[0]) + if err != nil { + return nil, err + } + args = &ptypes.AddRoleArgs{addr, argsS[1]} + case "rm_role": + addr, err := hex.DecodeString(argsS[0]) + if err != nil { + return nil, err + } + args = &ptypes.RmRoleArgs{addr, argsS[1]} + default: + return nil, fmt.Errorf("Invalid permission function for use in PermissionsTx: %s", permFunc) + } + // args := snativeArgs( + tx := txs.NewPermissionsTxWithNonce(pub, args, int(nonce)) + return tx, nil +} // type NameGetter struct { // client cclient.Client diff --git a/client/core/transaction_factory_test.go b/client/core/transaction_factory_test.go index f224b23ca22d12fbbf826cad24b952975535689a..aa492b986d1bb70a525422b1d83f944118183b0c 100644 --- a/client/core/transaction_factory_test.go +++ b/client/core/transaction_factory_test.go @@ -30,7 +30,7 @@ func TestTransactionFactory(t *testing.T) { testTransactionFactorySend(t, mockNodeClient, mockKeyClient) testTransactionFactoryCall(t, mockNodeClient, mockKeyClient) testTransactionFactoryName(t, mockNodeClient, mockKeyClient) - // t.Run("PermissionTransaction", ) + testTransactionFactoryPermissions(t, mockNodeClient, mockKeyClient) // t.Run("BondTransaction", ) // t.Run("UnbondTransaction", ) // t.Run("RebondTransaction", ) @@ -126,3 +126,28 @@ func testTransactionFactoryName(t *testing.T, } // TODO: test content of Transaction } + +func testTransactionFactoryPermissions(t *testing.T, + nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.MockKeyClient) { + + // generate an ED25519 key and ripemd160 address + addressString := fmt.Sprintf("%X", keyClient.NewKey()) + // Public key can be queried from mockKeyClient.PublicKey(address) + // but here we let the transaction factory retrieve the public key + // which will then also overwrite the address we provide the function. + // As a result we will assert whether address generated above, is identical + // to address in generated transation. + publicKeyString := "" + // generate an additional address to set permissions for + permAddressString := fmt.Sprintf("%X", keyClient.NewKey()) + // unset nonce so that we retrieve nonce from account + nonceString := "" + + _, err := Permissions(nodeClient, keyClient, publicKeyString, addressString, + nonceString, "set_base", []string{permAddressString, "root", "true"}) + if err != nil { + t.Logf("Error in PermissionsTx: %s", err) + t.Fail() + } + // TODO: test content of Transaction +} \ No newline at end of file diff --git a/client/core/transaction_factory_util.go b/client/core/transaction_factory_util.go index a3b9105c381d9b74227be8284fd6504cb316eb23..b5ed8250b4fc3affe355c85ac4d799c5f0086af6 100644 --- a/client/core/transaction_factory_util.go +++ b/client/core/transaction_factory_util.go @@ -28,6 +28,7 @@ import ( acc "github.com/eris-ltd/eris-db/account" "github.com/eris-ltd/eris-db/client" "github.com/eris-ltd/eris-db/keys" + ptypes "github.com/eris-ltd/eris-db/permission/types" "github.com/eris-ltd/eris-db/txs" ) @@ -83,45 +84,15 @@ func signTx(keyClient keys.KeyClient, chainID string, tx_ txs.Tx) ([]byte, txs.T return inputAddr, tx_, nil } -// readInputAddressFromTransacIm not tion returns the hexadecimal string form of the -// func readInputAddressFromTransaction(tx_ txs.Tx) (addressHex string) { -// // signBytes := fmt.Sprintf("%X", account.SignBytes(chainID, tx_)) -// var inputAddr []byte -// // var sigED crypto.SignatureEd25519 -// switch tx := tx_.(type) { -// case *txs.SendTx: -// inputAddr = tx.Inputs[0].Address -// // defer func(s *crypto.SignatureEd25519) { tx.Inputs[0].Signature = *s }(&sigED) -// case *txs.NameTx: -// inputAddr = tx.Input.Address -// // defer func(s *crypto.SignatureEd25519) { tx.Input.Signature = *s }(&sigED) -// case *txs.CallTx: -// inputAddr = tx.Input.Address -// // defer func(s *crypto.SignatureEd25519) { tx.Input.Signature = *s }(&sigED) -// case *txs.PermissionsTx: -// inputAddr = tx.Input.Address -// // defer func(s *crypto.SignatureEd25519) { tx.Input.Signature = *s }(&sigED) -// case *txs.BondTx: -// inputAddr = tx.Inputs[0].Address -// // defer func(s *crypto.SignatureEd25519) { -// // tx.Signature = *s -// // tx.Inputs[0].Signature = *s -// // }(&sigED) -// case *txs.UnbondTx: -// inputAddr = tx.Address -// // defer func(s *crypto.SignatureEd25519) { tx.Signature = *s }(&sigED) -// case *txs.RebondTx: -// inputAddr = tx.Address -// // defer func(s *crypto.SignatureEd25519) { tx.Signature = *s }(&sigED) -// } -// addressHex := fmt.Sprintf("%X", inputAddr) -// // sig, err := Sign(signBytes, addrHex, signAddr) -// // if err != nil { -// // return nil, nil, err -// // } -// // sigED = crypto.SignatureEd25519(sig) -// return addressHex -// } +func decodeAddressPermFlag(addrS, permFlagS string) (addr []byte, pFlag ptypes.PermFlag, err error) { + if addr, err = hex.DecodeString(addrS); err != nil { + return + } + if pFlag, err = ptypes.PermStringToFlag(permFlagS); err != nil { + return + } + return +} func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS, nonceS string) (pub crypto.PubKey, amt int64, nonce int64, err error) { if amtS == "" { @@ -199,4 +170,4 @@ func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, } return -} +} \ No newline at end of file