diff --git a/binary/bytes.go b/binary/bytes.go index 03a736c45df1e1ebddb7b2535051899a97194138..85588da2076332762373e5af185b31df06270211 100644 --- a/binary/bytes.go +++ b/binary/bytes.go @@ -20,3 +20,25 @@ func (hb HexBytes) MarshalText() ([]byte, error) { func (hb HexBytes) String() string { return hex.EncodeUpperToString(hb) } + +// Protobuf support +func (hb HexBytes) Marshal() ([]byte, error) { + return hb, nil +} + +func (hb *HexBytes) Unmarshal(data []byte) error { + *hb = data + return nil +} + +func (hb HexBytes) MarshalTo(data []byte) (int, error) { + return copy(data, hb), nil +} + +func (hb HexBytes) Size() int { + return len(hb) +} + +func (hb HexBytes) Bytes() []byte { + return hb +} diff --git a/binary/integer.go b/binary/integer.go index 5824a4a9a9efbdb0a596765dbbf004ede7ef02d4..82e757c2913db6219d50497d7b87d7c1b5300131 100644 --- a/binary/integer.go +++ b/binary/integer.go @@ -18,7 +18,6 @@ import ( "encoding/binary" "math" "math/big" - "sort" ) var big1 = big.NewInt(1) @@ -27,21 +26,6 @@ var tt256 = new(big.Int).Lsh(big1, 256) var tt256m1 = new(big.Int).Sub(new(big.Int).Lsh(big1, 256), big1) var tt255 = new(big.Int).Lsh(big1, 255) -// Sort for []uint64 - -type Uint64Slice []uint64 - -func (p Uint64Slice) Len() int { return len(p) } -func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] } -func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } -func (p Uint64Slice) Sort() { sort.Sort(p) } - -func SearchUint64s(a []uint64, x uint64) int { - return sort.Search(len(a), func(i int) bool { return a[i] >= x }) -} - -func (p Uint64Slice) Search(x uint64) int { return SearchUint64s(p, x) } - //-------------------------------------------------------------------------------- func PutUint64LE(dest []byte, i uint64) { diff --git a/binary/word256.go b/binary/word256.go index 7d69e60002b693adb184e3e39f2347041bf8de52..a41b60d7d54e797780c88dc931ed07121a91cf41 100644 --- a/binary/word256.go +++ b/binary/word256.go @@ -16,6 +16,7 @@ package binary import ( "bytes" + "fmt" "math/big" "sort" @@ -95,6 +96,37 @@ func (w Word256) UnpadRight() []byte { return bytes.TrimRight(w[:], trimCutSet) } +// Gogo proto support +func (w *Word256) Marshal() ([]byte, error) { + if w == nil { + return nil, nil + } + return w.Bytes(), nil +} + +func (w *Word256) Unmarshal(data []byte) error { + if len(data) == 0 { + return nil + } + if len(data) != Word256Length { + return fmt.Errorf("error unmarshallling Word256 '%X' from bytes: %d bytes but should have %d bytes", + data, len(data), Word256Length) + } + copy(w[:], data) + return nil +} + +func (w *Word256) MarshalTo(data []byte) (int, error) { + if w == nil { + return 0, nil + } + return copy(data, w[:]), nil +} + +func (w Word256) Size() int { + return Word256Length +} + func Uint64ToWord256(i uint64) Word256 { buf := [8]byte{} PutUint64BE(buf[:], i) diff --git a/blockchain/validators_test.go b/blockchain/validators_test.go index 35513d43af9c052f3c31a494ec6d5ea4ee7c149b..433db89eb006de0cd176a6851f9e7460e6435168 100644 --- a/blockchain/validators_test.go +++ b/blockchain/validators_test.go @@ -7,7 +7,7 @@ import ( "math/rand" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/client/client_do.go b/client/client_do.go deleted file mode 100644 index 4816cafd84eebc8c8107c5044745f7c94cb9a755..0000000000000000000000000000000000000000 --- a/client/client_do.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -type Do struct { - // Persistent flags not reflected in the configuration files - // only set through command line flags or environment variables - Debug bool // BURROW_DEBUG - Verbose bool // BURROW_VERBOSE - - // Following parameters are global flags for burrow-client tx - SignAddrFlag string - NodeAddrFlag string - PubkeyFlag string - AddrFlag string - - // signFlag bool // TODO: remove; unsafe signing without monax-keys - BroadcastFlag bool - WaitFlag bool - - // Following parameters are vary for different Transaction subcommands - // some of these are strings rather than flags because the `core` - // functions have a pure string interface so they work nicely from http - AmtFlag string - NonceFlag string - NameFlag string - DataFlag string - DataFileFlag string - ToFlag string - FeeFlag string - GasFlag string - UnbondtoFlag string - HeightFlag string -} - -func NewClientDo() *Do { - clientDo := new(Do) - clientDo.Debug = false - clientDo.Verbose = false - - clientDo.SignAddrFlag = "" - clientDo.NodeAddrFlag = "" - clientDo.PubkeyFlag = "" - clientDo.AddrFlag = "" - - // clientDo.signFlag = false - clientDo.BroadcastFlag = false - clientDo.WaitFlag = false - - clientDo.AmtFlag = "" - clientDo.NonceFlag = "" - clientDo.NameFlag = "" - clientDo.DataFlag = "" - clientDo.DataFileFlag = "" - clientDo.ToFlag = "" - clientDo.FeeFlag = "" - clientDo.GasFlag = "" - clientDo.UnbondtoFlag = "" - clientDo.HeightFlag = "" - - return clientDo -} diff --git a/client/cmd/burrow-client.go b/client/cmd/burrow-client.go deleted file mode 100644 index bbd1d75636713c2ca7030c697dbd966a31734c62..0000000000000000000000000000000000000000 --- a/client/cmd/burrow-client.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package commands - -import ( - "os" - "strconv" - - "fmt" - - "github.com/hyperledger/burrow/client" - "github.com/hyperledger/burrow/project" - "github.com/spf13/cobra" -) - -// Global flags for persistent flags -var clientDo *client.Do - -var BurrowClientCmd = &cobra.Command{ - Use: "burrow-client", - Short: "burrow-client interacts with a running burrow chain.", - Long: `burrow-client interacts with a running burrow chain. - -Made with <3 by Monax Industries. - -Complete documentation is available at https://monax.io/docs - -VERSION: ` + project.FullVersion(), - Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, -} - -func Execute() { - InitBurrowClientInit() - AddGlobalFlags() - AddClientCommands() - BurrowClientCmd.Execute() -} - -func InitBurrowClientInit() { - // initialise an empty Do struct for command execution - clientDo = client.NewClientDo() -} - -func AddGlobalFlags() { - BurrowClientCmd.PersistentFlags().BoolVarP(&clientDo.Verbose, "verbose", "v", defaultVerbose(), "verbose output; more output than no output flags; less output than debug level; default respects $BURROW_CLIENT_VERBOSE") - BurrowClientCmd.PersistentFlags().BoolVarP(&clientDo.Debug, "debug", "d", defaultDebug(), "debug level output; the most output available for burrow-client; if it is too chatty use verbose flag; default respects $BURROW_CLIENT_DEBUG") -} - -func AddClientCommands() { - BurrowClientCmd.AddCommand(buildTransactionCommand(), buildStatusCommand()) - BurrowClientCmd.AddCommand(&cobra.Command{ - Use: "version", - Short: "Print full version", - Run: func(cmd *cobra.Command, args []string) { fmt.Println(project.FullVersion()) }, - }) -} - -//------------------------------------------------------------------------------ -// Defaults - -// defaultVerbose is set to false unless the BURROW_CLIENT_VERBOSE environment -// variable is set to a parsable boolean. -func defaultVerbose() bool { - return setDefaultBool("BURROW_CLIENT_VERBOSE", false) -} - -// defaultDebug is set to false unless the BURROW_CLIENT_DEBUG environment -// variable is set to a parsable boolean. -func defaultDebug() bool { - return setDefaultBool("BURROW_CLIENT_DEBUG", false) -} - -// setDefaultBool returns the provided default value if the environment variable -// is not set or not parsable as a bool. -func setDefaultBool(environmentVariable string, defaultValue bool) bool { - value := os.Getenv(environmentVariable) - if value != "" { - if parsedValue, err := strconv.ParseBool(value); err == nil { - return parsedValue - } - } - return defaultValue -} - -func setDefaultString(envVar, def string) string { - env := os.Getenv(envVar) - if env != "" { - return env - } - return def -} diff --git a/client/cmd/burrow-client/main.go b/client/cmd/burrow-client/main.go deleted file mode 100644 index dc79298a937e5e1080a3d4515746db46cd02c207..0000000000000000000000000000000000000000 --- a/client/cmd/burrow-client/main.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - commands "github.com/hyperledger/burrow/client/cmd" -) - -func main() { - commands.Execute() -} diff --git a/client/cmd/status.go b/client/cmd/status.go deleted file mode 100644 index 555e9428d8214eb2a0c5b30a4e35ad041bf629e5..0000000000000000000000000000000000000000 --- a/client/cmd/status.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package commands - -import ( - "github.com/spf13/cobra" - - "github.com/hyperledger/burrow/client/methods" - "github.com/hyperledger/burrow/util" -) - -func buildStatusCommand() *cobra.Command { - statusCmd := &cobra.Command{ - Use: "status", - Short: "burrow-client status returns the current status from a chain.", - Long: `burrow-client status returns the current status from a chain. -`, - Run: func(cmd *cobra.Command, args []string) { - err := methods.Status(clientDo) - if err != nil { - util.Fatalf("Could not get status: %s", err) - } - }, - } - statusCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the burrow node rpc server address (default respects $BURROW_CLIENT_NODE_ADDRESS)") - // TransactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $BURROW_CLIENT_PUBLIC_KEY)") - // TransactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at monax-keys) (default respects $BURROW_CLIENT_ADDRESS)") - // TransactionCmd.PersistentFlags().StringVarP(&clientDo.ChainidFlag, "chain-id", "", defaultChainId(), "specify the chainID (default respects $CHAIN_ID)") - // TransactionCmd.PersistentFlags().StringVarP(&clientDo.NonceFlag, "sequence", "", "", "specify the sequence to use for the transaction (should equal the sender account's sequence + 1)") - - // // TransactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the monax-keys daemon") - // TransactionCmd.PersistentFlags().BoolVarP(&clientDo.BroadcastFlag, "broadcast", "b", true, "broadcast the transaction to the blockchain") - // TransactionCmd.PersistentFlags().BoolVarP(&clientDo.WaitFlag, "wait", "w", false, "wait for the transaction to be committed in a block") - - return statusCmd -} diff --git a/client/cmd/transaction.go b/client/cmd/transaction.go deleted file mode 100644 index a5a1c0ac1ad231de5d1c823a3ebd0888fc79b938..0000000000000000000000000000000000000000 --- a/client/cmd/transaction.go +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package commands - -import ( - "strings" - - "github.com/spf13/cobra" - - "github.com/hyperledger/burrow/client/methods" - "github.com/hyperledger/burrow/util" -) - -func buildTransactionCommand() *cobra.Command { - // Transaction command has subcommands send, name, call, bond, - // unbond, rebond, permissions. - transactionCmd := &cobra.Command{ - Use: "tx", - Short: "burrow-client tx formulates and signs a transaction to a chain", - Long: "burrow-client tx formulates and signs a transaction to a chain.", - Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, - } - - addTransactionPersistentFlags(transactionCmd) - - // SendTx - sendCmd := &cobra.Command{ - Use: "send", - Short: "burrow-client tx send --amt <amt> --to <addr>", - Long: "burrow-client tx send --amt <amt> --to <addr>", - Run: func(cmd *cobra.Command, args []string) { - err := methods.Send(clientDo) - if err != nil { - util.Fatalf("Could not complete send: %s", err) - } - }, - PreRun: assertParameters, - } - sendCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount") - sendCmd.Flags().StringVarP(&clientDo.ToFlag, "to", "t", "", "specify an address to send to") - - // NameTx - nameCmd := &cobra.Command{ - Use: "name", - Short: "burrow-client tx name --amt <amt> --name <name> --data <data>", - Long: "burrow-client tx name --amt <amt> --name <name> --data <data>", - Run: func(cmd *cobra.Command, args []string) { - // transaction.Name(clientDo) - }, - PreRun: assertParameters, - } - nameCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount") - nameCmd.Flags().StringVarP(&clientDo.NameFlag, "name", "n", "", "specify a name") - nameCmd.Flags().StringVarP(&clientDo.DataFlag, "data", "", "", "specify some data") - nameCmd.Flags().StringVarP(&clientDo.DataFileFlag, "data-file", "", "", "specify a file with some data") - nameCmd.Flags().StringVarP(&clientDo.FeeFlag, "fee", "f", "", "specify the fee to send") - - // CallTx - callCmd := &cobra.Command{ - Use: "call", - Short: "burrow-client tx call --amt <amt> --fee <fee> --gas <gas> --to <contract addr> --data <data>", - Long: "burrow-client tx call --amt <amt> --fee <fee> --gas <gas> --to <contract addr> --data <data>", - Run: func(cmd *cobra.Command, args []string) { - err := methods.Call(clientDo) - if err != nil { - util.Fatalf("Could not complete call: %s", err) - } - }, - PreRun: assertParameters, - } - callCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount") - callCmd.Flags().StringVarP(&clientDo.ToFlag, "to", "t", "", "specify an address to send to") - callCmd.Flags().StringVarP(&clientDo.DataFlag, "data", "", "", "specify some data") - callCmd.Flags().StringVarP(&clientDo.FeeFlag, "fee", "f", "", "specify the fee to send") - callCmd.Flags().StringVarP(&clientDo.GasFlag, "gas", "g", "", "specify the gas limit for a CallTx") - - // BondTx - bondCmd := &cobra.Command{ - Use: "bond", - Short: "burrow-client tx bond --pubkey <pubkey> --amt <amt> --unbond-to <address>", - Long: "burrow-client tx bond --pubkey <pubkey> --amt <amt> --unbond-to <address>", - Run: func(cmd *cobra.Command, args []string) { - // transaction.Bond(clientDo) - }, - PreRun: assertParameters, - } - bondCmd.Flags().StringVarP(&clientDo.AmtFlag, "amt", "a", "", "specify an amount") - bondCmd.Flags().StringVarP(&clientDo.UnbondtoFlag, "to", "t", "", "specify an address to unbond to") - - // UnbondTx - unbondCmd := &cobra.Command{ - Use: "unbond", - Short: "burrow-client tx unbond --addr <address> --height <block_height>", - Long: "burrow-client tx unbond --addr <address> --height <block_height>", - Run: func(cmd *cobra.Command, args []string) { - // transaction.Unbond(clientDo) - }, - PreRun: assertParameters, - } - unbondCmd.Flags().StringVarP(&clientDo.AddrFlag, "addr", "a", "", "specify an address") - unbondCmd.Flags().StringVarP(&clientDo.HeightFlag, "height", "n", "", "specify a height to unbond at") - - // RebondTx - var rebondCmd = &cobra.Command{ - Use: "rebond", - Short: "burrow-client tx rebond --addr <address> --height <block_height>", - Long: "burrow-client tx rebond --addr <address> --height <block_height>", - Run: func(cmd *cobra.Command, args []string) { - // transaction.Rebond(clientDo) - }, - PreRun: assertParameters, - } - rebondCmd.Flags().StringVarP(&clientDo.AddrFlag, "addr", "a", "", "specify an address") - rebondCmd.Flags().StringVarP(&clientDo.HeightFlag, "height", "n", "", "specify a height to unbond at") - - // PermissionsTx - permissionsCmd := &cobra.Command{ - Use: "permission", - Short: "burrow-client tx perm <function name> <args ...>", - Long: "burrow-client tx perm <function name> <args ...>", - Run: func(cmd *cobra.Command, args []string) { - // transaction.Permsissions(clientDo) - }, - PreRun: assertParameters, - } - - transactionCmd.AddCommand(sendCmd, nameCmd, callCmd, bondCmd, unbondCmd, rebondCmd, permissionsCmd) - return transactionCmd -} - -func addTransactionPersistentFlags(transactionCmd *cobra.Command) { - transactionCmd.PersistentFlags().StringVarP(&clientDo.SignAddrFlag, "sign-addr", "", defaultKeyDaemonAddress(), "set monax-keys daemon address (default respects $BURROW_CLIENT_SIGN_ADDRESS)") - transactionCmd.PersistentFlags().StringVarP(&clientDo.NodeAddrFlag, "node-addr", "", defaultNodeRpcAddress(), "set the burrow node rpc server address (default respects $BURROW_CLIENT_NODE_ADDRESS)") - transactionCmd.PersistentFlags().StringVarP(&clientDo.PubkeyFlag, "pubkey", "", defaultPublicKey(), "specify the public key to sign with (defaults to $BURROW_CLIENT_PUBLIC_KEY)") - transactionCmd.PersistentFlags().StringVarP(&clientDo.AddrFlag, "addr", "", defaultAddress(), "specify the account address (for which the public key can be found at monax-keys) (default respects $BURROW_CLIENT_ADDRESS)") - transactionCmd.PersistentFlags().StringVarP(&clientDo.NonceFlag, "sequence", "", "", "specify the sequence to use for the transaction (should equal the sender account's sequence + 1)") - - // transactionCmd.PersistentFlags().BoolVarP(&clientDo.SignFlag, "sign", "s", false, "sign the transaction using the monax-keys daemon") - transactionCmd.PersistentFlags().BoolVarP(&clientDo.BroadcastFlag, "broadcast", "b", true, "broadcast the transaction to the blockchain") - transactionCmd.PersistentFlags().BoolVarP(&clientDo.WaitFlag, "wait", "w", true, "wait for the transaction to be committed in a block") -} - -//------------------------------------------------------------------------------ -// Defaults - -func defaultKeyDaemonAddress() string { - return setDefaultString("BURROW_CLIENT_SIGN_ADDRESS", "http://127.0.0.1:4767") -} - -func defaultNodeRpcAddress() string { - return setDefaultString("BURROW_CLIENT_NODE_ADDRESS", "tcp://127.0.0.1:46657") -} - -func defaultPublicKey() string { - return setDefaultString("BURROW_CLIENT_PUBLIC_KEY", "") -} - -func defaultAddress() string { - return setDefaultString("BURROW_CLIENT_ADDRESS", "") -} - -//------------------------------------------------------------------------------ -// Helper functions - -func assertParameters(cmd *cobra.Command, args []string) { - if !strings.HasPrefix(clientDo.NodeAddrFlag, "tcp://") && - !strings.HasPrefix(clientDo.NodeAddrFlag, "unix://") { - // TODO: [ben] go-rpc will deprecate reformatting; also it is bad practice to auto-correct for this; - // TODO: [Silas] I've made this fatal, but I'm inclined to define the default as tcp:// and normalise as with http - // below - util.Fatalf(`Please use fully formed listening address for the node, including the tcp:// or unix:// prefix.`) - } - - if !strings.HasPrefix(clientDo.SignAddrFlag, "http://") { - // NOTE: [ben] we preserve the auto-correction here as it is a simple http request-response to the key server. - // TODO: [Silas] we don't have logging here to log that we've done this. I'm inclined to either urls without a scheme - // and be quiet about it, or to make non-compliance fatal - clientDo.SignAddrFlag = "http://" + clientDo.SignAddrFlag - } -} diff --git a/client/methods/call.go b/client/methods/call.go deleted file mode 100644 index 16655803f15bf4e7c1eaf8f8fcb936f756853cbc..0000000000000000000000000000000000000000 --- a/client/methods/call.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package methods - -import ( - "fmt" - - "github.com/hyperledger/burrow/client" - "github.com/hyperledger/burrow/client/rpc" - "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/txs" -) - -func Call(do *client.Do) error { - // construct two clients to call out to keys server and - // blockchain node. - logger, err := loggerFromClientDo(do, "Call") - if err != nil { - return fmt.Errorf("Could not generate logging config from Do: %s", err) - } - burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger) - if err != nil { - return fmt.Errorf("Could not create remote key client: %s", err) - } - burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger) - // form the call transaction - callTransaction, err := rpc.Call(burrowNodeClient, burrowKeyClient, - do.PubkeyFlag, do.AddrFlag, do.ToFlag, do.AmtFlag, do.NonceFlag, - do.GasFlag, do.FeeFlag, do.DataFlag) - if err != nil { - return fmt.Errorf("Failed on forming Call Transaction: %s", err) - } - _, chainID, _, err := burrowNodeClient.ChainId() - if err != nil { - return err - } - // TODO: [ben] we carry over the sign bool, but always set it to true, - // as we move away from and deprecate the api that allows sending unsigned - // transactions and relying on (our) receiving node to sign it. - txResult, err := rpc.SignAndBroadcast(burrowNodeClient, burrowKeyClient, - txs.Enclose(chainID, callTransaction), true, do.BroadcastFlag, do.WaitFlag) - - if err != nil { - return fmt.Errorf("Failed on signing (and broadcasting) transaction: %s", err) - } - unpackSignAndBroadcast(txResult, logger) - return nil -} diff --git a/client/methods/helpers.go b/client/methods/helpers.go deleted file mode 100644 index 6fbf1f46ebc2b2d3c863193f6c5312d4e270d777..0000000000000000000000000000000000000000 --- a/client/methods/helpers.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package methods - -import ( - "github.com/hyperledger/burrow/client" - "github.com/hyperledger/burrow/client/rpc" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/logging/config" - "github.com/hyperledger/burrow/logging/lifecycle" -) - -func unpackSignAndBroadcast(result *rpc.TxResult, logger *logging.Logger) { - if result == nil { - // if we don't provide --sign or --broadcast - return - } - - logger = logger.With("transaction hash", result.Hash) - - if result.Address != nil { - logger = logger.With("Contract Address", result.Address) - } - - if result.Return != nil { - logger = logger.With("Block Hash", result.BlockHash, - "Return Value", result.Return, - "Exception", result.Exception, - ) - } - - logger.InfoMsg("SignAndBroadcast result") -} - -func loggerFromClientDo(do *client.Do, scope string) (*logging.Logger, error) { - logger, err := lifecycle.NewLoggerFromLoggingConfig(config.DefaultClientLoggingConfig()) - if err != nil { - return nil, err - } - logger = logger.WithScope(scope) - lifecycle.CaptureStdlibLogOutput(logger) - return logger, nil -} diff --git a/client/methods/send.go b/client/methods/send.go deleted file mode 100644 index 6ce809721629d4c7e87b6f62dec578f51d6609c7..0000000000000000000000000000000000000000 --- a/client/methods/send.go +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package methods - -import ( - "fmt" - - "github.com/hyperledger/burrow/client" - "github.com/hyperledger/burrow/client/rpc" - "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/txs" -) - -func Send(do *client.Do) error { - // construct two clients to call out to keys server and - // blockchain node. - logger, err := loggerFromClientDo(do, "Send") - if err != nil { - return fmt.Errorf("Could not generate logging config from Do: %s", err) - } - burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger) - if err != nil { - return fmt.Errorf("Could not create remote key client: %s", err) - } - burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger) - // form the send transaction - sendTransaction, err := rpc.Send(burrowNodeClient, burrowKeyClient, - do.PubkeyFlag, do.AddrFlag, do.ToFlag, do.AmtFlag, do.NonceFlag) - if err != nil { - fmt.Errorf("Failed on forming Send Transaction: %s", err) - } - _, chainID, _, err := burrowNodeClient.ChainId() - if err != nil { - return err - } - // TODO: [ben] we carry over the sign bool, but always set it to true, - // as we move away from and deprecate the api that allows sending unsigned - // transactions and relying on (our) receiving node to sign it. - txResult, err := rpc.SignAndBroadcast(burrowNodeClient, burrowKeyClient, - txs.Enclose(chainID, sendTransaction), true, do.BroadcastFlag, do.WaitFlag) - if err != nil { - return fmt.Errorf("Failed on signing (and broadcasting) transaction: %s", err) - } - unpackSignAndBroadcast(txResult, logger) - return nil -} diff --git a/client/methods/status.go b/client/methods/status.go deleted file mode 100644 index 7487fdf19bafecda67104aad6a7d4b871ec8f080..0000000000000000000000000000000000000000 --- a/client/methods/status.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package methods - -import ( - "fmt" - - "github.com/hyperledger/burrow/client" -) - -func Status(do *client.Do) error { - logger, err := loggerFromClientDo(do, "Status") - if err != nil { - return fmt.Errorf("Could not generate logging config from Do: %s", err) - } - burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger) - genesisHash, validatorPublicKey, latestBlockHash, latestBlockHeight, latestBlockTime, err := burrowNodeClient.Status() - if err != nil { - return fmt.Errorf("Error requesting status from chain at (%s): %s", do.NodeAddrFlag, err) - } - - chainName, chainId, genesisHashfromChainId, err := burrowNodeClient.ChainId() - if err != nil { - return fmt.Errorf("Error requesting chainId from chain at (%s): %s", do.NodeAddrFlag, err) - } - - logger.Info.Log("chain", do.NodeAddrFlag, - "genesisHash", fmt.Sprintf("%X", genesisHash), - "chainName", chainName, - "chainId", chainId, - "genesisHash from chainId", fmt.Sprintf("%X", genesisHashfromChainId), - "validator public key", fmt.Sprintf("%X", validatorPublicKey), - "latest block hash", fmt.Sprintf("%X", latestBlockHash), - "latest block height", latestBlockHeight, - "latest block time", latestBlockTime, - ) - return nil -} diff --git a/client/mock/client_mock.go b/client/mock/client_mock.go deleted file mode 100644 index 2231661225556c619474ea9f2e607f51d6784d1b..0000000000000000000000000000000000000000 --- a/client/mock/client_mock.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package mock - -import ( - acm "github.com/hyperledger/burrow/account" - . "github.com/hyperledger/burrow/client" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/txs" -) - -var _ NodeClient = (*MockNodeClient)(nil) - -type MockNodeClient struct { - accounts map[string]*acm.ConcreteAccount -} - -func NewMockNodeClient() *MockNodeClient { - return &MockNodeClient{ - accounts: make(map[string]*acm.ConcreteAccount), - } -} - -func (mock *MockNodeClient) Broadcast(txEnv *txs.Envelope) (*txs.Receipt, error) { - // make zero transaction receipt - txReceipt := &txs.Receipt{ - TxHash: make([]byte, 20), - CreatesContract: false, - } - return txReceipt, nil -} - -func (mock *MockNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) { - return nil, nil -} - -func (mock *MockNodeClient) GetAccount(address crypto.Address) (acm.Account, error) { - // make zero account - return acm.FromAddressable(acm.GeneratePrivateAccountFromSecret("mock-node-client-account")), nil -} - -func (mock *MockNodeClient) MockAddAccount(account *acm.ConcreteAccount) { - addressString := string(account.Address[:]) - mock.accounts[addressString] = account.Copy() -} - -func (mock *MockNodeClient) Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte, - BlockHeight uint64, LatestBlockTime int64, err error) { - // fill return values - ChainId = make([]byte, 64) - LatestBlockHash = make([]byte, 64) - BlockHeight = 0 - LatestBlockTime = 0 - return -} - -// QueryContract executes the contract code at address with the given data -func (mock *MockNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address, - data []byte) (ret []byte, gasUsed uint64, err error) { - - // return zero - ret = make([]byte, 0) - return -} - -// QueryContractCode executes the contract code at address with the given data but with provided code -func (mock *MockNodeClient) QueryContractCode(address crypto.Address, code, - data []byte) (ret []byte, gasUsed uint64, err error) { - // return zero - ret = make([]byte, 0) - return -} - -func (mock *MockNodeClient) DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error) { - return -} - -func (mock *MockNodeClient) GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error) { - return -} - -func (mock *MockNodeClient) ListValidators() (blockHeight uint64, bondedValidators, - unbondingValidators []acm.Validator, err error) { - return -} - -func (mock *MockNodeClient) Logger() *logging.Logger { - return logging.NewNoopLogger() -} diff --git a/client/node_client.go b/client/node_client.go deleted file mode 100644 index 8c3464cf09088211428a4383d6197a33f4a349cb..0000000000000000000000000000000000000000 --- a/client/node_client.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "fmt" - - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/rpc" - rpcClient "github.com/hyperledger/burrow/rpc/lib/client" - tmClient "github.com/hyperledger/burrow/rpc/tm/client" - "github.com/hyperledger/burrow/txs" -) - -type NodeClient interface { - Broadcast(transaction *txs.Envelope) (*txs.Receipt, error) - DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) - - Status() (ChainId []byte, ValidatorPublicKey []byte, LatestBlockHash []byte, - LatestBlockHeight uint64, LatestBlockTime int64, err error) - GetAccount(address crypto.Address) (acm.Account, error) - QueryContract(callerAddress, calleeAddress crypto.Address, data []byte) (ret []byte, gasUsed uint64, err error) - QueryContractCode(address crypto.Address, code, data []byte) (ret []byte, gasUsed uint64, err error) - - DumpStorage(address crypto.Address) (storage *rpc.ResultDumpStorage, err error) - GetName(name string) (owner crypto.Address, data string, expirationBlock uint64, err error) - ListValidators() (blockHeight uint64, bondedValidators, unbondingValidators []acm.Validator, err error) - - // Logging context for this NodeClient - Logger() *logging.Logger -} - -type NodeWebsocketClient interface { - Subscribe(eventId string) error - Unsubscribe(eventId string) error - WaitForConfirmation(tx *txs.Envelope, inputAddr crypto.Address) (chan Confirmation, error) - Close() -} - -// NOTE [ben] Compiler check to ensure burrowNodeClient successfully implements -// burrow/client.NodeClient -var _ NodeClient = (*burrowNodeClient)(nil) - -// burrow-client is a simple struct exposing the client rpc methods -type burrowNodeClient struct { - broadcastRPC string - logger *logging.Logger -} - -// BurrowKeyClient.New returns a new monax-keys client for provided rpc location -// Monax-keys connects over http request-responses -func NewBurrowNodeClient(rpcString string, logger *logging.Logger) *burrowNodeClient { - return &burrowNodeClient{ - broadcastRPC: rpcString, - logger: logger.WithScope("BurrowNodeClient"), - } -} - -//------------------------------------------------------------------------------------ -// broadcast to blockchain node - -func (burrowNodeClient *burrowNodeClient) Broadcast(txEnv *txs.Envelope) (*txs.Receipt, error) { - client := rpcClient.NewURIClient(burrowNodeClient.broadcastRPC) - receipt, err := tmClient.BroadcastTx(client, txEnv) - if err != nil { - return nil, err - } - return receipt, nil -} - -func (burrowNodeClient *burrowNodeClient) DeriveWebsocketClient() (nodeWsClient NodeWebsocketClient, err error) { - var wsAddr string - // TODO: clean up this inherited mess on dealing with the address prefixes. - nodeAddr := burrowNodeClient.broadcastRPC - // if strings.HasPrefix(nodeAddr, "http://") { - // wsAddr = strings.TrimPrefix(nodeAddr, "http://") - // } - // if strings.HasPrefix(nodeAddr, "tcp://") { - // wsAddr = strings.TrimPrefix(nodeAddr, "tcp://") - // } - // if strings.HasPrefix(nodeAddr, "unix://") { - // log.WithFields(log.Fields{ - // "node address": nodeAddr, - // }).Error("Unable to subscribe to websocket from unix socket.") - // return nil, fmt.Errorf("Unable to construct websocket from unix socket: %s", nodeAddr) - // } - // wsAddr = "ws://" + wsAddr - wsAddr = nodeAddr - burrowNodeClient.logger.TraceMsg("Subscribing to websocket address", - "websocket address", wsAddr, - "endpoint", "/websocket", - ) - wsClient := rpcClient.NewWSClient(wsAddr, "/websocket") - if err = wsClient.Start(); err != nil { - return nil, err - } - derivedBurrowNodeWebsocketClient := &burrowNodeWebsocketClient{ - tendermintWebsocket: wsClient, - logger: burrowNodeClient.logger.WithScope("BurrowNodeWebsocketClient"), - } - return derivedBurrowNodeWebsocketClient, nil -} - -//------------------------------------------------------------------------------------ -// RPC requests other than transaction related - -// Status returns the ChainId (GenesisHash), validator's PublicKey, latest block hash -// the block height and the latest block time. -func (burrowNodeClient *burrowNodeClient) Status() (GenesisHash []byte, ValidatorPublicKey []byte, - LatestBlockHash []byte, LatestBlockHeight uint64, LatestBlockTime int64, err error) { - - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - res, err := tmClient.Status(client) - if err != nil { - err = fmt.Errorf("error connecting to node (%s) to get status: %s", - burrowNodeClient.broadcastRPC, err.Error()) - return - } - - // unwrap return results - GenesisHash = res.GenesisHash - ValidatorPublicKey = res.PubKey.RawBytes() - LatestBlockHash = res.LatestBlockHash - LatestBlockHeight = res.LatestBlockHeight - LatestBlockTime = res.LatestBlockTime - return -} - -func (burrowNodeClient *burrowNodeClient) ChainId() (ChainName, ChainId string, GenesisHash []byte, err error) { - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - chainIdResult, err := tmClient.ChainId(client) - if err != nil { - err = fmt.Errorf("error connecting to node (%s) to get chain id: %s", - burrowNodeClient.broadcastRPC, err.Error()) - return "", "", nil, err - } - // unwrap results - ChainName = chainIdResult.ChainName - ChainId = chainIdResult.ChainId - GenesisHash = make([]byte, len(chainIdResult.GenesisHash)) - copy(GenesisHash[:], chainIdResult.GenesisHash) - return -} - -// QueryContract executes the contract code at address with the given data -// NOTE: there is no check on the caller; -func (burrowNodeClient *burrowNodeClient) QueryContract(callerAddress, calleeAddress crypto.Address, - data []byte) (ret []byte, gasUsed uint64, err error) { - - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - callResult, err := tmClient.Call(client, callerAddress, calleeAddress, data) - if err != nil { - err = fmt.Errorf("error (%v) connnecting to node (%s) to query contract at (%s) with data (%X)", - err.Error(), burrowNodeClient.broadcastRPC, calleeAddress, data) - return - } - return callResult.Return, callResult.GasUsed, nil -} - -// QueryContractCode executes the contract code at address with the given data but with provided code -func (burrowNodeClient *burrowNodeClient) QueryContractCode(address crypto.Address, code, - data []byte) (ret []byte, gasUsed uint64, err error) { - - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - // TODO: [ben] Call and CallCode have an inconsistent signature; it makes sense for both to only - // have a single address that is the contract to query. - callResult, err := tmClient.CallCode(client, address, code, data) - if err != nil { - err = fmt.Errorf("error connnecting to node (%s) to query contract code at (%s) with data (%X) and code (%X): %v", - burrowNodeClient.broadcastRPC, address, data, code, err.Error()) - return nil, uint64(0), err - } - return callResult.Return, callResult.GasUsed, nil -} - -// GetAccount returns a copy of the account -func (burrowNodeClient *burrowNodeClient) GetAccount(address crypto.Address) (acm.Account, error) { - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - account, err := tmClient.GetAccount(client, address) - if err != nil { - err = fmt.Errorf("error connecting to node (%s) to fetch account (%s): %s", - burrowNodeClient.broadcastRPC, address, err.Error()) - return nil, err - } - if account == nil { - err = fmt.Errorf("unknown account %s at node (%s)", address, burrowNodeClient.broadcastRPC) - return nil, err - } - - return account, nil -} - -// DumpStorage returns the full storage for an acm. -func (burrowNodeClient *burrowNodeClient) DumpStorage(address crypto.Address) (*rpc.ResultDumpStorage, error) { - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - resultStorage, err := tmClient.DumpStorage(client, address) - if err != nil { - return nil, fmt.Errorf("error connecting to node (%s) to get storage for account (%X): %s", - burrowNodeClient.broadcastRPC, address, err.Error()) - } - return resultStorage, nil -} - -//-------------------------------------------------------------------------------------------- -// Name registry - -func (burrowNodeClient *burrowNodeClient) GetName(name string) (owner crypto.Address, data string, - expirationBlock uint64, err error) { - - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - entryResult, err := tmClient.GetName(client, name) - if err != nil { - err = fmt.Errorf("error connecting to node (%s) to get name registrar entry for name (%s)", - burrowNodeClient.broadcastRPC, name) - return crypto.ZeroAddress, "", 0, err - } - // unwrap return results - owner = entryResult.Owner - data = entryResult.Data - expirationBlock = entryResult.Expires - return -} - -//-------------------------------------------------------------------------------------------- - -func (burrowNodeClient *burrowNodeClient) ListValidators() (blockHeight uint64, - bondedValidators, unbondingValidators []acm.Validator, err error) { - - client := rpcClient.NewJSONRPCClient(burrowNodeClient.broadcastRPC) - validatorsResult, err := tmClient.ListValidators(client) - if err != nil { - err = fmt.Errorf("error connecting to node (%s) to get validators", burrowNodeClient.broadcastRPC) - return - } - // unwrap return results - blockHeight = validatorsResult.BlockHeight - bondedValidators = make([]acm.Validator, len(validatorsResult.BondedValidators)) - for i, cv := range validatorsResult.BondedValidators { - bondedValidators[i] = cv.Validator() - } - unbondingValidators = make([]acm.Validator, len(validatorsResult.UnbondingValidators)) - for i, cv := range validatorsResult.UnbondingValidators { - unbondingValidators[i] = cv.Validator() - } - return -} - -func (burrowNodeClient *burrowNodeClient) Logger() *logging.Logger { - return burrowNodeClient.logger -} diff --git a/client/rpc/client.go b/client/rpc/client.go deleted file mode 100644 index 9e5364246cc38ae2975b50f2252391db73ae46be..0000000000000000000000000000000000000000 --- a/client/rpc/client.go +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package rpc - -import ( - "encoding/hex" - "fmt" - "strconv" - - "github.com/hyperledger/burrow/client" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/permission/snatives" - ptypes "github.com/hyperledger/burrow/permission/types" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" -) - -//------------------------------------------------------------------------------------ -// core functions with string args. -// validates strings and forms transaction - -func Send(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, toAddr, amtS, sequenceS string) (*payload.SendTx, error) { - pub, amt, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addr, amtS, sequenceS) - if err != nil { - return nil, err - } - - if toAddr == "" { - return nil, fmt.Errorf("destination address must be given with --to flag") - } - - toAddress, err := addressFromHexString(toAddr) - if err != nil { - return nil, err - } - - tx := payload.NewSendTx() - tx.AddInputWithSequence(pub, amt, sequence) - tx.AddOutput(toAddress, amt) - - return tx, nil -} - -func Call(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, toAddr, amtS, sequenceS, gasS, feeS, data string) (*payload.CallTx, error) { - pub, amt, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addr, amtS, sequenceS) - if err != nil { - return nil, err - } - - var toAddress *crypto.Address - - if toAddr != "" { - address, err := addressFromHexString(toAddr) - if err != nil { - return nil, fmt.Errorf("toAddr is bad hex: %v", err) - } - toAddress = &address - } - - fee, err := strconv.ParseUint(feeS, 10, 64) - if err != nil { - return nil, fmt.Errorf("fee is misformatted: %v", err) - } - - gas, err := strconv.ParseUint(gasS, 10, 64) - if err != nil { - return nil, fmt.Errorf("gas is misformatted: %v", err) - } - - dataBytes, err := hex.DecodeString(data) - if err != nil { - return nil, fmt.Errorf("data is bad hex: %v", err) - } - - tx := payload.NewCallTxWithSequence(pub, toAddress, dataBytes, amt, gas, fee, sequence) - return tx, nil -} - -func Name(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS, sequenceS, feeS, name, data string) (*payload.NameTx, error) { - pub, amt, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addr, amtS, sequenceS) - if err != nil { - return nil, err - } - - fee, err := strconv.ParseUint(feeS, 10, 64) - if err != nil { - return nil, fmt.Errorf("fee is misformatted: %v", err) - } - - tx := payload.NewNameTxWithSequence(pub, name, data, amt, fee, sequence) - return tx, nil -} - -func Permissions(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addrS, sequenceS string, - action, target, permissionFlag, role, value string) (*payload.PermissionsTx, error) { - - pub, _, sequence, err := checkCommon(nodeClient, keyClient, pubkey, addrS, "0", sequenceS) - if err != nil { - return nil, err - } - permFlag, err := ptypes.PermStringToFlag(action) - if err != nil { - return nil, fmt.Errorf("could not convert action '%s' to PermFlag: %v", action, err) - } - permArgs := snatives.PermArgs{ - PermFlag: permFlag, - } - - // Try and set each PermArg field for which a string has been provided we'll validate afterwards - if target != "" { - address, err := crypto.AddressFromHexString(target) - if err != nil { - return nil, err - } - permArgs.Address = &address - } - - if value != "" { - valueBool := value == "true" - permArgs.Value = &valueBool - if !valueBool && value != "false" { - return nil, fmt.Errorf("did not recognise value %s as boolean, use 'true' or 'false'", value) - } - permArgs.Value = &valueBool - } - - if permissionFlag != "" { - permission, err := ptypes.PermStringToFlag(permissionFlag) - if err != nil { - return nil, err - } - permArgs.Permission = &permission - } - - if role != "" { - permArgs.Role = &role - } - - err = permArgs.EnsureValid() - if err != nil { - return nil, err - } - - tx := payload.NewPermissionsTxWithSequence(pub, permArgs, sequence) - return tx, nil -} - -func Bond(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, unbondAddr, amtS, sequenceS string) (*payload.BondTx, error) { - return nil, fmt.Errorf("Bond Transaction formation to be implemented on 0.12.0") - // pub, amt, sequence, err := checkCommon(nodeAddr, signAddr, pubkey, "", amtS, sequenceS) - // if err != nil { - // return nil, err - // } - // var pubKey acm.PublicKeyEd25519 - // var unbondAddrBytes []byte - - // if unbondAddr == "" { - // pkb, _ := hex.DecodeString(pubkey) - // copy(pubKey[:], pkb) - // unbondAddrBytes = pubKey.Address() - // } else { - // unbondAddrBytes, err = hex.DecodeString(unbondAddr) - // if err != nil { - // return nil, fmt.Errorf("unbondAddr is bad hex: %v", err) - // } - - // } - - // tx, err := types.NewBondTx(pub) - // if err != nil { - // return nil, err - // } - // tx.AddInputWithSequence(pub, amt, int(sequence)) - // tx.AddOutput(unbondAddrBytes, amt) - - // return tx, nil -} - -func Unbond(addrS, heightS string) (*payload.UnbondTx, error) { - return nil, fmt.Errorf("Unbond Transaction formation to be implemented on 0.12.0") - // if addrS == "" { - // return nil, fmt.Errorf("Validator address must be given with --addr flag") - // } - - // addrBytes, err := hex.DecodeString(addrS) - // if err != nil { - // return nil, fmt.Errorf("addr is bad hex: %v", err) - // } - - // height, err := strconv.ParseInt(heightS, 10, 32) - // if err != nil { - // return nil, fmt.Errorf("height is misformatted: %v", err) - // } - - // return &types.UnbondTx{ - // Address: addrBytes, - // Height: int(height), - // }, nil -} - -type TxResult struct { - BlockHash []byte // all txs get in a block - Hash []byte // all txs get a hash - - // only CallTx - Address *crypto.Address // only for new contracts - Return []byte - Exception string - - //TODO: make Broadcast() errors more responsive so we - // can differentiate mempool errors from other -} - -// Preserve -func SignAndBroadcast(nodeClient client.NodeClient, keyClient keys.KeyClient, txEnv *txs.Envelope, sign, - broadcast, wait bool) (txResult *TxResult, err error) { - - var inputAddr crypto.Address - if sign { - inputAddr, txEnv, err = signTx(keyClient, txEnv.Tx) - if err != nil { - return nil, err - } - } - - if broadcast { - if wait { - var wsClient client.NodeWebsocketClient - wsClient, err = nodeClient.DeriveWebsocketClient() - if err != nil { - return nil, err - } - var confirmationChannel chan client.Confirmation - confirmationChannel, err = wsClient.WaitForConfirmation(txEnv, inputAddr) - if err != nil { - return nil, err - } - defer func() { - if err != nil { - // if broadcast threw an error, just return - return - } - if txResult == nil { - err = fmt.Errorf("txResult unexpectedly not initialised in SignAndBroadcast") - return - } - confirmation := <-confirmationChannel - if confirmation.Error != nil { - err = fmt.Errorf("encountered error waiting for event: %s", confirmation.Error) - return - } - if confirmation.Exception != nil { - err = fmt.Errorf("encountered Exception from chain: %s", confirmation.Exception) - return - } - txResult.BlockHash = confirmation.BlockHash - txResult.Exception = "" - eventDataTx := confirmation.EventDataTx - if eventDataTx == nil { - err = fmt.Errorf("EventDataTx was nil") - return - } - txResult.Return = eventDataTx.Return - }() - } - - var receipt *txs.Receipt - receipt, err = nodeClient.Broadcast(txEnv) - if err != nil { - return nil, err - } - txResult = &TxResult{ - Hash: receipt.TxHash, - } - // NOTE: [ben] is this consistent with the Ethereum protocol? It should seem - // reasonable to get this returned from the chain directly. Alternatively, - // the benefit is that the we don't need to trust the chain node - if tx_, ok := txEnv.Tx.Payload.(*payload.CallTx); ok { - if tx_.Address == nil { - address := crypto.NewContractAddress(tx_.Input.Address, tx_.Input.Sequence) - txResult.Address = &address - } - } - } - return -} - -func addressFromHexString(addrString string) (crypto.Address, error) { - addrBytes, err := hex.DecodeString(addrString) - if err != nil { - return crypto.Address{}, err - } - return crypto.AddressFromBytes(addrBytes) -} diff --git a/client/rpc/client_test.go b/client/rpc/client_test.go deleted file mode 100644 index 3a8ebc42d7d11c1f5627b360097dcdd785499d84..0000000000000000000000000000000000000000 --- a/client/rpc/client_test.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package rpc - -import ( - "encoding/json" - "fmt" - "testing" - - // "github.com/stretchr/testify/assert" - - mockclient "github.com/hyperledger/burrow/client/mock" - mockkeys "github.com/hyperledger/burrow/keys/mock" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestSend(t *testing.T) { - mockKeyClient := mockkeys.NewKeyClient() - mockNodeClient := mockclient.NewMockNodeClient() - testSend(t, mockNodeClient, mockKeyClient) -} - -func TestCall(t *testing.T) { - mockKeyClient := mockkeys.NewKeyClient() - mockNodeClient := mockclient.NewMockNodeClient() - testCall(t, mockNodeClient, mockKeyClient) -} - -func TestName(t *testing.T) { - mockKeyClient := mockkeys.NewKeyClient() - mockNodeClient := mockclient.NewMockNodeClient() - testName(t, mockNodeClient, mockKeyClient) -} - -func TestPermissions(t *testing.T) { - mockKeyClient := mockkeys.NewKeyClient() - mockNodeClient := mockclient.NewMockNodeClient() - testPermissions(t, mockNodeClient, mockKeyClient) -} - -func testSend(t *testing.T, - nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) { - - // generate an ED25519 key and ripemd160 address - addressString := keyClient.NewKey("").String() - // 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 send amount to - toAddressString := keyClient.NewKey("").String() - // set an amount to transfer - amountString := "1000" - // unset sequence so that we retrieve sequence from account - sequenceString := "" - - _, err := Send(nodeClient, keyClient, publicKeyString, addressString, - toAddressString, amountString, sequenceString) - require.NoError(t, err, "Error in Send") - // assert.NotEqual(t, txSend) - // TODO: test content of Transaction -} - -func testCall(t *testing.T, - nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) { - - // generate an ED25519 key and ripemd160 address - addressString := keyClient.NewKey("").String() - // 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 send amount to - toAddressString := keyClient.NewKey("").String() - // set an amount to transfer - amountString := "1000" - // unset sequence so that we retrieve sequence from account - sequenceString := "" - // set gas - gasString := "1000" - // set fee - feeString := "100" - // set data - dataString := fmt.Sprintf("%X", "We are DOUG.") - - _, err := Call(nodeClient, keyClient, publicKeyString, addressString, - toAddressString, amountString, sequenceString, gasString, feeString, dataString) - if err != nil { - t.Logf("Error in CallTx: %s", err) - t.Fail() - } - // TODO: test content of Transaction -} - -func testName(t *testing.T, - nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) { - - // generate an ED25519 key and ripemd160 address - addressString := keyClient.NewKey("").String() - // 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 := "" - // set an amount to transfer - amountString := "1000" - // unset sequence so that we retrieve sequence from account - sequenceString := "" - // set fee - feeString := "100" - // set data - dataString := fmt.Sprintf("%X", "We are DOUG.") - // set name - nameString := "DOUG" - - _, err := Name(nodeClient, keyClient, publicKeyString, addressString, - amountString, sequenceString, feeString, nameString, dataString) - if err != nil { - t.Logf("Error in NameTx: %s", err) - t.Fail() - } - // TODO: test content of Transaction -} - -func testPermissions(t *testing.T, - nodeClient *mockclient.MockNodeClient, keyClient *mockkeys.KeyClient) { - - // generate an ED25519 key and ripemd160 address - addressString := keyClient.NewKey("").String() - // 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 := keyClient.NewKey("").String() - // unset sequence so that we retrieve sequence from account - sequenceString := "" - - tx, err := Permissions(nodeClient, keyClient, publicKeyString, addressString, - sequenceString, "setBase", permAddressString, "root", "", "true") - if err != nil { - t.Logf("Error in PermissionsTx: %s", err) - t.Fail() - } - - bs, err := json.Marshal(tx.PermArgs) - require.NoError(t, err) - expected := fmt.Sprintf(`{"PermFlag":256,"Address":"%s","Permission":1,"Value":true}`, permAddressString) - assert.Equal(t, expected, string(bs)) -} diff --git a/client/rpc/client_util.go b/client/rpc/client_util.go deleted file mode 100644 index d59453a7c2cea259c863962cc69ca311f61e719c..0000000000000000000000000000000000000000 --- a/client/rpc/client_util.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package rpc - -import ( - "encoding/hex" - "fmt" - "strconv" - - "github.com/hyperledger/burrow/client" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/txs" -) - -//------------------------------------------------------------------------------------ -// sign and broadcast convenience - -// tx has either one input or we default to the first one (ie for send/bond) -// TODO: better support for multisig and bonding -func signTx(keyClient keys.KeyClient, tx *txs.Tx) (crypto.Address, *txs.Envelope, error) { - txEnv := tx.Enclose() - inputs := tx.GetInputs() - signer, err := keys.AddressableSigner(keyClient, inputs[0].Address) - if err != nil { - return crypto.ZeroAddress, nil, err - } - err = txEnv.Sign(signer) - if err != nil { - return crypto.ZeroAddress, nil, err - } - return signer.Address(), txEnv, nil -} - -func checkCommon(nodeClient client.NodeClient, keyClient keys.KeyClient, pubkey, addr, amtS, - sequenceS string) (pub crypto.PublicKey, amt uint64, sequence uint64, err error) { - - if amtS == "" { - err = fmt.Errorf("input must specify an amount with the --amt flag") - return - } - - if pubkey == "" && addr == "" { - err = fmt.Errorf("at least one of --pubkey or --addr must be given") - return - } else if pubkey != "" { - if addr != "" { - nodeClient.Logger().InfoMsg("Both a public key and an address have been specified. The public key takes precedent.", - "public_key", pubkey, - "address", addr, - ) - } - var pubKeyBytes []byte - pubKeyBytes, err = hex.DecodeString(pubkey) - if err != nil { - err = fmt.Errorf("pubkey is bad hex: %v", err) - return - } - pub, err = crypto.PublicKeyFromBytes(pubKeyBytes, crypto.CurveTypeEd25519) - if err != nil { - return - } - } else { - // grab the pubkey from monax-keys - addressBytes, err2 := hex.DecodeString(addr) - if err2 != nil { - err = fmt.Errorf("Bad hex string for address (%s): %v", addr, err) - return - } - address, err2 := crypto.AddressFromBytes(addressBytes) - if err2 != nil { - err = fmt.Errorf("Could not convert bytes (%X) to address: %v", addressBytes, err2) - } - pub, err2 = keyClient.PublicKey(address) - if err2 != nil { - err = fmt.Errorf("Failed to fetch pubkey for address (%s): %v", addr, err2) - return - } - } - - var address crypto.Address - address = pub.Address() - - amt, err = strconv.ParseUint(amtS, 10, 64) - if err != nil { - err = fmt.Errorf("amt is misformatted: %v", err) - } - - if sequenceS == "" { - if nodeClient == nil { - err = fmt.Errorf("input must specify a sequence with the --sequence flag or use --node-addr (or BURROW_CLIENT_NODE_ADDR) to fetch the sequence from a node") - return - } - // fetch sequence from node - account, err2 := nodeClient.GetAccount(address) - if err2 != nil { - return pub, amt, sequence, err2 - } - sequence = account.Sequence() + 1 - nodeClient.Logger().TraceMsg("Fetch sequence from node", - "sequence", sequence, - "account address", address, - ) - } else { - sequence, err = strconv.ParseUint(sequenceS, 10, 64) - if err != nil { - err = fmt.Errorf("sequence is misformatted: %v", err) - return - } - } - - return -} diff --git a/client/websocket_client.go b/client/websocket_client.go deleted file mode 100644 index 2580dc4bb0096e4241814fe806590727cd7aa342..0000000000000000000000000000000000000000 --- a/client/websocket_client.go +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "bytes" - "fmt" - "time" - - "encoding/json" - - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/errors" - exeEvents "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/logging/structure" - "github.com/hyperledger/burrow/rpc" - rpcClient "github.com/hyperledger/burrow/rpc/lib/client" - "github.com/hyperledger/burrow/rpc/tm/client" - "github.com/hyperledger/burrow/txs" - tmTypes "github.com/tendermint/tendermint/types" -) - -const ( - MaxCommitWaitTimeSeconds = 10 -) - -type Confirmation struct { - BlockHash []byte - EventDataTx *exeEvents.EventDataTx - Exception error - Error error -} - -// NOTE [ben] Compiler check to ensure burrowNodeClient successfully implements -// burrow/client.NodeClient -var _ NodeWebsocketClient = (*burrowNodeWebsocketClient)(nil) - -type burrowNodeWebsocketClient struct { - // TODO: assert no memory leak on closing with open websocket - tendermintWebsocket *rpcClient.WSClient - logger *logging.Logger -} - -// Subscribe to an eventid -func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Subscribe(eventId string) error { - // TODO we can in the background listen to the subscription id and remember it to ease unsubscribing later. - return client.Subscribe(burrowNodeWebsocketClient.tendermintWebsocket, - eventId) -} - -// Unsubscribe from an eventid -func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Unsubscribe(subscriptionId string) error { - return client.Unsubscribe(burrowNodeWebsocketClient.tendermintWebsocket, - subscriptionId) -} - -// Returns a channel that will receive a confirmation with a result or the exception that -// has been confirmed; or an error is returned and the confirmation channel is nil. -func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) WaitForConfirmation(txEnv *txs.Envelope, - inputAddr crypto.Address) (chan Confirmation, error) { - - // Setup the confirmation channel to be returned - confirmationChannel := make(chan Confirmation, 1) - var latestBlockHash []byte - - eventID := exeEvents.EventStringAccountInput(inputAddr) - if err := burrowNodeWebsocketClient.Subscribe(eventID); err != nil { - return nil, fmt.Errorf("Error subscribing to AccInput event (%s): %v", eventID, err) - } - if err := burrowNodeWebsocketClient.Subscribe(tmTypes.EventNewBlock); err != nil { - return nil, fmt.Errorf("Error subscribing to NewBlock event: %v", err) - } - // Read the incoming events - go func() { - var err error - - timeoutTimer := time.NewTimer(time.Duration(MaxCommitWaitTimeSeconds) * time.Second) - defer func() { - if !timeoutTimer.Stop() { - <-timeoutTimer.C - } - }() - - for { - select { - case <-timeoutTimer.C: - confirmationChannel <- Confirmation{ - BlockHash: nil, - EventDataTx: nil, - Exception: nil, - Error: fmt.Errorf("timed out waiting for event"), - } - return - - case response := <-burrowNodeWebsocketClient.tendermintWebsocket.ResponsesCh: - if response.Error != nil { - burrowNodeWebsocketClient.logger.InfoMsg( - "Error received on websocket channel", structure.ErrorKey, err) - continue - } - - switch response.ID { - case client.SubscribeRequestID: - resultSubscribe := new(rpc.ResultSubscribe) - err = json.Unmarshal(response.Result, resultSubscribe) - if err != nil { - burrowNodeWebsocketClient.logger.InfoMsg("Unable to unmarshal ResultSubscribe", - structure.ErrorKey, err) - continue - } - // TODO: collect subscription IDs, push into channel and on completion - burrowNodeWebsocketClient.logger.InfoMsg("Received confirmation for event", - "event", resultSubscribe.EventID, - "subscription_id", resultSubscribe.SubscriptionID) - - case client.EventResponseID(tmTypes.EventNewBlock): - resultEvent := new(rpc.ResultEvent) - err = json.Unmarshal(response.Result, resultEvent) - if err != nil { - burrowNodeWebsocketClient.logger.InfoMsg("Unable to unmarshal ResultEvent", - structure.ErrorKey, err) - continue - } - blockData := resultEvent.Tendermint.EventDataNewBlock() - if blockData != nil { - latestBlockHash = blockData.Block.Hash() - burrowNodeWebsocketClient.logger.TraceMsg("Registered new block", - "block", blockData.Block, - "latest_block_hash", latestBlockHash, - ) - } - - case client.EventResponseID(eventID): - resultEvent := new(rpc.ResultEvent) - err = json.Unmarshal(response.Result, resultEvent) - if err != nil { - burrowNodeWebsocketClient.logger.InfoMsg("Unable to unmarshal ResultEvent", - structure.ErrorKey, err) - continue - } - - eventDataTx := resultEvent.Execution.GetTx() - if eventDataTx == nil { - // We are on the lookout for EventDataTx - confirmationChannel <- Confirmation{ - BlockHash: latestBlockHash, - EventDataTx: nil, - Exception: fmt.Errorf("response error: expected result.Data to be *types.EventDataTx"), - Error: nil, - } - return - } - - if !bytes.Equal(eventDataTx.Tx.Hash(), txEnv.Tx.Hash()) { - burrowNodeWebsocketClient.logger.TraceMsg("Received different event", - // TODO: consider re-implementing TxID again, or other more clear debug - "received transaction event", eventDataTx.Tx.Hash()) - continue - } - - if eventDataTx.Exception != nil && eventDataTx.Exception.ErrorCode() != errors.ErrorCodeExecutionReverted { - confirmationChannel <- Confirmation{ - BlockHash: latestBlockHash, - EventDataTx: eventDataTx, - Exception: errors.Wrap(eventDataTx.Exception, - "transaction confirmed but execution gave exception: %v"), - Error: nil, - } - return - } - // success, return the full event and blockhash and exit go-routine - confirmationChannel <- Confirmation{ - BlockHash: latestBlockHash, - EventDataTx: eventDataTx, - Exception: nil, - Error: nil, - } - return - - default: - burrowNodeWebsocketClient.logger.InfoMsg("Received unsolicited response", - "response_id", response.ID, - "expected_response_id", client.EventResponseID(eventID)) - } - } - } - - }() - - return confirmationChannel, nil -} - -func (burrowNodeWebsocketClient *burrowNodeWebsocketClient) Close() { - if burrowNodeWebsocketClient.tendermintWebsocket != nil { - burrowNodeWebsocketClient.tendermintWebsocket.Stop() - } -} diff --git a/client/ws_client.go b/client/ws_client.go deleted file mode 100644 index cdcb0b570af2b87926e888d0ef009b125d89e8f5..0000000000000000000000000000000000000000 --- a/client/ws_client.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -// NOTE: this websocket client acts on rpc/v0, -// uses github.com/gorilla/websocket -// and will be deprecated after 0.12 -// It is recommended to use the interfaces NodeClient -// and NodeWebsocketClient. -// Websocket client implementation. This will be used in tests. - -import ( - "fmt" - "net/http" - - "github.com/gorilla/websocket" -) - -// A websocket client subscribes and unsubscribes to events -type WSClient struct { - host string - closed bool - conn *websocket.Conn -} - -// create a new connection -func NewWSClient(addr string) *WSClient { - return &WSClient{ - host: addr, - } -} - -func (this *WSClient) Dial() (*http.Response, error) { - dialer := websocket.DefaultDialer - rHeader := http.Header{} - conn, r, err := dialer.Dial(this.host, rHeader) - if err != nil { - return r, err - } - this.conn = conn - - return r, nil -} - -// returns a channel from which messages can be pulled -// from a go routine that reads the socket. -// if the ws returns an error (eg. closes), we return -func (this *WSClient) StartRead() <-chan []byte { - ch := make(chan []byte) - go func() { - for { - _, msg, err := this.conn.ReadMessage() - if err != nil { - if !this.closed { - // TODO For now. - fmt.Println("Error: " + err.Error()) - close(ch) - } - return - } - ch <- msg - } - }() - return ch -} - -func (this *WSClient) WriteMsg(msg []byte) { - this.conn.WriteMessage(websocket.TextMessage, msg) -} - -func (this *WSClient) Close() { - this.closed = true - this.conn.Close() -} diff --git a/cmd/burrow/commands/configure.go b/cmd/burrow/commands/configure.go index 142309de5775e4719a72d3ea42b2ab5fb86ed66e..c64d4c72a2cb953bf901e489241060d803f1250b 100644 --- a/cmd/burrow/commands/configure.go +++ b/cmd/burrow/commands/configure.go @@ -17,8 +17,8 @@ import ( "github.com/hyperledger/burrow/logging" logging_config "github.com/hyperledger/burrow/logging/config" "github.com/hyperledger/burrow/logging/config/presets" - "github.com/jawher/mow.cli" - "github.com/tendermint/go-amino" + cli "github.com/jawher/mow.cli" + amino "github.com/tendermint/go-amino" tm_crypto "github.com/tendermint/go-crypto" "github.com/tendermint/tendermint/p2p" ) diff --git a/cmd/burrow/commands/keys.go b/cmd/burrow/commands/keys.go index e8ba5d4b09221a4e741137aeccdba97baf57897d..8fcf1a8175968219a37ce372aa642adefdec94c5 100644 --- a/cmd/burrow/commands/keys.go +++ b/cmd/burrow/commands/keys.go @@ -7,6 +7,7 @@ import ( "os" "github.com/hyperledger/burrow/deployment" + cli "github.com/jawher/mow.cli" "time" @@ -16,9 +17,7 @@ import ( "github.com/hyperledger/burrow/config" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging/lifecycle" - "github.com/jawher/mow.cli" "google.golang.org/grpc" ) @@ -38,14 +37,14 @@ func Keys(output Output) func(cmd *cli.Cmd) { EnvVar: "MONAX_KEYS_PORT", }) - grpcKeysClient := func(output Output) pbkeys.KeysClient { + grpcKeysClient := func(output Output) keys.KeysClient { var opts []grpc.DialOption opts = append(opts, grpc.WithInsecure()) conn, err := grpc.Dial(*keysHost+":"+*keysPort, opts...) if err != nil { output.Fatalf("Failed to connect to grpc server: %v", err) } - return pbkeys.NewKeysClient(conn) + return keys.NewKeysClient(conn) } cmd.Command("server", "run keys server", func(cmd *cli.Cmd) { @@ -108,7 +107,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Passphrase: password, Curvetype: curve.String(), Keyname: *keyName}) + resp, err := c.GenerateKey(ctx, &keys.GenRequest{Passphrase: password, CurveType: curve.String(), KeyName: *keyName}) if err != nil { output.Fatalf("failed to generate key: %v", err) } @@ -139,7 +138,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: *hashType, Message: message}) + resp, err := c.Hash(ctx, &keys.HashRequest{Hashtype: *hashType, Message: message}) if err != nil { output.Fatalf("failed to get public key: %v", err) } @@ -158,7 +157,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.Export(ctx, &pbkeys.ExportRequest{Passphrase: *passphrase, Name: *keyName, Address: *keyAddr}) + resp, err := c.Export(ctx, &keys.ExportRequest{Passphrase: *passphrase, Name: *keyName, Address: *keyAddr}) if err != nil { output.Fatalf("failed to export key: %v", err) } @@ -170,7 +169,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { key := deployment.Key{ Name: *keyName, - CurveType: resp.GetCurvetype(), + CurveType: resp.GetCurveType(), Address: addr, PublicKey: resp.GetPublickey(), PrivateKey: resp.GetPrivatekey(), @@ -212,7 +211,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { defer cancel() if (*key)[:1] == "{" { - resp, err := c.ImportJSON(ctx, &pbkeys.ImportJSONRequest{JSON: *key}) + resp, err := c.ImportJSON(ctx, &keys.ImportJSONRequest{JSON: *key}) if err != nil { output.Fatalf("failed to import json key: %v", err) } @@ -223,7 +222,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { if err != nil { output.Fatalf("failed to hex decode key: %s", *key) } - resp, err := c.Import(ctx, &pbkeys.ImportRequest{Passphrase: password, Keybytes: privKeyBytes, Curvetype: *curveType}) + resp, err := c.Import(ctx, &keys.ImportRequest{Passphrase: password, KeyBytes: privKeyBytes, CurveType: *curveType}) if err != nil { output.Fatalf("failed to import json key: %v", err) } @@ -242,12 +241,12 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Name: *name, Address: *addr}) + resp, err := c.PublicKey(ctx, &keys.PubRequest{Name: *name, Address: *addr}) if err != nil { output.Fatalf("failed to get public key: %v", err) } - fmt.Printf("%X\n", resp.GetPub()) + fmt.Printf("%X\n", resp.GetPublicKey()) } }) @@ -266,7 +265,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.Sign(ctx, &pbkeys.SignRequest{Passphrase: *passphrase, Name: *name, Address: *addr, Message: message}) + resp, err := c.Sign(ctx, &keys.SignRequest{Passphrase: *passphrase, Name: *name, Address: *addr, Message: message}) if err != nil { output.Fatalf("failed to get public key: %v", err) } @@ -300,7 +299,10 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Curvetype: *curveType, Pub: publickey, Signature: signature, Message: message}) + _, err = c.Verify(ctx, &keys.VerifyRequest{ + CurveType: *curveType, + PublicKey: publickey, + Signature: signature, Message: message}) if err != nil { output.Fatalf("failed to verify: %v", err) } @@ -316,7 +318,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, err := c.AddName(ctx, &pbkeys.AddNameRequest{Keyname: *keyname, Address: *addr}) + _, err := c.AddName(ctx, &keys.AddNameRequest{Keyname: *keyname, Address: *addr}) if err != nil { output.Fatalf("failed to add name to addr: %v", err) } @@ -330,13 +332,13 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.List(ctx, &pbkeys.ListRequest{}) + resp, err := c.List(ctx, &keys.ListRequest{}) if err != nil { output.Fatalf("failed to list key names: %v", err) } if *name != "" { for _, k := range resp.Key { - if k.Keyname == *name { + if k.KeyName == *name { output.Printf("%s\n", k.Address) } } @@ -355,7 +357,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, err := c.RemoveName(ctx, &pbkeys.RemoveNameRequest{Keyname: *name}) + _, err := c.RemoveName(ctx, &keys.RemoveNameRequest{KeyName: *name}) if err != nil { output.Fatalf("failed to remove key: %v", err) } diff --git a/cmd/burrow/commands/spec.go b/cmd/burrow/commands/spec.go index 36fad65a7fcd53b66bd6385bc133f7b3e927db79..1110d869e52d816dec4b905cb0bfed4305954077 100644 --- a/cmd/burrow/commands/spec.go +++ b/cmd/burrow/commands/spec.go @@ -5,7 +5,7 @@ import ( "github.com/hyperledger/burrow/config/source" "github.com/hyperledger/burrow/genesis/spec" - "github.com/jawher/mow.cli" + cli "github.com/jawher/mow.cli" ) func Spec(output Output) func(cmd *cli.Cmd) { diff --git a/cmd/burrow/commands/start.go b/cmd/burrow/commands/start.go index e3d11c1309f25bcdefce95a73de4a76be745b1a3..e6b56f09beaf4e003772e572bf957306dc6df808 100644 --- a/cmd/burrow/commands/start.go +++ b/cmd/burrow/commands/start.go @@ -4,7 +4,7 @@ import ( "context" "github.com/hyperledger/burrow/crypto" - "github.com/jawher/mow.cli" + cli "github.com/jawher/mow.cli" ) func Start(output Output) func(cmd *cli.Cmd) { diff --git a/cmd/burrow/main.go b/cmd/burrow/main.go index 0bc40136364d7fcf5b66de2c3c394cf43745f2ef..38c17d59fffbe6bc08eba6f48b81b258d26dcc8e 100644 --- a/cmd/burrow/main.go +++ b/cmd/burrow/main.go @@ -6,7 +6,7 @@ import ( "github.com/hyperledger/burrow/cmd/burrow/commands" "github.com/hyperledger/burrow/project" - "github.com/jawher/mow.cli" + cli "github.com/jawher/mow.cli" ) func main() { diff --git a/config/config.go b/config/config.go index c9958d56df2cccc1ddcbfc233db4f81bef7681fd..c22ddbb1194d883ff262431a62c7fa4663e1620e 100644 --- a/config/config.go +++ b/config/config.go @@ -40,6 +40,7 @@ func DefaultBurrowConfig() *BurrowConfig { Tendermint: tendermint.DefaultBurrowTendermintConfig(), Keys: keys.DefaultKeysConfig(), RPC: rpc.DefaultRPCConfig(), + Execution: execution.DefaultExecutionConfig(), Logging: logging_config.DefaultNodeLoggingConfig(), } } diff --git a/consensus/tendermint/abci/app.go b/consensus/tendermint/abci/app.go index ba7fec9f55324e640ec2f24b0ccf6a440f5c97b9..6c5247481b86a1e59fd3a7d71ee61efb66d0a9dd 100644 --- a/consensus/tendermint/abci/app.go +++ b/consensus/tendermint/abci/app.go @@ -5,7 +5,7 @@ import ( "sync" "time" - "encoding/json" + "runtime/debug" bcm "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/consensus/tendermint/codes" @@ -26,11 +26,13 @@ type App struct { blockchain *bcm.Blockchain checker execution.BatchExecutor committer execution.BatchCommitter + checkTx func(txBytes []byte) abciTypes.ResponseCheckTx + deliverTx func(txBytes []byte) abciTypes.ResponseCheckTx mempoolLocker sync.Locker // We need to cache these from BeginBlock for when we need actually need it in Commit block *abciTypes.RequestBeginBlock - // Utility - txDecoder txs.Decoder + // Function to use to fail gracefully from panic rather than letting Tendermint make us a zombie + panicFunc func(error) // Logging logger *logging.Logger } @@ -38,12 +40,14 @@ type App struct { var _ abciTypes.Application = &App{} func NewApp(blockchain *bcm.Blockchain, checker execution.BatchExecutor, committer execution.BatchCommitter, - txDecoder txs.Decoder, logger *logging.Logger) *App { + txDecoder txs.Decoder, panicFunc func(error), logger *logging.Logger) *App { return &App{ blockchain: blockchain, checker: checker, committer: committer, - txDecoder: txDecoder, + checkTx: txExecutor(checker, txDecoder, logger.WithScope("CheckTx")), + deliverTx: txExecutor(committer, txDecoder, logger.WithScope("DeliverTx")), + panicFunc: panicFunc, logger: logger.WithScope("abci.NewApp").With(structure.ComponentKey, "ABCI_App"), } } @@ -77,50 +81,6 @@ func (app *App) Query(reqQuery abciTypes.RequestQuery) (respQuery abciTypes.Resp return } -func (app *App) CheckTx(txBytes []byte) abciTypes.ResponseCheckTx { - txEnv, err := app.txDecoder.DecodeTx(txBytes) - if err != nil { - app.logger.TraceMsg("CheckTx decoding error", - "tag", "CheckTx", - structure.ErrorKey, err) - return abciTypes.ResponseCheckTx{ - Code: codes.EncodingErrorCode, - Log: fmt.Sprintf("Encoding error: %s", err), - } - } - receipt := txEnv.Tx.GenerateReceipt() - - err = app.checker.Execute(txEnv) - if err != nil { - app.logger.TraceMsg("CheckTx execution error", - structure.ErrorKey, err, - "tag", "CheckTx", - "tx_hash", receipt.TxHash, - "creates_contract", receipt.CreatesContract) - return abciTypes.ResponseCheckTx{ - Code: codes.EncodingErrorCode, - Log: fmt.Sprintf("CheckTx could not execute transaction: %s, error: %v", txEnv, err), - } - } - - receiptBytes, err := json.Marshal(receipt) - if err != nil { - return abciTypes.ResponseCheckTx{ - Code: codes.TxExecutionErrorCode, - Log: fmt.Sprintf("CheckTx could not serialise receipt: %s", err), - } - } - app.logger.TraceMsg("CheckTx success", - "tag", "CheckTx", - "tx_hash", receipt.TxHash, - "creates_contract", receipt.CreatesContract) - return abciTypes.ResponseCheckTx{ - Code: codes.TxExecutionSuccessCode, - Log: "CheckTx success - receipt in data", - Data: receiptBytes, - } -} - func (app *App) InitChain(chain abciTypes.RequestInitChain) (respInitChain abciTypes.ResponseInitChain) { // Could verify agreement on initial validator set here return @@ -131,47 +91,74 @@ func (app *App) BeginBlock(block abciTypes.RequestBeginBlock) (respBeginBlock ab return } +func (app *App) CheckTx(txBytes []byte) abciTypes.ResponseCheckTx { + defer func() { + if r := recover(); r != nil { + app.panicFunc(fmt.Errorf("panic occurred in abci.App/CheckTx: %v\n%s", r, debug.Stack())) + } + }() + return app.checkTx(txBytes) +} + func (app *App) DeliverTx(txBytes []byte) abciTypes.ResponseDeliverTx { - txEnv, err := app.txDecoder.DecodeTx(txBytes) - if err != nil { - app.logger.TraceMsg("DeliverTx decoding error", - "tag", "DeliverTx", - structure.ErrorKey, err) - return abciTypes.ResponseDeliverTx{ - Code: codes.EncodingErrorCode, - Log: fmt.Sprintf("Encoding error: %s", err), + defer func() { + if r := recover(); r != nil { + app.panicFunc(fmt.Errorf("panic occurred in abci.App/DeliverTx: %v\n%s", r, debug.Stack())) } + }() + ctr := app.deliverTx(txBytes) + // Currently these message types are identical, if they are ever different can map between + return abciTypes.ResponseDeliverTx{ + Code: ctr.Code, + Log: ctr.Log, + Data: ctr.Data, + Tags: ctr.Tags, + Fee: ctr.Fee, + GasUsed: ctr.GasUsed, + GasWanted: ctr.GasWanted, + Info: ctr.Info, } +} - receipt := txEnv.Tx.GenerateReceipt() - err = app.committer.Execute(txEnv) - if err != nil { - app.logger.TraceMsg("DeliverTx execution error", - structure.ErrorKey, err, - "tag", "DeliverTx", - "tx_hash", receipt.TxHash, - "creates_contract", receipt.CreatesContract) - return abciTypes.ResponseDeliverTx{ - Code: codes.TxExecutionErrorCode, - Log: fmt.Sprintf("DeliverTx could not execute transaction: %s, error: %s", txEnv, err), +func txExecutor(executor execution.BatchExecutor, txDecoder txs.Decoder, logger *logging.Logger) func(txBytes []byte) abciTypes.ResponseCheckTx { + return func(txBytes []byte) abciTypes.ResponseCheckTx { + txEnv, err := txDecoder.DecodeTx(txBytes) + if err != nil { + logger.TraceMsg("Decoding error", + structure.ErrorKey, err) + return abciTypes.ResponseCheckTx{ + Code: codes.EncodingErrorCode, + Log: fmt.Sprintf("Encoding error: %s", err), + } } - } - app.logger.TraceMsg("DeliverTx success", - "tag", "DeliverTx", - "tx_hash", receipt.TxHash, - "creates_contract", receipt.CreatesContract) - receiptBytes, err := json.Marshal(receipt) - if err != nil { - return abciTypes.ResponseDeliverTx{ - Code: codes.TxExecutionErrorCode, - Log: fmt.Sprintf("DeliverTx could not serialise receipt: %s", err), + txe, err := executor.Execute(txEnv) + if err != nil { + logger.TraceMsg("Execution error", + structure.ErrorKey, err, + "tx_hash", txEnv.Tx.Hash()) + return abciTypes.ResponseCheckTx{ + Code: codes.EncodingErrorCode, + Log: fmt.Sprintf("Could not execute transaction: %s, error: %v", txEnv, err), + } + } + + bs, err := txe.Receipt.Encode() + if err != nil { + return abciTypes.ResponseCheckTx{ + Code: codes.TxExecutionErrorCode, + Log: fmt.Sprintf("Could not serialise receipt: %s", err), + } + } + logger.TraceMsg("Execution success", + "tx_hash", txe.TxHash, + "contract_address", txe.Receipt.ContractAddress, + "creates_contract", txe.Receipt.CreatesContract) + return abciTypes.ResponseCheckTx{ + Code: codes.TxExecutionSuccessCode, + Log: "Execution success - TxExecution in data", + Data: bs, } - } - return abciTypes.ResponseDeliverTx{ - Code: codes.TxExecutionSuccessCode, - Log: "DeliverTx success - receipt in data", - Data: receiptBytes, } } @@ -192,6 +179,11 @@ func (app *App) EndBlock(reqEndBlock abciTypes.RequestEndBlock) abciTypes.Respon } func (app *App) Commit() abciTypes.ResponseCommit { + defer func() { + if r := recover(); r != nil { + app.panicFunc(fmt.Errorf("panic occurred in abci.App/Commit: %v\n%s", r, debug.Stack())) + } + }() app.logger.InfoMsg("Committing block", "tag", "Commit", structure.ScopeKey, "Commit()", @@ -229,7 +221,8 @@ func (app *App) Commit() abciTypes.ResponseCommit { // First commit the app start, this app hash will not get checkpointed until the next block when we are sure // that nothing in the downstream commit process could have failed. At worst we go back one block. - appHash, err := app.committer.Commit() + blockHeader := app.block.Header + appHash, err := app.committer.Commit(&blockHeader) if err != nil { panic(errors.Wrap(err, "Could not commit transactions in block to execution state")) } diff --git a/consensus/tendermint/events.go b/consensus/tendermint/events.go deleted file mode 100644 index c85f976c0d20cad99722976c4393e9d0d261df41..0000000000000000000000000000000000000000 --- a/consensus/tendermint/events.go +++ /dev/null @@ -1,103 +0,0 @@ -package tendermint - -import ( - "context" - - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/logging/structure" - "github.com/tendermint/tendermint/libs/pubsub" - tm_types "github.com/tendermint/tendermint/types" -) - -// Publishes all tendermint events available on subscribable to publisher -func PublishAllEvents(ctx context.Context, fromSubscribable event.Subscribable, subscriber string, - toPublisher event.Publisher) error { - - var err error - - // This is a work-around for the fact we cannot access a message's tags and need a separate query for each event type - tendermintEventTypes := []string{ - tm_types.EventBond, - tm_types.EventCompleteProposal, - tm_types.EventDupeout, - tm_types.EventFork, - tm_types.EventLock, - tm_types.EventNewBlock, - tm_types.EventNewBlockHeader, - tm_types.EventNewRound, - tm_types.EventNewRoundStep, - tm_types.EventPolka, - tm_types.EventRebond, - tm_types.EventRelock, - tm_types.EventTimeoutPropose, - tm_types.EventTimeoutWait, - tm_types.EventTx, - tm_types.EventUnbond, - tm_types.EventUnlock, - tm_types.EventVote, - tm_types.EventProposalHeartbeat, - } - - for _, eventType := range tendermintEventTypes { - publishErr := PublishEvent(ctx, fromSubscribable, subscriber, eventType, toPublisher) - if publishErr != nil && err == nil { - err = publishErr - } - } - - return err -} - -func PublishEvent(ctx context.Context, fromSubscribable event.Subscribable, subscriber string, eventType string, - toPublisher event.Publisher) error { - tags := map[string]interface{}{ - structure.ComponentKey: "Tendermint", - tm_types.EventTypeKey: eventType, - event.EventIDKey: eventType, - } - return event.PublishAll(ctx, fromSubscribable, subscriber, query.WrapQuery(tm_types.QueryForEvent(eventType)), - toPublisher, tags) -} - -type eventBusSubscriber struct { - tm_types.EventBusSubscriber -} - -func EventBusAsSubscribable(eventBus tm_types.EventBusSubscriber) event.Subscribable { - return eventBusSubscriber{eventBus} -} - -func (ebs eventBusSubscriber) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, - out chan<- interface{}) error { - qry, err := queryable.Query() - if err != nil { - return err - } - return ebs.EventBusSubscriber.Subscribe(ctx, subscriber, qry, out) -} - -func (ebs eventBusSubscriber) Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error { - qry, err := queryable.Query() - if err != nil { - return err - } - return ebs.EventBusSubscriber.Unsubscribe(ctx, subscriber, qry) -} - -type subscribableEventBus struct { - event.Subscribable -} - -func SubscribableAsEventBus(subscribable event.Subscribable) tm_types.EventBusSubscriber { - return subscribableEventBus{subscribable} -} - -func (seb subscribableEventBus) Subscribe(ctx context.Context, subscriber string, qry pubsub.Query, - out chan<- interface{}) error { - return seb.Subscribable.Subscribe(ctx, subscriber, query.WrapQuery(qry), out) -} - -func (seb subscribableEventBus) Unsubscribe(ctx context.Context, subscriber string, qry pubsub.Query) error { - return seb.Subscribable.Unsubscribe(ctx, subscriber, query.WrapQuery(qry)) -} diff --git a/consensus/tendermint/logger.go b/consensus/tendermint/logger.go index 6022f47307eade096ddbd9e92c492cda12c9ae85..2a73c22fb234525dd95d3abd0ae5602e91ce3443 100644 --- a/consensus/tendermint/logger.go +++ b/consensus/tendermint/logger.go @@ -9,7 +9,7 @@ type tendermintLogger struct { logger *logging.Logger } -func NewLogger(logger *logging.Logger) *tendermintLogger { +func NewLogger(logger *logging.Logger) log.Logger { return &tendermintLogger{ logger: logger, } diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index e7ddf260b6622e13cdf1e30d0e9a2ec739963c59..3ada43cf2c49f6fd915e3de4b6342593cbf854e0 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -1,25 +1,22 @@ package tendermint import ( - "context" - "os" "path" bcm "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/consensus/tendermint/abci" "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/event/query" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/txs" - tm_crypto "github.com/tendermint/go-crypto" + tmCrypto "github.com/tendermint/go-crypto" "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/proxy" - tm_types "github.com/tendermint/tendermint/types" + tmTypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tmlibs/db" ) @@ -31,7 +28,7 @@ type Node struct { } } -var NewBlockQuery = query.Must(event.QueryForEventID(tm_types.EventNewBlock).Query()) +var NewBlockQuery = event.QueryForEventID(tmTypes.EventNewBlock) func DBProvider(ID string, backendType dbm.DBBackendType, dbDir string) dbm.DB { return dbm.NewDB(ID, backendType, dbDir) @@ -50,9 +47,9 @@ func (n *Node) Close() { } } -func NewNode(conf *config.Config, privValidator tm_types.PrivValidator, genesisDoc *tm_types.GenesisDoc, +func NewNode(conf *config.Config, privValidator tmTypes.PrivValidator, genesisDoc *tmTypes.GenesisDoc, blockchain *bcm.Blockchain, checker execution.BatchExecutor, committer execution.BatchCommitter, - txDecoder txs.Decoder, logger *logging.Logger) (*Node, error) { + txDecoder txs.Decoder, panicFunc func(error), logger *logging.Logger) (*Node, error) { var err error // disable Tendermint's RPC @@ -64,11 +61,11 @@ func NewNode(conf *config.Config, privValidator tm_types.PrivValidator, genesisD } nde := &Node{} - app := abci.NewApp(blockchain, checker, committer, txDecoder, logger) + app := abci.NewApp(blockchain, checker, committer, txDecoder, panicFunc, logger) conf.NodeKeyFile() nde.Node, err = node.NewNode(conf, privValidator, proxy.NewLocalClientCreator(app), - func() (*tm_types.GenesisDoc, error) { + func() (*tmTypes.GenesisDoc, error) { return genesisDoc, nil }, nde.DBProvider, @@ -81,56 +78,33 @@ func NewNode(conf *config.Config, privValidator tm_types.PrivValidator, genesisD return nde, nil } -func DeriveGenesisDoc(burrowGenesisDoc *genesis.GenesisDoc) *tm_types.GenesisDoc { - validators := make([]tm_types.GenesisValidator, len(burrowGenesisDoc.Validators)) +func DeriveGenesisDoc(burrowGenesisDoc *genesis.GenesisDoc) *tmTypes.GenesisDoc { + validators := make([]tmTypes.GenesisValidator, len(burrowGenesisDoc.Validators)) for i, validator := range burrowGenesisDoc.Validators { - tm := tm_crypto.PubKeyEd25519{} + tm := tmCrypto.PubKeyEd25519{} copy(tm[:], validator.PublicKey.RawBytes()) - validators[i] = tm_types.GenesisValidator{ + validators[i] = tmTypes.GenesisValidator{ PubKey: tm, Name: validator.Name, Power: int64(validator.Amount), } } - return &tm_types.GenesisDoc{ + return &tmTypes.GenesisDoc{ ChainID: burrowGenesisDoc.ChainID(), GenesisTime: burrowGenesisDoc.GenesisTime, Validators: validators, AppHash: burrowGenesisDoc.Hash(), - ConsensusParams: tm_types.DefaultConsensusParams(), + ConsensusParams: tmTypes.DefaultConsensusParams(), } } -func NewBlockEvent(message interface{}) *tm_types.EventDataNewBlock { - tmEventData, ok := message.(tm_types.TMEventData) +func NewBlockEvent(message interface{}) *tmTypes.EventDataNewBlock { + tmEventData, ok := message.(tmTypes.TMEventData) if ok { - eventDataNewBlock, ok := tmEventData.(tm_types.EventDataNewBlock) + eventDataNewBlock, ok := tmEventData.(tmTypes.EventDataNewBlock) if ok { return &eventDataNewBlock } } return nil } - -// Subscribe to NewBlock event safely that ensures progress by a non-blocking receive as well as handling unsubscribe -func SubscribeNewBlock(ctx context.Context, subscribable event.Subscribable) (<-chan *tm_types.EventDataNewBlock, error) { - subID, err := event.GenerateSubscriptionID() - if err != nil { - return nil, err - } - const unconsumedBlocksBeforeUnsubscribe = 3 - ch := make(chan *tm_types.EventDataNewBlock, unconsumedBlocksBeforeUnsubscribe) - return ch, event.SubscribeCallback(ctx, subscribable, subID, NewBlockQuery, func(message interface{}) (stop bool) { - eventDataNewBlock := NewBlockEvent(message) - if eventDataNewBlock != nil { - select { - case ch <- eventDataNewBlock: - return false - default: - // If we can't send shut down the channel - return true - } - } - return - }) -} diff --git a/consensus/tendermint/validator/priv_validator_memory.go b/consensus/tendermint/validator/priv_validator_memory.go index 7f5077c1f10fa89200f23e7f0b941d021d76eae7..05455cba2ab81ec8ef4a256d33d5b46836a65136 100644 --- a/consensus/tendermint/validator/priv_validator_memory.go +++ b/consensus/tendermint/validator/priv_validator_memory.go @@ -1,7 +1,7 @@ package validator import ( - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" tm_crypto "github.com/tendermint/go-crypto" tm_types "github.com/tendermint/tendermint/types" diff --git a/core/kernel.go b/core/kernel.go index 1ea5f95b9791405126d2659c4bb5ce3e27084613..fee805da88c4770fe9bfd719330f711607627428 100644 --- a/core/kernel.go +++ b/core/kernel.go @@ -32,32 +32,28 @@ import ( "github.com/hyperledger/burrow/consensus/tendermint/query" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution" - "github.com/hyperledger/burrow/execution/events/pbevents" - "github.com/hyperledger/burrow/execution/pbtransactor" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/process" "github.com/hyperledger/burrow/rpc" "github.com/hyperledger/burrow/rpc/metrics" "github.com/hyperledger/burrow/rpc/rpcevents" - "github.com/hyperledger/burrow/rpc/rpctransactor" + "github.com/hyperledger/burrow/rpc/rpcquery" + "github.com/hyperledger/burrow/rpc/rpctransact" "github.com/hyperledger/burrow/rpc/tm" - "github.com/hyperledger/burrow/rpc/v0" - v0_server "github.com/hyperledger/burrow/rpc/v0/server" "github.com/hyperledger/burrow/txs" - tm_config "github.com/tendermint/tendermint/config" - tm_types "github.com/tendermint/tendermint/types" + tmConfig "github.com/tendermint/tendermint/config" + tmTypes "github.com/tendermint/tendermint/types" dbm "github.com/tendermint/tmlibs/db" - "google.golang.org/grpc/reflection" ) const ( CooldownMilliseconds = 1000 ServerShutdownTimeoutMilliseconds = 1000 LoggingCallerDepth = 5 + AccountsRingMutexCount = 100 ) // Kernel is the root structure of Burrow @@ -74,10 +70,14 @@ type Kernel struct { shutdownOnce sync.Once } -func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_types.PrivValidator, - genesisDoc *genesis.GenesisDoc, tmConf *tm_config.Config, rpcConfig *rpc.RPCConfig, keyConfig *keys.KeysConfig, +func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tmTypes.PrivValidator, + genesisDoc *genesis.GenesisDoc, tmConf *tmConfig.Config, rpcConfig *rpc.RPCConfig, keyConfig *keys.KeysConfig, keyStore *keys.KeyStore, exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) { + kern := &Kernel{ + processes: make(map[string]process.Process), + shutdownNotify: make(chan struct{}), + } logger = logger.WithScope("NewKernel()").With(structure.TimeKey, kitlog.DefaultTimestampUTC) tmLogger := logger.With(structure.CallerKey, kitlog.Caller(LoggingCallerDepth+1)) logger = logger.WithInfo(structure.CallerKey, kitlog.Caller(LoggingCallerDepth)) @@ -107,16 +107,17 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t emitter := event.NewEmitter(logger) committer := execution.NewBatchCommitter(state, blockchain.Tip, emitter, logger, exeOptions...) tmNode, err := tendermint.NewNode(tmConf, privValidator, tmGenesisDoc, blockchain, checker, committer, txCodec, - tmLogger) + kern.Panic, tmLogger) if err != nil { return nil, err } - transactor := execution.NewTransactor(blockchain.Tip, emitter, tmNode.MempoolReactor().BroadcastTx, txCodec, - logger) + + transactor := execution.NewTransactor(blockchain.Tip, emitter, execution.NewAccounts(checker, keyClient, AccountsRingMutexCount), + tmNode.MempoolReactor().BroadcastTx, txCodec, logger) nameRegState := state accountState := state - service := rpc.NewService(ctx, accountState, nameRegState, checker, emitter, blockchain, keyClient, transactor, + service := rpc.NewService(accountState, nameRegState, blockchain, transactor, query.NewNodeView(tmNode, txCodec), logger) launchers := []process.Launcher{ @@ -155,14 +156,6 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t if err != nil { return nil, fmt.Errorf("error starting Tendermint node: %v", err) } - subscriber := fmt.Sprintf("TendermintFireHose-%s-%s", genesisDoc.ChainName, genesisDoc.ChainID()) - // Multiplex Tendermint and EVM events - - err = tendermint.PublishAllEvents(ctx, tendermint.EventBusAsSubscribable(tmNode.EventBus()), subscriber, - emitter) - if err != nil { - return nil, fmt.Errorf("could not subscribe to Tendermint events: %v", err) - } return process.ShutdownFunc(func(ctx context.Context) error { err := tmNode.Stop() // Close tendermint database connections using our wrapper @@ -185,7 +178,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t Name: "RPC/tm", Enabled: rpcConfig.TM.Enabled, Launch: func() (process.Process, error) { - server, err := tm.StartServer(service, "/websocket", rpcConfig.TM.ListenAddress, emitter, logger) + server, err := tm.StartServer(service, "/websocket", rpcConfig.TM.ListenAddress, logger) if err != nil { return nil, err } @@ -203,26 +196,6 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t return server, nil }, }, - { - Name: "RPC/V0", - Enabled: rpcConfig.V0.Enabled, - Launch: func() (process.Process, error) { - codec := v0.NewTCodec() - jsonServer := v0.NewJSONServer(v0.NewJSONService(codec, service, logger)) - websocketServer := v0_server.NewWebSocketServer(rpcConfig.V0.Server.WebSocket.MaxWebSocketSessions, - v0.NewWebsocketService(codec, service, logger), logger) - - serveProcess, err := v0_server.NewServeProcess(rpcConfig.V0.Server, logger, jsonServer, websocketServer) - if err != nil { - return nil, err - } - err = serveProcess.Start() - if err != nil { - return nil, err - } - return serveProcess, nil - }, - }, { Name: "RPC/GRPC", Enabled: rpcConfig.GRPC.Enabled, @@ -231,6 +204,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t if err != nil { return nil, err } + listen.Addr() grpcServer := rpc.NewGRPCServer(logger) var ks *keys.KeyStore @@ -242,19 +216,18 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t if keyStore == nil { ks = keys.NewKeyStore(keyConfig.KeysDirectory, keyConfig.AllowBadFilePermissions, logger) } - pbkeys.RegisterKeysServer(grpcServer, ks) + keys.RegisterKeysServer(grpcServer, ks) } - pbtransactor.RegisterTransactorServer(grpcServer, rpctransactor.NewTransactorServer(service.Transactor(), - service.MempoolAccounts(), state, txCodec)) + rpcquery.RegisterQueryServer(grpcServer, rpcquery.NewQueryServer(state, nameRegState)) - pbevents.RegisterEventsServer(grpcServer, rpcevents.NewEventsServer(rpc.NewSubscriptions(service))) + rpctransact.RegisterTransactServer(grpcServer, rpctransact.NewTransactServer(transactor, txCodec)) - pbevents.RegisterExecutionEventsServer(grpcServer, rpcevents.NewExecutionEventsServer(state, emitter, - blockchain.Tip)) + rpcevents.RegisterExecutionEventsServer(grpcServer, rpcevents.NewExecutionEventsServer(state, emitter, + blockchain.Tip, logger)) // Provides metadata about services registered - reflection.Register(grpcServer) + //reflection.Register(grpcServer) go grpcServer.Serve(listen) @@ -267,16 +240,13 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t }, } - return &Kernel{ - Emitter: emitter, - Service: service, - Launchers: launchers, - State: state, - Blockchain: blockchain, - Logger: logger, - processes: make(map[string]process.Process), - shutdownNotify: make(chan struct{}), - }, nil + kern.Emitter = emitter + kern.Service = service + kern.Launchers = launchers + kern.State = state + kern.Blockchain = blockchain + kern.Logger = logger + return kern, nil } // Boot the kernel starting Tendermint and RPC layers @@ -295,6 +265,12 @@ func (kern *Kernel) Boot() error { return nil } +func (kern *Kernel) Panic(err error) { + fmt.Fprintf(os.Stderr, "Kernel shutting down due to panic: %v", err) + kern.Shutdown(context.Background()) + os.Exit(1) +} + // Wait for a graceful shutdown func (kern *Kernel) WaitForShutdown() { // Supports multiple goroutines waiting for shutdown since channel is closed diff --git a/crypto/address.go b/crypto/address.go index a72f8c02d9d4456d4e638780d902c0e3ecc09123..9dab201555b8262b792bcfc3328ba81100c7ae3b 100644 --- a/crypto/address.go +++ b/crypto/address.go @@ -120,6 +120,35 @@ func (address *Address) UnmarshalText(text []byte) error { func (address Address) MarshalText() ([]byte, error) { return ([]byte)(hex.EncodeUpperToString(address[:])), nil + +} + +// Gogo proto support +func (address *Address) Marshal() ([]byte, error) { + if address == nil { + return nil, nil + } + return address.Bytes(), nil +} + +func (address *Address) Unmarshal(data []byte) error { + if len(data) == 0 { + return nil + } + if len(data) != binary.Word160Length { + return fmt.Errorf("error unmarshallling address '%X' from bytes: %d bytes but should have %d bytes", + data, len(data), binary.Word160Length) + } + copy(address[:], data) + return nil +} + +func (address *Address) MarshalTo(data []byte) (int, error) { + return copy(data, address[:]), nil +} + +func (address *Address) Size() int { + return binary.Word160Length } func NewContractAddress(caller Address, sequence uint64) (newAddr Address) { diff --git a/crypto/crypto.go b/crypto/crypto.go index a1d588e9094571333c531b9d53bb0490112b3cbf..e5f62db1024847f61d3e239ce7322be26cc6ec75 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -4,7 +4,7 @@ import ( "fmt" ) -type CurveType int8 +type CurveType uint32 const ( CurveTypeSecp256k1 CurveType = iota diff --git a/crypto/crypto.pb.go b/crypto/crypto.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..230f0f5e5efe55c40feffe0ac493737355a061e3 --- /dev/null +++ b/crypto/crypto.pb.go @@ -0,0 +1,555 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: crypto.proto + +/* + Package crypto is a generated protocol buffer package. + + It is generated from these files: + crypto.proto + + It has these top-level messages: + PublicKey + PrivateKey +*/ +package crypto + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +// PublicKey +type PublicKey struct { + CurveType CurveType `protobuf:"varint,1,opt,name=CurveType,proto3,casttype=CurveType" json:"CurveType,omitempty"` + PublicKey []byte `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"` +} + +func (m *PublicKey) Reset() { *m = PublicKey{} } +func (*PublicKey) ProtoMessage() {} +func (*PublicKey) Descriptor() ([]byte, []int) { return fileDescriptorCrypto, []int{0} } + +func (m *PublicKey) GetCurveType() CurveType { + if m != nil { + return m.CurveType + } + return 0 +} + +func (m *PublicKey) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func (*PublicKey) XXX_MessageName() string { + return "crypto.PublicKey" +} + +type PrivateKey struct { + CurveType CurveType `protobuf:"varint,1,opt,name=CurveType,proto3,casttype=CurveType" json:"CurveType,omitempty"` + // Note may need initialisation + PublicKey []byte `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"` + PrivateKey []byte `protobuf:"bytes,3,opt,name=PrivateKey,proto3" json:"PrivateKey,omitempty"` +} + +func (m *PrivateKey) Reset() { *m = PrivateKey{} } +func (*PrivateKey) ProtoMessage() {} +func (*PrivateKey) Descriptor() ([]byte, []int) { return fileDescriptorCrypto, []int{1} } + +func (*PrivateKey) XXX_MessageName() string { + return "crypto.PrivateKey" +} +func init() { + proto.RegisterType((*PublicKey)(nil), "crypto.PublicKey") + golang_proto.RegisterType((*PublicKey)(nil), "crypto.PublicKey") + proto.RegisterType((*PrivateKey)(nil), "crypto.PrivateKey") + golang_proto.RegisterType((*PrivateKey)(nil), "crypto.PrivateKey") +} +func (m *PublicKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PublicKey) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.CurveType != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(m.CurveType)) + } + if len(m.PublicKey) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(len(m.PublicKey))) + i += copy(dAtA[i:], m.PublicKey) + } + return i, nil +} + +func (m *PrivateKey) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PrivateKey) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.CurveType != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(m.CurveType)) + } + if len(m.PublicKey) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintCrypto(dAtA, i, uint64(len(m.PublicKey))) + i += copy(dAtA[i:], m.PublicKey) + } + if len(m.PrivateKey) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintCrypto(dAtA, i, uint64(len(m.PrivateKey))) + i += copy(dAtA[i:], m.PrivateKey) + } + return i, nil +} + +func encodeVarintCrypto(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *PublicKey) Size() (n int) { + var l int + _ = l + if m.CurveType != 0 { + n += 1 + sovCrypto(uint64(m.CurveType)) + } + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovCrypto(uint64(l)) + } + return n +} + +func (m *PrivateKey) Size() (n int) { + var l int + _ = l + if m.CurveType != 0 { + n += 1 + sovCrypto(uint64(m.CurveType)) + } + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovCrypto(uint64(l)) + } + l = len(m.PrivateKey) + if l > 0 { + n += 1 + l + sovCrypto(uint64(l)) + } + return n +} + +func sovCrypto(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozCrypto(x uint64) (n int) { + return sovCrypto(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PublicKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PublicKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublicKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + m.CurveType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurveType |= (CurveType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCrypto + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCrypto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PrivateKey) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PrivateKey: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PrivateKey: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + m.CurveType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurveType |= (CurveType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCrypto + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PrivateKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowCrypto + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthCrypto + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PrivateKey = append(m.PrivateKey[:0], dAtA[iNdEx:postIndex]...) + if m.PrivateKey == nil { + m.PrivateKey = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipCrypto(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthCrypto + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipCrypto(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthCrypto + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowCrypto + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipCrypto(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthCrypto = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowCrypto = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("crypto.proto", fileDescriptorCrypto) } +func init() { golang_proto.RegisterFile("crypto.proto", fileDescriptorCrypto) } + +var fileDescriptorCrypto = []byte{ + // 221 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2e, 0xaa, 0x2c, + 0x28, 0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0xa4, 0x74, 0xd3, 0x33, + 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xd2, + 0x49, 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xb4, 0x29, 0xc5, 0x70, 0x71, 0x06, 0x94, + 0x26, 0xe5, 0x64, 0x26, 0x7b, 0xa7, 0x56, 0x0a, 0x69, 0x73, 0x71, 0x3a, 0x97, 0x16, 0x95, 0xa5, + 0x86, 0x54, 0x16, 0xa4, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x3a, 0xf1, 0xfe, 0xba, 0x27, 0x8f, + 0x10, 0x0c, 0x42, 0x30, 0x85, 0x64, 0x90, 0x74, 0x4a, 0x30, 0x29, 0x30, 0x6a, 0xf0, 0x04, 0x21, + 0x04, 0xac, 0x58, 0x66, 0x2c, 0x90, 0x67, 0x50, 0x6a, 0x64, 0xe4, 0xe2, 0x0a, 0x28, 0xca, 0x2c, + 0x4b, 0x2c, 0x49, 0xa5, 0xae, 0xf9, 0x42, 0x72, 0xc8, 0x06, 0x4b, 0x30, 0x83, 0xa5, 0x91, 0x44, + 0xac, 0x38, 0x3a, 0x16, 0xc8, 0x33, 0x80, 0xdc, 0xe0, 0x64, 0x75, 0xe2, 0x91, 0x1c, 0xe3, 0x85, + 0x47, 0x72, 0x8c, 0x0f, 0x1e, 0xc9, 0x31, 0x1e, 0x78, 0x2c, 0xc7, 0x78, 0xe2, 0xb1, 0x1c, 0x63, + 0x94, 0x0a, 0x52, 0x30, 0x65, 0x54, 0x16, 0xa4, 0x16, 0xe5, 0xa4, 0xa6, 0xa4, 0xa7, 0x16, 0xe9, + 0x27, 0x95, 0x16, 0x15, 0xe5, 0x97, 0xeb, 0x43, 0x02, 0x33, 0x89, 0x0d, 0x1c, 0x48, 0xc6, 0x80, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x49, 0x55, 0xc8, 0x6b, 0x01, 0x00, 0x00, +} diff --git a/crypto/private_key.go b/crypto/private_key.go index f1bad18969e89de0d4882a293e6f2b0117a19709..91252e09f1e1543921e108962db1291d7cd820af 100644 --- a/crypto/private_key.go +++ b/crypto/private_key.go @@ -11,12 +11,6 @@ import ( "golang.org/x/crypto/ed25519" ) -type PrivateKey struct { - CurveType CurveType - PublicKey []byte - PrivateKey []byte -} - // Currently this is a stub that reads the raw bytes returned by key_client and returns // an ed25519 public key. func PublicKeyFromBytes(bs []byte, curveType CurveType) (PublicKey, error) { @@ -46,25 +40,25 @@ func (p PrivateKey) Sign(msg []byte) (Signature, error) { switch p.CurveType { case CurveTypeEd25519: if len(p.PrivateKey) != ed25519.PrivateKeySize { - return Signature{}, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes", + return nil, fmt.Errorf("bytes passed have length %v but ed25519 private keys have %v bytes", len(p.PrivateKey), ed25519.PrivateKeySize) } privKey := ed25519.PrivateKey(p.PrivateKey) - return Signature{ed25519.Sign(privKey, msg)}, nil + return ed25519.Sign(privKey, msg), nil case CurveTypeSecp256k1: if len(p.PrivateKey) != btcec.PrivKeyBytesLen { - return Signature{}, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes", + return nil, fmt.Errorf("bytes passed have length %v but secp256k1 private keys have %v bytes", len(p.PrivateKey), btcec.PrivKeyBytesLen) } privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), p.PrivateKey) sig, err := privKey.Sign(msg) if err != nil { - return Signature{}, err + return nil, err } - return Signature{Signature: sig.Serialize()}, nil + return sig.Serialize(), nil default: - return Signature{}, ErrInvalidCurve(p.CurveType) + return nil, ErrInvalidCurve(p.CurveType) } } @@ -72,6 +66,20 @@ func (p PrivateKey) GetPublicKey() PublicKey { return PublicKey{CurveType: p.CurveType, PublicKey: p.PublicKey} } +// Reinitialise after serialisation +func (p *PrivateKey) Reinitialise() error { + initP, err := PrivateKeyFromRawBytes(p.RawBytes(), p.CurveType) + if err != nil { + return err + } + *p = initP + return nil +} + +func (p PrivateKey) String() string { + return fmt.Sprintf("PrivateKey<PublicKey:%X>", p.PublicKey) +} + func PrivateKeyFromRawBytes(privKeyBytes []byte, curveType CurveType) (PrivateKey, error) { switch curveType { case CurveTypeEd25519: @@ -86,7 +94,10 @@ func PrivateKeyFromRawBytes(privKeyBytes []byte, curveType CurveType) (PrivateKe len(privKeyBytes), btcec.PrivKeyBytesLen) } privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes) - return PrivateKey{PrivateKey: privKey.Serialize(), PublicKey: pubKey.SerializeCompressed(), CurveType: CurveTypeSecp256k1}, nil + if !bytes.Equal(privKey.Serialize(), privKeyBytes) { + return PrivateKey{}, fmt.Errorf("serialisation of Secp256k1 private key bytes does not equal") + } + return PrivateKey{PrivateKey: privKeyBytes, PublicKey: pubKey.SerializeCompressed(), CurveType: CurveTypeSecp256k1}, nil default: return PrivateKey{}, ErrInvalidCurve(curveType) } diff --git a/crypto/public_key.go b/crypto/public_key.go index b3281c61fceaae826678264145a6ec7aa830e7ea..f837b38d1a27a201b4c5affe1101b9dc0bf78b0b 100644 --- a/crypto/public_key.go +++ b/crypto/public_key.go @@ -13,14 +13,6 @@ import ( "golang.org/x/crypto/ripemd160" ) -// PublicKey -type PublicKey struct { - CurveType CurveType - PublicKey []byte - // memoised address - address *Address -} - type PublicKeyJSON struct { CurveType string PublicKey string @@ -83,13 +75,13 @@ func (p PublicKey) IsValid() bool { func (p PublicKey) Verify(msg []byte, signature Signature) bool { switch p.CurveType { case CurveTypeEd25519: - return ed25519.Verify(p.PublicKey, msg, signature.Signature[:]) + return ed25519.Verify(p.PublicKey, msg, signature) case CurveTypeSecp256k1: pub, err := btcec.ParsePubKey(p.PublicKey, btcec.S256()) if err != nil { return false } - sig, err := btcec.ParseDERSignature(signature.Signature, btcec.S256()) + sig, err := btcec.ParseDERSignature(signature, btcec.S256()) if err != nil { return false } @@ -100,14 +92,6 @@ func (p PublicKey) Verify(msg []byte, signature Signature) bool { } func (p PublicKey) Address() Address { - if p.address == nil { - address := p.computeAddress() - p.address = &address - } - return *p.address -} - -func (p PublicKey) computeAddress() Address { switch p.CurveType { case CurveTypeEd25519: // FIMXE: tendermint go-crypto-0.5.0 uses weird scheme, this is fixed in 0.6.0 diff --git a/crypto/public_key_test.go b/crypto/public_key_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f6c211a35d2c64de9050ab75a689fb85881bdf33 --- /dev/null +++ b/crypto/public_key_test.go @@ -0,0 +1,30 @@ +package crypto + +import ( + "encoding/json" + "testing" + + "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPublicKeySerialisation(t *testing.T) { + priv := PrivateKeyFromSecret("foo", CurveTypeEd25519) + pub := priv.GetPublicKey() + expectedAddress := Address{ + 0x83, 0x20, 0x78, 0x17, 0xdc, 0x38, 0x14, 0xb9, 0x6f, 0x57, + 0xef, 0xf9, 0x25, 0xf4, 0x67, 0xe0, 0x7c, 0xaa, 0x91, 0x38, + } + assert.Equal(t, expectedAddress, pub.Address()) + bs, err := proto.Marshal(&pub) + require.NoError(t, err) + var pubOut PublicKey + err = proto.Unmarshal(bs, &pubOut) + assert.Equal(t, pub, pubOut) + + bs, err = json.Marshal(pub) + require.NoError(t, err) + assert.Equal(t, `{"CurveType":"ed25519","PublicKey":"34D26579DBB456693E540672CF922F52DDE0D6532E35BF06BE013A7C532F20E0"}`, + string(bs)) +} diff --git a/crypto/signature.go b/crypto/signature.go index 0ef84f4619ec6f63f7e69159549b143275f994f5..be11336ee7bd2c8052dcb9834c8d33b47f15ccf3 100644 --- a/crypto/signature.go +++ b/crypto/signature.go @@ -3,37 +3,64 @@ package crypto import ( "fmt" - "github.com/hyperledger/burrow/binary" + "github.com/tmthrgd/go-hex" "golang.org/x/crypto/ed25519" ) -type Signature struct { - Signature binary.HexBytes -} +type Signature []byte -// Currently this is a stub that reads the raw bytes returned by key_client and returns -// an ed25519 signature. func SignatureFromBytes(bs []byte, curveType CurveType) (Signature, error) { switch curveType { case CurveTypeEd25519: - signatureEd25519 := Signature{} + var signatureEd25519 Signature if len(bs) != ed25519.SignatureSize { - return Signature{}, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes", + return nil, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes", len(bs), ed25519.SignatureSize) } - copy(signatureEd25519.Signature[:], bs) - return Signature{ - Signature: bs, - }, nil + copy(signatureEd25519, bs) + return bs, nil case CurveTypeSecp256k1: - return Signature{ - Signature: bs, - }, nil + return bs, nil default: - return Signature{}, nil + return nil, nil } } func (sig Signature) RawBytes() []byte { - return sig.Signature + return sig +} + +func (sig *Signature) UnmarshalText(hexBytes []byte) error { + bs, err := hex.DecodeString(string(hexBytes)) + if err != nil { + return err + } + *sig = bs + return nil +} + +func (sig Signature) MarshalText() ([]byte, error) { + return []byte(sig.String()), nil +} + +func (sig Signature) String() string { + return hex.EncodeUpperToString(sig) +} + +// Protobuf support +func (sig Signature) Marshal() ([]byte, error) { + return sig, nil +} + +func (sig *Signature) Unmarshal(data []byte) error { + *sig = data + return nil +} + +func (sig Signature) MarshalTo(data []byte) (int, error) { + return copy(data, sig), nil +} + +func (sig Signature) Size() int { + return len(sig) } diff --git a/deployment/config.go b/deployment/config.go index dc70796d6595948bfc62268b2274163e1a045e2e..ff935f05d2af150d174b35d94866477a5157d6f3 100644 --- a/deployment/config.go +++ b/deployment/config.go @@ -11,8 +11,8 @@ import ( "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/genesis" "github.com/pkg/errors" - "github.com/tmthrgd/go-hex" - "gopkg.in/yaml.v2" + hex "github.com/tmthrgd/go-hex" + yaml "gopkg.in/yaml.v2" ) type Validator struct { diff --git a/event/cache.go b/event/cache.go deleted file mode 100644 index 75f676cfc1333daaabd7520f5a69b68e43b68cea..0000000000000000000000000000000000000000 --- a/event/cache.go +++ /dev/null @@ -1,88 +0,0 @@ -package event - -import ( - "context" -) - -// When exceeded we will trim the buffer's backing array capacity to avoid excessive -// allocation -const maximumBufferCapacityToLengthRatio = 2 - -// A Cache buffers events for a Publisher. -type Cache struct { - events []messageInfo -} - -// If message implement this interface we will provide them with an index in the cache -type Indexable interface { - ProvideIndex(index uint64) -} - -var _ Publisher = &Cache{} - -// Create a new Cache with an EventSwitch as backend -func NewCache() *Cache { - return &Cache{} -} - -// a cached event -type messageInfo struct { - // Hmm... might be unintended interactions with pushing a deadline into a cache - though usually we publish with an - // empty context - ctx context.Context - message interface{} - tags Tags -} - -// Cache an event to be fired upon finality. -func (evc *Cache) Publish(ctx context.Context, message interface{}, tags Tags) error { - // append to list (go will grow our backing array exponentially) - evc.events = append(evc.events, messageInfo{ - ctx: ctx, - message: evc.provideIndex(message), - tags: tags, - }) - return nil -} - -func (evc *Cache) Flush(publisher Publisher) error { - err := evc.Sync(publisher) - if err != nil { - return err - } - evc.Reset() - return nil -} - -// Clears cached events by flushing them to Publisher -func (evc *Cache) Sync(publisher Publisher) error { - var err error - for _, mi := range evc.events { - publishErr := publisher.Publish(mi.ctx, mi.message, mi.tags) - // Capture first by try to sync the rest - if publishErr != nil && err == nil { - err = publishErr - } - } - return err -} - -func (evc *Cache) Reset() { - // Clear the buffer by re-slicing its length to zero - if cap(evc.events) > len(evc.events)*maximumBufferCapacityToLengthRatio { - // Trim the backing array capacity when it is more than double the length of the slice to avoid tying up memory - // after a spike in the number of events to buffer - evc.events = evc.events[:0:len(evc.events)] - } else { - // Re-slice the length to 0 to clear buffer but hang on to spare capacity in backing array that has been added - // in previous cache round - evc.events = evc.events[:0] - } -} - -func (evc *Cache) provideIndex(message interface{}) interface{} { - if im, ok := message.(Indexable); ok { - im.ProvideIndex(uint64(len(evc.events))) - } - return message -} diff --git a/event/cache_test.go b/event/cache_test.go deleted file mode 100644 index 52bcbd6640a0f7008caf061cc504eb6cdfec00d6..0000000000000000000000000000000000000000 --- a/event/cache_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package event - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/logging" - "github.com/stretchr/testify/assert" -) - -func TestEventCache_Flush(t *testing.T) { - //ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second) - //defer cancel() - ctx := context.Background() - errCh := make(chan error) - flushed := false - - em := NewEmitter(logging.NewNoopLogger()) - SubscribeCallback(ctx, em, "nothingness", query.NewBuilder(), func(message interface{}) (stop bool) { - // Check against sending a buffer of zeroed messages - if message == nil { - errCh <- fmt.Errorf("recevied empty message but none sent") - } - return true - }) - evc := NewCache() - evc.Flush(em) - // Check after reset - evc.Flush(em) - SubscribeCallback(ctx, em, "somethingness", query.NewBuilder().AndEquals("foo", "bar"), - func(interface{}) (stop bool) { - if flushed { - errCh <- nil - return false - } else { - errCh <- fmt.Errorf("callback was run before messages were flushed") - return true - } - }) - - numMessages := 3 - tags := TagMap{"foo": "bar"} - for i := 0; i < numMessages; i++ { - evc.Publish(ctx, fmt.Sprintf("something_%v", i), tags) - } - flushed = true - evc.Flush(em) - for i := 0; i < numMessages; i++ { - select { - case <-time.After(2 * time.Second): - t.Fatalf("callback did not run before timeout after messages were sent") - case err := <-errCh: - if err != nil { - t.Error(err) - } - } - } -} - -func TestEventCacheGrowth(t *testing.T) { - em := NewEmitter(logging.NewNoopLogger()) - evc := NewCache() - - fireNEvents(evc, 100) - c := cap(evc.events) - evc.Flush(em) - assert.Equal(t, c, cap(evc.events), "cache cap should remain the same after flushing events") - - fireNEvents(evc, c/maximumBufferCapacityToLengthRatio+1) - evc.Flush(em) - assert.Equal(t, c, cap(evc.events), "cache cap should remain the same after flushing more than half "+ - "the number of events as last time") - - fireNEvents(evc, c/maximumBufferCapacityToLengthRatio-1) - evc.Flush(em) - assert.True(t, c > cap(evc.events), "cache cap should drop after flushing fewer than half "+ - "the number of events as last time") - - fireNEvents(evc, c*2*maximumBufferCapacityToLengthRatio) - evc.Flush(em) - assert.True(t, c < cap(evc.events), "cache cap should grow after flushing more events than seen before") - - for numEvents := 100; numEvents >= 0; numEvents-- { - fireNEvents(evc, numEvents) - evc.Flush(em) - assert.True(t, cap(evc.events) <= maximumBufferCapacityToLengthRatio*numEvents, - "cap (%v) should be at most twice numEvents (%v)", cap(evc.events), numEvents) - } -} - -func fireNEvents(evc *Cache, n int) { - for i := 0; i < n; i++ { - evc.Publish(context.Background(), "something", nil) - } -} diff --git a/event/convention.go b/event/convention.go index dede8493bbc98eba5ada4947d3e0816d857f8714..4f586c152b847c8d46672256d7ed06865f0b1471 100644 --- a/event/convention.go +++ b/event/convention.go @@ -1,12 +1,6 @@ package event import ( - "context" - - "time" - - "fmt" - "github.com/hyperledger/burrow/event/query" ) @@ -14,88 +8,15 @@ const ( EventTypeKey = "EventType" EventIDKey = "EventID" MessageTypeKey = "MessageType" - TxTypeKey = "TxType" TxHashKey = "TxHash" HeightKey = "Height" IndexKey = "Index" - NameKey = "Name" - PermissionKey = "Permission" StackDepthKey = "StackDepth" AddressKey = "Address" - OriginKey = "Origin" - CalleeKey = "Callee" - CallerKey = "Caller" - ValueKey = "Value" - GasKey = "Gas" - ExceptionKey = "Exception" - LogNKeyPrefix = "Log" ) -func LogNKey(topic int) string { - return fmt.Sprintf("%s%d", LogNKeyPrefix, topic) -} - -func LogNTextKey(topic int) string { - return fmt.Sprintf("%s%dText", LogNKeyPrefix, topic) -} - -const SubscribeCallbackTimeout = 2 * time.Second - // Get a query that matches events with a specific eventID func QueryForEventID(eventID string) *query.Builder { // Since we're accepting external output here there is a chance it won't parse... return query.NewBuilder().AndEquals(EventIDKey, eventID) } - -// Subscribe to messages matching query and launch a goroutine to run a callback for each one. The goroutine will exit -// if the callback returns true for 'stop' and clean up the subscription and channel. -func SubscribeCallback(ctx context.Context, subscribable Subscribable, subscriber string, queryable query.Queryable, - callback func(message interface{}) (stop bool)) error { - - out := make(chan interface{}, 1) - stopCh := make(chan bool) - - go func() { - for msg := range out { - go func() { - stopCh <- callback(msg) - }() - - // Stop unless the callback returns - stop := true - select { - case stop = <-stopCh: - case <-time.After(SubscribeCallbackTimeout): - } - - if stop { - // Callback is requesting stop so unsubscribe and drain channel - subscribable.Unsubscribe(context.Background(), subscriber, queryable) - // Not draining channel can starve other subscribers - for range out { - } - return - } - } - }() - err := subscribable.Subscribe(ctx, subscriber, queryable, out) - if err != nil { - // To clean up goroutine - otherwise subscribable should close channel for us - close(out) - } - return err -} - -func PublishAll(ctx context.Context, subscribable Subscribable, subscriber string, queryable query.Queryable, - publisher Publisher, extraTags map[string]interface{}) error { - - return SubscribeCallback(ctx, subscribable, subscriber, queryable, func(message interface{}) (stop bool) { - tags := make(map[string]interface{}) - for k, v := range extraTags { - tags[k] = v - } - // Help! I can't tell which tags the original publisher used - so I can't forward them on - publisher.Publish(ctx, message, TagMap(tags)) - return - }) -} diff --git a/event/convention_test.go b/event/convention_test.go deleted file mode 100644 index 2fd0202dee11da929840814755b45e4f87e57842..0000000000000000000000000000000000000000 --- a/event/convention_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package event - -import ( - "context" - "testing" - "time" - - "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/logging" - "github.com/stretchr/testify/assert" -) - -func TestSubscribeCallback(t *testing.T) { - ctx := context.Background() - em := NewEmitter(logging.NewNoopLogger()) - ch := make(chan interface{}) - SubscribeCallback(ctx, em, "TestSubscribeCallback", query.MatchAllQueryable(), - func(msg interface{}) (stop bool) { - ch <- msg - return - }) - - sent := "FROTHY" - - n := 10 - for i := 0; i < n; i++ { - - em.Publish(ctx, sent, nil) - } - - for i := 0; i < n; i++ { - select { - case <-time.After(2 * time.Second): - t.Fatalf("Timed out waiting for event") - case msg := <-ch: - assert.Equal(t, sent, msg) - } - } -} diff --git a/event/emitter.go b/event/emitter.go index 1fd09e81a4a0fb5afb61bbc33b57410f4c82ddf4..c4d1fd413aba16c811aa7be9fdb0fa37d269c627 100644 --- a/event/emitter.go +++ b/event/emitter.go @@ -16,17 +16,15 @@ package event import ( "context" - "crypto/rand" - "encoding/hex" - "fmt" - "strings" + "math/rand" + "github.com/hyperledger/burrow/event/pubsub" "github.com/hyperledger/burrow/event/query" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/process" - "github.com/tendermint/tendermint/libs/pubsub" "github.com/tendermint/tmlibs/common" + "github.com/tmthrgd/go-hex" ) const DefaultEventBufferCapacity = 2 << 10 @@ -36,21 +34,21 @@ const DefaultEventBufferCapacity = 2 << 10 type Subscribable interface { // Subscribe to all events matching query, which is a valid tmlibs Query. Blocking the out channel blocks the entire // pubsub. - Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, out chan<- interface{}) error + Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, bufferSize int) (out <-chan interface{}, err error) // Unsubscribe subscriber from a specific query string. Note the subscribe channel must be drained. Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error UnsubscribeAll(ctx context.Context, subscriber string) error } type Publisher interface { - Publish(ctx context.Context, message interface{}, tag Tags) error + Publish(ctx context.Context, message interface{}, tag query.Tagged) error } var _ Publisher = PublisherFunc(nil) -type PublisherFunc func(ctx context.Context, message interface{}, tags Tags) error +type PublisherFunc func(ctx context.Context, message interface{}, tags query.Tagged) error -func (pf PublisherFunc) Publish(ctx context.Context, message interface{}, tags Tags) error { +func (pf PublisherFunc) Publish(ctx context.Context, message interface{}, tags query.Tagged) error { return pf(ctx, message, tags) } @@ -83,17 +81,17 @@ func (em *emitter) Shutdown(ctx context.Context) error { } // Publisher -func (em *emitter) Publish(ctx context.Context, message interface{}, tags Tags) error { +func (em *emitter) Publish(ctx context.Context, message interface{}, tags query.Tagged) error { return em.pubsubServer.PublishWithTags(ctx, message, tags) } // Subscribable -func (em *emitter) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, out chan<- interface{}) error { - pubsubQuery, err := queryable.Query() +func (em *emitter) Subscribe(ctx context.Context, subscriber string, queryable query.Queryable, bufferSize int) (<-chan interface{}, error) { + qry, err := queryable.Query() if err != nil { - return nil + return nil, err } - return em.pubsubServer.Subscribe(ctx, subscriber, pubsubQuery, out) + return em.pubsubServer.Subscribe(ctx, subscriber, qry, bufferSize) } func (em *emitter) Unsubscribe(ctx context.Context, subscriber string, queryable query.Queryable) error { @@ -116,20 +114,15 @@ func NewNoOpPublisher() Publisher { type noOpPublisher struct { } -func (nop *noOpPublisher) Publish(ctx context.Context, message interface{}, tags Tags) error { +func (nop *noOpPublisher) Publish(ctx context.Context, message interface{}, tags query.Tagged) error { return nil } // ************************************************************************************** // Helper function -func GenerateSubscriptionID() (string, error) { - b := make([]byte, 32) - _, err := rand.Read(b) - if err != nil { - return "", fmt.Errorf("could not generate random bytes for a subscription"+ - " id: %v", err) - } - rStr := hex.EncodeToString(b) - return strings.ToUpper(rStr), nil +func GenSubID() string { + bs := make([]byte, 32) + rand.Read(bs) + return hex.EncodeUpperToString(bs) } diff --git a/event/emitter_test.go b/event/emitter_test.go index 8325456db81515e406e6705e962ce362b1b110d1..99d8fc76030a2fed7e2c63f3112f695a152a6c95 100644 --- a/event/emitter_test.go +++ b/event/emitter_test.go @@ -5,6 +5,8 @@ import ( "testing" "time" + "strings" + "github.com/hyperledger/burrow/event/query" "github.com/hyperledger/burrow/logging" "github.com/stretchr/testify/assert" @@ -14,17 +16,16 @@ import ( func TestEmitter(t *testing.T) { em := NewEmitter(logging.NewNoopLogger()) ctx := context.Background() - out := make(chan interface{}) - err := em.Subscribe(ctx, "TestEmitter", query.NewBuilder().AndStrictlyGreaterThan("foo", 10), out) + out, err := em.Subscribe(ctx, "TestEmitter", query.NewBuilder().AndStrictlyGreaterThan("foo", 10), 1) require.NoError(t, err) msgMiss := struct{ flob string }{"flib"} - err = em.Publish(ctx, msgMiss, TagMap(map[string]interface{}{"foo": 10})) + err = em.Publish(ctx, msgMiss, query.TagMap{"foo": 10}) assert.NoError(t, err) msgHit := struct{ blib string }{"blab"} - err = em.Publish(ctx, msgHit, TagMap(map[string]interface{}{"foo": 11})) + err = em.Publish(ctx, msgHit, query.TagMap{"foo": 11}) assert.NoError(t, err) select { @@ -38,16 +39,15 @@ func TestEmitter(t *testing.T) { func TestOrdering(t *testing.T) { em := NewEmitter(logging.NewNoopLogger()) ctx := context.Background() - out := make(chan interface{}) - err := em.Subscribe(ctx, "TestOrdering1", query.NewBuilder().AndEquals("foo", "bar"), out) + out1, err := em.Subscribe(ctx, "TestOrdering1", query.NewBuilder().AndEquals("foo", "bar"), 10) require.NoError(t, err) - err = em.Subscribe(ctx, "TestOrdering2", query.NewBuilder().AndEquals("foo", "baz"), out) + out2, err := em.Subscribe(ctx, "TestOrdering2", query.NewBuilder().AndEquals("foo", "baz"), 10) require.NoError(t, err) - barTag := TagMap{"foo": "bar"} - bazTag := TagMap{"foo": "baz"} + barTag := query.TagMap{"foo": "bar"} + bazTag := query.TagMap{"foo": "baz"} msgs := [][]interface{}{ {"baz1", bazTag}, @@ -61,12 +61,17 @@ func TestOrdering(t *testing.T) { go func() { for _, msg := range msgs { - em.Publish(ctx, msg[0], msg[1].(TagMap)) + em.Publish(ctx, msg[0], msg[1].(query.TagMap)) } em.Publish(ctx, "stop", bazTag) }() for _, msg := range msgs { - assert.Equal(t, msg[0], <-out) + str := msg[0].(string) + if strings.HasPrefix(str, "bar") { + assert.Equal(t, str, <-out1) + } else { + assert.Equal(t, str, <-out2) + } } } diff --git a/event/pubsub/example_test.go b/event/pubsub/example_test.go new file mode 100644 index 0000000000000000000000000000000000000000..68772bd14117be7409f12ecdcb5f87051776d249 --- /dev/null +++ b/event/pubsub/example_test.go @@ -0,0 +1,23 @@ +package pubsub_test + +import ( + "context" + "testing" + + "github.com/hyperledger/burrow/event/pubsub" + "github.com/hyperledger/burrow/event/query" + "github.com/stretchr/testify/require" +) + +func TestExample(t *testing.T) { + s := pubsub.NewServer() + s.Start() + defer s.Stop() + + ctx := context.Background() + ch, err := s.Subscribe(ctx, "example-client", query.MustParse("abci.account.name='John'"), 1) + require.NoError(t, err) + err = s.PublishWithTags(ctx, "Tombstone", query.TagMap(map[string]interface{}{"abci.account.name": "John"})) + require.NoError(t, err) + assertReceive(t, "Tombstone", ch) +} diff --git a/event/pubsub/pubsub.go b/event/pubsub/pubsub.go new file mode 100644 index 0000000000000000000000000000000000000000..8d710773036e6cc828b870c76c83e9be5b69a5a6 --- /dev/null +++ b/event/pubsub/pubsub.go @@ -0,0 +1,330 @@ +// This package was extracted from Tendermint +// +// Package pubsub implements a pub-sub model with a single publisher (Server) +// and multiple subscribers (clients). +// +// Though you can have multiple publishers by sharing a pointer to a server or +// by giving the same channel to each publisher and publishing messages from +// that channel (fan-in). +// +// Clients subscribe for messages, which could be of any type, using a query. +// When some message is published, we match it with all queries. If there is a +// match, this message will be pushed to all clients, subscribed to that query. +// See query subpackage for our implementation. +package pubsub + +import ( + "context" + "errors" + "sync" + + "github.com/hyperledger/burrow/event/query" + "github.com/tendermint/tmlibs/common" +) + +type operation int + +const ( + sub operation = iota + pub + unsub + shutdown +) + +var ( + // ErrSubscriptionNotFound is returned when a client tries to unsubscribe + // from not existing subscription. + ErrSubscriptionNotFound = errors.New("subscription not found") + + // ErrAlreadySubscribed is returned when a client tries to subscribe twice or + // more using the same query. + ErrAlreadySubscribed = errors.New("already subscribed") +) + +type cmd struct { + op operation + query query.Query + ch chan interface{} + clientID string + msg interface{} + tags query.Tagged +} + +// Server allows clients to subscribe/unsubscribe for messages, publishing +// messages with or without tags, and manages internal state. +type Server struct { + common.BaseService + + cmds chan cmd + cmdsCap int + + mtx sync.RWMutex + subscriptions map[string]map[string]query.Query // subscriber -> query (string) -> query.Query +} + +// Option sets a parameter for the server. +type Option func(*Server) + +// NewServer returns a new server. See the commentary on the Option functions +// for a detailed description of how to configure buffering. If no options are +// provided, the resulting server's queue is unbuffered. +func NewServer(options ...Option) *Server { + s := &Server{ + subscriptions: make(map[string]map[string]query.Query), + } + s.BaseService = *common.NewBaseService(nil, "PubSub", s) + + for _, option := range options { + option(s) + } + + // if BufferCapacity option was not set, the channel is unbuffered + s.cmds = make(chan cmd, s.cmdsCap) + + return s +} + +// BufferCapacity allows you to specify capacity for the internal server's +// queue. Since the server, given Y subscribers, could only process X messages, +// this option could be used to survive spikes (e.g. high amount of +// transactions during peak hours). +func BufferCapacity(cap int) Option { + return func(s *Server) { + if cap > 0 { + s.cmdsCap = cap + } + } +} + +// BufferCapacity returns capacity of the internal server's queue. +func (s *Server) BufferCapacity() int { + return s.cmdsCap +} + +// Subscribe creates a subscription for the given client. It accepts a channel +// on which messages matching the given query can be received. An error will be +// returned to the caller if the context is canceled or if subscription already +// exist for pair clientID and query. +func (s *Server) Subscribe(ctx context.Context, clientID string, qry query.Query, outBuffer int) (<-chan interface{}, error) { + s.mtx.RLock() + clientSubscriptions, ok := s.subscriptions[clientID] + if ok { + _, ok = clientSubscriptions[qry.String()] + } + s.mtx.RUnlock() + if ok { + return nil, ErrAlreadySubscribed + } + // We are responsible for closing this channel so we create it + out := make(chan interface{}, outBuffer) + select { + case s.cmds <- cmd{op: sub, clientID: clientID, query: qry, ch: out}: + s.mtx.Lock() + if _, ok = s.subscriptions[clientID]; !ok { + s.subscriptions[clientID] = make(map[string]query.Query) + } + // preserve original query + // see Unsubscribe + s.subscriptions[clientID][qry.String()] = qry + s.mtx.Unlock() + return out, nil + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +// Unsubscribe removes the subscription on the given query. An error will be +// returned to the caller if the context is canceled or if subscription does +// not exist. +func (s *Server) Unsubscribe(ctx context.Context, clientID string, qry query.Query) error { + var origQuery query.Query + s.mtx.RLock() + clientSubscriptions, ok := s.subscriptions[clientID] + if ok { + origQuery, ok = clientSubscriptions[qry.String()] + } + s.mtx.RUnlock() + if !ok { + return ErrSubscriptionNotFound + } + + // original query is used here because we're using pointers as map keys + select { + case s.cmds <- cmd{op: unsub, clientID: clientID, query: origQuery}: + s.mtx.Lock() + delete(clientSubscriptions, qry.String()) + s.mtx.Unlock() + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +// UnsubscribeAll removes all client subscriptions. An error will be returned +// to the caller if the context is canceled or if subscription does not exist. +func (s *Server) UnsubscribeAll(ctx context.Context, clientID string) error { + s.mtx.RLock() + _, ok := s.subscriptions[clientID] + s.mtx.RUnlock() + if !ok { + return ErrSubscriptionNotFound + } + + select { + case s.cmds <- cmd{op: unsub, clientID: clientID}: + s.mtx.Lock() + delete(s.subscriptions, clientID) + s.mtx.Unlock() + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +// Publish publishes the given message. An error will be returned to the caller +// if the context is canceled. +func (s *Server) Publish(ctx context.Context, msg interface{}) error { + return s.PublishWithTags(ctx, msg, query.TagMap(make(map[string]interface{}))) +} + +// PublishWithTags publishes the given message with the set of tags. The set is +// matched with clients queries. If there is a match, the message is sent to +// the client. +func (s *Server) PublishWithTags(ctx context.Context, msg interface{}, tags query.Tagged) error { + select { + case s.cmds <- cmd{op: pub, msg: msg, tags: tags}: + return nil + case <-ctx.Done(): + return ctx.Err() + } +} + +// OnStop implements Service.OnStop by shutting down the server. +func (s *Server) OnStop() { + s.cmds <- cmd{op: shutdown} +} + +// NOTE: not goroutine safe +type state struct { + // query -> client -> ch + queries map[query.Query]map[string]chan interface{} + // client -> query -> struct{} + clients map[string]map[query.Query]struct{} +} + +// OnStart implements Service.OnStart by starting the server. +func (s *Server) OnStart() error { + go s.loop(state{ + queries: make(map[query.Query]map[string]chan interface{}), + clients: make(map[string]map[query.Query]struct{}), + }) + return nil +} + +// OnReset implements Service.OnReset +func (s *Server) OnReset() error { + return nil +} + +func (s *Server) loop(state state) { +loop: + for cmd := range s.cmds { + switch cmd.op { + case unsub: + if cmd.query != nil { + state.remove(cmd.clientID, cmd.query) + } else { + state.removeAll(cmd.clientID) + } + case shutdown: + for clientID := range state.clients { + state.removeAll(clientID) + } + break loop + case sub: + state.add(cmd.clientID, cmd.query, cmd.ch) + case pub: + state.send(cmd.msg, cmd.tags) + } + } +} + +func (state *state) add(clientID string, q query.Query, ch chan interface{}) { + // add query if needed + if _, ok := state.queries[q]; !ok { + state.queries[q] = make(map[string]chan interface{}) + } + + // create subscription + state.queries[q][clientID] = ch + + // add client if needed + if _, ok := state.clients[clientID]; !ok { + state.clients[clientID] = make(map[query.Query]struct{}) + } + state.clients[clientID][q] = struct{}{} +} + +func (state *state) remove(clientID string, q query.Query) { + clientToChannelMap, ok := state.queries[q] + if !ok { + return + } + + ch, ok := clientToChannelMap[clientID] + if ok { + closeAndDrain(ch) + + delete(state.clients[clientID], q) + + // if it not subscribed to anything else, remove the client + if len(state.clients[clientID]) == 0 { + delete(state.clients, clientID) + } + + delete(state.queries[q], clientID) + if len(state.queries[q]) == 0 { + delete(state.queries, q) + } + } +} + +func (state *state) removeAll(clientID string) { + queryMap, ok := state.clients[clientID] + if !ok { + return + } + + for q := range queryMap { + ch := state.queries[q][clientID] + closeAndDrain(ch) + + delete(state.queries[q], clientID) + if len(state.queries[q]) == 0 { + delete(state.queries, q) + } + } + delete(state.clients, clientID) +} + +func closeAndDrain(ch chan interface{}) { + close(ch) + for range ch { + } +} + +func (state *state) send(msg interface{}, tags query.Tagged) { + for q, clientToChannelMap := range state.queries { + if q.Matches(tags) { + for _, ch := range clientToChannelMap { + select { + case ch <- msg: + default: + // It's difficult to do anything sensible here with retries/times outs since we may reorder a client's + // view of events by sending a later message before an earlier message we retry. If per-client order + // matters then we need a queue per client. Possible for us it does not... + } + } + } + } +} diff --git a/event/pubsub/pubsub_test.go b/event/pubsub/pubsub_test.go new file mode 100644 index 0000000000000000000000000000000000000000..ec777450c165be1bfe133e967641f6c3a44b5dde --- /dev/null +++ b/event/pubsub/pubsub_test.go @@ -0,0 +1,237 @@ +package pubsub_test + +import ( + "context" + "fmt" + "runtime/debug" + "testing" + "time" + + "github.com/hyperledger/burrow/event/pubsub" + "github.com/hyperledger/burrow/event/query" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + clientID = "test-client" +) + +func TestSubscribe(t *testing.T) { + s := pubsub.NewServer() + s.Start() + defer s.Stop() + + ctx := context.Background() + ch, err := s.Subscribe(ctx, clientID, query.Empty{}, 1) + require.NoError(t, err) + err = s.Publish(ctx, "Ka-Zar") + require.NoError(t, err) + assertReceive(t, "Ka-Zar", ch) + + err = s.Publish(ctx, "Quicksilver") + require.NoError(t, err) + assertReceive(t, "Quicksilver", ch) +} + +func TestDifferentClients(t *testing.T) { + s := pubsub.NewServer() + s.Start() + defer s.Stop() + + ctx := context.Background() + ch1, err := s.Subscribe(ctx, "client-1", query.MustParse("tm.events.type='NewBlock'"), 1) + require.NoError(t, err) + err = s.PublishWithTags(ctx, "Iceman", query.TagMap{"tm.events.type": "NewBlock"}) + require.NoError(t, err) + assertReceive(t, "Iceman", ch1) + + ch2, err := s.Subscribe(ctx, "client-2", query.MustParse("tm.events.type='NewBlock' AND abci.account.name='Igor'"), 1) + require.NoError(t, err) + err = s.PublishWithTags(ctx, "Ultimo", query.TagMap{"tm.events.type": "NewBlock", "abci.account.name": "Igor"}) + require.NoError(t, err) + assertReceive(t, "Ultimo", ch1) + assertReceive(t, "Ultimo", ch2) + + ch3, err := s.Subscribe(ctx, "client-3", query.MustParse("tm.events.type='NewRoundStep' AND abci.account.name='Igor' AND abci.invoice.number = 10"), 1) + require.NoError(t, err) + err = s.PublishWithTags(ctx, "Valeria Richards", query.TagMap{"tm.events.type": "NewRoundStep"}) + require.NoError(t, err) + assert.Zero(t, len(ch3)) +} + +func TestClientSubscribesTwice(t *testing.T) { + s := pubsub.NewServer() + + s.Start() + defer s.Stop() + + ctx := context.Background() + q := query.MustParse("tm.events.type='NewBlock'") + + ch1, err := s.Subscribe(ctx, clientID, q, 1) + require.NoError(t, err) + err = s.PublishWithTags(ctx, "Goblin Queen", query.TagMap{"tm.events.type": "NewBlock"}) + require.NoError(t, err) + assertReceive(t, "Goblin Queen", ch1) + + _, err = s.Subscribe(ctx, clientID, q, 1) + require.Error(t, err) + + err = s.PublishWithTags(ctx, "Spider-Man", query.TagMap{"tm.events.type": "NewBlock"}) + require.NoError(t, err) + assertReceive(t, "Spider-Man", ch1) +} + +func TestUnsubscribe(t *testing.T) { + s := pubsub.NewServer() + + s.Start() + defer s.Stop() + + ctx := context.Background() + ch, err := s.Subscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlock'"), 0) + require.NoError(t, err) + err = s.Unsubscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlock'")) + require.NoError(t, err) + + err = s.Publish(ctx, "Nick Fury") + require.NoError(t, err) + assert.Zero(t, len(ch), "Should not receive anything after Unsubscribe") + + _, ok := <-ch + assert.False(t, ok) +} + +func TestResubscribe(t *testing.T) { + s := pubsub.NewServer() + + s.Start() + defer s.Stop() + + ctx := context.Background() + ch, err := s.Subscribe(ctx, clientID, query.Empty{}, 0) + require.NoError(t, err) + err = s.Unsubscribe(ctx, clientID, query.Empty{}) + require.NoError(t, err) + ch, err = s.Subscribe(ctx, clientID, query.Empty{}, 0) + require.NoError(t, err) + + err = s.Publish(ctx, "Cable") + require.NoError(t, err) + assertReceive(t, "Cable", ch) +} + +func TestUnsubscribeAll(t *testing.T) { + s := pubsub.NewServer() + + s.Start() + defer s.Stop() + + ctx := context.Background() + ch1, err := s.Subscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlock'"), 1) + require.NoError(t, err) + ch2, err := s.Subscribe(ctx, clientID, query.MustParse("tm.events.type='NewBlockHeader'"), 1) + require.NoError(t, err) + + err = s.UnsubscribeAll(ctx, clientID) + require.NoError(t, err) + + err = s.Publish(ctx, "Nick Fury") + require.NoError(t, err) + assert.Zero(t, len(ch1), "Should not receive anything after UnsubscribeAll") + assert.Zero(t, len(ch2), "Should not receive anything after UnsubscribeAll") + + _, ok := <-ch1 + assert.False(t, ok) + _, ok = <-ch2 + assert.False(t, ok) +} + +func TestBufferCapacity(t *testing.T) { + s := pubsub.NewServer(pubsub.BufferCapacity(2)) + + assert.Equal(t, 2, s.BufferCapacity()) + + ctx := context.Background() + err := s.Publish(ctx, "Nighthawk") + require.NoError(t, err) + err = s.Publish(ctx, "Sage") + require.NoError(t, err) + + ctx, cancel := context.WithTimeout(ctx, 10*time.Millisecond) + defer cancel() + err = s.Publish(ctx, "Ironclad") + if assert.Error(t, err) { + assert.Equal(t, context.DeadlineExceeded, err) + } +} + +func Benchmark10Clients(b *testing.B) { benchmarkNClients(10, b) } +func Benchmark100Clients(b *testing.B) { benchmarkNClients(100, b) } +func Benchmark1000Clients(b *testing.B) { benchmarkNClients(1000, b) } + +func Benchmark10ClientsOneQuery(b *testing.B) { benchmarkNClientsOneQuery(10, b) } +func Benchmark100ClientsOneQuery(b *testing.B) { benchmarkNClientsOneQuery(100, b) } +func Benchmark1000ClientsOneQuery(b *testing.B) { benchmarkNClientsOneQuery(1000, b) } + +func benchmarkNClients(n int, b *testing.B) { + s := pubsub.NewServer() + s.Start() + defer s.Stop() + + ctx := context.Background() + for i := 0; i < n; i++ { + ch, err := s.Subscribe(ctx, clientID, query.MustParse(fmt.Sprintf("abci.Account.Owner = 'Ivan' AND abci.Invoices.Number = %d", i)), 0) + require.NoError(b, err) + go func() { + for range ch { + } + }() + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + s.PublishWithTags(ctx, "Gamora", query.TagMap{"abci.Account.Owner": "Ivan", "abci.Invoices.Number": string(i)}) + } +} + +func benchmarkNClientsOneQuery(n int, b *testing.B) { + s := pubsub.NewServer() + s.Start() + defer s.Stop() + + ctx := context.Background() + q := query.MustParse("abci.Account.Owner = 'Ivan' AND abci.Invoices.Number = 1") + for i := 0; i < n; i++ { + ch, err := s.Subscribe(ctx, clientID, q, 0) + require.NoError(b, err) + go func() { + for range ch { + } + }() + } + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + s.PublishWithTags(ctx, "Gamora", query.TagMap{"abci.Account.Owner": "Ivan", "abci.Invoices.Number": "1"}) + } +} + +/////////////////////////////////////////////////////////////////////////////// +/// HELPERS +/////////////////////////////////////////////////////////////////////////////// + +func assertReceive(t *testing.T, expected interface{}, ch <-chan interface{}, msgAndArgs ...interface{}) { + select { + case actual := <-ch: + if actual != nil { + assert.Equal(t, expected, actual, msgAndArgs...) + } + case <-time.After(1 * time.Second): + t.Errorf("Expected to receive %v from the channel, got nothing after 1s", expected) + debug.PrintStack() + } +} diff --git a/event/query/Makefile b/event/query/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..91030ef098b4fc74a3728c5e62b8c78df2838532 --- /dev/null +++ b/event/query/Makefile @@ -0,0 +1,11 @@ +gen_query_parser: + @go get github.com/pointlander/peg + peg -inline -switch query.peg + +fuzzy_test: + @go get github.com/dvyukov/go-fuzz/go-fuzz + @go get github.com/dvyukov/go-fuzz/go-fuzz-build + go-fuzz-build github.com/tendermint/tendermint/libs/pubsub/query/fuzz_test + go-fuzz -bin=./fuzz_test-fuzz.zip -workdir=./fuzz_test/output + +.PHONY: gen_query_parser fuzzy_test diff --git a/event/query/builder.go b/event/query/builder.go new file mode 100644 index 0000000000000000000000000000000000000000..1395a39aa1d34fcf0c74e23660f515e388b2e81c --- /dev/null +++ b/event/query/builder.go @@ -0,0 +1,263 @@ +package query + +import ( + "bytes" + "fmt" + "reflect" + "strconv" + "strings" + "text/template" + "time" +) + +const ( + MultipleValueTagSeparator = ";" + + // Operators + equalString = "=" + greaterThanString = ">" + lessThanString = "<" + greaterOrEqualString = ">=" + lessOrEqualString = "<=" + containsString = "CONTAINS" + andString = "AND" + + // Values + trueString = "true" + falseString = "false" + emptyString = "empty" + timeString = "TIME" + dateString = "DATE" +) + +type Query interface { + Matches(tags Tagged) bool + String() string +} + +type Queryable interface { + Query() (Query, error) +} + +type parsedQuery struct { + query Query +} + +func AsQueryable(query Query) parsedQuery { + return parsedQuery{query: query} +} + +func (pq parsedQuery) Query() (Query, error) { + return pq.query, nil +} + +// A yet-to-parsed query +type String string + +func Must(qry Query, err error) Query { + if err != nil { + panic(fmt.Errorf("could not compile: %v", qry)) + } + return qry +} + +func (qs String) Query() (Query, error) { + if isEmpty(string(qs)) { + return Empty{}, nil + } + return New(string(qs)) +} + +func MatchAllQueryable() Queryable { + return Empty{} +} + +// A fluent query builder +type Builder struct { + queryString string + condition + // reusable buffer for building queryString + bytes.Buffer + error +} + +// Templates +type condition struct { + Tag string + Op string + Operand string +} + +var conditionTemplate = template.Must(template.New("condition").Parse("{{.Tag}} {{.Op}} {{.Operand}}")) + +// Creates a new query builder with a base query that is the conjunction of all queries passed +func NewBuilder(queries ...string) *Builder { + qb := new(Builder) + qb.queryString = qb.and(stringIterator(queries...)) + return qb +} + +func (qb *Builder) String() string { + return qb.queryString +} + +func (qb *Builder) Query() (Query, error) { + if qb.error != nil { + return nil, qb.error + } + if isEmpty(qb.queryString) { + return Empty{}, nil + } + return New(qb.String()) +} + +// Creates the conjunction of Builder and rightQuery +func (qb *Builder) And(queryBuilders ...*Builder) *Builder { + return NewBuilder(qb.and(queryBuilderIterator(queryBuilders...))) +} + +// Creates the conjunction of Builder and tag = operand +func (qb *Builder) AndEquals(tag string, operand interface{}) *Builder { + qb.condition.Tag = tag + qb.condition.Op = equalString + qb.condition.Operand = operandString(operand) + return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +} + +func (qb *Builder) AndGreaterThanOrEqual(tag string, operand interface{}) *Builder { + qb.condition.Tag = tag + qb.condition.Op = greaterOrEqualString + qb.condition.Operand = operandString(operand) + return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +} + +func (qb *Builder) AndLessThanOrEqual(tag string, operand interface{}) *Builder { + qb.condition.Tag = tag + qb.condition.Op = lessOrEqualString + qb.condition.Operand = operandString(operand) + return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +} + +func (qb *Builder) AndStrictlyGreaterThan(tag string, operand interface{}) *Builder { + qb.condition.Tag = tag + qb.condition.Op = greaterThanString + qb.condition.Operand = operandString(operand) + return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +} + +func (qb *Builder) AndStrictlyLessThan(tag string, operand interface{}) *Builder { + qb.condition.Tag = tag + qb.condition.Op = lessThanString + qb.condition.Operand = operandString(operand) + return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +} + +func (qb *Builder) AndContains(tag string, operand interface{}) *Builder { + qb.condition.Tag = tag + qb.condition.Op = containsString + qb.condition.Operand = operandString(operand) + return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +} + +func (qb *Builder) and(queryIterator func(func(string))) string { + defer qb.Buffer.Reset() + qb.Buffer.WriteString(qb.queryString) + queryIterator(func(q string) { + if !isEmpty(q) { + if qb.Buffer.Len() > 0 { + qb.Buffer.WriteByte(' ') + qb.Buffer.WriteString(andString) + qb.Buffer.WriteByte(' ') + } + qb.Buffer.WriteString(q) + } + }) + return qb.Buffer.String() +} + +func operandString(value interface{}) string { + buf := new(bytes.Buffer) + switch v := value.(type) { + case string: + buf.WriteByte('\'') + buf.WriteString(v) + buf.WriteByte('\'') + return buf.String() + case fmt.Stringer: + return operandString(v.String()) + default: + return StringFromValue(v) + } +} + +func StringFromValue(value interface{}) string { + switch v := value.(type) { + case string: + return v + case fmt.Stringer: + return v.String() + case bool: + if v { + return trueString + } + return falseString + case int: + return strconv.FormatInt(int64(v), 10) + case int32: + return strconv.FormatInt(int64(v), 10) + case int64: + return strconv.FormatInt(v, 10) + case uint: + return strconv.FormatUint(uint64(v), 10) + case uint32: + return strconv.FormatUint(uint64(v), 10) + case uint64: + return strconv.FormatUint(v, 10) + case float32: + return strconv.FormatFloat(float64(v), 'f', -1, 32) + case float64: + return strconv.FormatFloat(float64(v), 'f', -1, 64) + case time.Time: + return timeString + " " + v.Format(time.RFC3339) + default: + rv := reflect.ValueOf(v) + if rv.Kind() == reflect.Slice { + values := make([]string, rv.Len()) + for i := 0; i < rv.Len(); i++ { + values[i] = StringFromValue(rv.Index(i).Interface()) + } + return strings.Join(values, MultipleValueTagSeparator) + } + return fmt.Sprintf("%v", v) + } +} + +func (qb *Builder) conditionString() string { + defer qb.Buffer.Reset() + err := conditionTemplate.Execute(&qb.Buffer, qb.condition) + if err != nil && qb.error == nil { + qb.error = err + } + return qb.Buffer.String() +} + +func isEmpty(queryString string) bool { + return queryString == "" || queryString == emptyString +} + +// Iterators over some strings +func stringIterator(strs ...string) func(func(string)) { + return func(callback func(string)) { + for _, s := range strs { + callback(s) + } + } +} + +func queryBuilderIterator(qbs ...*Builder) func(func(string)) { + return func(callback func(string)) { + for _, qb := range qbs { + callback(qb.String()) + } + } +} diff --git a/event/query/builder_test.go b/event/query/builder_test.go new file mode 100644 index 0000000000000000000000000000000000000000..15da502d01c440179e27b72595470fffcba04828 --- /dev/null +++ b/event/query/builder_test.go @@ -0,0 +1,52 @@ +package query + +import ( + "testing" + + "github.com/hyperledger/burrow/logging/structure" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestQueryBuilder(t *testing.T) { + qb := NewBuilder() + qry, err := qb.Query() + require.NoError(t, err) + assert.Equal(t, emptyString, qry.String()) + + qb = qb.AndGreaterThanOrEqual("foo.size", 45) + qry, err = qb.Query() + require.NoError(t, err) + assert.Equal(t, "foo.size >= 45", qry.String()) + + qb = qb.AndEquals("bar.name", "marmot") + qry, err = qb.Query() + require.NoError(t, err) + assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot'", qry.String()) + + assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot"))) + assert.False(t, qry.Matches(makeTagMap("foo.size", 8, "bar.name", "marmot"))) + assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marot"))) + + qb = qb.AndContains("bar.desc", "burrow") + qry, err = qb.Query() + require.NoError(t, err) + assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot' AND bar.desc CONTAINS 'burrow'", qry.String()) + + assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a burrow"))) + assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a shoe"))) + + qb = NewBuilder().AndEquals("foo", "bar") + qb = qb.And(NewBuilder().AndGreaterThanOrEqual("frogs", 4)) + qry, err = qb.Query() + require.NoError(t, err) + assert.Equal(t, "foo = 'bar' AND frogs >= 4", qry.String()) +} + +func makeTagMap(keyvals ...interface{}) TagMap { + tmap := make(TagMap) + for i := 0; i < len(keyvals); i += 2 { + tmap[keyvals[i].(string)] = structure.StringifyKey(keyvals[i+1]) + } + return tmap +} diff --git a/event/query/empty.go b/event/query/empty.go index c83169e18b5224a178d6812439393bac69231dd2..5d10ce4c7a29401ecb6f3696702fe1ec11b03a25 100644 --- a/event/query/empty.go +++ b/event/query/empty.go @@ -1,13 +1,21 @@ package query -import ( - "github.com/tendermint/tendermint/libs/pubsub" - "github.com/tendermint/tendermint/libs/pubsub/query" -) +// Empty query matches any set of tags. +type Empty struct { +} + +var _ Query = Empty{} +var _ Queryable = Empty{} -// Matches everything -type Empty query.Empty +// Matches always returns true. +func (Empty) Matches(tags Tagged) bool { + return true +} + +func (Empty) String() string { + return "empty" +} -func (Empty) Query() (pubsub.Query, error) { - return query.Empty{}, nil +func (Empty) Query() (Query, error) { + return Empty{}, nil } diff --git a/event/query/empty_test.go b/event/query/empty_test.go new file mode 100644 index 0000000000000000000000000000000000000000..d7237112f536fe56ae9bb0cc0454e9dff11dc4f9 --- /dev/null +++ b/event/query/empty_test.go @@ -0,0 +1,15 @@ +package query + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEmptyQueryMatchesAnything(t *testing.T) { + q := Empty{} + assert.True(t, q.Matches(TagMap{})) + assert.True(t, q.Matches(TagMap{"Asher": "Roth"})) + assert.True(t, q.Matches(TagMap{"Route": "66"})) + assert.True(t, q.Matches(TagMap{"Route": "66", "Billy": "Blue"})) +} diff --git a/event/query/parser_test.go b/event/query/parser_test.go new file mode 100644 index 0000000000000000000000000000000000000000..dca8b1ed2c370e19b6c67e896b34fbfa164681e1 --- /dev/null +++ b/event/query/parser_test.go @@ -0,0 +1,90 @@ +package query + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +// TODO: fuzzy testing? +func TestParser(t *testing.T) { + cases := []struct { + query string + valid bool + }{ + {"tm.events.type='NewBlock'", true}, + {"tm.events.type = 'NewBlock'", true}, + {"tm.events.name = ''", true}, + {"tm.events.type='TIME'", true}, + {"tm.events.type='DATE'", true}, + {"tm.events.type='='", true}, + {"tm.events.type='TIME", false}, + {"tm.events.type=TIME'", false}, + {"tm.events.type==", false}, + {"tm.events.type=NewBlock", false}, + {">==", false}, + {"tm.events.type 'NewBlock' =", false}, + {"tm.events.type>'NewBlock'", false}, + {"", false}, + {"=", false}, + {"='NewBlock'", false}, + {"tm.events.type=", false}, + + {"tm.events.typeNewBlock", false}, + {"tm.events.type'NewBlock'", false}, + {"'NewBlock'", false}, + {"NewBlock", false}, + {"", false}, + + {"tm.events.type='NewBlock' AND abci.account.name='Igor'", true}, + {"tm.events.type='NewBlock' AND", false}, + {"tm.events.type='NewBlock' AN", false}, + {"tm.events.type='NewBlock' AN tm.events.type='NewBlockHeader'", false}, + {"AND tm.events.type='NewBlock' ", false}, + + {"abci.account.name CONTAINS 'Igor'", true}, + + {"tx.date > DATE 2013-05-03", true}, + {"tx.date < DATE 2013-05-03", true}, + {"tx.date <= DATE 2013-05-03", true}, + {"tx.date >= DATE 2013-05-03", true}, + {"tx.date >= DAT 2013-05-03", false}, + {"tx.date <= DATE2013-05-03", false}, + {"tx.date <= DATE -05-03", false}, + {"tx.date >= DATE 20130503", false}, + {"tx.date >= DATE 2013+01-03", false}, + // incorrect year, month, day + {"tx.date >= DATE 0013-01-03", false}, + {"tx.date >= DATE 2013-31-03", false}, + {"tx.date >= DATE 2013-01-83", false}, + + {"tx.date > TIME 2013-05-03T14:45:00+07:00", true}, + {"tx.date < TIME 2013-05-03T14:45:00-02:00", true}, + {"tx.date <= TIME 2013-05-03T14:45:00Z", true}, + {"tx.date >= TIME 2013-05-03T14:45:00Z", true}, + {"tx.date >= TIME2013-05-03T14:45:00Z", false}, + {"tx.date = IME 2013-05-03T14:45:00Z", false}, + {"tx.date = TIME 2013-05-:45:00Z", false}, + {"tx.date >= TIME 2013-05-03T14:45:00", false}, + {"tx.date >= TIME 0013-00-00T14:45:00Z", false}, + {"tx.date >= TIME 2013+05=03T14:45:00Z", false}, + + {"account.balance=100", true}, + {"account.balance >= 200", true}, + {"account.balance >= -300", false}, + {"account.balance >>= 400", false}, + {"account.balance=33.22.1", false}, + + {"hash='136E18F7E4C348B780CF873A0BF43922E5BAFA63'", true}, + {"hash=136E18F7E4C348B780CF873A0BF43922E5BAFA63", false}, + } + + for _, c := range cases { + _, err := New(c.query) + if c.valid { + assert.NoErrorf(t, err, "Query was '%s'", c.query) + } else { + assert.Errorf(t, err, "Query was '%s'", c.query) + } + } +} diff --git a/event/query/query.go b/event/query/query.go index fc107968b1541927f0c1a9f7e9edb1f9f9f9a4ae..17946b7704e197b09f5145e93cfdc1ffe4a60d4f 100644 --- a/event/query/query.go +++ b/event/query/query.go @@ -1,250 +1,344 @@ +// Package query provides a parser for a custom query format: +// +// abci.invoice.number=22 AND abci.invoice.owner=Ivan +// +// See query.peg for the grammar, which is a https://en.wikipedia.org/wiki/Parsing_expression_grammar. +// More: https://github.com/PhilippeSigaud/Pegged/wiki/PEG-Basics +// +// It has a support for numbers (integer and floating point), dates and times. package query import ( - "bytes" "fmt" + "reflect" "strconv" - "text/template" + "strings" "time" - - "github.com/tendermint/tendermint/libs/pubsub" - "github.com/tendermint/tendermint/libs/pubsub/query" ) -const ( - // Operators - equalString = "=" - greaterThanString = ">" - lessThanString = "<" - greaterOrEqualString = ">=" - lessOrEqualString = "<=" - containsString = "CONTAINS" - andString = "AND" - - // Values - trueString = "true" - falseString = "false" - emptyString = "empty" - timeString = "TIME" - dateString = "DATE" -) - -type Queryable interface { - Query() (pubsub.Query, error) -} - -// A yet-to-parsed query -type String string - -func Must(qry pubsub.Query, err error) Query { - if err != nil { - panic(fmt.Errorf("could not compile: %v", qry)) - } - return WrapQuery(qry) -} - -func (qs String) Query() (pubsub.Query, error) { - if isEmpty(string(qs)) { - return query.Empty{}, nil - } - return query.New(string(qs)) -} +var _ Query = &query{} +var _ Queryable = &query{} -func MatchAllQueryable() Queryable { - return WrapQuery(query.Empty{}) +// Query holds the query string and the query parser. +type query struct { + str string + parser *QueryParser } -// A pre-parsed query -type Query struct { - query pubsub.Query -} - -func WrapQuery(qry pubsub.Query) Query { - return Query{qry} -} - -func (q Query) Query() (pubsub.Query, error) { - return q.query, nil -} - -// A fluent query builder -type Builder struct { - queryString string - condition - // reusable buffer for building queryString - bytes.Buffer - error -} - -// Templates -type condition struct { +// Condition represents a single condition within a query and consists of tag +// (e.g. "tx.gas"), operator (e.g. "=") and operand (e.g. "7"). +type Condition struct { Tag string - Op string - Operand string + Op Operator + Operand interface{} } -var conditionTemplate = template.Must(template.New("condition").Parse("{{.Tag}} {{.Op}} {{.Operand}}")) - -// Creates a new query builder with a base query that is the conjunction of all queries passed -func NewBuilder(queries ...string) *Builder { - qb := new(Builder) - qb.queryString = qb.and(stringIterator(queries...)) - return qb -} - -func (qb *Builder) String() string { - return qb.queryString -} - -func (qb *Builder) Query() (pubsub.Query, error) { - if qb.error != nil { - return nil, qb.error - } - if isEmpty(qb.queryString) { - return query.Empty{}, nil +// New parses the given string and returns a query or error if the string is +// invalid. +func New(s string) (*query, error) { + p := &QueryParser{Buffer: fmt.Sprintf(`"%s"`, s)} + p.Init() + if err := p.Parse(); err != nil { + return nil, err } - return query.New(qb.String()) + return &query{str: s, parser: p}, nil } -// Creates the conjunction of Builder and rightQuery -func (qb *Builder) And(queryBuilders ...*Builder) *Builder { - return NewBuilder(qb.and(queryBuilderIterator(queryBuilders...))) -} - -// Creates the conjunction of Builder and tag = operand -func (qb *Builder) AndEquals(tag string, operand interface{}) *Builder { - qb.condition.Tag = tag - qb.condition.Op = equalString - qb.condition.Operand = operandString(operand) - return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +// MustParse turns the given string into a query or panics; for tests or others +// cases where you know the string is valid. +func MustParse(s string) *query { + q, err := New(s) + if err != nil { + panic(fmt.Sprintf("failed to parse %s: %v", s, err)) + } + return q } -func (qb *Builder) AndGreaterThanOrEqual(tag string, operand interface{}) *Builder { - qb.condition.Tag = tag - qb.condition.Op = greaterOrEqualString - qb.condition.Operand = operandString(operand) - return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +// String returns the original string. +func (q *query) String() string { + return q.str } -func (qb *Builder) AndLessThanOrEqual(tag string, operand interface{}) *Builder { - qb.condition.Tag = tag - qb.condition.Op = lessOrEqualString - qb.condition.Operand = operandString(operand) - return NewBuilder(qb.and(stringIterator(qb.conditionString()))) +func (q *query) Query() (Query, error) { + return q, nil } -func (qb *Builder) AndStrictlyGreaterThan(tag string, operand interface{}) *Builder { - qb.condition.Tag = tag - qb.condition.Op = greaterThanString - qb.condition.Operand = operandString(operand) - return NewBuilder(qb.and(stringIterator(qb.conditionString()))) -} +// Operator is an operator that defines some kind of relation between tag and +// operand (equality, etc.). +type Operator uint8 -func (qb *Builder) AndStrictlyLessThan(tag string, operand interface{}) *Builder { - qb.condition.Tag = tag - qb.condition.Op = lessThanString - qb.condition.Operand = operandString(operand) - return NewBuilder(qb.and(stringIterator(qb.conditionString()))) -} +const ( + // "<=" + OpLessEqual Operator = iota + // ">=" + OpGreaterEqual + // "<" + OpLess + // ">" + OpGreater + // "=" + OpEqual + // "CONTAINS"; used to check if a string contains a certain sub string. + OpContains +) -func (qb *Builder) AndContains(tag string, operand interface{}) *Builder { - qb.condition.Tag = tag - qb.condition.Op = containsString - qb.condition.Operand = operandString(operand) - return NewBuilder(qb.and(stringIterator(qb.conditionString()))) -} +const ( + // DateLayout defines a layout for all dates (`DATE date`) + DateLayout = "2006-01-02" + // TimeLayout defines a layout for all times (`TIME time`) + TimeLayout = time.RFC3339 +) -func (qb *Builder) and(queryIterator func(func(string))) string { - defer qb.Buffer.Reset() - qb.Buffer.WriteString(qb.queryString) - queryIterator(func(q string) { - if !isEmpty(q) { - if qb.Buffer.Len() > 0 { - qb.Buffer.WriteByte(' ') - qb.Buffer.WriteString(andString) - qb.Buffer.WriteByte(' ') +// Conditions returns a list of conditions. +func (q *query) Conditions() []Condition { + conditions := make([]Condition, 0) + + buffer, begin, end := q.parser.Buffer, 0, 0 + + var tag string + var op Operator + + // tokens must be in the following order: tag ("tx.gas") -> operator ("=") -> operand ("7") + for _, token := range q.parser.Tokens() { + switch token.pegRule { + + case rulePegText: + begin, end = int(token.begin), int(token.end) + case ruletag: + tag = buffer[begin:end] + case rulele: + op = OpLessEqual + case rulege: + op = OpGreaterEqual + case rulel: + op = OpLess + case ruleg: + op = OpGreater + case ruleequal: + op = OpEqual + case rulecontains: + op = OpContains + case rulevalue: + // strip single quotes from value (i.e. "'NewBlock'" -> "NewBlock") + valueWithoutSingleQuotes := buffer[begin+1 : end-1] + conditions = append(conditions, Condition{tag, op, valueWithoutSingleQuotes}) + case rulenumber: + number := buffer[begin:end] + if strings.ContainsAny(number, ".") { // if it looks like a floating-point number + value, err := strconv.ParseFloat(number, 64) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as float64 (should never happen if the grammar is correct)", err, number)) + } + conditions = append(conditions, Condition{tag, op, value}) + } else { + value, err := strconv.ParseInt(number, 10, 64) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as int64 (should never happen if the grammar is correct)", err, number)) + } + conditions = append(conditions, Condition{tag, op, value}) + } + case ruletime: + value, err := time.Parse(TimeLayout, buffer[begin:end]) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / RFC3339 (should never happen if the grammar is correct)", err, buffer[begin:end])) + } + conditions = append(conditions, Condition{tag, op, value}) + case ruledate: + value, err := time.Parse("2006-01-02", buffer[begin:end]) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / '2006-01-02' (should never happen if the grammar is correct)", err, buffer[begin:end])) } - qb.Buffer.WriteString(q) + conditions = append(conditions, Condition{tag, op, value}) } - }) - return qb.Buffer.String() -} - -func operandString(value interface{}) string { - buf := new(bytes.Buffer) - switch v := value.(type) { - case string: - buf.WriteByte('\'') - buf.WriteString(v) - buf.WriteByte('\'') - return buf.String() - case fmt.Stringer: - return operandString(v.String()) - default: - return StringFromValue(v) } -} -func StringFromValue(value interface{}) string { - switch v := value.(type) { - case string: - return v - case fmt.Stringer: - return v.String() - case bool: - if v { - return trueString - } - return falseString - case int: - return strconv.FormatInt(int64(v), 10) - case int32: - return strconv.FormatInt(int64(v), 10) - case int64: - return strconv.FormatInt(v, 10) - case uint: - return strconv.FormatUint(uint64(v), 10) - case uint32: - return strconv.FormatUint(uint64(v), 10) - case uint64: - return strconv.FormatUint(v, 10) - case float32: - return strconv.FormatFloat(float64(v), 'f', -1, 32) - case float64: - return strconv.FormatFloat(float64(v), 'f', -1, 64) - case time.Time: - return timeString + " " + v.Format(time.RFC3339) - default: - return fmt.Sprintf("%v", v) - } + return conditions } -func (qb *Builder) conditionString() string { - defer qb.Buffer.Reset() - err := conditionTemplate.Execute(&qb.Buffer, qb.condition) - if err != nil && qb.error == nil { - qb.error = err +// Matches returns true if the query matches the given set of tags, false otherwise. +// +// For example, query "name=John" matches tags = {"name": "John"}. More +// examples could be found in parser_test.go and query_test.go. +func (q *query) Matches(tags Tagged) bool { + if tags.Len() == 0 { + return false } - return qb.Buffer.String() -} -func isEmpty(queryString string) bool { - return queryString == "" || queryString == emptyString -} - -// Iterators over some strings -func stringIterator(strs ...string) func(func(string)) { - return func(callback func(string)) { - for _, s := range strs { - callback(s) + buffer, begin, end := q.parser.Buffer, 0, 0 + + var tag string + var op Operator + + // tokens must be in the following order: tag ("tx.gas") -> operator ("=") -> operand ("7") + for _, token := range q.parser.Tokens() { + switch token.pegRule { + + case rulePegText: + begin, end = int(token.begin), int(token.end) + case ruletag: + tag = buffer[begin:end] + case rulele: + op = OpLessEqual + case rulege: + op = OpGreaterEqual + case rulel: + op = OpLess + case ruleg: + op = OpGreater + case ruleequal: + op = OpEqual + case rulecontains: + op = OpContains + case rulevalue: + // strip single quotes from value (i.e. "'NewBlock'" -> "NewBlock") + valueWithoutSingleQuotes := buffer[begin+1 : end-1] + + // see if the triplet (tag, operator, operand) matches any tag + // "tx.gas", "=", "7", { "tx.gas": 7, "tx.ID": "4AE393495334" } + if !match(tag, op, reflect.ValueOf(valueWithoutSingleQuotes), tags) { + return false + } + case rulenumber: + number := buffer[begin:end] + if strings.ContainsAny(number, ".") { // if it looks like a floating-point number + value, err := strconv.ParseFloat(number, 64) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as float64 (should never happen if the grammar is correct)", err, number)) + } + if !match(tag, op, reflect.ValueOf(value), tags) { + return false + } + } else { + value, err := strconv.ParseInt(number, 10, 64) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as int64 (should never happen if the grammar is correct)", err, number)) + } + if !match(tag, op, reflect.ValueOf(value), tags) { + return false + } + } + case ruletime: + value, err := time.Parse(TimeLayout, buffer[begin:end]) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / RFC3339 (should never happen if the grammar is correct)", err, buffer[begin:end])) + } + if !match(tag, op, reflect.ValueOf(value), tags) { + return false + } + case ruledate: + value, err := time.Parse("2006-01-02", buffer[begin:end]) + if err != nil { + panic(fmt.Sprintf("got %v while trying to parse %s as time.Time / '2006-01-02' (should never happen if the grammar is correct)", err, buffer[begin:end])) + } + if !match(tag, op, reflect.ValueOf(value), tags) { + return false + } } } + + return true } -func queryBuilderIterator(qbs ...*Builder) func(func(string)) { - return func(callback func(string)) { - for _, qb := range qbs { - callback(qb.String()) +// match returns true if the given triplet (tag, operator, operand) matches any tag. +// +// First, it looks up the tag in tags and if it finds one, tries to compare the +// value from it to the operand using the operator. +// +// "tx.gas", "=", "7", { "tx.gas": 7, "tx.ID": "4AE393495334" } +func match(tag string, op Operator, operand reflect.Value, tags Tagged) bool { + // look up the tag from the query in tags + value, ok := tags.Get(tag) + if !ok { + return false + } + switch operand.Kind() { + case reflect.Struct: // time + operandAsTime := operand.Interface().(time.Time) + // try our best to convert value from tags to time.Time + var ( + v time.Time + err error + ) + if strings.ContainsAny(value, "T") { + v, err = time.Parse(TimeLayout, value) + } else { + v, err = time.Parse(DateLayout, value) + } + if err != nil { + panic(fmt.Sprintf("Failed to convert value %v from tag to time.Time: %v", value, err)) + } + switch op { + case OpLessEqual: + return v.Before(operandAsTime) || v.Equal(operandAsTime) + case OpGreaterEqual: + return v.Equal(operandAsTime) || v.After(operandAsTime) + case OpLess: + return v.Before(operandAsTime) + case OpGreater: + return v.After(operandAsTime) + case OpEqual: + return v.Equal(operandAsTime) + } + case reflect.Float64: + operandFloat64 := operand.Interface().(float64) + var v float64 + // try our best to convert value from tags to float64 + v, err := strconv.ParseFloat(value, 64) + if err != nil { + panic(fmt.Sprintf("Failed to convert value %v from tag to float64: %v", value, err)) } + switch op { + case OpLessEqual: + return v <= operandFloat64 + case OpGreaterEqual: + return v >= operandFloat64 + case OpLess: + return v < operandFloat64 + case OpGreater: + return v > operandFloat64 + case OpEqual: + return v == operandFloat64 + } + case reflect.Int64: + operandInt := operand.Interface().(int64) + var v int64 + // if value looks like float, we try to parse it as float + if strings.ContainsAny(value, ".") { + v1, err := strconv.ParseFloat(value, 64) + if err != nil { + panic(fmt.Sprintf("Failed to convert value %v from tag to float64: %v", value, err)) + } + v = int64(v1) + } else { + var err error + // try our best to convert value from tags to int64 + v, err = strconv.ParseInt(value, 10, 64) + if err != nil { + panic(fmt.Sprintf("Failed to convert value %v from tag to int64: %v", value, err)) + } + } + switch op { + case OpLessEqual: + return v <= operandInt + case OpGreaterEqual: + return v >= operandInt + case OpLess: + return v < operandInt + case OpGreater: + return v > operandInt + case OpEqual: + return v == operandInt + } + case reflect.String: + switch op { + case OpEqual: + return value == operand.String() + case OpContains: + return strings.Contains(value, operand.String()) + } + default: + panic(fmt.Sprintf("Unknown kind of operand %v", operand.Kind())) } + + return false } diff --git a/event/query/query.peg b/event/query/query.peg new file mode 100644 index 0000000000000000000000000000000000000000..739892e4f704db4221676f0b84da3ca63889bb44 --- /dev/null +++ b/event/query/query.peg @@ -0,0 +1,33 @@ +package query + +type QueryParser Peg { +} + +e <- '\"' condition ( ' '+ and ' '+ condition )* '\"' !. + +condition <- tag ' '* (le ' '* (number / time / date) + / ge ' '* (number / time / date) + / l ' '* (number / time / date) + / g ' '* (number / time / date) + / equal ' '* (number / time / date / value) + / contains ' '* value + ) + +tag <- < (![ \t\n\r\\()"'=><] .)+ > +value <- < '\'' (!["'] .)* '\''> +number <- < ('0' + / [1-9] digit* ('.' digit*)?) > +digit <- [0-9] +time <- "TIME " < year '-' month '-' day 'T' digit digit ':' digit digit ':' digit digit (('-' / '+') digit digit ':' digit digit / 'Z') > +date <- "DATE " < year '-' month '-' day > +year <- ('1' / '2') digit digit digit +month <- ('0' / '1') digit +day <- ('0' / '1' / '2' / '3') digit +and <- "AND" + +equal <- "=" +contains <- "CONTAINS" +le <- "<=" +ge <- ">=" +l <- "<" +g <- ">" diff --git a/event/query/query.peg.go b/event/query/query.peg.go new file mode 100644 index 0000000000000000000000000000000000000000..c86e4a47fb41be45336dfc7717d5a3703dfaee01 --- /dev/null +++ b/event/query/query.peg.go @@ -0,0 +1,1553 @@ +// nolint +package query + +import ( + "fmt" + "math" + "sort" + "strconv" +) + +const endSymbol rune = 1114112 + +/* The rule types inferred from the grammar are below. */ +type pegRule uint8 + +const ( + ruleUnknown pegRule = iota + rulee + rulecondition + ruletag + rulevalue + rulenumber + ruledigit + ruletime + ruledate + ruleyear + rulemonth + ruleday + ruleand + ruleequal + rulecontains + rulele + rulege + rulel + ruleg + rulePegText +) + +var rul3s = [...]string{ + "Unknown", + "e", + "condition", + "tag", + "value", + "number", + "digit", + "time", + "date", + "year", + "month", + "day", + "and", + "equal", + "contains", + "le", + "ge", + "l", + "g", + "PegText", +} + +type token32 struct { + pegRule + begin, end uint32 +} + +func (t *token32) String() string { + return fmt.Sprintf("\x1B[34m%v\x1B[m %v %v", rul3s[t.pegRule], t.begin, t.end) +} + +type node32 struct { + token32 + up, next *node32 +} + +func (node *node32) print(pretty bool, buffer string) { + var print func(node *node32, depth int) + print = func(node *node32, depth int) { + for node != nil { + for c := 0; c < depth; c++ { + fmt.Printf(" ") + } + rule := rul3s[node.pegRule] + quote := strconv.Quote(string(([]rune(buffer)[node.begin:node.end]))) + if !pretty { + fmt.Printf("%v %v\n", rule, quote) + } else { + fmt.Printf("\x1B[34m%v\x1B[m %v\n", rule, quote) + } + if node.up != nil { + print(node.up, depth+1) + } + node = node.next + } + } + print(node, 0) +} + +func (node *node32) Print(buffer string) { + node.print(false, buffer) +} + +func (node *node32) PrettyPrint(buffer string) { + node.print(true, buffer) +} + +type tokens32 struct { + tree []token32 +} + +func (t *tokens32) Trim(length uint32) { + t.tree = t.tree[:length] +} + +func (t *tokens32) Print() { + for _, token := range t.tree { + fmt.Println(token.String()) + } +} + +func (t *tokens32) AST() *node32 { + type element struct { + node *node32 + down *element + } + tokens := t.Tokens() + var stack *element + for _, token := range tokens { + if token.begin == token.end { + continue + } + node := &node32{token32: token} + for stack != nil && stack.node.begin >= token.begin && stack.node.end <= token.end { + stack.node.next = node.up + node.up = stack.node + stack = stack.down + } + stack = &element{node: node, down: stack} + } + if stack != nil { + return stack.node + } + return nil +} + +func (t *tokens32) PrintSyntaxTree(buffer string) { + t.AST().Print(buffer) +} + +func (t *tokens32) PrettyPrintSyntaxTree(buffer string) { + t.AST().PrettyPrint(buffer) +} + +func (t *tokens32) Add(rule pegRule, begin, end, index uint32) { + if tree := t.tree; int(index) >= len(tree) { + expanded := make([]token32, 2*len(tree)) + copy(expanded, tree) + t.tree = expanded + } + t.tree[index] = token32{ + pegRule: rule, + begin: begin, + end: end, + } +} + +func (t *tokens32) Tokens() []token32 { + return t.tree +} + +type QueryParser struct { + Buffer string + buffer []rune + rules [20]func() bool + parse func(rule ...int) error + reset func() + Pretty bool + tokens32 +} + +func (p *QueryParser) Parse(rule ...int) error { + return p.parse(rule...) +} + +func (p *QueryParser) Reset() { + p.reset() +} + +type textPosition struct { + line, symbol int +} + +type textPositionMap map[int]textPosition + +func translatePositions(buffer []rune, positions []int) textPositionMap { + length, translations, j, line, symbol := len(positions), make(textPositionMap, len(positions)), 0, 1, 0 + sort.Ints(positions) + +search: + for i, c := range buffer { + if c == '\n' { + line, symbol = line+1, 0 + } else { + symbol++ + } + if i == positions[j] { + translations[positions[j]] = textPosition{line, symbol} + for j++; j < length; j++ { + if i != positions[j] { + continue search + } + } + break search + } + } + + return translations +} + +type parseError struct { + p *QueryParser + max token32 +} + +func (e *parseError) Error() string { + tokens, error := []token32{e.max}, "\n" + positions, p := make([]int, 2*len(tokens)), 0 + for _, token := range tokens { + positions[p], p = int(token.begin), p+1 + positions[p], p = int(token.end), p+1 + } + translations := translatePositions(e.p.buffer, positions) + format := "parse error near %v (line %v symbol %v - line %v symbol %v):\n%v\n" + if e.p.Pretty { + format = "parse error near \x1B[34m%v\x1B[m (line %v symbol %v - line %v symbol %v):\n%v\n" + } + for _, token := range tokens { + begin, end := int(token.begin), int(token.end) + error += fmt.Sprintf(format, + rul3s[token.pegRule], + translations[begin].line, translations[begin].symbol, + translations[end].line, translations[end].symbol, + strconv.Quote(string(e.p.buffer[begin:end]))) + } + + return error +} + +func (p *QueryParser) PrintSyntaxTree() { + if p.Pretty { + p.tokens32.PrettyPrintSyntaxTree(p.Buffer) + } else { + p.tokens32.PrintSyntaxTree(p.Buffer) + } +} + +func (p *QueryParser) Init() { + var ( + max token32 + position, tokenIndex uint32 + buffer []rune + ) + p.reset = func() { + max = token32{} + position, tokenIndex = 0, 0 + + p.buffer = []rune(p.Buffer) + if len(p.buffer) == 0 || p.buffer[len(p.buffer)-1] != endSymbol { + p.buffer = append(p.buffer, endSymbol) + } + buffer = p.buffer + } + p.reset() + + _rules := p.rules + tree := tokens32{tree: make([]token32, math.MaxInt16)} + p.parse = func(rule ...int) error { + r := 1 + if len(rule) > 0 { + r = rule[0] + } + matches := p.rules[r]() + p.tokens32 = tree + if matches { + p.Trim(tokenIndex) + return nil + } + return &parseError{p, max} + } + + add := func(rule pegRule, begin uint32) { + tree.Add(rule, begin, position, tokenIndex) + tokenIndex++ + if begin != position && position > max.end { + max = token32{rule, begin, position} + } + } + + matchDot := func() bool { + if buffer[position] != endSymbol { + position++ + return true + } + return false + } + + /*matchChar := func(c byte) bool { + if buffer[position] == c { + position++ + return true + } + return false + }*/ + + /*matchRange := func(lower byte, upper byte) bool { + if c := buffer[position]; c >= lower && c <= upper { + position++ + return true + } + return false + }*/ + + _rules = [...]func() bool{ + nil, + /* 0 e <- <('"' condition (' '+ and ' '+ condition)* '"' !.)> */ + func() bool { + position0, tokenIndex0 := position, tokenIndex + { + position1 := position + if buffer[position] != rune('"') { + goto l0 + } + position++ + if !_rules[rulecondition]() { + goto l0 + } + l2: + { + position3, tokenIndex3 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l3 + } + position++ + l4: + { + position5, tokenIndex5 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l5 + } + position++ + goto l4 + l5: + position, tokenIndex = position5, tokenIndex5 + } + { + position6 := position + { + position7, tokenIndex7 := position, tokenIndex + if buffer[position] != rune('a') { + goto l8 + } + position++ + goto l7 + l8: + position, tokenIndex = position7, tokenIndex7 + if buffer[position] != rune('A') { + goto l3 + } + position++ + } + l7: + { + position9, tokenIndex9 := position, tokenIndex + if buffer[position] != rune('n') { + goto l10 + } + position++ + goto l9 + l10: + position, tokenIndex = position9, tokenIndex9 + if buffer[position] != rune('N') { + goto l3 + } + position++ + } + l9: + { + position11, tokenIndex11 := position, tokenIndex + if buffer[position] != rune('d') { + goto l12 + } + position++ + goto l11 + l12: + position, tokenIndex = position11, tokenIndex11 + if buffer[position] != rune('D') { + goto l3 + } + position++ + } + l11: + add(ruleand, position6) + } + if buffer[position] != rune(' ') { + goto l3 + } + position++ + l13: + { + position14, tokenIndex14 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l14 + } + position++ + goto l13 + l14: + position, tokenIndex = position14, tokenIndex14 + } + if !_rules[rulecondition]() { + goto l3 + } + goto l2 + l3: + position, tokenIndex = position3, tokenIndex3 + } + if buffer[position] != rune('"') { + goto l0 + } + position++ + { + position15, tokenIndex15 := position, tokenIndex + if !matchDot() { + goto l15 + } + goto l0 + l15: + position, tokenIndex = position15, tokenIndex15 + } + add(rulee, position1) + } + return true + l0: + position, tokenIndex = position0, tokenIndex0 + return false + }, + /* 1 condition <- <(tag ' '* ((le ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / (ge ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number))) / ((&('=') (equal ' '* ((&('\'') value) | (&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('>') (g ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('<') (l ' '* ((&('D' | 'd') date) | (&('T' | 't') time) | (&('0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9') number)))) | (&('C' | 'c') (contains ' '* value)))))> */ + func() bool { + position16, tokenIndex16 := position, tokenIndex + { + position17 := position + { + position18 := position + { + position19 := position + { + position22, tokenIndex22 := position, tokenIndex + { + switch buffer[position] { + case '<': + if buffer[position] != rune('<') { + goto l22 + } + position++ + break + case '>': + if buffer[position] != rune('>') { + goto l22 + } + position++ + break + case '=': + if buffer[position] != rune('=') { + goto l22 + } + position++ + break + case '\'': + if buffer[position] != rune('\'') { + goto l22 + } + position++ + break + case '"': + if buffer[position] != rune('"') { + goto l22 + } + position++ + break + case ')': + if buffer[position] != rune(')') { + goto l22 + } + position++ + break + case '(': + if buffer[position] != rune('(') { + goto l22 + } + position++ + break + case '\\': + if buffer[position] != rune('\\') { + goto l22 + } + position++ + break + case '\r': + if buffer[position] != rune('\r') { + goto l22 + } + position++ + break + case '\n': + if buffer[position] != rune('\n') { + goto l22 + } + position++ + break + case '\t': + if buffer[position] != rune('\t') { + goto l22 + } + position++ + break + default: + if buffer[position] != rune(' ') { + goto l22 + } + position++ + break + } + } + + goto l16 + l22: + position, tokenIndex = position22, tokenIndex22 + } + if !matchDot() { + goto l16 + } + l20: + { + position21, tokenIndex21 := position, tokenIndex + { + position24, tokenIndex24 := position, tokenIndex + { + switch buffer[position] { + case '<': + if buffer[position] != rune('<') { + goto l24 + } + position++ + break + case '>': + if buffer[position] != rune('>') { + goto l24 + } + position++ + break + case '=': + if buffer[position] != rune('=') { + goto l24 + } + position++ + break + case '\'': + if buffer[position] != rune('\'') { + goto l24 + } + position++ + break + case '"': + if buffer[position] != rune('"') { + goto l24 + } + position++ + break + case ')': + if buffer[position] != rune(')') { + goto l24 + } + position++ + break + case '(': + if buffer[position] != rune('(') { + goto l24 + } + position++ + break + case '\\': + if buffer[position] != rune('\\') { + goto l24 + } + position++ + break + case '\r': + if buffer[position] != rune('\r') { + goto l24 + } + position++ + break + case '\n': + if buffer[position] != rune('\n') { + goto l24 + } + position++ + break + case '\t': + if buffer[position] != rune('\t') { + goto l24 + } + position++ + break + default: + if buffer[position] != rune(' ') { + goto l24 + } + position++ + break + } + } + + goto l21 + l24: + position, tokenIndex = position24, tokenIndex24 + } + if !matchDot() { + goto l21 + } + goto l20 + l21: + position, tokenIndex = position21, tokenIndex21 + } + add(rulePegText, position19) + } + add(ruletag, position18) + } + l26: + { + position27, tokenIndex27 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l27 + } + position++ + goto l26 + l27: + position, tokenIndex = position27, tokenIndex27 + } + { + position28, tokenIndex28 := position, tokenIndex + { + position30 := position + if buffer[position] != rune('<') { + goto l29 + } + position++ + if buffer[position] != rune('=') { + goto l29 + } + position++ + add(rulele, position30) + } + l31: + { + position32, tokenIndex32 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l32 + } + position++ + goto l31 + l32: + position, tokenIndex = position32, tokenIndex32 + } + { + switch buffer[position] { + case 'D', 'd': + if !_rules[ruledate]() { + goto l29 + } + break + case 'T', 't': + if !_rules[ruletime]() { + goto l29 + } + break + default: + if !_rules[rulenumber]() { + goto l29 + } + break + } + } + + goto l28 + l29: + position, tokenIndex = position28, tokenIndex28 + { + position35 := position + if buffer[position] != rune('>') { + goto l34 + } + position++ + if buffer[position] != rune('=') { + goto l34 + } + position++ + add(rulege, position35) + } + l36: + { + position37, tokenIndex37 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l37 + } + position++ + goto l36 + l37: + position, tokenIndex = position37, tokenIndex37 + } + { + switch buffer[position] { + case 'D', 'd': + if !_rules[ruledate]() { + goto l34 + } + break + case 'T', 't': + if !_rules[ruletime]() { + goto l34 + } + break + default: + if !_rules[rulenumber]() { + goto l34 + } + break + } + } + + goto l28 + l34: + position, tokenIndex = position28, tokenIndex28 + { + switch buffer[position] { + case '=': + { + position40 := position + if buffer[position] != rune('=') { + goto l16 + } + position++ + add(ruleequal, position40) + } + l41: + { + position42, tokenIndex42 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l42 + } + position++ + goto l41 + l42: + position, tokenIndex = position42, tokenIndex42 + } + { + switch buffer[position] { + case '\'': + if !_rules[rulevalue]() { + goto l16 + } + break + case 'D', 'd': + if !_rules[ruledate]() { + goto l16 + } + break + case 'T', 't': + if !_rules[ruletime]() { + goto l16 + } + break + default: + if !_rules[rulenumber]() { + goto l16 + } + break + } + } + + break + case '>': + { + position44 := position + if buffer[position] != rune('>') { + goto l16 + } + position++ + add(ruleg, position44) + } + l45: + { + position46, tokenIndex46 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l46 + } + position++ + goto l45 + l46: + position, tokenIndex = position46, tokenIndex46 + } + { + switch buffer[position] { + case 'D', 'd': + if !_rules[ruledate]() { + goto l16 + } + break + case 'T', 't': + if !_rules[ruletime]() { + goto l16 + } + break + default: + if !_rules[rulenumber]() { + goto l16 + } + break + } + } + + break + case '<': + { + position48 := position + if buffer[position] != rune('<') { + goto l16 + } + position++ + add(rulel, position48) + } + l49: + { + position50, tokenIndex50 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l50 + } + position++ + goto l49 + l50: + position, tokenIndex = position50, tokenIndex50 + } + { + switch buffer[position] { + case 'D', 'd': + if !_rules[ruledate]() { + goto l16 + } + break + case 'T', 't': + if !_rules[ruletime]() { + goto l16 + } + break + default: + if !_rules[rulenumber]() { + goto l16 + } + break + } + } + + break + default: + { + position52 := position + { + position53, tokenIndex53 := position, tokenIndex + if buffer[position] != rune('c') { + goto l54 + } + position++ + goto l53 + l54: + position, tokenIndex = position53, tokenIndex53 + if buffer[position] != rune('C') { + goto l16 + } + position++ + } + l53: + { + position55, tokenIndex55 := position, tokenIndex + if buffer[position] != rune('o') { + goto l56 + } + position++ + goto l55 + l56: + position, tokenIndex = position55, tokenIndex55 + if buffer[position] != rune('O') { + goto l16 + } + position++ + } + l55: + { + position57, tokenIndex57 := position, tokenIndex + if buffer[position] != rune('n') { + goto l58 + } + position++ + goto l57 + l58: + position, tokenIndex = position57, tokenIndex57 + if buffer[position] != rune('N') { + goto l16 + } + position++ + } + l57: + { + position59, tokenIndex59 := position, tokenIndex + if buffer[position] != rune('t') { + goto l60 + } + position++ + goto l59 + l60: + position, tokenIndex = position59, tokenIndex59 + if buffer[position] != rune('T') { + goto l16 + } + position++ + } + l59: + { + position61, tokenIndex61 := position, tokenIndex + if buffer[position] != rune('a') { + goto l62 + } + position++ + goto l61 + l62: + position, tokenIndex = position61, tokenIndex61 + if buffer[position] != rune('A') { + goto l16 + } + position++ + } + l61: + { + position63, tokenIndex63 := position, tokenIndex + if buffer[position] != rune('i') { + goto l64 + } + position++ + goto l63 + l64: + position, tokenIndex = position63, tokenIndex63 + if buffer[position] != rune('I') { + goto l16 + } + position++ + } + l63: + { + position65, tokenIndex65 := position, tokenIndex + if buffer[position] != rune('n') { + goto l66 + } + position++ + goto l65 + l66: + position, tokenIndex = position65, tokenIndex65 + if buffer[position] != rune('N') { + goto l16 + } + position++ + } + l65: + { + position67, tokenIndex67 := position, tokenIndex + if buffer[position] != rune('s') { + goto l68 + } + position++ + goto l67 + l68: + position, tokenIndex = position67, tokenIndex67 + if buffer[position] != rune('S') { + goto l16 + } + position++ + } + l67: + add(rulecontains, position52) + } + l69: + { + position70, tokenIndex70 := position, tokenIndex + if buffer[position] != rune(' ') { + goto l70 + } + position++ + goto l69 + l70: + position, tokenIndex = position70, tokenIndex70 + } + if !_rules[rulevalue]() { + goto l16 + } + break + } + } + + } + l28: + add(rulecondition, position17) + } + return true + l16: + position, tokenIndex = position16, tokenIndex16 + return false + }, + /* 2 tag <- <<(!((&('<') '<') | (&('>') '>') | (&('=') '=') | (&('\'') '\'') | (&('"') '"') | (&(')') ')') | (&('(') '(') | (&('\\') '\\') | (&('\r') '\r') | (&('\n') '\n') | (&('\t') '\t') | (&(' ') ' ')) .)+>> */ + nil, + /* 3 value <- <<('\'' (!('"' / '\'') .)* '\'')>> */ + func() bool { + position72, tokenIndex72 := position, tokenIndex + { + position73 := position + { + position74 := position + if buffer[position] != rune('\'') { + goto l72 + } + position++ + l75: + { + position76, tokenIndex76 := position, tokenIndex + { + position77, tokenIndex77 := position, tokenIndex + { + position78, tokenIndex78 := position, tokenIndex + if buffer[position] != rune('"') { + goto l79 + } + position++ + goto l78 + l79: + position, tokenIndex = position78, tokenIndex78 + if buffer[position] != rune('\'') { + goto l77 + } + position++ + } + l78: + goto l76 + l77: + position, tokenIndex = position77, tokenIndex77 + } + if !matchDot() { + goto l76 + } + goto l75 + l76: + position, tokenIndex = position76, tokenIndex76 + } + if buffer[position] != rune('\'') { + goto l72 + } + position++ + add(rulePegText, position74) + } + add(rulevalue, position73) + } + return true + l72: + position, tokenIndex = position72, tokenIndex72 + return false + }, + /* 4 number <- <<('0' / ([1-9] digit* ('.' digit*)?))>> */ + func() bool { + position80, tokenIndex80 := position, tokenIndex + { + position81 := position + { + position82 := position + { + position83, tokenIndex83 := position, tokenIndex + if buffer[position] != rune('0') { + goto l84 + } + position++ + goto l83 + l84: + position, tokenIndex = position83, tokenIndex83 + if c := buffer[position]; c < rune('1') || c > rune('9') { + goto l80 + } + position++ + l85: + { + position86, tokenIndex86 := position, tokenIndex + if !_rules[ruledigit]() { + goto l86 + } + goto l85 + l86: + position, tokenIndex = position86, tokenIndex86 + } + { + position87, tokenIndex87 := position, tokenIndex + if buffer[position] != rune('.') { + goto l87 + } + position++ + l89: + { + position90, tokenIndex90 := position, tokenIndex + if !_rules[ruledigit]() { + goto l90 + } + goto l89 + l90: + position, tokenIndex = position90, tokenIndex90 + } + goto l88 + l87: + position, tokenIndex = position87, tokenIndex87 + } + l88: + } + l83: + add(rulePegText, position82) + } + add(rulenumber, position81) + } + return true + l80: + position, tokenIndex = position80, tokenIndex80 + return false + }, + /* 5 digit <- <[0-9]> */ + func() bool { + position91, tokenIndex91 := position, tokenIndex + { + position92 := position + if c := buffer[position]; c < rune('0') || c > rune('9') { + goto l91 + } + position++ + add(ruledigit, position92) + } + return true + l91: + position, tokenIndex = position91, tokenIndex91 + return false + }, + /* 6 time <- <(('t' / 'T') ('i' / 'I') ('m' / 'M') ('e' / 'E') ' ' <(year '-' month '-' day 'T' digit digit ':' digit digit ':' digit digit ((('-' / '+') digit digit ':' digit digit) / 'Z'))>)> */ + func() bool { + position93, tokenIndex93 := position, tokenIndex + { + position94 := position + { + position95, tokenIndex95 := position, tokenIndex + if buffer[position] != rune('t') { + goto l96 + } + position++ + goto l95 + l96: + position, tokenIndex = position95, tokenIndex95 + if buffer[position] != rune('T') { + goto l93 + } + position++ + } + l95: + { + position97, tokenIndex97 := position, tokenIndex + if buffer[position] != rune('i') { + goto l98 + } + position++ + goto l97 + l98: + position, tokenIndex = position97, tokenIndex97 + if buffer[position] != rune('I') { + goto l93 + } + position++ + } + l97: + { + position99, tokenIndex99 := position, tokenIndex + if buffer[position] != rune('m') { + goto l100 + } + position++ + goto l99 + l100: + position, tokenIndex = position99, tokenIndex99 + if buffer[position] != rune('M') { + goto l93 + } + position++ + } + l99: + { + position101, tokenIndex101 := position, tokenIndex + if buffer[position] != rune('e') { + goto l102 + } + position++ + goto l101 + l102: + position, tokenIndex = position101, tokenIndex101 + if buffer[position] != rune('E') { + goto l93 + } + position++ + } + l101: + if buffer[position] != rune(' ') { + goto l93 + } + position++ + { + position103 := position + if !_rules[ruleyear]() { + goto l93 + } + if buffer[position] != rune('-') { + goto l93 + } + position++ + if !_rules[rulemonth]() { + goto l93 + } + if buffer[position] != rune('-') { + goto l93 + } + position++ + if !_rules[ruleday]() { + goto l93 + } + if buffer[position] != rune('T') { + goto l93 + } + position++ + if !_rules[ruledigit]() { + goto l93 + } + if !_rules[ruledigit]() { + goto l93 + } + if buffer[position] != rune(':') { + goto l93 + } + position++ + if !_rules[ruledigit]() { + goto l93 + } + if !_rules[ruledigit]() { + goto l93 + } + if buffer[position] != rune(':') { + goto l93 + } + position++ + if !_rules[ruledigit]() { + goto l93 + } + if !_rules[ruledigit]() { + goto l93 + } + { + position104, tokenIndex104 := position, tokenIndex + { + position106, tokenIndex106 := position, tokenIndex + if buffer[position] != rune('-') { + goto l107 + } + position++ + goto l106 + l107: + position, tokenIndex = position106, tokenIndex106 + if buffer[position] != rune('+') { + goto l105 + } + position++ + } + l106: + if !_rules[ruledigit]() { + goto l105 + } + if !_rules[ruledigit]() { + goto l105 + } + if buffer[position] != rune(':') { + goto l105 + } + position++ + if !_rules[ruledigit]() { + goto l105 + } + if !_rules[ruledigit]() { + goto l105 + } + goto l104 + l105: + position, tokenIndex = position104, tokenIndex104 + if buffer[position] != rune('Z') { + goto l93 + } + position++ + } + l104: + add(rulePegText, position103) + } + add(ruletime, position94) + } + return true + l93: + position, tokenIndex = position93, tokenIndex93 + return false + }, + /* 7 date <- <(('d' / 'D') ('a' / 'A') ('t' / 'T') ('e' / 'E') ' ' <(year '-' month '-' day)>)> */ + func() bool { + position108, tokenIndex108 := position, tokenIndex + { + position109 := position + { + position110, tokenIndex110 := position, tokenIndex + if buffer[position] != rune('d') { + goto l111 + } + position++ + goto l110 + l111: + position, tokenIndex = position110, tokenIndex110 + if buffer[position] != rune('D') { + goto l108 + } + position++ + } + l110: + { + position112, tokenIndex112 := position, tokenIndex + if buffer[position] != rune('a') { + goto l113 + } + position++ + goto l112 + l113: + position, tokenIndex = position112, tokenIndex112 + if buffer[position] != rune('A') { + goto l108 + } + position++ + } + l112: + { + position114, tokenIndex114 := position, tokenIndex + if buffer[position] != rune('t') { + goto l115 + } + position++ + goto l114 + l115: + position, tokenIndex = position114, tokenIndex114 + if buffer[position] != rune('T') { + goto l108 + } + position++ + } + l114: + { + position116, tokenIndex116 := position, tokenIndex + if buffer[position] != rune('e') { + goto l117 + } + position++ + goto l116 + l117: + position, tokenIndex = position116, tokenIndex116 + if buffer[position] != rune('E') { + goto l108 + } + position++ + } + l116: + if buffer[position] != rune(' ') { + goto l108 + } + position++ + { + position118 := position + if !_rules[ruleyear]() { + goto l108 + } + if buffer[position] != rune('-') { + goto l108 + } + position++ + if !_rules[rulemonth]() { + goto l108 + } + if buffer[position] != rune('-') { + goto l108 + } + position++ + if !_rules[ruleday]() { + goto l108 + } + add(rulePegText, position118) + } + add(ruledate, position109) + } + return true + l108: + position, tokenIndex = position108, tokenIndex108 + return false + }, + /* 8 year <- <(('1' / '2') digit digit digit)> */ + func() bool { + position119, tokenIndex119 := position, tokenIndex + { + position120 := position + { + position121, tokenIndex121 := position, tokenIndex + if buffer[position] != rune('1') { + goto l122 + } + position++ + goto l121 + l122: + position, tokenIndex = position121, tokenIndex121 + if buffer[position] != rune('2') { + goto l119 + } + position++ + } + l121: + if !_rules[ruledigit]() { + goto l119 + } + if !_rules[ruledigit]() { + goto l119 + } + if !_rules[ruledigit]() { + goto l119 + } + add(ruleyear, position120) + } + return true + l119: + position, tokenIndex = position119, tokenIndex119 + return false + }, + /* 9 month <- <(('0' / '1') digit)> */ + func() bool { + position123, tokenIndex123 := position, tokenIndex + { + position124 := position + { + position125, tokenIndex125 := position, tokenIndex + if buffer[position] != rune('0') { + goto l126 + } + position++ + goto l125 + l126: + position, tokenIndex = position125, tokenIndex125 + if buffer[position] != rune('1') { + goto l123 + } + position++ + } + l125: + if !_rules[ruledigit]() { + goto l123 + } + add(rulemonth, position124) + } + return true + l123: + position, tokenIndex = position123, tokenIndex123 + return false + }, + /* 10 day <- <(((&('3') '3') | (&('2') '2') | (&('1') '1') | (&('0') '0')) digit)> */ + func() bool { + position127, tokenIndex127 := position, tokenIndex + { + position128 := position + { + switch buffer[position] { + case '3': + if buffer[position] != rune('3') { + goto l127 + } + position++ + break + case '2': + if buffer[position] != rune('2') { + goto l127 + } + position++ + break + case '1': + if buffer[position] != rune('1') { + goto l127 + } + position++ + break + default: + if buffer[position] != rune('0') { + goto l127 + } + position++ + break + } + } + + if !_rules[ruledigit]() { + goto l127 + } + add(ruleday, position128) + } + return true + l127: + position, tokenIndex = position127, tokenIndex127 + return false + }, + /* 11 and <- <(('a' / 'A') ('n' / 'N') ('d' / 'D'))> */ + nil, + /* 12 equal <- <'='> */ + nil, + /* 13 contains <- <(('c' / 'C') ('o' / 'O') ('n' / 'N') ('t' / 'T') ('a' / 'A') ('i' / 'I') ('n' / 'N') ('s' / 'S'))> */ + nil, + /* 14 le <- <('<' '=')> */ + nil, + /* 15 ge <- <('>' '=')> */ + nil, + /* 16 l <- <'<'> */ + nil, + /* 17 g <- <'>'> */ + nil, + nil, + } + p.rules = _rules +} diff --git a/event/query/query_test.go b/event/query/query_test.go index a7116b0a8b43c50e2099f82b6ede2178fa22bcdc..0951bf434e92f7f1cd6e17c572bc22fd504f06cb 100644 --- a/event/query/query_test.go +++ b/event/query/query_test.go @@ -1,53 +1,84 @@ package query import ( + "fmt" "testing" + "time" - "github.com/hyperledger/burrow/logging/structure" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/libs/pubsub" ) -func TestQueryBuilder(t *testing.T) { - qb := NewBuilder() - qry, err := qb.Query() - require.NoError(t, err) - assert.Equal(t, emptyString, qry.String()) +func TestMatches(t *testing.T) { + var ( + txDate = "2017-01-01" + txTime = "2018-05-03T14:45:00Z" + ) - qb = qb.AndGreaterThanOrEqual("foo.size", 45) - qry, err = qb.Query() - require.NoError(t, err) - assert.Equal(t, "foo.size >= 45", qry.String()) + testCases := []struct { + s string + tags map[string]interface{} + err bool + matches bool + }{ + {"tm.events.type='NewBlock'", map[string]interface{}{"tm.events.type": "NewBlock"}, false, true}, - qb = qb.AndEquals("bar.name", "marmot") - qry, err = qb.Query() - require.NoError(t, err) - assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot'", qry.String()) + {"tx.gas > 7", map[string]interface{}{"tx.gas": "8"}, false, true}, + {"tx.gas > 7 AND tx.gas < 9", map[string]interface{}{"tx.gas": "8"}, false, true}, + {"body.weight >= 3.5", map[string]interface{}{"body.weight": "3.5"}, false, true}, + {"account.balance < 1000.0", map[string]interface{}{"account.balance": "900"}, false, true}, + {"apples.kg <= 4", map[string]interface{}{"apples.kg": "4.0"}, false, true}, + {"body.weight >= 4.5", map[string]interface{}{"body.weight": fmt.Sprintf("%v", float32(4.5))}, false, true}, + {"oranges.kg < 4 AND watermellons.kg > 10", map[string]interface{}{"oranges.kg": "3", "watermellons.kg": "12"}, false, true}, + {"peaches.kg < 4", map[string]interface{}{"peaches.kg": "5"}, false, false}, - assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot"))) - assert.False(t, qry.Matches(makeTagMap("foo.size", 8, "bar.name", "marmot"))) - assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marot"))) + {"tx.date > DATE 2017-01-01", map[string]interface{}{"tx.date": time.Now().Format(DateLayout)}, false, true}, + {"tx.date = DATE 2017-01-01", map[string]interface{}{"tx.date": txDate}, false, true}, + {"tx.date = DATE 2018-01-01", map[string]interface{}{"tx.date": txDate}, false, false}, - qb = qb.AndContains("bar.desc", "burrow") - qry, err = qb.Query() - require.NoError(t, err) - assert.Equal(t, "foo.size >= 45 AND bar.name = 'marmot' AND bar.desc CONTAINS 'burrow'", qry.String()) + {"tx.time >= TIME 2013-05-03T14:45:00Z", map[string]interface{}{"tx.time": time.Now().Format(TimeLayout)}, false, true}, + {"tx.time = TIME 2013-05-03T14:45:00Z", map[string]interface{}{"tx.time": txTime}, false, false}, - assert.True(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a burrow"))) - assert.False(t, qry.Matches(makeTagMap("foo.size", 80, "bar.name", "marmot", "bar.desc", "lives in a shoe"))) + {"abci.owner.name CONTAINS 'Igor'", map[string]interface{}{"abci.owner.name": "Igor,Ivan"}, false, true}, + {"abci.owner.name CONTAINS 'Igor'", map[string]interface{}{"abci.owner.name": "Pavel,Ivan"}, false, false}, + } - qb = NewBuilder().AndEquals("foo", "bar") - qb = qb.And(NewBuilder().AndGreaterThanOrEqual("frogs", 4)) - qry, err = qb.Query() - require.NoError(t, err) - assert.Equal(t, "foo = 'bar' AND frogs >= 4", qry.String()) + for _, tc := range testCases { + q, err := New(tc.s) + if !tc.err { + require.Nil(t, err) + } + + if tc.matches { + assert.True(t, q.Matches(TagMap(tc.tags)), "Query '%s' should match %v", tc.s, tc.tags) + } else { + assert.False(t, q.Matches(TagMap(tc.tags)), "Query '%s' should not match %v", tc.s, tc.tags) + } + } } -func makeTagMap(keyvals ...interface{}) pubsub.TagMap { - tmap := make(map[string]string) - for i := 0; i < len(keyvals); i += 2 { - tmap[keyvals[i].(string)] = structure.StringifyKey(keyvals[i+1]) +func TestMustParse(t *testing.T) { + assert.Panics(t, func() { MustParse("=") }) + assert.NotPanics(t, func() { MustParse("tm.events.type='NewBlock'") }) +} + +func TestConditions(t *testing.T) { + txTime, err := time.Parse(time.RFC3339, "2013-05-03T14:45:00Z") + require.NoError(t, err) + + testCases := []struct { + s string + conditions []Condition + }{ + {s: "tm.events.type='NewBlock'", conditions: []Condition{{Tag: "tm.events.type", Op: OpEqual, Operand: "NewBlock"}}}, + {s: "tx.gas > 7 AND tx.gas < 9", conditions: []Condition{{Tag: "tx.gas", Op: OpGreater, Operand: int64(7)}, {Tag: "tx.gas", Op: OpLess, Operand: int64(9)}}}, + {s: "tx.time >= TIME 2013-05-03T14:45:00Z", conditions: []Condition{{Tag: "tx.time", Op: OpGreaterEqual, Operand: txTime}}}, + } + + for _, tc := range testCases { + q, err := New(tc.s) + require.Nil(t, err) + + assert.Equal(t, tc.conditions, q.Conditions()) } - return pubsub.NewTagMap(tmap) } diff --git a/event/query/reflect_tagged.go b/event/query/reflect_tagged.go new file mode 100644 index 0000000000000000000000000000000000000000..b5cc6386452ce25029bd56f7e9130c99a881f057 --- /dev/null +++ b/event/query/reflect_tagged.go @@ -0,0 +1,99 @@ +package query + +import ( + "fmt" + "reflect" +) + +type ReflectTagged struct { + rv reflect.Value + keys []string + ks map[string]struct{} +} + +var _ Tagged = &ReflectTagged{} + +func MustReflectTags(value interface{}, fieldNames ...string) *ReflectTagged { + rt, err := ReflectTags(value, fieldNames...) + if err != nil { + panic(err) + } + return rt +} + +// ReflectTags provides a query.Tagged on a structs exported fields using query.StringFromValue to derive the string +// values associated with each field. If passed explicit field names will only only provide those fields as tags, +// otherwise all exported fields are provided. +func ReflectTags(value interface{}, fieldNames ...string) (*ReflectTagged, error) { + rv := reflect.ValueOf(value) + if rv.IsNil() { + return &ReflectTagged{}, nil + } + if rv.Kind() != reflect.Ptr { + return nil, fmt.Errorf("ReflectStructTags needs a pointer to a struct but %v is not a pointer", + rv.Interface()) + } + if rv.Elem().Kind() != reflect.Struct { + return nil, fmt.Errorf("ReflectStructTags needs a pointer to a struct but %v does not point to a struct", + rv.Interface()) + } + ty := rv.Elem().Type() + + numField := ty.NumField() + if len(fieldNames) > 0 { + if len(fieldNames) > numField { + return nil, fmt.Errorf("ReflectTags asked to tag %v fields but %v only has %v fields", + len(fieldNames), rv.Interface(), numField) + } + numField = len(fieldNames) + } + rt := &ReflectTagged{ + rv: rv, + ks: make(map[string]struct{}, numField), + keys: make([]string, 0, numField), + } + if len(fieldNames) > 0 { + for _, fieldName := range fieldNames { + field, ok := ty.FieldByName(fieldName) + if !ok { + return nil, fmt.Errorf("ReflectTags asked to tag field named %s by no such field on %v", + fieldName, rv.Interface()) + } + ok = rt.registerField(field) + if !ok { + return nil, fmt.Errorf("field %s of %v is not exported so cannot act as tag", fieldName, + rv.Interface()) + } + } + } else { + for i := 0; i < numField; i++ { + rt.registerField(ty.Field(i)) + } + } + return rt, nil +} + +func (rt *ReflectTagged) registerField(field reflect.StructField) (ok bool) { + // Empty iff struct field is exported + if field.PkgPath == "" { + rt.keys = append(rt.keys, field.Name) + rt.ks[field.Name] = struct{}{} + return true + } + return false +} + +func (rt *ReflectTagged) Keys() []string { + return rt.keys +} + +func (rt *ReflectTagged) Get(key string) (value string, ok bool) { + if _, ok := rt.ks[key]; ok { + return StringFromValue(rt.rv.Elem().FieldByName(key).Interface()), true + } + return "", false +} + +func (rt *ReflectTagged) Len() int { + return len(rt.keys) +} diff --git a/event/query/reflect_tagged_test.go b/event/query/reflect_tagged_test.go new file mode 100644 index 0000000000000000000000000000000000000000..1a2fe1aa774fd874ee925e68dbc6fd12b40ce926 --- /dev/null +++ b/event/query/reflect_tagged_test.go @@ -0,0 +1,97 @@ +package query + +import ( + "testing" + + "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type testTaggable struct { + Foo string + Bar string + Baz binary.HexBytes + Address crypto.Address + Indices []int + unexported int +} + +func TestReflectTagged_Keys(t *testing.T) { + rt, err := ReflectTags(&testTaggable{}) + require.NoError(t, err) + assert.Equal(t, []string{"Foo", "Bar", "Baz", "Address", "Indices"}, rt.Keys()) +} + +func TestReflectTagged_Get(t *testing.T) { + tt := testTaggable{ + Foo: "Thumbs", + Bar: "Numbed", + Baz: []byte{255, 255, 255}, + Address: crypto.Address{1, 2, 3}, + Indices: []int{5, 7, 9}, + } + rt, err := ReflectTags(&tt) + require.NoError(t, err) + + value, ok := rt.Get("Foo") + assert.True(t, ok) + assert.Equal(t, tt.Foo, value) + + value, ok = rt.Get("Bar") + assert.True(t, ok) + assert.Equal(t, tt.Bar, value) + + value, ok = rt.Get("Baz") + assert.True(t, ok) + assert.Equal(t, "FFFFFF", value) + + value, ok = rt.Get("Indices") + assert.True(t, ok) + assert.Equal(t, "5;7;9", value) + + value, ok = rt.Get("Address") + assert.True(t, ok) + assert.Equal(t, "0102030000000000000000000000000000000000", value) + + // Make sure we see updates through pointer + tt.Foo = "Plums" + value, ok = rt.Get("Foo") + assert.True(t, ok) + assert.Equal(t, tt.Foo, value) +} + +func TestReflectTagged_Len(t *testing.T) { + rt, err := ReflectTags(&testTaggable{}) + require.NoError(t, err) + assert.Equal(t, 5, rt.Len()) +} + +func TestExplicitFields(t *testing.T) { + tt := testTaggable{ + Foo: "Thumbs", + Bar: "Numbed", + Baz: []byte{255, 255, 255}, + Address: crypto.Address{1, 2, 3}, + } + rt, err := ReflectTags(&tt, "Foo", "Address") + require.NoError(t, err) + + value, ok := rt.Get("Foo") + assert.True(t, ok) + assert.Equal(t, tt.Foo, value) + + value, ok = rt.Get("Address") + assert.True(t, ok) + assert.Equal(t, "0102030000000000000000000000000000000000", value) + + _, ok = rt.Get("Bar") + assert.False(t, ok) + + _, ok = rt.Get("Barsss") + assert.False(t, ok) + + _, err = ReflectTags(&tt, "Foo", "Address", "Balloons") + require.Error(t, err) +} diff --git a/event/query/tags.go b/event/query/tags.go new file mode 100644 index 0000000000000000000000000000000000000000..d177b1a09e43ca16a0545bca85972b111c878999 --- /dev/null +++ b/event/query/tags.go @@ -0,0 +1,126 @@ +package query + +import ( + "fmt" + "strings" +) + +type Tagged interface { + Keys() []string + Get(key string) (value string, ok bool) + // Len returns the number of tags. + Len() int +} + +type TagMap map[string]interface{} + +func MapFromTagged(tagged Tagged) map[string]interface{} { + tags := make(map[string]interface{}) + for _, k := range tagged.Keys() { + v, ok := tagged.Get(k) + if ok { + tags[k] = v + } + } + return tags +} + +func (ts TagMap) Get(key string) (value string, ok bool) { + var vint interface{} + vint, ok = ts[key] + if !ok { + return + } + switch v := vint.(type) { + case string: + value = v + case fmt.Stringer: + value = v.String() + default: + value = fmt.Sprintf("%v", v) + } + return +} + +func (ts TagMap) Len() int { + return len(ts) +} + +func (ts TagMap) Map() map[string]interface{} { + return ts +} + +func (ts TagMap) Keys() []string { + keys := make([]string, 0, len(ts)) + for k := range ts { + keys = append(keys, k) + } + return keys +} + +type CombinedTags struct { + keys []string + ks map[string][]Tagged + concat bool +} + +func NewCombinedTags() *CombinedTags { + return &CombinedTags{ + ks: make(map[string][]Tagged), + } +} + +func MergeTags(tags ...Tagged) *CombinedTags { + ct := NewCombinedTags() + ct.AddTags(false, tags...) + return ct +} + +func ConcatTags(tags ...Tagged) *CombinedTags { + ct := NewCombinedTags() + ct.AddTags(true, tags...) + return ct +} + +// Adds each of tagsList to CombinedTags - choosing whether values for the same key should +// be concatenated or whether the first should value should stick +func (ct *CombinedTags) AddTags(concat bool, tagsList ...Tagged) { + for _, t := range tagsList { + for _, k := range t.Keys() { + if len(ct.ks[k]) == 0 { + ct.keys = append(ct.keys, k) + // Store reference to key-holder amongst Taggeds + ct.ks[k] = append(ct.ks[k], t) + } else if concat { + // Store additional tag reference only if concat, otherwise first key-holder wins + ct.ks[k] = append(ct.ks[k], t) + } + } + } +} + +func (ct *CombinedTags) Get(key string) (string, bool) { + ts := ct.ks[key] + if len(ts) == 0 { + return "", false + } + values := make([]string, 0, len(ts)) + for _, t := range ts { + value, ok := t.Get(key) + if ok { + values = append(values, value) + } + } + if len(values) == 0 { + return "", false + } + return strings.Join(values, MultipleValueTagSeparator), true +} + +func (ct *CombinedTags) Len() (length int) { + return len(ct.keys) +} + +func (ct *CombinedTags) Keys() []string { + return ct.keys +} diff --git a/event/tags.go b/event/tags.go deleted file mode 100644 index 759d035d734b6ee4987cd1952c3b63da47373f39..0000000000000000000000000000000000000000 --- a/event/tags.go +++ /dev/null @@ -1,87 +0,0 @@ -package event - -import ( - "fmt" - - "github.com/tendermint/tendermint/libs/pubsub" -) - -type Tags interface { - pubsub.TagMap - Keys() []string -} - -type TagMap map[string]interface{} - -func (ts TagMap) Get(key string) (value string, ok bool) { - var vint interface{} - vint, ok = ts[key] - if !ok { - return - } - switch v := vint.(type) { - case string: - value = v - case fmt.Stringer: - value = v.String() - default: - value = fmt.Sprintf("%v", v) - } - return -} - -func (ts TagMap) Len() int { - return len(ts) -} - -func (ts TagMap) Map() map[string]interface{} { - return ts -} - -func (ts TagMap) Keys() []string { - keys := make([]string, 0, len(ts)) - for k := range ts { - keys = append(keys, k) - } - return keys -} - -type CombinedTags []Tags - -func (ct CombinedTags) Get(key string) (value string, ok bool) { - for _, t := range ct { - value, ok = t.Get(key) - if ok { - return - } - } - return -} - -func (ct CombinedTags) Len() (length int) { - for _, t := range ct { - length += t.Len() - } - return length -} - -func (ct CombinedTags) Map() map[string]interface{} { - tags := make(map[string]interface{}) - for _, t := range ct { - for _, k := range t.Keys() { - v, ok := t.Get(k) - if ok { - tags[k] = v - } - } - } - return tags -} - -func (ct CombinedTags) Keys() []string { - var keys []string - for _, t := range ct { - keys = append(keys, t.Keys()...) - } - return keys -} diff --git a/execution/accounts.go b/execution/accounts.go index 8125ef0a10d9546c8165b9c98d65b04881e7f717..396f43302fd4fbc60f9fb57b1dfee0d5f064adb1 100644 --- a/execution/accounts.go +++ b/execution/accounts.go @@ -1,11 +1,10 @@ package execution import ( - "fmt" "sync" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys" burrow_sync "github.com/hyperledger/burrow/sync" @@ -25,6 +24,7 @@ type SigningAccount struct { } type SequentialSigningAccount struct { + Address crypto.Address accountLocker sync.Locker getter func() (*SigningAccount, error) } @@ -37,7 +37,11 @@ func NewAccounts(reader state.Reader, keyClient keys.KeyClient, mutexCount int) keyClient: keyClient, } } -func (accs *Accounts) SigningAccount(address crypto.Address, signer crypto.Signer) (*SigningAccount, error) { +func (accs *Accounts) SigningAccount(address crypto.Address) (*SigningAccount, error) { + signer, err := keys.AddressableSigner(accs.keyClient, address) + if err != nil { + return nil, err + } account, err := state.GetMutableAccount(accs, address) if err != nil { return nil, err @@ -60,50 +64,15 @@ func (accs *Accounts) SigningAccount(address crypto.Address, signer crypto.Signe } func (accs *Accounts) SequentialSigningAccount(address crypto.Address) (*SequentialSigningAccount, error) { - signer, err := keys.AddressableSigner(accs.keyClient, address) - if err != nil { - return nil, err - } return &SequentialSigningAccount{ + Address: address, accountLocker: accs.Mutex(address.Bytes()), getter: func() (*SigningAccount, error) { - return accs.SigningAccount(address, signer) - }, - }, nil -} - -func (accs *Accounts) SequentialSigningAccountFromPrivateKey(privateKeyBytes []byte) (*SequentialSigningAccount, error) { - if len(privateKeyBytes) != 64 { - return nil, fmt.Errorf("private key is not of the right length: %d\n", len(privateKeyBytes)) - } - privateAccount, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(privateKeyBytes) - if err != nil { - return nil, err - } - return &SequentialSigningAccount{ - accountLocker: accs.Mutex(privateAccount.Address().Bytes()), - getter: func() (*SigningAccount, error) { - return accs.SigningAccount(privateAccount.Address(), privateAccount) + return accs.SigningAccount(address) }, }, nil } -// Gets signing account from onr of private key or address - failing if both are provided -func (accs *Accounts) GetSequentialSigningAccount(address, privateKey []byte) (*SequentialSigningAccount, error) { - if len(address) > 0 { - if len(privateKey) > 0 { - return nil, fmt.Errorf("address and private key provided but only one or the other should be given") - } - address, err := crypto.AddressFromBytes(address) - if err != nil { - return nil, err - } - return accs.SequentialSigningAccount(address) - } - - return accs.SequentialSigningAccountFromPrivateKey(privateKey) -} - type UnlockFunc func() func (ssa *SequentialSigningAccount) Lock() (*SigningAccount, UnlockFunc, error) { diff --git a/execution/config.go b/execution/config.go index f90b6a02c529fcd5aa67fee1abf1011f725673d2..1f61d068f394dd1c7b8514b49b64fa72a099cc01 100644 --- a/execution/config.go +++ b/execution/config.go @@ -21,6 +21,14 @@ func DefaultExecutionConfig() *ExecutionConfig { return &ExecutionConfig{} } +type ExecutionOption func(*executor) + +func VMOptions(vmOptions ...func(*evm.VM)) func(*executor) { + return func(exe *executor) { + exe.vmOptions = vmOptions + } +} + func (ec *ExecutionConfig) ExecutionOptions() ([]ExecutionOption, error) { var exeOptions []ExecutionOption var vmOptions []func(*evm.VM) diff --git a/execution/errors/errors.go b/execution/errors/errors.go index ba15497f0212b37909f772f9b2f321a89ef08567..8e3bd2cc144312712983a4ddb2418dea055daace 100644 --- a/execution/errors/errors.go +++ b/execution/errors/errors.go @@ -1,9 +1,6 @@ package errors -import ( - "encoding/json" - "fmt" -) +import "fmt" type CodedError interface { error @@ -33,6 +30,8 @@ const ( ErrorCodePermissionDenied ErrorCodeNativeFunction ErrorCodeEventPublish + ErrorCodeInvalidString + ErrorCodeEventMapping ) func (c Code) ErrorCode() Code { @@ -77,6 +76,10 @@ func (c Code) Error() string { return "Native function error" case ErrorCodeEventPublish: return "Event publish error" + case ErrorCodeInvalidString: + return "Invalid string" + case ErrorCodeEventMapping: + return "Event mapping error" case ErrorCodeGeneric: return "Generic error" default: @@ -89,15 +92,13 @@ func NewCodedError(errorCode Code, exception string) *Exception { return nil } return &Exception{ - Code: &ErrorCode{ - Code: uint32(errorCode), - }, + Code: errorCode, Exception: exception, } } // Wraps any error as a Exception -func AsCodedError(err error) *Exception { +func AsException(err error) *Exception { if err == nil { return nil } @@ -115,11 +116,11 @@ func Wrap(err CodedError, message string) *Exception { return NewCodedError(err.ErrorCode(), message+": "+err.Error()) } -func Errorf(format string, a ...interface{}) CodedError { +func Errorf(format string, a ...interface{}) *Exception { return ErrorCodef(ErrorCodeGeneric, format, a...) } -func ErrorCodef(errorCode Code, format string, a ...interface{}) CodedError { +func ErrorCodef(errorCode Code, format string, a ...interface{}) *Exception { return NewCodedError(errorCode, fmt.Sprintf(format, a...)) } @@ -132,26 +133,16 @@ func (e *Exception) AsError() error { } func (e *Exception) ErrorCode() Code { - return Code(e.GetCode().Code) + return e.Code +} + +func (e *Exception) String() string { + return e.Error() } func (e *Exception) Error() string { if e == nil { return "" } - return fmt.Sprintf("Error %v: %s", e.Code.Code, e.Exception) -} - -func NewErrorCode(code Code) *ErrorCode { - return &ErrorCode{ - Code: uint32(code), - } -} - -func (e ErrorCode) MarshalJSON() ([]byte, error) { - return json.Marshal(e.Code) -} - -func (e *ErrorCode) UnmarshalJSON(bs []byte) error { - return json.Unmarshal(bs, &(e.Code)) + return fmt.Sprintf("Error %v: %s", e.Code, e.Exception) } diff --git a/execution/errors/errors.pb.go b/execution/errors/errors.pb.go index 14d297a6c41cda1f905353a1f056f72b5fab3895..859a4c2044ef022da6a0ab341ab399fb8ef46e9f 100644 --- a/execution/errors/errors.pb.go +++ b/execution/errors/errors.pb.go @@ -1,14 +1,28 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/hyperledger/burrow/execution/errors/errors.proto +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: errors.proto +/* + Package errors is a generated protocol buffer package. + + It is generated from these files: + errors.proto + + It has these top-level messages: + Exception +*/ package errors -import proto "github.com/golang/protobuf/proto" +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" import fmt "fmt" import math "math" +import _ "github.com/gogo/protobuf/gogoproto" + +import io "io" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal +var _ = golang_proto.Marshal var _ = fmt.Errorf var _ = math.Inf @@ -16,46 +30,22 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package type Exception struct { - Code *ErrorCode `protobuf:"bytes,1,opt,name=Code,proto3" json:"Code,omitempty"` - Exception string `protobuf:"bytes,2,opt,name=Exception,proto3" json:"Exception,omitempty"` - BS []byte `protobuf:"bytes,3,opt,name=BS,proto3" json:"BS,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Exception) Reset() { *m = Exception{} } -func (m *Exception) String() string { return proto.CompactTextString(m) } -func (*Exception) ProtoMessage() {} -func (*Exception) Descriptor() ([]byte, []int) { - return fileDescriptor_errors_e7e9443965b28d5d, []int{0} -} -func (m *Exception) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Exception.Unmarshal(m, b) -} -func (m *Exception) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Exception.Marshal(b, m, deterministic) -} -func (dst *Exception) XXX_Merge(src proto.Message) { - xxx_messageInfo_Exception.Merge(dst, src) -} -func (m *Exception) XXX_Size() int { - return xxx_messageInfo_Exception.Size(m) -} -func (m *Exception) XXX_DiscardUnknown() { - xxx_messageInfo_Exception.DiscardUnknown(m) + Code Code `protobuf:"varint,1,opt,name=Code,proto3,casttype=Code" json:"Code,omitempty"` + Exception string `protobuf:"bytes,2,opt,name=Exception,proto3" json:"Exception,omitempty"` } -var xxx_messageInfo_Exception proto.InternalMessageInfo +func (m *Exception) Reset() { *m = Exception{} } +func (*Exception) ProtoMessage() {} +func (*Exception) Descriptor() ([]byte, []int) { return fileDescriptorErrors, []int{0} } -func (m *Exception) GetCode() *ErrorCode { +func (m *Exception) GetCode() Code { if m != nil { return m.Code } - return nil + return 0 } func (m *Exception) GetException() string { @@ -65,71 +55,295 @@ func (m *Exception) GetException() string { return "" } -func (m *Exception) GetBS() []byte { - if m != nil { - return m.BS +func (*Exception) XXX_MessageName() string { + return "errors.Exception" +} +func init() { + proto.RegisterType((*Exception)(nil), "errors.Exception") + golang_proto.RegisterType((*Exception)(nil), "errors.Exception") +} +func (m *Exception) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err } - return nil + return dAtA[:n], nil } -type ErrorCode struct { - Code uint32 `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` +func (m *Exception) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Code != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintErrors(dAtA, i, uint64(m.Code)) + } + if len(m.Exception) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintErrors(dAtA, i, uint64(len(m.Exception))) + i += copy(dAtA[i:], m.Exception) + } + return i, nil } -func (m *ErrorCode) Reset() { *m = ErrorCode{} } -func (m *ErrorCode) String() string { return proto.CompactTextString(m) } -func (*ErrorCode) ProtoMessage() {} -func (*ErrorCode) Descriptor() ([]byte, []int) { - return fileDescriptor_errors_e7e9443965b28d5d, []int{1} -} -func (m *ErrorCode) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ErrorCode.Unmarshal(m, b) -} -func (m *ErrorCode) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ErrorCode.Marshal(b, m, deterministic) +func encodeVarintErrors(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 } -func (dst *ErrorCode) XXX_Merge(src proto.Message) { - xxx_messageInfo_ErrorCode.Merge(dst, src) +func (m *Exception) Size() (n int) { + var l int + _ = l + if m.Code != 0 { + n += 1 + sovErrors(uint64(m.Code)) + } + l = len(m.Exception) + if l > 0 { + n += 1 + l + sovErrors(uint64(l)) + } + return n } -func (m *ErrorCode) XXX_Size() int { - return xxx_messageInfo_ErrorCode.Size(m) + +func sovErrors(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n } -func (m *ErrorCode) XXX_DiscardUnknown() { - xxx_messageInfo_ErrorCode.DiscardUnknown(m) +func sozErrors(x uint64) (n int) { + return sovErrors(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *Exception) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrors + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Exception: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Exception: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrors + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= (Code(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Exception", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowErrors + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthErrors + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Exception = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipErrors(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthErrors + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -var xxx_messageInfo_ErrorCode proto.InternalMessageInfo - -func (m *ErrorCode) GetCode() uint32 { - if m != nil { - return m.Code + if iNdEx > l { + return io.ErrUnexpectedEOF } - return 0 + return nil } - -func init() { - proto.RegisterType((*Exception)(nil), "errors.Exception") - proto.RegisterType((*ErrorCode)(nil), "errors.ErrorCode") +func skipErrors(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrors + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrors + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrors + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthErrors + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowErrors + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipErrors(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") } -func init() { - proto.RegisterFile("github.com/hyperledger/burrow/execution/errors/errors.proto", fileDescriptor_errors_e7e9443965b28d5d) -} +var ( + ErrInvalidLengthErrors = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowErrors = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("errors.proto", fileDescriptorErrors) } +func init() { golang_proto.RegisterFile("errors.proto", fileDescriptorErrors) } -var fileDescriptor_errors_e7e9443965b28d5d = []byte{ - // 168 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4e, 0xcf, 0x2c, 0xc9, - 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0xa8, 0x2c, 0x48, 0x2d, 0xca, 0x49, 0x4d, 0x49, - 0x4f, 0x2d, 0xd2, 0x4f, 0x2a, 0x2d, 0x2a, 0xca, 0x2f, 0xd7, 0x4f, 0xad, 0x48, 0x4d, 0x2e, 0x2d, - 0xc9, 0xcc, 0xcf, 0xd3, 0x4f, 0x2d, 0x2a, 0xca, 0x2f, 0x2a, 0x86, 0x52, 0x7a, 0x05, 0x45, 0xf9, - 0x25, 0xf9, 0x42, 0x6c, 0x10, 0x9e, 0x52, 0x02, 0x17, 0xa7, 0x6b, 0x45, 0x72, 0x6a, 0x01, 0x48, - 0xa1, 0x90, 0x2a, 0x17, 0x8b, 0x73, 0x7e, 0x4a, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xb7, 0x91, - 0xa0, 0x1e, 0x54, 0x87, 0x2b, 0x88, 0x02, 0x49, 0x04, 0x81, 0xa5, 0x85, 0x64, 0x90, 0xf4, 0x48, - 0x30, 0x29, 0x30, 0x6a, 0x70, 0x06, 0x21, 0x19, 0xc2, 0xc7, 0xc5, 0xe4, 0x14, 0x2c, 0xc1, 0xac, - 0xc0, 0xa8, 0xc1, 0x13, 0xc4, 0xe4, 0x14, 0xac, 0x24, 0xcf, 0xc5, 0x09, 0x37, 0x40, 0x48, 0x08, - 0xc9, 0x06, 0x5e, 0x88, 0x71, 0x49, 0x6c, 0x60, 0x17, 0x19, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, - 0x20, 0x37, 0xb1, 0xd9, 0xd0, 0x00, 0x00, 0x00, +var fileDescriptorErrors = []byte{ + // 190 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0x2d, 0x2a, 0xca, + 0x2f, 0x2a, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0xa4, 0x74, 0xd3, 0x33, + 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xd2, + 0x49, 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xb4, 0x29, 0xf9, 0x72, 0x71, 0xba, 0x56, + 0x24, 0xa7, 0x16, 0x94, 0x64, 0xe6, 0xe7, 0x09, 0xc9, 0x70, 0xb1, 0x38, 0xe7, 0xa7, 0xa4, 0x4a, + 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x3a, 0x71, 0xfc, 0xba, 0x27, 0x0f, 0xe6, 0x07, 0x81, 0x49, 0x21, + 0x19, 0x24, 0xa5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x2b, 0x96, 0x19, 0x0b, + 0xe4, 0x19, 0x9c, 0x5c, 0x4e, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, + 0xc6, 0x03, 0x8f, 0xe5, 0x18, 0x4f, 0x3c, 0x96, 0x63, 0x8c, 0xd2, 0x43, 0x72, 0x53, 0x46, 0x65, + 0x41, 0x6a, 0x51, 0x4e, 0x6a, 0x4a, 0x7a, 0x6a, 0x91, 0x7e, 0x52, 0x69, 0x51, 0x51, 0x7e, 0xb9, + 0x7e, 0x6a, 0x45, 0x6a, 0x72, 0x29, 0xc8, 0x10, 0x7d, 0x88, 0x1f, 0x92, 0xd8, 0xc0, 0x6e, 0x33, + 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x33, 0x9a, 0x19, 0x05, 0xe2, 0x00, 0x00, 0x00, } diff --git a/execution/errors/errors.proto b/execution/errors/errors.proto deleted file mode 100644 index 2620fdd403e97fd1d7037ab49be92bfbb4e94bac..0000000000000000000000000000000000000000 --- a/execution/errors/errors.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -package errors; - -message Exception { - ErrorCode Code = 1; - string Exception = 2; - bytes BS = 3; -} - -message ErrorCode { - uint32 Code = 1; -} diff --git a/execution/errors/errors_test.go b/execution/errors/errors_test.go index 3b85c4adbd71f64b1c1fcd82460dc3e428c41ed9..2a4a0a37bfda11113edfeb08417a37cf497c0e25 100644 --- a/execution/errors/errors_test.go +++ b/execution/errors/errors_test.go @@ -4,39 +4,18 @@ import ( "encoding/json" "testing" - "fmt" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/tendermint/abci/types" ) func TestErrorCode_MarshalJSON(t *testing.T) { - ec := NewErrorCode(ErrorCodeDataStackOverflow) + ec := NewCodedError(ErrorCodeDataStackOverflow, "arrg") bs, err := json.Marshal(ec) require.NoError(t, err) - ecOut := new(ErrorCode) + ecOut := new(Exception) err = json.Unmarshal(bs, ecOut) require.NoError(t, err) assert.Equal(t, ec, ecOut) } - -func TestException_MarshalJSON(t *testing.T) { - ex := NewCodedError(ErrorCodeExecutionReverted, "Oh noes we reverted") - ex.BS = []byte{2, 3, 4, 5} - bs, err := json.Marshal(ex) - require.NoError(t, err) - fmt.Println(string(bs)) - exOut := new(Exception) - err = json.Unmarshal(bs, exOut) - require.NoError(t, err) - - bb := types.RequestBeginBlock{ - Hash: []byte{2, 3, 4}, - } - bs, err = json.Marshal(bb) - require.NoError(t, err) - fmt.Println(string(bs)) -} diff --git a/execution/errors/vm.go b/execution/errors/vm.go index f2d40983fd03377db7064a8716c3c2cc1bff0c6c..7e97d37504205e5d509f7f4262932f3a48c98046 100644 --- a/execution/errors/vm.go +++ b/execution/errors/vm.go @@ -5,11 +5,11 @@ import ( "fmt" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" ) type PermissionDenied struct { - Perm types.PermFlag + Perm permission.PermFlag } func (err PermissionDenied) ErrorCode() Code { diff --git a/execution/events/call.go b/execution/events/call.go deleted file mode 100644 index 23e047248756c6f4a8362af08b5dbf8bce36cb0b..0000000000000000000000000000000000000000 --- a/execution/events/call.go +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package events - -import ( - "context" - "fmt" - - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/execution/errors" - "github.com/hyperledger/burrow/txs" - hex "github.com/tmthrgd/go-hex" -) - -// Functions to generate eventId strings - -func EventStringAccountCall(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) } - -//---------------------------------------- - -// EventDataCall fires when we call a contract, and when a contract calls another contract -type EventDataCall struct { - CallData *CallData - Origin crypto.Address - StackDepth uint64 - Return binary.HexBytes - Exception *errors.Exception -} - -type CallData struct { - Caller crypto.Address - Callee crypto.Address - Data binary.HexBytes - Value uint64 - Gas uint64 -} - -// Publish/Subscribe -func PublishAccountCall(publisher event.Publisher, tx *txs.Tx, height uint64, call *EventDataCall) error { - eventID := EventStringAccountCall(call.CallData.Callee) - ev := &Event{ - Header: &Header{ - TxType: tx.Type(), - TxHash: tx.Hash(), - EventType: TypeCall, - EventID: eventID, - Height: height, - }, - Call: call, - } - return publisher.Publish(context.Background(), ev, ev.Tags()) -} - -// Subscribe to account call event - if TxHash is provided listens for a specifc Tx otherwise captures all, if -// stackDepth is greater than or equal to 0 captures calls at a specific stack depth (useful for capturing the return -// of the root call over recursive calls -func SubscribeAccountCall(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address, - txHash []byte, stackDepth int, ch chan<- *EventDataCall) error { - - query := event.QueryForEventID(EventStringAccountCall(address)) - - if len(txHash) > 0 { - query = query.AndEquals(event.TxHashKey, hex.EncodeUpperToString(txHash)) - } - - if stackDepth >= 0 { - query = query.AndEquals(event.StackDepthKey, stackDepth) - } - - return event.SubscribeCallback(ctx, subscribable, subscriber, query, func(message interface{}) (stop bool) { - ev, ok := message.(*Event) - if ok && ev.Call != nil { - ch <- ev.Call - } - return - }) -} - -// Tags - -var callTagKeys = []string{ - event.CalleeKey, - event.CallerKey, - event.ValueKey, - event.GasKey, - event.StackDepthKey, - event.OriginKey, - event.ExceptionKey, -} - -// Implements Tags for events -func (call *EventDataCall) Get(key string) (string, bool) { - var value interface{} - switch key { - case event.CalleeKey: - value = call.CallData.Callee - case event.CallerKey: - value = call.CallData.Caller - case event.ValueKey: - value = call.CallData.Value - case event.GasKey: - value = call.CallData.Gas - case event.StackDepthKey: - value = call.StackDepth - case event.OriginKey: - value = call.Origin - case event.ExceptionKey: - value = call.Exception - default: - return "", false - } - return query.StringFromValue(value), true -} - -func (call *EventDataCall) Len() int { - return len(callTagKeys) -} - -func (call *EventDataCall) Keys() []string { - return callTagKeys -} - -func (call *EventDataCall) Tags(tags map[string]interface{}) map[string]interface{} { - tags[event.CalleeKey] = call.CallData.Callee - tags[event.CallerKey] = call.CallData.Caller - tags[event.ValueKey] = call.CallData.Value - tags[event.GasKey] = call.CallData.Gas - tags[event.StackDepthKey] = call.StackDepth - tags[event.OriginKey] = call.Origin - if call.Exception != nil { - tags[event.ExceptionKey] = call.Exception - } - return tags -} diff --git a/execution/events/event.go b/execution/events/event.go deleted file mode 100644 index 508c96776e19b5e360c61830ffa2ccae90ac8525..0000000000000000000000000000000000000000 --- a/execution/events/event.go +++ /dev/null @@ -1,121 +0,0 @@ -package events - -import ( - "fmt" - - "reflect" - - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/txs" -) - -var cdc = txs.NewAminoCodec() - -var eventMessageTag = event.TagMap{event.MessageTypeKey: reflect.TypeOf(&Event{}).String()} - -type Provider interface { - // Get events between startKey (inclusive) and endKey (exclusive) - i.e. the half open interval [start, end) - GetEvents(startKey, endKey Key, consumer func(*Event) (stop bool)) (stopped bool, err error) - LatestEventKey() Key -} - -type Event struct { - Header *Header - Call *EventDataCall `json:",omitempty"` - Log *EventDataLog `json:",omitempty"` - Tx *EventDataTx `json:",omitempty"` - tags event.Tags -} - -func DecodeEvent(bs []byte) (*Event, error) { - ev := new(Event) - err := cdc.UnmarshalBinary(bs, ev) - if err != nil { - return nil, err - } - return ev, nil -} - -func (ev *Event) Key() Key { - return ev.Header.Key() -} - -// Performs a shallow copy of Event -func (ev *Event) Copy() *Event { - h := *ev.Header - evCopy := Event{ - Header: &h, - } - if ev.Tx != nil { - tx := *ev.Tx - evCopy.Tx = &tx - } - if ev.Call != nil { - call := *ev.Call - evCopy.Call = &call - } - if ev.Log != nil { - log := *ev.Log - evCopy.Log = &log - } - return &evCopy -} - -func (ev *Event) Encode() ([]byte, error) { - return cdc.MarshalBinary(ev) -} - -func (ev *Event) Tags() event.Tags { - if ev.tags == nil { - ev.tags = event.CombinedTags{ - ev.Header, - eventMessageTag, - ev.Tx, - ev.Call, - ev.Log, - } - } - return ev.tags -} - -func (ev *Event) Get(key string) (value string, ok bool) { - return ev.Tags().Get(key) -} - -func (ev *Event) Keys() []string { - return ev.Tags().Keys() -} - -func (ev *Event) Len() int { - return ev.Tags().Len() -} - -// event.Cache will provide an index through this methods of Indexable -func (ev *Event) ProvideIndex(index uint64) { - ev.Header.Index = index -} - -func (ev *Event) String() string { - return fmt.Sprintf("%v", ev.Header) -} - -func (ev *Event) GetTx() *EventDataTx { - if ev == nil { - return nil - } - return ev.Tx -} - -func (ev *Event) GetCall() *EventDataCall { - if ev == nil { - return nil - } - return ev.Call -} - -func (ev *Event) GetLog() *EventDataLog { - if ev == nil { - return nil - } - return ev.Log -} diff --git a/execution/events/event_test.go b/execution/events/event_test.go deleted file mode 100644 index 4831edfe2760a4fcc5d2d97b2471ddfbf5bf6987..0000000000000000000000000000000000000000 --- a/execution/events/event_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package events - -import ( - "testing" - - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/event/query" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tmthrgd/go-hex" -) - -func TestHeader_Key(t *testing.T) { - h := &Header{ - EventID: "Foos", - Height: 2345345232, - Index: 34, - } - key := h.Key() - keyString := hex.EncodeUpperToString(key) - assert.Equal(t, "000000008BCB20D00000000000000022", keyString) - assert.Len(t, keyString, 32, "should be 16 bytes") - assert.Equal(t, h.Height, key.Height()) - assert.Equal(t, h.Index, key.Index()) -} - -func TestKey_IsSuccessorOf(t *testing.T) { - assert.True(t, NewKey(1, 0).IsSuccessorOf(NewKey(0, 1))) - assert.True(t, NewKey(100, 24).IsSuccessorOf(NewKey(100, 23))) - assert.False(t, NewKey(100, 23).IsSuccessorOf(NewKey(100, 25))) - assert.False(t, NewKey(1, 1).IsSuccessorOf(NewKey(0, 25))) - assert.True(t, NewKey(3, 0).IsSuccessorOf(NewKey(2, 0))) -} - -func TestEventTagQueries(t *testing.T) { - addressHex := "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" - address, err := crypto.AddressFromHexString(addressHex) - require.NoError(t, err) - ev := &Event{ - Header: &Header{ - EventType: TypeLog, - EventID: "foo/bar", - TxHash: []byte{2, 3, 4}, - Height: 34, - Index: 2, - }, - Log: &EventDataLog{ - Address: address, - Topics: []binary.Word256{binary.RightPadWord256([]byte("marmot"))}, - }, - } - - qb := query.NewBuilder().AndEquals(event.EventTypeKey, TypeLog.String()) - qry, err := qb.Query() - require.NoError(t, err) - assert.True(t, qry.Matches(ev)) - - qb = qb.AndContains(event.EventIDKey, "bar") - qry, err = qb.Query() - require.NoError(t, err) - assert.True(t, qry.Matches(ev)) - - qb = qb.AndEquals(event.TxHashKey, hex.EncodeUpperToString(ev.Header.TxHash)) - qry, err = qb.Query() - require.NoError(t, err) - assert.True(t, qry.Matches(ev)) - - qb = qb.AndGreaterThanOrEqual(event.HeightKey, ev.Header.Height) - qry, err = qb.Query() - require.NoError(t, err) - assert.True(t, qry.Matches(ev)) - - qb = qb.AndStrictlyLessThan(event.IndexKey, ev.Header.Index+1) - qry, err = qb.Query() - require.NoError(t, err) - assert.True(t, qry.Matches(ev)) - - qb = qb.AndEquals(event.AddressKey, addressHex) - qry, err = qb.Query() - require.NoError(t, err) - assert.True(t, qry.Matches(ev)) - - qb = qb.AndEquals(event.LogNTextKey(0), "marmot") - qry, err = qb.Query() - require.NoError(t, err) - assert.True(t, qry.Matches(ev)) - - t.Logf("Query: %v", qry) - t.Logf("Keys: %v", ev.Keys()) -} diff --git a/execution/events/header.go b/execution/events/header.go deleted file mode 100644 index d5b09749b3c3bbbe3d57b1e6ea3f8800c81d0b5b..0000000000000000000000000000000000000000 --- a/execution/events/header.go +++ /dev/null @@ -1,76 +0,0 @@ -package events - -import ( - "fmt" - - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/txs/payload" -) - -type Header struct { - TxType payload.Type - TxHash binary.HexBytes - EventType Type - EventID string - Height uint64 - Index uint64 -} - -var headerTagKeys = []string{ - event.TxTypeKey, - event.TxHashKey, - event.EventTypeKey, - event.EventIDKey, - event.HeightKey, - event.IndexKey, -} - -// Implements Tags for events -func (h *Header) Get(key string) (value string, ok bool) { - var v interface{} - switch key { - case event.TxTypeKey: - v = h.TxType - case event.TxHashKey: - v = h.TxHash - case event.EventTypeKey: - v = h.EventType - case event.EventIDKey: - v = h.EventID - case event.HeightKey: - v = h.Height - case event.IndexKey: - v = h.Index - default: - return "", false - } - return query.StringFromValue(v), true -} - -func (h *Header) Len() int { - return len(headerTagKeys) -} - -func (h *Header) Map() map[string]interface{} { - tags := make(map[string]interface{}) - for _, key := range headerTagKeys { - tags[key], _ = h.Get(key) - } - return tags -} - -func (h *Header) Keys() []string { - return headerTagKeys -} - -// Returns a lexicographically sortable key encoding the height and index of this event -func (h *Header) Key() Key { - return NewKey(h.Height, h.Index) -} - -func (h *Header) String() string { - return fmt.Sprintf("Header{Tx{%v}: %v; Event{%v}: %v; Height: %v; Index: %v}", - h.TxType, h.TxHash, h.EventType, h.EventID, h.Height, h.Index) -} diff --git a/execution/events/key.go b/execution/events/key.go deleted file mode 100644 index 52371518fb6c5ac7a6a3f4cb53fa32f9289f90b0..0000000000000000000000000000000000000000 --- a/execution/events/key.go +++ /dev/null @@ -1,57 +0,0 @@ -package events - -import ( - "bytes" - "fmt" - - "github.com/hyperledger/burrow/binary" -) - -type Key []byte - -func NewKey(height, index uint64) Key { - k := make(Key, 16) - // Will order first by height then by index so events from the same block will be consecutive - binary.PutUint64BE(k[:8], height) - binary.PutUint64BE(k[8:], index) - return k -} - -// -1 if k < k2 -// 0 if k == k2 -// 1 if k > k2 -func (k Key) Compare(k2 Key) int { - return bytes.Compare(k, k2) -} - -// Returns true iff k is a valid successor key to p; -// iff (the height is the same and the index is one greater) or (the height is greater and the index is zero) or (p -// is uninitialised) -func (k Key) IsSuccessorOf(p Key) bool { - if len(p) == 0 { - return true - } - ph, kh := p.Height(), k.Height() - pi, ki := p.Index(), k.Index() - return ph == kh && pi+1 == ki || ph < kh && ki == 0 -} - -func (k Key) IncHeight() Key { - return NewKey(k.Height()+1, k.Index()) -} - -func (k Key) Bytes() []byte { - return k -} - -func (k Key) Height() uint64 { - return binary.GetUint64BE(k[:8]) -} - -func (k Key) Index() uint64 { - return binary.GetUint64BE(k[8:]) -} - -func (k Key) String() string { - return fmt.Sprintf("Key{Height: %v; Index: %v}", k.Height(), k.Index()) -} diff --git a/execution/events/pbevents/events.go b/execution/events/pbevents/events.go deleted file mode 100644 index 99bc841b766b8df191a7c8fe881e0431a81d5be2..0000000000000000000000000000000000000000 --- a/execution/events/pbevents/events.go +++ /dev/null @@ -1,168 +0,0 @@ -package pbevents - -import ( - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/txs/payload" -) - -// this mostly contains tedious mapping between protobuf and our domain objects, but it may be worth -// the pain to avoid complexity and edge cases using gogoproto or other techniques. - -func GetEventDataCall(edt *events.EventDataCall) *EventDataCall { - return &EventDataCall{ - Origin: edt.Origin.Bytes(), - CallData: GetCallData(edt.CallData), - StackDepth: edt.StackDepth, - Return: edt.Return, - Exception: edt.Exception, - } -} - -func GetCallData(cd *events.CallData) *CallData { - return &CallData{ - Caller: cd.Caller.Bytes(), - Callee: cd.Callee.Bytes(), - Data: cd.Data, - Gas: cd.Gas, - } -} - -func GetExecutionEvent(event *events.Event) *ExecutionEvent { - return &ExecutionEvent{ - Header: GetEventHeader(event.Header), - EventData: GetEventData(event), - } -} - -func GetEventHeader(header *events.Header) *EventHeader { - return &EventHeader{ - TxType: header.TxType.String(), - TxHash: header.TxHash, - EventType: header.EventType.String(), - EventID: header.EventID, - Height: header.Height, - Index: header.Index, - } -} - -func GetEventData(ev *events.Event) isExecutionEvent_EventData { - if ev.Call != nil { - return &ExecutionEvent_EventDataCall{ - EventDataCall: &EventDataCall{ - CallData: GetCallData(ev.Call.CallData), - Origin: ev.Call.Origin.Bytes(), - StackDepth: ev.Call.StackDepth, - Return: ev.Call.Return, - Exception: ev.Call.Exception, - }, - } - } - - if ev.Log != nil { - return &ExecutionEvent_EventDataLog{ - EventDataLog: &EventDataLog{ - Address: ev.Log.Address.Bytes(), - Data: ev.Log.Data, - Topics: GetTopic(ev.Log.Topics), - }, - } - } - - if ev.Tx != nil { - return &ExecutionEvent_EventDataTx{ - EventDataTx: &EventDataTx{ - Return: ev.Tx.Return, - Exception: ev.Tx.Exception, - }, - } - } - - return nil -} - -func GetTopic(topics []binary.Word256) [][]byte { - topicBytes := make([][]byte, len(topics)) - for i, t := range topics { - topicBytes[i] = t.Bytes() - } - return topicBytes -} - -func (ee *ExecutionEvent) Event() *events.Event { - return &events.Event{ - Header: ee.GetHeader().Header(), - Tx: ee.GetEventDataTx().Tx(), - Log: ee.GetEventDataLog().Log(ee.Header.Height), - Call: ee.GetEventDataCall().Call(ee.Header.TxHash), - } -} - -func (ee *ExecutionEvent) Key() events.Key { - return ee.Header.Key() -} - -func (h *EventHeader) Key() events.Key { - return events.NewKey(h.Height, h.Index) -} - -func (h *EventHeader) Header() *events.Header { - return &events.Header{ - TxType: payload.TxTypeFromString(h.TxType), - TxHash: h.TxHash, - EventType: events.EventTypeFromString(h.EventType), - EventID: h.EventID, - Height: h.Height, - Index: h.Index, - } -} - -func (tx *EventDataTx) Tx() *events.EventDataTx { - if tx == nil { - return nil - } - return &events.EventDataTx{ - Return: tx.Return, - Exception: tx.Exception, - } -} - -func (log *EventDataLog) Log(height uint64) *events.EventDataLog { - if log == nil { - return nil - } - topicWords := make([]binary.Word256, len(log.Topics)) - for i, bs := range log.Topics { - topicWords[i] = binary.LeftPadWord256(bs) - } - return &events.EventDataLog{ - Height: height, - Topics: topicWords, - Address: crypto.MustAddressFromBytes(log.Address), - Data: log.Data, - } -} - -func (call *EventDataCall) Call(txHash []byte) *events.EventDataCall { - if call == nil { - return nil - } - return &events.EventDataCall{ - Return: call.Return, - CallData: call.CallData.CallData(), - Origin: crypto.MustAddressFromBytes(call.Origin), - StackDepth: call.StackDepth, - Exception: call.Exception, - } -} - -func (cd *CallData) CallData() *events.CallData { - return &events.CallData{ - Caller: crypto.MustAddressFromBytes(cd.Caller), - Callee: crypto.MustAddressFromBytes(cd.Callee), - Value: cd.Value, - Gas: cd.Gas, - Data: cd.Data, - } -} diff --git a/execution/events/pbevents/events.pb.go b/execution/events/pbevents/events.pb.go deleted file mode 100644 index 132817582cfcda6667e5e75c5fc750bf1b565a4a..0000000000000000000000000000000000000000 --- a/execution/events/pbevents/events.pb.go +++ /dev/null @@ -1,1403 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/hyperledger/burrow/execution/events/pbevents/events.proto - -package pbevents // import "github.com/hyperledger/burrow/execution/events/pbevents" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import errors "github.com/hyperledger/burrow/execution/errors" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type Bound_BoundType int32 - -const ( - // Index is absolute index of object in collection - Bound_ABSOLUTE Bound_BoundType = 0 - // Index is an offset relative to another bound determined by context - Bound_RELATIVE Bound_BoundType = 1 - // The first block - Bound_FIRST Bound_BoundType = 2 - // Ignore provided index and evaluate to latest index - Bound_LATEST Bound_BoundType = 3 - // Ignore provided index and stream new objects as they are generated - Bound_STREAM Bound_BoundType = 4 -) - -var Bound_BoundType_name = map[int32]string{ - 0: "ABSOLUTE", - 1: "RELATIVE", - 2: "FIRST", - 3: "LATEST", - 4: "STREAM", -} -var Bound_BoundType_value = map[string]int32{ - "ABSOLUTE": 0, - "RELATIVE": 1, - "FIRST": 2, - "LATEST": 3, - "STREAM": 4, -} - -func (x Bound_BoundType) String() string { - return proto.EnumName(Bound_BoundType_name, int32(x)) -} -func (Bound_BoundType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{7, 0} -} - -// Params -type EventIdParam struct { - EventId string `protobuf:"bytes,1,opt,name=eventId,proto3" json:"eventId,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventIdParam) Reset() { *m = EventIdParam{} } -func (m *EventIdParam) String() string { return proto.CompactTextString(m) } -func (*EventIdParam) ProtoMessage() {} -func (*EventIdParam) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{0} -} -func (m *EventIdParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventIdParam.Unmarshal(m, b) -} -func (m *EventIdParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventIdParam.Marshal(b, m, deterministic) -} -func (dst *EventIdParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventIdParam.Merge(dst, src) -} -func (m *EventIdParam) XXX_Size() int { - return xxx_messageInfo_EventIdParam.Size(m) -} -func (m *EventIdParam) XXX_DiscardUnknown() { - xxx_messageInfo_EventIdParam.DiscardUnknown(m) -} - -var xxx_messageInfo_EventIdParam proto.InternalMessageInfo - -func (m *EventIdParam) GetEventId() string { - if m != nil { - return m.EventId - } - return "" -} - -type SubIdParam struct { - SubId string `protobuf:"bytes,1,opt,name=subId,proto3" json:"subId,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SubIdParam) Reset() { *m = SubIdParam{} } -func (m *SubIdParam) String() string { return proto.CompactTextString(m) } -func (*SubIdParam) ProtoMessage() {} -func (*SubIdParam) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{1} -} -func (m *SubIdParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SubIdParam.Unmarshal(m, b) -} -func (m *SubIdParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SubIdParam.Marshal(b, m, deterministic) -} -func (dst *SubIdParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_SubIdParam.Merge(dst, src) -} -func (m *SubIdParam) XXX_Size() int { - return xxx_messageInfo_SubIdParam.Size(m) -} -func (m *SubIdParam) XXX_DiscardUnknown() { - xxx_messageInfo_SubIdParam.DiscardUnknown(m) -} - -var xxx_messageInfo_SubIdParam proto.InternalMessageInfo - -func (m *SubIdParam) GetSubId() string { - if m != nil { - return m.SubId - } - return "" -} - -// Results -type EventUnSub struct { - Result bool `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventUnSub) Reset() { *m = EventUnSub{} } -func (m *EventUnSub) String() string { return proto.CompactTextString(m) } -func (*EventUnSub) ProtoMessage() {} -func (*EventUnSub) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{2} -} -func (m *EventUnSub) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventUnSub.Unmarshal(m, b) -} -func (m *EventUnSub) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventUnSub.Marshal(b, m, deterministic) -} -func (dst *EventUnSub) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventUnSub.Merge(dst, src) -} -func (m *EventUnSub) XXX_Size() int { - return xxx_messageInfo_EventUnSub.Size(m) -} -func (m *EventUnSub) XXX_DiscardUnknown() { - xxx_messageInfo_EventUnSub.DiscardUnknown(m) -} - -var xxx_messageInfo_EventUnSub proto.InternalMessageInfo - -func (m *EventUnSub) GetResult() bool { - if m != nil { - return m.Result - } - return false -} - -type PollResponse struct { - Events []*Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PollResponse) Reset() { *m = PollResponse{} } -func (m *PollResponse) String() string { return proto.CompactTextString(m) } -func (*PollResponse) ProtoMessage() {} -func (*PollResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{3} -} -func (m *PollResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PollResponse.Unmarshal(m, b) -} -func (m *PollResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PollResponse.Marshal(b, m, deterministic) -} -func (dst *PollResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PollResponse.Merge(dst, src) -} -func (m *PollResponse) XXX_Size() int { - return xxx_messageInfo_PollResponse.Size(m) -} -func (m *PollResponse) XXX_DiscardUnknown() { - xxx_messageInfo_PollResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_PollResponse proto.InternalMessageInfo - -func (m *PollResponse) GetEvents() []*Event { - if m != nil { - return m.Events - } - return nil -} - -type Event struct { - Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` - // Types that are valid to be assigned to Event: - // *Event_ExecutionEvent - // *Event_TendermintEventJSON - Event isEvent_Event `protobuf_oneof:"Event"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Event) Reset() { *m = Event{} } -func (m *Event) String() string { return proto.CompactTextString(m) } -func (*Event) ProtoMessage() {} -func (*Event) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{4} -} -func (m *Event) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Event.Unmarshal(m, b) -} -func (m *Event) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Event.Marshal(b, m, deterministic) -} -func (dst *Event) XXX_Merge(src proto.Message) { - xxx_messageInfo_Event.Merge(dst, src) -} -func (m *Event) XXX_Size() int { - return xxx_messageInfo_Event.Size(m) -} -func (m *Event) XXX_DiscardUnknown() { - xxx_messageInfo_Event.DiscardUnknown(m) -} - -var xxx_messageInfo_Event proto.InternalMessageInfo - -type isEvent_Event interface { - isEvent_Event() -} - -type Event_ExecutionEvent struct { - ExecutionEvent *ExecutionEvent `protobuf:"bytes,2,opt,name=ExecutionEvent,proto3,oneof"` -} -type Event_TendermintEventJSON struct { - TendermintEventJSON string `protobuf:"bytes,3,opt,name=TendermintEventJSON,proto3,oneof"` -} - -func (*Event_ExecutionEvent) isEvent_Event() {} -func (*Event_TendermintEventJSON) isEvent_Event() {} - -func (m *Event) GetEvent() isEvent_Event { - if m != nil { - return m.Event - } - return nil -} - -func (m *Event) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Event) GetExecutionEvent() *ExecutionEvent { - if x, ok := m.GetEvent().(*Event_ExecutionEvent); ok { - return x.ExecutionEvent - } - return nil -} - -func (m *Event) GetTendermintEventJSON() string { - if x, ok := m.GetEvent().(*Event_TendermintEventJSON); ok { - return x.TendermintEventJSON - } - return "" -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*Event) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _Event_OneofMarshaler, _Event_OneofUnmarshaler, _Event_OneofSizer, []interface{}{ - (*Event_ExecutionEvent)(nil), - (*Event_TendermintEventJSON)(nil), - } -} - -func _Event_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*Event) - // Event - switch x := m.Event.(type) { - case *Event_ExecutionEvent: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.ExecutionEvent); err != nil { - return err - } - case *Event_TendermintEventJSON: - b.EncodeVarint(3<<3 | proto.WireBytes) - b.EncodeStringBytes(x.TendermintEventJSON) - case nil: - default: - return fmt.Errorf("Event.Event has unexpected type %T", x) - } - return nil -} - -func _Event_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*Event) - switch tag { - case 2: // Event.ExecutionEvent - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(ExecutionEvent) - err := b.DecodeMessage(msg) - m.Event = &Event_ExecutionEvent{msg} - return true, err - case 3: // Event.TendermintEventJSON - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - x, err := b.DecodeStringBytes() - m.Event = &Event_TendermintEventJSON{x} - return true, err - default: - return false, nil - } -} - -func _Event_OneofSizer(msg proto.Message) (n int) { - m := msg.(*Event) - // Event - switch x := m.Event.(type) { - case *Event_ExecutionEvent: - s := proto.Size(x.ExecutionEvent) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *Event_TendermintEventJSON: - n += 1 // tag and wire - n += proto.SizeVarint(uint64(len(x.TendermintEventJSON))) - n += len(x.TendermintEventJSON) - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type GetEventsRequest struct { - BlockRange *BlockRange `protobuf:"bytes,1,opt,name=BlockRange,proto3" json:"BlockRange,omitempty"` - // Specify a query on which to match the tags of events. - // Tag | Match type | Values - // ----------------------------------------- - // All events - // ----------------------------------------- - // TxType | String | "UnknownTx", "SendTx", "CallTx", "NameTx", "BondTx", "UnbondTx", "PermissionsTx", "GovernanceTx" - // TxHash | String | bytes - // EventType | String | "CallEvent", "LogEvent", "AccountInputEvent", "AccountOutputEvent" - // EventID | String | string - // Height | Integer | uint64 - // Index | Integer | uint64 - // MessageType | String | Go type name - // ----------------------------------------- - // Log event - // ----------------------------------------- - // Address | String | Address (hex) - // Log<0-4> | String | Word256 (hex) - // Log<0-4>Text | String | string (trimmed) - // ----------------------------------------- - // Call event - // ----------------------------------------- - // Origin | String | Address (hex) - // Callee | String | Address (hex) - // Caller | String | Address (hex) - // Value | Integer | uint64 - // Gas | Integer | uint64 - // StackDepth | Integer | uint64 - // Exception | String | string - // ----------------------------------------- - // Tx event (input/output) - // ----------------------------------------- - // Exception | String | string - // - // For example: - // EventType = 'LogEvent' AND EventID CONTAINS 'bar' AND TxHash = '020304' AND Height >= 34 AND Index < 3 AND Address = 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF' - Query string `protobuf:"bytes,2,opt,name=Query,proto3" json:"Query,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetEventsRequest) Reset() { *m = GetEventsRequest{} } -func (m *GetEventsRequest) String() string { return proto.CompactTextString(m) } -func (*GetEventsRequest) ProtoMessage() {} -func (*GetEventsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{5} -} -func (m *GetEventsRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetEventsRequest.Unmarshal(m, b) -} -func (m *GetEventsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetEventsRequest.Marshal(b, m, deterministic) -} -func (dst *GetEventsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetEventsRequest.Merge(dst, src) -} -func (m *GetEventsRequest) XXX_Size() int { - return xxx_messageInfo_GetEventsRequest.Size(m) -} -func (m *GetEventsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_GetEventsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_GetEventsRequest proto.InternalMessageInfo - -func (m *GetEventsRequest) GetBlockRange() *BlockRange { - if m != nil { - return m.BlockRange - } - return nil -} - -func (m *GetEventsRequest) GetQuery() string { - if m != nil { - return m.Query - } - return "" -} - -type GetEventsResponse struct { - Events []*ExecutionEvent `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GetEventsResponse) Reset() { *m = GetEventsResponse{} } -func (m *GetEventsResponse) String() string { return proto.CompactTextString(m) } -func (*GetEventsResponse) ProtoMessage() {} -func (*GetEventsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{6} -} -func (m *GetEventsResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GetEventsResponse.Unmarshal(m, b) -} -func (m *GetEventsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GetEventsResponse.Marshal(b, m, deterministic) -} -func (dst *GetEventsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GetEventsResponse.Merge(dst, src) -} -func (m *GetEventsResponse) XXX_Size() int { - return xxx_messageInfo_GetEventsResponse.Size(m) -} -func (m *GetEventsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_GetEventsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_GetEventsResponse proto.InternalMessageInfo - -func (m *GetEventsResponse) GetEvents() []*ExecutionEvent { - if m != nil { - return m.Events - } - return nil -} - -type Bound struct { - Type Bound_BoundType `protobuf:"varint,1,opt,name=Type,proto3,enum=pbevents.Bound_BoundType" json:"Type,omitempty"` - Index uint64 `protobuf:"varint,2,opt,name=Index,proto3" json:"Index,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Bound) Reset() { *m = Bound{} } -func (m *Bound) String() string { return proto.CompactTextString(m) } -func (*Bound) ProtoMessage() {} -func (*Bound) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{7} -} -func (m *Bound) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Bound.Unmarshal(m, b) -} -func (m *Bound) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Bound.Marshal(b, m, deterministic) -} -func (dst *Bound) XXX_Merge(src proto.Message) { - xxx_messageInfo_Bound.Merge(dst, src) -} -func (m *Bound) XXX_Size() int { - return xxx_messageInfo_Bound.Size(m) -} -func (m *Bound) XXX_DiscardUnknown() { - xxx_messageInfo_Bound.DiscardUnknown(m) -} - -var xxx_messageInfo_Bound proto.InternalMessageInfo - -func (m *Bound) GetType() Bound_BoundType { - if m != nil { - return m.Type - } - return Bound_ABSOLUTE -} - -func (m *Bound) GetIndex() uint64 { - if m != nil { - return m.Index - } - return 0 -} - -// An inclusive range of blocks to include in output -type BlockRange struct { - // Bounds can be set to: - // absolute: block height - // relative: block height counting back from latest - // latest: latest block when call is processed - // stream: for End keep sending new blocks, for start same as latest - Start *Bound `protobuf:"bytes,1,opt,name=Start,proto3" json:"Start,omitempty"` - End *Bound `protobuf:"bytes,2,opt,name=End,proto3" json:"End,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *BlockRange) Reset() { *m = BlockRange{} } -func (m *BlockRange) String() string { return proto.CompactTextString(m) } -func (*BlockRange) ProtoMessage() {} -func (*BlockRange) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{8} -} -func (m *BlockRange) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_BlockRange.Unmarshal(m, b) -} -func (m *BlockRange) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_BlockRange.Marshal(b, m, deterministic) -} -func (dst *BlockRange) XXX_Merge(src proto.Message) { - xxx_messageInfo_BlockRange.Merge(dst, src) -} -func (m *BlockRange) XXX_Size() int { - return xxx_messageInfo_BlockRange.Size(m) -} -func (m *BlockRange) XXX_DiscardUnknown() { - xxx_messageInfo_BlockRange.DiscardUnknown(m) -} - -var xxx_messageInfo_BlockRange proto.InternalMessageInfo - -func (m *BlockRange) GetStart() *Bound { - if m != nil { - return m.Start - } - return nil -} - -func (m *BlockRange) GetEnd() *Bound { - if m != nil { - return m.End - } - return nil -} - -type EventHeader struct { - // Transaction type - TxType string `protobuf:"bytes,1,opt,name=TxType,proto3" json:"TxType,omitempty"` - // The hash of the transaction that caused this event to be generated - TxHash []byte `protobuf:"bytes,2,opt,name=TxHash,proto3" json:"TxHash,omitempty"` - // The type of event - EventType string `protobuf:"bytes,3,opt,name=EventType,proto3" json:"EventType,omitempty"` - // EventID published with event - EventID string `protobuf:"bytes,4,opt,name=EventID,proto3" json:"EventID,omitempty"` - // The block height at which this event was emitted - Height uint64 `protobuf:"varint,5,opt,name=Height,proto3" json:"Height,omitempty"` - // The index amongst all other events in the block of this event - Index uint64 `protobuf:"varint,6,opt,name=Index,proto3" json:"Index,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventHeader) Reset() { *m = EventHeader{} } -func (m *EventHeader) String() string { return proto.CompactTextString(m) } -func (*EventHeader) ProtoMessage() {} -func (*EventHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{9} -} -func (m *EventHeader) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventHeader.Unmarshal(m, b) -} -func (m *EventHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventHeader.Marshal(b, m, deterministic) -} -func (dst *EventHeader) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventHeader.Merge(dst, src) -} -func (m *EventHeader) XXX_Size() int { - return xxx_messageInfo_EventHeader.Size(m) -} -func (m *EventHeader) XXX_DiscardUnknown() { - xxx_messageInfo_EventHeader.DiscardUnknown(m) -} - -var xxx_messageInfo_EventHeader proto.InternalMessageInfo - -func (m *EventHeader) GetTxType() string { - if m != nil { - return m.TxType - } - return "" -} - -func (m *EventHeader) GetTxHash() []byte { - if m != nil { - return m.TxHash - } - return nil -} - -func (m *EventHeader) GetEventType() string { - if m != nil { - return m.EventType - } - return "" -} - -func (m *EventHeader) GetEventID() string { - if m != nil { - return m.EventID - } - return "" -} - -func (m *EventHeader) GetHeight() uint64 { - if m != nil { - return m.Height - } - return 0 -} - -func (m *EventHeader) GetIndex() uint64 { - if m != nil { - return m.Index - } - return 0 -} - -type ExecutionEvent struct { - Header *EventHeader `protobuf:"bytes,1,opt,name=Header,proto3" json:"Header,omitempty"` - // Types that are valid to be assigned to EventData: - // *ExecutionEvent_EventDataTx - // *ExecutionEvent_EventDataCall - // *ExecutionEvent_EventDataLog - EventData isExecutionEvent_EventData `protobuf_oneof:"EventData"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ExecutionEvent) Reset() { *m = ExecutionEvent{} } -func (m *ExecutionEvent) String() string { return proto.CompactTextString(m) } -func (*ExecutionEvent) ProtoMessage() {} -func (*ExecutionEvent) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{10} -} -func (m *ExecutionEvent) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ExecutionEvent.Unmarshal(m, b) -} -func (m *ExecutionEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ExecutionEvent.Marshal(b, m, deterministic) -} -func (dst *ExecutionEvent) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExecutionEvent.Merge(dst, src) -} -func (m *ExecutionEvent) XXX_Size() int { - return xxx_messageInfo_ExecutionEvent.Size(m) -} -func (m *ExecutionEvent) XXX_DiscardUnknown() { - xxx_messageInfo_ExecutionEvent.DiscardUnknown(m) -} - -var xxx_messageInfo_ExecutionEvent proto.InternalMessageInfo - -type isExecutionEvent_EventData interface { - isExecutionEvent_EventData() -} - -type ExecutionEvent_EventDataTx struct { - EventDataTx *EventDataTx `protobuf:"bytes,2,opt,name=EventDataTx,proto3,oneof"` -} -type ExecutionEvent_EventDataCall struct { - EventDataCall *EventDataCall `protobuf:"bytes,3,opt,name=EventDataCall,proto3,oneof"` -} -type ExecutionEvent_EventDataLog struct { - EventDataLog *EventDataLog `protobuf:"bytes,4,opt,name=EventDataLog,proto3,oneof"` -} - -func (*ExecutionEvent_EventDataTx) isExecutionEvent_EventData() {} -func (*ExecutionEvent_EventDataCall) isExecutionEvent_EventData() {} -func (*ExecutionEvent_EventDataLog) isExecutionEvent_EventData() {} - -func (m *ExecutionEvent) GetEventData() isExecutionEvent_EventData { - if m != nil { - return m.EventData - } - return nil -} - -func (m *ExecutionEvent) GetHeader() *EventHeader { - if m != nil { - return m.Header - } - return nil -} - -func (m *ExecutionEvent) GetEventDataTx() *EventDataTx { - if x, ok := m.GetEventData().(*ExecutionEvent_EventDataTx); ok { - return x.EventDataTx - } - return nil -} - -func (m *ExecutionEvent) GetEventDataCall() *EventDataCall { - if x, ok := m.GetEventData().(*ExecutionEvent_EventDataCall); ok { - return x.EventDataCall - } - return nil -} - -func (m *ExecutionEvent) GetEventDataLog() *EventDataLog { - if x, ok := m.GetEventData().(*ExecutionEvent_EventDataLog); ok { - return x.EventDataLog - } - return nil -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*ExecutionEvent) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _ExecutionEvent_OneofMarshaler, _ExecutionEvent_OneofUnmarshaler, _ExecutionEvent_OneofSizer, []interface{}{ - (*ExecutionEvent_EventDataTx)(nil), - (*ExecutionEvent_EventDataCall)(nil), - (*ExecutionEvent_EventDataLog)(nil), - } -} - -func _ExecutionEvent_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*ExecutionEvent) - // EventData - switch x := m.EventData.(type) { - case *ExecutionEvent_EventDataTx: - b.EncodeVarint(2<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.EventDataTx); err != nil { - return err - } - case *ExecutionEvent_EventDataCall: - b.EncodeVarint(3<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.EventDataCall); err != nil { - return err - } - case *ExecutionEvent_EventDataLog: - b.EncodeVarint(4<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.EventDataLog); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("ExecutionEvent.EventData has unexpected type %T", x) - } - return nil -} - -func _ExecutionEvent_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*ExecutionEvent) - switch tag { - case 2: // EventData.EventDataTx - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(EventDataTx) - err := b.DecodeMessage(msg) - m.EventData = &ExecutionEvent_EventDataTx{msg} - return true, err - case 3: // EventData.EventDataCall - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(EventDataCall) - err := b.DecodeMessage(msg) - m.EventData = &ExecutionEvent_EventDataCall{msg} - return true, err - case 4: // EventData.EventDataLog - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(EventDataLog) - err := b.DecodeMessage(msg) - m.EventData = &ExecutionEvent_EventDataLog{msg} - return true, err - default: - return false, nil - } -} - -func _ExecutionEvent_OneofSizer(msg proto.Message) (n int) { - m := msg.(*ExecutionEvent) - // EventData - switch x := m.EventData.(type) { - case *ExecutionEvent_EventDataTx: - s := proto.Size(x.EventDataTx) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *ExecutionEvent_EventDataCall: - s := proto.Size(x.EventDataCall) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *ExecutionEvent_EventDataLog: - s := proto.Size(x.EventDataLog) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -type EventDataLog struct { - Address []byte `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=Data,proto3" json:"Data,omitempty"` - Topics [][]byte `protobuf:"bytes,3,rep,name=Topics,proto3" json:"Topics,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventDataLog) Reset() { *m = EventDataLog{} } -func (m *EventDataLog) String() string { return proto.CompactTextString(m) } -func (*EventDataLog) ProtoMessage() {} -func (*EventDataLog) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{11} -} -func (m *EventDataLog) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventDataLog.Unmarshal(m, b) -} -func (m *EventDataLog) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventDataLog.Marshal(b, m, deterministic) -} -func (dst *EventDataLog) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventDataLog.Merge(dst, src) -} -func (m *EventDataLog) XXX_Size() int { - return xxx_messageInfo_EventDataLog.Size(m) -} -func (m *EventDataLog) XXX_DiscardUnknown() { - xxx_messageInfo_EventDataLog.DiscardUnknown(m) -} - -var xxx_messageInfo_EventDataLog proto.InternalMessageInfo - -func (m *EventDataLog) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *EventDataLog) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -func (m *EventDataLog) GetTopics() [][]byte { - if m != nil { - return m.Topics - } - return nil -} - -type EventDataTx struct { - Return []byte `protobuf:"bytes,1,opt,name=Return,proto3" json:"Return,omitempty"` - Exception *errors.Exception `protobuf:"bytes,2,opt,name=Exception,proto3" json:"Exception,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventDataTx) Reset() { *m = EventDataTx{} } -func (m *EventDataTx) String() string { return proto.CompactTextString(m) } -func (*EventDataTx) ProtoMessage() {} -func (*EventDataTx) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{12} -} -func (m *EventDataTx) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventDataTx.Unmarshal(m, b) -} -func (m *EventDataTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventDataTx.Marshal(b, m, deterministic) -} -func (dst *EventDataTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventDataTx.Merge(dst, src) -} -func (m *EventDataTx) XXX_Size() int { - return xxx_messageInfo_EventDataTx.Size(m) -} -func (m *EventDataTx) XXX_DiscardUnknown() { - xxx_messageInfo_EventDataTx.DiscardUnknown(m) -} - -var xxx_messageInfo_EventDataTx proto.InternalMessageInfo - -func (m *EventDataTx) GetReturn() []byte { - if m != nil { - return m.Return - } - return nil -} - -func (m *EventDataTx) GetException() *errors.Exception { - if m != nil { - return m.Exception - } - return nil -} - -type EventDataCall struct { - CallData *CallData `protobuf:"bytes,1,opt,name=CallData,proto3" json:"CallData,omitempty"` - Origin []byte `protobuf:"bytes,2,opt,name=Origin,proto3" json:"Origin,omitempty"` - StackDepth uint64 `protobuf:"varint,3,opt,name=StackDepth,proto3" json:"StackDepth,omitempty"` - Return []byte `protobuf:"bytes,4,opt,name=Return,proto3" json:"Return,omitempty"` - Exception *errors.Exception `protobuf:"bytes,5,opt,name=Exception,proto3" json:"Exception,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventDataCall) Reset() { *m = EventDataCall{} } -func (m *EventDataCall) String() string { return proto.CompactTextString(m) } -func (*EventDataCall) ProtoMessage() {} -func (*EventDataCall) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{13} -} -func (m *EventDataCall) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventDataCall.Unmarshal(m, b) -} -func (m *EventDataCall) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventDataCall.Marshal(b, m, deterministic) -} -func (dst *EventDataCall) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventDataCall.Merge(dst, src) -} -func (m *EventDataCall) XXX_Size() int { - return xxx_messageInfo_EventDataCall.Size(m) -} -func (m *EventDataCall) XXX_DiscardUnknown() { - xxx_messageInfo_EventDataCall.DiscardUnknown(m) -} - -var xxx_messageInfo_EventDataCall proto.InternalMessageInfo - -func (m *EventDataCall) GetCallData() *CallData { - if m != nil { - return m.CallData - } - return nil -} - -func (m *EventDataCall) GetOrigin() []byte { - if m != nil { - return m.Origin - } - return nil -} - -func (m *EventDataCall) GetStackDepth() uint64 { - if m != nil { - return m.StackDepth - } - return 0 -} - -func (m *EventDataCall) GetReturn() []byte { - if m != nil { - return m.Return - } - return nil -} - -func (m *EventDataCall) GetException() *errors.Exception { - if m != nil { - return m.Exception - } - return nil -} - -type CallData struct { - Caller []byte `protobuf:"bytes,1,opt,name=Caller,proto3" json:"Caller,omitempty"` - Callee []byte `protobuf:"bytes,2,opt,name=Callee,proto3" json:"Callee,omitempty"` - Data []byte `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"` - Value uint64 `protobuf:"varint,4,opt,name=Value,proto3" json:"Value,omitempty"` - Gas uint64 `protobuf:"varint,5,opt,name=Gas,proto3" json:"Gas,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CallData) Reset() { *m = CallData{} } -func (m *CallData) String() string { return proto.CompactTextString(m) } -func (*CallData) ProtoMessage() {} -func (*CallData) Descriptor() ([]byte, []int) { - return fileDescriptor_events_a0e2b84614955cff, []int{14} -} -func (m *CallData) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CallData.Unmarshal(m, b) -} -func (m *CallData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CallData.Marshal(b, m, deterministic) -} -func (dst *CallData) XXX_Merge(src proto.Message) { - xxx_messageInfo_CallData.Merge(dst, src) -} -func (m *CallData) XXX_Size() int { - return xxx_messageInfo_CallData.Size(m) -} -func (m *CallData) XXX_DiscardUnknown() { - xxx_messageInfo_CallData.DiscardUnknown(m) -} - -var xxx_messageInfo_CallData proto.InternalMessageInfo - -func (m *CallData) GetCaller() []byte { - if m != nil { - return m.Caller - } - return nil -} - -func (m *CallData) GetCallee() []byte { - if m != nil { - return m.Callee - } - return nil -} - -func (m *CallData) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -func (m *CallData) GetValue() uint64 { - if m != nil { - return m.Value - } - return 0 -} - -func (m *CallData) GetGas() uint64 { - if m != nil { - return m.Gas - } - return 0 -} - -func init() { - proto.RegisterType((*EventIdParam)(nil), "pbevents.EventIdParam") - proto.RegisterType((*SubIdParam)(nil), "pbevents.SubIdParam") - proto.RegisterType((*EventUnSub)(nil), "pbevents.EventUnSub") - proto.RegisterType((*PollResponse)(nil), "pbevents.PollResponse") - proto.RegisterType((*Event)(nil), "pbevents.Event") - proto.RegisterType((*GetEventsRequest)(nil), "pbevents.GetEventsRequest") - proto.RegisterType((*GetEventsResponse)(nil), "pbevents.GetEventsResponse") - proto.RegisterType((*Bound)(nil), "pbevents.Bound") - proto.RegisterType((*BlockRange)(nil), "pbevents.BlockRange") - proto.RegisterType((*EventHeader)(nil), "pbevents.EventHeader") - proto.RegisterType((*ExecutionEvent)(nil), "pbevents.ExecutionEvent") - proto.RegisterType((*EventDataLog)(nil), "pbevents.EventDataLog") - proto.RegisterType((*EventDataTx)(nil), "pbevents.EventDataTx") - proto.RegisterType((*EventDataCall)(nil), "pbevents.EventDataCall") - proto.RegisterType((*CallData)(nil), "pbevents.CallData") - proto.RegisterEnum("pbevents.Bound_BoundType", Bound_BoundType_name, Bound_BoundType_value) -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// EventsClient is the client API for Events service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type EventsClient interface { - EventPoll(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*PollResponse, error) - EventSubscribe(ctx context.Context, in *EventIdParam, opts ...grpc.CallOption) (*SubIdParam, error) - EventUnsubscribe(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*EventUnSub, error) -} - -type eventsClient struct { - cc *grpc.ClientConn -} - -func NewEventsClient(cc *grpc.ClientConn) EventsClient { - return &eventsClient{cc} -} - -func (c *eventsClient) EventPoll(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*PollResponse, error) { - out := new(PollResponse) - err := c.cc.Invoke(ctx, "/pbevents.Events/EventPoll", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eventsClient) EventSubscribe(ctx context.Context, in *EventIdParam, opts ...grpc.CallOption) (*SubIdParam, error) { - out := new(SubIdParam) - err := c.cc.Invoke(ctx, "/pbevents.Events/EventSubscribe", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eventsClient) EventUnsubscribe(ctx context.Context, in *SubIdParam, opts ...grpc.CallOption) (*EventUnSub, error) { - out := new(EventUnSub) - err := c.cc.Invoke(ctx, "/pbevents.Events/EventUnsubscribe", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// EventsServer is the server API for Events service. -type EventsServer interface { - EventPoll(context.Context, *SubIdParam) (*PollResponse, error) - EventSubscribe(context.Context, *EventIdParam) (*SubIdParam, error) - EventUnsubscribe(context.Context, *SubIdParam) (*EventUnSub, error) -} - -func RegisterEventsServer(s *grpc.Server, srv EventsServer) { - s.RegisterService(&_Events_serviceDesc, srv) -} - -func _Events_EventPoll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SubIdParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(EventsServer).EventPoll(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbevents.Events/EventPoll", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(EventsServer).EventPoll(ctx, req.(*SubIdParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Events_EventSubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EventIdParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(EventsServer).EventSubscribe(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbevents.Events/EventSubscribe", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(EventsServer).EventSubscribe(ctx, req.(*EventIdParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Events_EventUnsubscribe_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SubIdParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(EventsServer).EventUnsubscribe(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbevents.Events/EventUnsubscribe", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(EventsServer).EventUnsubscribe(ctx, req.(*SubIdParam)) - } - return interceptor(ctx, in, info, handler) -} - -var _Events_serviceDesc = grpc.ServiceDesc{ - ServiceName: "pbevents.Events", - HandlerType: (*EventsServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "EventPoll", - Handler: _Events_EventPoll_Handler, - }, - { - MethodName: "EventSubscribe", - Handler: _Events_EventSubscribe_Handler, - }, - { - MethodName: "EventUnsubscribe", - Handler: _Events_EventUnsubscribe_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "github.com/hyperledger/burrow/execution/events/pbevents/events.proto", -} - -// ExecutionEventsClient is the client API for ExecutionEvents service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type ExecutionEventsClient interface { - // GetEvents provides events streaming one block at a time - that is all events emitted in a particular block - // are guaranteed to be delivered in each GetEventsResponse - GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error) -} - -type executionEventsClient struct { - cc *grpc.ClientConn -} - -func NewExecutionEventsClient(cc *grpc.ClientConn) ExecutionEventsClient { - return &executionEventsClient{cc} -} - -func (c *executionEventsClient) GetEvents(ctx context.Context, in *GetEventsRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error) { - stream, err := c.cc.NewStream(ctx, &_ExecutionEvents_serviceDesc.Streams[0], "/pbevents.ExecutionEvents/GetEvents", opts...) - if err != nil { - return nil, err - } - x := &executionEventsGetEventsClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type ExecutionEvents_GetEventsClient interface { - Recv() (*GetEventsResponse, error) - grpc.ClientStream -} - -type executionEventsGetEventsClient struct { - grpc.ClientStream -} - -func (x *executionEventsGetEventsClient) Recv() (*GetEventsResponse, error) { - m := new(GetEventsResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// ExecutionEventsServer is the server API for ExecutionEvents service. -type ExecutionEventsServer interface { - // GetEvents provides events streaming one block at a time - that is all events emitted in a particular block - // are guaranteed to be delivered in each GetEventsResponse - GetEvents(*GetEventsRequest, ExecutionEvents_GetEventsServer) error -} - -func RegisterExecutionEventsServer(s *grpc.Server, srv ExecutionEventsServer) { - s.RegisterService(&_ExecutionEvents_serviceDesc, srv) -} - -func _ExecutionEvents_GetEvents_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(GetEventsRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(ExecutionEventsServer).GetEvents(m, &executionEventsGetEventsServer{stream}) -} - -type ExecutionEvents_GetEventsServer interface { - Send(*GetEventsResponse) error - grpc.ServerStream -} - -type executionEventsGetEventsServer struct { - grpc.ServerStream -} - -func (x *executionEventsGetEventsServer) Send(m *GetEventsResponse) error { - return x.ServerStream.SendMsg(m) -} - -var _ExecutionEvents_serviceDesc = grpc.ServiceDesc{ - ServiceName: "pbevents.ExecutionEvents", - HandlerType: (*ExecutionEventsServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "GetEvents", - Handler: _ExecutionEvents_GetEvents_Handler, - ServerStreams: true, - }, - }, - Metadata: "github.com/hyperledger/burrow/execution/events/pbevents/events.proto", -} - -func init() { - proto.RegisterFile("github.com/hyperledger/burrow/execution/events/pbevents/events.proto", fileDescriptor_events_a0e2b84614955cff) -} - -var fileDescriptor_events_a0e2b84614955cff = []byte{ - // 907 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xdd, 0x6e, 0xdc, 0x44, - 0x14, 0x5e, 0x67, 0x7f, 0x1a, 0x9f, 0x5d, 0x12, 0x77, 0x08, 0xc5, 0x04, 0x84, 0x82, 0x05, 0x22, - 0x37, 0xdd, 0xad, 0x0c, 0x52, 0x15, 0x81, 0x8a, 0x76, 0x89, 0xdb, 0x4d, 0xb5, 0x34, 0x65, 0xec, - 0x46, 0x82, 0x0b, 0x24, 0x7b, 0x3d, 0xda, 0xb5, 0xea, 0xd8, 0x66, 0xc6, 0x2e, 0x9b, 0x17, 0xe0, - 0x19, 0xb8, 0xe0, 0x8e, 0x17, 0x41, 0xe2, 0xc5, 0xd0, 0xfc, 0xf8, 0x97, 0xad, 0x54, 0x71, 0x13, - 0xcf, 0x37, 0xe7, 0x9b, 0x6f, 0xcf, 0xf9, 0xce, 0xfc, 0x04, 0x2e, 0x37, 0x51, 0xbe, 0x2d, 0x82, - 0xe9, 0x3a, 0xbd, 0x9d, 0x6d, 0xef, 0x32, 0x42, 0x63, 0x12, 0x6e, 0x08, 0x9d, 0x05, 0x05, 0xa5, - 0xe9, 0x6f, 0x33, 0xb2, 0x23, 0xeb, 0x22, 0x8f, 0xd2, 0x64, 0x46, 0xde, 0x90, 0x24, 0x67, 0xb3, - 0x2c, 0x50, 0x03, 0xf9, 0x99, 0x66, 0x34, 0xcd, 0x53, 0x74, 0x58, 0x4e, 0x9f, 0x7e, 0xf3, 0xce, - 0x7a, 0x94, 0xa6, 0x94, 0xa9, 0x8f, 0x94, 0xb1, 0xce, 0x61, 0xe2, 0x70, 0x99, 0xab, 0xf0, 0xa5, - 0x4f, 0xfd, 0x5b, 0x64, 0xc2, 0x3d, 0x22, 0xb1, 0xa9, 0x9d, 0x69, 0xe7, 0x3a, 0x2e, 0xa1, 0x65, - 0x01, 0xb8, 0x45, 0x50, 0xf2, 0x4e, 0x60, 0xc8, 0x38, 0x52, 0x2c, 0x09, 0xac, 0xcf, 0x01, 0x84, - 0xda, 0xab, 0xc4, 0x2d, 0x02, 0xf4, 0x00, 0x46, 0x94, 0xb0, 0x22, 0xce, 0x05, 0xe9, 0x10, 0x2b, - 0x64, 0x3d, 0x86, 0xc9, 0xcb, 0x34, 0x8e, 0x31, 0x61, 0x59, 0x9a, 0x30, 0x82, 0xbe, 0x84, 0x91, - 0x2c, 0xc5, 0xd4, 0xce, 0xfa, 0xe7, 0x63, 0xfb, 0x78, 0x5a, 0xd6, 0x36, 0x15, 0x6a, 0x58, 0x85, - 0xad, 0x3f, 0x35, 0x18, 0x8a, 0x19, 0x84, 0x60, 0xf0, 0xc2, 0xbf, 0x25, 0xea, 0xd7, 0xc5, 0x18, - 0x2d, 0xe0, 0xc8, 0x29, 0x6b, 0x15, 0x2c, 0xf3, 0xe0, 0x4c, 0x3b, 0x1f, 0xdb, 0x66, 0x43, 0xae, - 0x15, 0x5f, 0xf6, 0x70, 0x67, 0x05, 0xb2, 0xe1, 0x7d, 0x8f, 0x24, 0x21, 0xa1, 0xb7, 0x51, 0x92, - 0x8b, 0xa9, 0xe7, 0xee, 0xf5, 0x0b, 0xb3, 0xcf, 0x7f, 0x66, 0xd9, 0xc3, 0xfb, 0x82, 0x8b, 0x7b, - 0x2a, 0x29, 0xeb, 0x17, 0x30, 0x9e, 0x11, 0x19, 0x60, 0x98, 0xfc, 0x5a, 0x10, 0x96, 0xa3, 0xaf, - 0x01, 0x16, 0x71, 0xba, 0x7e, 0x8d, 0xfd, 0x64, 0x23, 0xd3, 0x1d, 0xdb, 0x27, 0x75, 0x42, 0x75, - 0x0c, 0x37, 0x78, 0xdc, 0xdd, 0x1f, 0x0b, 0x42, 0xef, 0x44, 0x05, 0x3a, 0x96, 0xc0, 0x72, 0xe0, - 0x7e, 0x43, 0x5f, 0x99, 0xf7, 0xa8, 0x63, 0xde, 0x5b, 0xab, 0xad, 0x5c, 0xfc, 0x43, 0x83, 0xe1, - 0x22, 0x2d, 0x92, 0x10, 0x3d, 0x84, 0x81, 0x77, 0x97, 0xc9, 0xb4, 0x8e, 0xec, 0x8f, 0x1a, 0x69, - 0xf1, 0xb0, 0xfc, 0xcb, 0x09, 0x58, 0xd0, 0x78, 0x56, 0x57, 0x49, 0x48, 0x76, 0x22, 0xab, 0x01, - 0x96, 0xc0, 0x7a, 0x0e, 0x7a, 0x45, 0x44, 0x13, 0x38, 0x9c, 0x2f, 0xdc, 0xeb, 0xd5, 0x2b, 0xcf, - 0x31, 0x7a, 0x1c, 0x61, 0x67, 0x35, 0xf7, 0xae, 0x6e, 0x1c, 0x43, 0x43, 0x3a, 0x0c, 0x9f, 0x5e, - 0x61, 0xd7, 0x33, 0x0e, 0x10, 0xc0, 0x68, 0x35, 0xf7, 0x1c, 0xd7, 0x33, 0xfa, 0x7c, 0xec, 0x7a, - 0xd8, 0x99, 0xff, 0x60, 0x0c, 0xac, 0x9b, 0xa6, 0x5b, 0xe8, 0x0b, 0x18, 0xba, 0xb9, 0x4f, 0x73, - 0x65, 0xdb, 0x71, 0x27, 0x3f, 0x2c, 0xa3, 0xe8, 0x33, 0xe8, 0x3b, 0x49, 0xa8, 0x9a, 0xfd, 0x1f, - 0x12, 0x8f, 0x59, 0x7f, 0x69, 0x30, 0x96, 0x2d, 0x27, 0x7e, 0x48, 0x28, 0xdf, 0x99, 0xde, 0xae, - 0x2a, 0x5d, 0xc7, 0x0a, 0xc9, 0xf9, 0xa5, 0xcf, 0xb6, 0x42, 0x6d, 0x82, 0x15, 0x42, 0x9f, 0x80, - 0x2e, 0x96, 0x8b, 0x25, 0x62, 0x33, 0xe0, 0x7a, 0x82, 0x9f, 0x19, 0x79, 0x86, 0x2e, 0xcd, 0x81, - 0x3c, 0x33, 0x0a, 0x72, 0xbd, 0x25, 0x89, 0x36, 0xdb, 0xdc, 0x1c, 0x0a, 0xcb, 0x14, 0xaa, 0x9d, - 0x1c, 0x35, 0x9d, 0xfc, 0xfd, 0xa0, 0xbb, 0x83, 0xd1, 0x43, 0x2e, 0xc0, 0x53, 0x56, 0x1e, 0x7c, - 0xd0, 0x39, 0x1a, 0x32, 0x88, 0x15, 0x09, 0x5d, 0xa8, 0x32, 0x2f, 0xfd, 0xdc, 0xf7, 0x76, 0xca, - 0x92, 0xee, 0x1a, 0x19, 0x5c, 0xf6, 0x70, 0x93, 0x8b, 0xbe, 0x83, 0xf7, 0x2a, 0xf8, 0xbd, 0x1f, - 0xc7, 0xa2, 0xcc, 0xb1, 0xfd, 0xe1, 0x9e, 0xc5, 0x3c, 0xbc, 0xec, 0xe1, 0x36, 0x1f, 0x7d, 0xab, - 0x6e, 0x12, 0x3e, 0xb1, 0x4a, 0x37, 0xc2, 0x8a, 0xb1, 0xfd, 0x60, 0xcf, 0xfa, 0x55, 0xba, 0x59, - 0xf6, 0x70, 0x8b, 0xbd, 0x18, 0x2b, 0x87, 0x39, 0xb6, 0xbc, 0xb6, 0x14, 0x37, 0x78, 0x1e, 0x86, - 0x94, 0x30, 0x26, 0x6c, 0x98, 0xe0, 0x12, 0xf2, 0x7b, 0x80, 0x93, 0x54, 0xbb, 0xc4, 0x58, 0x34, - 0x31, 0xcd, 0xa2, 0x35, 0x33, 0xfb, 0x67, 0x7d, 0xd1, 0x44, 0x81, 0xac, 0x9b, 0x96, 0x39, 0x9c, - 0x86, 0x49, 0x5e, 0xd0, 0x44, 0x69, 0x2a, 0x84, 0x66, 0xa0, 0x3b, 0xbb, 0x35, 0xc9, 0x78, 0x13, - 0x94, 0x83, 0xf7, 0xa7, 0xea, 0xce, 0xac, 0x02, 0xb8, 0xe6, 0x58, 0x7f, 0x6b, 0x1d, 0xeb, 0xd0, - 0x14, 0x0e, 0xf9, 0x57, 0x64, 0x26, 0xfb, 0x86, 0x6a, 0x1b, 0xca, 0x08, 0xae, 0x38, 0x3c, 0x95, - 0x6b, 0x1a, 0x6d, 0xa2, 0xa4, 0xdc, 0x76, 0x12, 0xa1, 0x4f, 0x01, 0xdc, 0xdc, 0x5f, 0xbf, 0xbe, - 0x24, 0x59, 0xbe, 0x15, 0x0d, 0x19, 0xe0, 0xc6, 0x4c, 0xa3, 0x84, 0xc1, 0xdb, 0x4b, 0x18, 0xbe, - 0x43, 0x09, 0x6f, 0xa0, 0x95, 0x0c, 0x1f, 0xab, 0x2d, 0x37, 0xc1, 0x0a, 0x55, 0xf3, 0xa4, 0x4c, - 0x52, 0xa2, 0xaa, 0x05, 0xfd, 0x46, 0x0b, 0x4e, 0x60, 0x78, 0xe3, 0xc7, 0x05, 0x11, 0x79, 0x0d, - 0xb0, 0x04, 0xc8, 0x80, 0xfe, 0x33, 0x9f, 0xa9, 0xa3, 0xc0, 0x87, 0xf6, 0x3f, 0x1a, 0x8c, 0xe4, - 0x7d, 0x86, 0x2e, 0xd4, 0x06, 0xe0, 0x2f, 0x03, 0x6a, 0xdc, 0x90, 0xf5, 0x9b, 0x73, 0xda, 0xd8, - 0x4b, 0xad, 0xf7, 0xe3, 0x09, 0x1c, 0x89, 0xa5, 0x6e, 0x11, 0xb0, 0x35, 0x8d, 0x02, 0x82, 0xba, - 0xbb, 0xae, 0x54, 0xd8, 0xab, 0x8b, 0x9e, 0x80, 0xa1, 0x5e, 0x2d, 0x56, 0x29, 0xec, 0xcf, 0xe0, - 0xa4, 0xa3, 0x2b, 0xde, 0x39, 0xfb, 0x27, 0x38, 0x6e, 0x1f, 0x5b, 0x86, 0x9e, 0x82, 0x5e, 0x5d, - 0xd5, 0xe8, 0xb4, 0x5e, 0xd5, 0x7d, 0x1f, 0x4e, 0x3f, 0xde, 0x1b, 0x93, 0x85, 0x3d, 0xd2, 0x16, - 0x17, 0x3f, 0x3f, 0xfe, 0x9f, 0xff, 0x2d, 0x04, 0x23, 0xf1, 0xc0, 0x7f, 0xf5, 0x6f, 0x00, 0x00, - 0x00, 0xff, 0xff, 0x6f, 0x28, 0x40, 0xd9, 0x6f, 0x08, 0x00, 0x00, -} diff --git a/execution/events/pbevents/events.proto b/execution/events/pbevents/events.proto deleted file mode 100644 index 67cb46c39152e9ba95ab05d4539c55b80cbf803e..0000000000000000000000000000000000000000 --- a/execution/events/pbevents/events.proto +++ /dev/null @@ -1,177 +0,0 @@ -syntax = 'proto3'; - -option go_package = "github.com/hyperledger/burrow/execution/events/pbevents"; - -import "github.com/hyperledger/burrow/execution/errors/errors.proto"; - -package pbevents; - -//-------------------------------------------------- -// Event Service Definition -service Events { - rpc EventPoll (SubIdParam) returns (PollResponse); - rpc EventSubscribe (EventIdParam) returns (SubIdParam); - rpc EventUnsubscribe (SubIdParam) returns (EventUnSub); -} - -// Params -message EventIdParam { - string eventId = 1; -} - -message SubIdParam { - string subId = 1; -} - -// Results -message EventUnSub { - bool result = 1; -} - -message PollResponse { - repeated Event events = 1; -} - -message Event { - string Name = 1; - oneof Event { - // Burrow's execution domain events generated deterministically from transactions - ExecutionEvent ExecutionEvent = 2; - // Operational events from tendermint serialised into their standard JSON representation - string TendermintEventJSON = 3; - } -} - -//-------------------------------------------------- -// Execution events -service ExecutionEvents { - // GetEvents provides events streaming one block at a time - that is all events emitted in a particular block - // are guaranteed to be delivered in each GetEventsResponse - rpc GetEvents (GetEventsRequest) returns (stream GetEventsResponse); -} - -message GetEventsRequest { - BlockRange BlockRange = 1; - // Specify a query on which to match the tags of events. - // Tag | Match type | Values - // ----------------------------------------- - // All events - // ----------------------------------------- - // TxType | String | "UnknownTx", "SendTx", "CallTx", "NameTx", "BondTx", "UnbondTx", "PermissionsTx", "GovernanceTx" - // TxHash | String | bytes - // EventType | String | "CallEvent", "LogEvent", "AccountInputEvent", "AccountOutputEvent" - // EventID | String | string - // Height | Integer | uint64 - // Index | Integer | uint64 - // MessageType | String | Go type name - // ----------------------------------------- - // Log event - // ----------------------------------------- - // Address | String | Address (hex) - // Log<0-4> | String | Word256 (hex) - // Log<0-4>Text | String | string (trimmed) - // ----------------------------------------- - // Call event - // ----------------------------------------- - // Origin | String | Address (hex) - // Callee | String | Address (hex) - // Caller | String | Address (hex) - // Value | Integer | uint64 - // Gas | Integer | uint64 - // StackDepth | Integer | uint64 - // Exception | String | string - // ----------------------------------------- - // Tx event (input/output) - // ----------------------------------------- - // Exception | String | string - // - // For example: - // EventType = 'LogEvent' AND EventID CONTAINS 'bar' AND TxHash = '020304' AND Height >= 34 AND Index < 3 AND Address = 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF' - string Query = 2; -} - -message GetEventsResponse { - repeated ExecutionEvent events = 1; -} - -message Bound { - BoundType Type = 1; - uint64 Index = 2; - enum BoundType { - // Index is absolute index of object in collection - ABSOLUTE = 0; - // Index is an offset relative to another bound determined by context - RELATIVE = 1; - // The first block - FIRST = 2; - // Ignore provided index and evaluate to latest index - LATEST = 3; - // Ignore provided index and stream new objects as they are generated - STREAM = 4; - } -} - -// An inclusive range of blocks to include in output -message BlockRange { - // Bounds can be set to: - // absolute: block height - // relative: block height counting back from latest - // latest: latest block when call is processed - // stream: for End keep sending new blocks, for start same as latest - Bound Start = 1; - Bound End = 2; -} - -//-------------------------------------------------- -// Event types - -message EventHeader { - // Transaction type - string TxType = 1; - // The hash of the transaction that caused this event to be generated - bytes TxHash = 2; - // The type of event - string EventType = 3; - // EventID published with event - string EventID = 4; - // The block height at which this event was emitted - uint64 Height = 5; - // The index amongst all other events in the block of this event - uint64 Index = 6; -} - -message ExecutionEvent { - EventHeader Header = 1; - oneof EventData { - EventDataTx EventDataTx = 2; - EventDataCall EventDataCall = 3; - EventDataLog EventDataLog = 4; - } -} - -message EventDataLog { - bytes Address = 1; - bytes Data = 2; - repeated bytes Topics = 3; -} - -message EventDataTx { - bytes Return = 1; - errors.Exception Exception = 2; -} - -message EventDataCall { - CallData CallData = 1; - bytes Origin = 2; - uint64 StackDepth = 3; - bytes Return = 4; - errors.Exception Exception = 5; -} - -message CallData { - bytes Caller = 1; - bytes Callee = 2; - bytes Data = 3; - uint64 Value = 4; - uint64 Gas = 5; -} diff --git a/execution/events/tx.go b/execution/events/tx.go deleted file mode 100644 index c1da5c62d4856d96e6d6fbdd5c1feff9d58dbc67..0000000000000000000000000000000000000000 --- a/execution/events/tx.go +++ /dev/null @@ -1,134 +0,0 @@ -package events - -import ( - "context" - "fmt" - - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/execution/errors" - ptypes "github.com/hyperledger/burrow/permission/types" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" - "github.com/tmthrgd/go-hex" -) - -func EventStringAccountInput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Input", addr) } -func EventStringAccountOutput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) } -func EventStringNameReg(name string) string { return fmt.Sprintf("NameReg/%s", name) } -func EventStringPermissions(perm ptypes.PermFlag) string { return fmt.Sprintf("Permissions/%v", perm) } -func EventStringBond() string { return "Bond" } -func EventStringUnbond() string { return "Unbond" } - -// All txs fire EventDataTx, but only CallTx might have Return or Exception -type EventDataTx struct { - Tx *txs.Tx - Return binary.HexBytes - Exception *errors.Exception -} - -// For re-use -var sendTxQuery = query.NewBuilder(). - AndEquals(event.TxTypeKey, payload.TypeSend.String()) - -var callTxQuery = query.NewBuilder(). - AndEquals(event.TxTypeKey, payload.TypeCall.String()) - -// Publish/Subscribe -func PublishAccountInput(publisher event.Publisher, height uint64, address crypto.Address, tx *txs.Tx, ret []byte, - exception *errors.Exception) error { - - ev := txEvent(height, TypeAccountInput, EventStringAccountInput(address), tx, ret, exception) - return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{ - event.AddressKey: address, - }}) -} - -func PublishAccountOutput(publisher event.Publisher, height uint64, address crypto.Address, tx *txs.Tx, ret []byte, - exception *errors.Exception) error { - - ev := txEvent(height, TypeAccountOutput, EventStringAccountOutput(address), tx, ret, exception) - return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{ - event.AddressKey: address, - }}) -} - -func PublishNameReg(publisher event.Publisher, height uint64, tx *txs.Tx) error { - nameTx, ok := tx.Payload.(*payload.NameTx) - if !ok { - return fmt.Errorf("Tx payload must be NameTx to PublishNameReg") - } - ev := txEvent(height, TypeAccountInput, EventStringNameReg(nameTx.Name), tx, nil, nil) - return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{ - event.NameKey: nameTx.Name, - }}) -} - -func PublishPermissions(publisher event.Publisher, height uint64, tx *txs.Tx) error { - permTx, ok := tx.Payload.(*payload.PermissionsTx) - if !ok { - return fmt.Errorf("Tx payload must be PermissionsTx to PublishPermissions") - } - ev := txEvent(height, TypeAccountInput, EventStringPermissions(permTx.PermArgs.PermFlag), tx, nil, nil) - return publisher.Publish(context.Background(), ev, event.CombinedTags{ev.Tags(), event.TagMap{ - event.PermissionKey: permTx.PermArgs.PermFlag.String(), - }}) -} - -func SubscribeAccountOutputSendTx(ctx context.Context, subscribable event.Subscribable, subscriber string, - address crypto.Address, txHash []byte, ch chan<- *payload.SendTx) error { - - qry := sendTxQuery.And(event.QueryForEventID(EventStringAccountOutput(address))). - AndEquals(event.TxHashKey, hex.EncodeUpperToString(txHash)) - - return event.SubscribeCallback(ctx, subscribable, subscriber, qry, func(message interface{}) (stop bool) { - if ev, ok := message.(*Event); ok && ev.Tx != nil { - if sendTx, ok := ev.Tx.Tx.Payload.(*payload.SendTx); ok { - ch <- sendTx - } - } - return - }) -} - -func txEvent(height uint64, eventType Type, eventID string, tx *txs.Tx, ret []byte, exception *errors.Exception) *Event { - return &Event{ - Header: &Header{ - TxType: tx.Type(), - TxHash: tx.Hash(), - EventType: eventType, - EventID: eventID, - Height: height, - }, - Tx: &EventDataTx{ - Tx: tx, - Return: ret, - Exception: exception, - }, - } -} - -// Tags - -var txTagKeys = []string{event.ExceptionKey} - -func (tx *EventDataTx) Get(key string) (string, bool) { - var value interface{} - switch key { - case event.ExceptionKey: - value = tx.Exception - default: - return "", false - } - return query.StringFromValue(value), true -} - -func (tx *EventDataTx) Len() int { - return len(txTagKeys) -} - -func (tx *EventDataTx) Keys() []string { - return txTagKeys -} diff --git a/execution/events/type.go b/execution/events/type.go deleted file mode 100644 index 8fe49f60df52439f06d14a9b12473601a9133119..0000000000000000000000000000000000000000 --- a/execution/events/type.go +++ /dev/null @@ -1,47 +0,0 @@ -package events - -type Type int8 - -// Execution event types -const ( - TypeCall = Type(0x00) - TypeLog = Type(0x01) - TypeAccountInput = Type(0x02) - TypeAccountOutput = Type(0x03) -) - -var nameFromType = map[Type]string{ - TypeCall: "CallEvent", - TypeLog: "LogEvent", - TypeAccountInput: "AccountInputEvent", - TypeAccountOutput: "AccountOutputEvent", -} - -var typeFromName = make(map[string]Type) - -func init() { - for t, n := range nameFromType { - typeFromName[n] = t - } -} - -func EventTypeFromString(name string) Type { - return typeFromName[name] -} - -func (typ Type) String() string { - name, ok := nameFromType[typ] - if ok { - return name - } - return "UnknownTx" -} - -func (typ Type) MarshalText() ([]byte, error) { - return []byte(typ.String()), nil -} - -func (typ *Type) UnmarshalText(data []byte) error { - *typ = EventTypeFromString(string(data)) - return nil -} diff --git a/execution/evm/accounts.go b/execution/evm/accounts.go index 1bd61df33a38a91f98fa338e4023c163c71e5053..65c578e375a9485f05d3976484e414240954fe88 100644 --- a/execution/evm/accounts.go +++ b/execution/evm/accounts.go @@ -1,16 +1,16 @@ package evm import ( - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/logging" - ptypes "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" ) // Create a new account from a parent 'creator' account. The creator account will have its // sequence number incremented -func DeriveNewAccount(creator acm.MutableAccount, permissions ptypes.AccountPermissions, - logger *logging.Logger) acm.MutableAccount { +func DeriveNewAccount(creator *acm.MutableAccount, permissions permission.AccountPermissions, + logger *logging.Logger) *acm.MutableAccount { // Generate an address sequence := creator.Sequence() logger.TraceMsg("Incrementing sequence number in DeriveNewAccount()", diff --git a/execution/evm/asm/opcodes.go b/execution/evm/asm/opcodes.go index 3017c213862a4dbbe7baa498115a73b56126c264..4467b7aebc2ba02adc5d26314d70c2593438b9c9 100644 --- a/execution/evm/asm/opcodes.go +++ b/execution/evm/asm/opcodes.go @@ -368,7 +368,7 @@ func (o OpCode) String() string { func (o OpCode) Name() string { str := opCodeNames[o] if len(str) == 0 { - return fmt.Sprintf("Missing opcode 0x%x", int(o)) + return fmt.Sprintf("Non-opcode 0x%x", int(o)) } return str diff --git a/execution/evm/fake_app_state.go b/execution/evm/fake_app_state.go index 8b1bd9ac473eedcee79134b1a33a10016bc7de09..eb2dbd3acefb11eef58bb3b9dff11359202a4954 100644 --- a/execution/evm/fake_app_state.go +++ b/execution/evm/fake_app_state.go @@ -19,8 +19,8 @@ import ( "bytes" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" . "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" ) diff --git a/execution/evm/log_event_test.go b/execution/evm/log_event_test.go index 7789c3b96824859001cd3d5573b0fd209ff6364e..2d2ba41ef5fcfd458639f79690f8ff648a47df6f 100644 --- a/execution/evm/log_event_test.go +++ b/execution/evm/log_event_test.go @@ -15,20 +15,17 @@ package evm import ( + "testing" + "bytes" - "context" "reflect" - "testing" - "time" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" . "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/events" . "github.com/hyperledger/burrow/execution/evm/asm" - "github.com/hyperledger/burrow/logging" + "github.com/hyperledger/burrow/execution/exec" "github.com/stretchr/testify/require" ) @@ -56,13 +53,8 @@ func TestLog4(t *testing.T) { ourVm := NewVM(newParams(), crypto.ZeroAddress, nil, logger) - emitter := event.NewEmitter(logging.NewNoopLogger()) - - ch := make(chan *events.EventDataLog) - - require.NoError(t, events.SubscribeLogEvent(context.Background(), emitter, "test", account2.Address(), ch)) - - ourVm.SetPublisher(emitter) + txe := new(exec.TxExecution) + ourVm.SetEventSink(txe) var gas uint64 = 100000 @@ -87,18 +79,20 @@ func TestLog4(t *testing.T) { _, err := ourVm.Call(cache, account1, account2, code, []byte{}, 0, &gas) require.NoError(t, err) - select { - case <-time.After(5 * time.Second): - t.Fatalf("timedout waiting for EventDataLog") - case eventDataLog := <-ch: - if !reflect.DeepEqual(eventDataLog.Topics, expectedTopics) { - t.Errorf("Event topics are wrong. Got: %v. Expected: %v", eventDataLog.Topics, expectedTopics) - } - if !bytes.Equal(eventDataLog.Data, expectedData) { - t.Errorf("Event data is wrong. Got: %s. Expected: %s", eventDataLog.Data, expectedData) - } - if eventDataLog.Height != expectedHeight { - t.Errorf("Event block height is wrong. Got: %d. Expected: %d", eventDataLog.Height, expectedHeight) + + for _, ev := range txe.Events { + if ev.Log != nil { + if !reflect.DeepEqual(ev.Log.Topics, expectedTopics) { + t.Errorf("Event topics are wrong. Got: %v. Expected: %v", ev.Log.Topics, expectedTopics) + } + if !bytes.Equal(ev.Log.Data, expectedData) { + t.Errorf("Event data is wrong. Got: %s. Expected: %s", ev.Log.Data, expectedData) + } + if ev.Header.Height != expectedHeight { + t.Errorf("Event block height is wrong. Got: %d. Expected: %d", ev.Header.Height, expectedHeight) + } + return } } + t.Fatalf("Did not see LogEvent") } diff --git a/execution/evm/native.go b/execution/evm/native.go index c4577ea901995f82eeb8a5577825c70ad5cb18ec..74f072aab77370c7e9f4865f91a154074a2d3fda 100644 --- a/execution/evm/native.go +++ b/execution/evm/native.go @@ -17,8 +17,8 @@ package evm import ( "crypto/sha256" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" . "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/errors" diff --git a/execution/evm/snative.go b/execution/evm/snative.go index 234cfb1a547b18c4882a3df4c7f748daf6de77a9..06254915bdccdf5a4ee94fa7ff814cf24ae487ce 100644 --- a/execution/evm/snative.go +++ b/execution/evm/snative.go @@ -19,8 +19,8 @@ import ( "strings" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" . "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/errors" @@ -28,7 +28,7 @@ import ( "github.com/hyperledger/burrow/execution/evm/sha3" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" - ptypes "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" ) // @@ -61,7 +61,7 @@ type SNativeFunctionDescription struct { // Function return value Return abi.Return // Permissions required to call function - PermFlag ptypes.PermFlag + PermFlag permission.PermFlag // Native function to which calls will be dispatched when a containing // contract is called with a FunctionSelector matching this NativeContract F NativeContract @@ -98,7 +98,7 @@ func SNativeContracts() map[string]*SNativeContractDescription { abiArg("_role", roleTypeName), }, abiReturn("result", abi.BoolTypeName), - ptypes.AddRole, + permission.AddRole, addRole}, &SNativeFunctionDescription{` @@ -113,7 +113,7 @@ func SNativeContracts() map[string]*SNativeContractDescription { abiArg("_role", roleTypeName), }, abiReturn("result", abi.BoolTypeName), - ptypes.RemoveRole, + permission.RemoveRole, removeRole}, &SNativeFunctionDescription{` @@ -128,7 +128,7 @@ func SNativeContracts() map[string]*SNativeContractDescription { abiArg("_role", roleTypeName), }, abiReturn("result", abi.BoolTypeName), - ptypes.HasRole, + permission.HasRole, hasRole}, &SNativeFunctionDescription{` @@ -145,7 +145,7 @@ func SNativeContracts() map[string]*SNativeContractDescription { abiArg("_set", abi.BoolTypeName), }, abiReturn("result", permFlagTypeName), - ptypes.SetBase, + permission.SetBase, setBase}, &SNativeFunctionDescription{` @@ -159,7 +159,7 @@ func SNativeContracts() map[string]*SNativeContractDescription { abiArg("_account", abi.AddressTypeName), abiArg("_permission", permFlagTypeName)}, abiReturn("result", permFlagTypeName), - ptypes.UnsetBase, + permission.UnsetBase, unsetBase}, &SNativeFunctionDescription{` @@ -173,7 +173,7 @@ func SNativeContracts() map[string]*SNativeContractDescription { abiArg("_account", abi.AddressTypeName), abiArg("_permission", permFlagTypeName)}, abiReturn("result", abi.BoolTypeName), - ptypes.HasBase, + permission.HasBase, hasBase}, &SNativeFunctionDescription{` @@ -187,7 +187,7 @@ func SNativeContracts() map[string]*SNativeContractDescription { abiArg("_permission", permFlagTypeName), abiArg("_set", abi.BoolTypeName)}, abiReturn("result", permFlagTypeName), - ptypes.SetGlobal, + permission.SetGlobal, setGlobal}, ), } @@ -355,9 +355,9 @@ func hasBase(state state.ReaderWriter, caller acm.Account, args []byte, gas *uin if acc == nil { return nil, fmt.Errorf("unknown account %s", address) } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) // already shifted + permN := permission.PermFlag(Uint64FromWord256(permNum)) // already shifted if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) + return nil, permission.ErrInvalidPermission(permN) } hasPermission := HasPermission(state, acc, permN) permInt := byteFromBool(hasPermission) @@ -381,9 +381,9 @@ func setBase(stateWriter state.ReaderWriter, caller acm.Account, args []byte, ga if acc == nil { return nil, fmt.Errorf("unknown account %s", address) } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) + permN := permission.PermFlag(Uint64FromWord256(permNum)) if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) + return nil, permission.ErrInvalidPermission(permN) } permV := !permVal.IsZero() if err = acc.MutablePermissions().Base.Set(permN, permV); err != nil { @@ -408,9 +408,9 @@ func unsetBase(stateWriter state.ReaderWriter, caller acm.Account, args []byte, if acc == nil { return nil, fmt.Errorf("unknown account %s", address) } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) + permN := permission.PermFlag(Uint64FromWord256(permNum)) if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) + return nil, permission.ErrInvalidPermission(permN) } if err = acc.MutablePermissions().Base.Unset(permN); err != nil { return nil, err @@ -434,9 +434,9 @@ func setGlobal(stateWriter state.ReaderWriter, caller acm.Account, args []byte, if acc == nil { panic("cant find the global permissions account") } - permN := ptypes.PermFlag(Uint64FromWord256(permNum)) + permN := permission.PermFlag(Uint64FromWord256(permNum)) if !ValidPermN(permN) { - return nil, ptypes.ErrInvalidPermission(permN) + return nil, permission.ErrInvalidPermission(permN) } permV := !permVal.IsZero() if err = acc.MutablePermissions().Base.Set(permN, permV); err != nil { @@ -518,23 +518,23 @@ func removeRole(stateWriter state.ReaderWriter, caller acm.Account, args []byte, // Errors and utility funcs // Checks if a permission flag is valid (a known base chain or snative permission) -func ValidPermN(n ptypes.PermFlag) bool { - return n <= ptypes.AllPermFlags +func ValidPermN(n permission.PermFlag) bool { + return n <= permission.AllPermFlags } // Get the global BasePermissions -func globalPerms(stateWriter state.ReaderWriter) ptypes.BasePermissions { +func globalPerms(stateWriter state.ReaderWriter) permission.BasePermissions { return state.GlobalAccountPermissions(stateWriter).Base } // Compute the effective permissions from an acm.Account's BasePermissions by // taking the bitwise or with the global BasePermissions resultant permissions -func effectivePermBytes(basePerms ptypes.BasePermissions, - globalPerms ptypes.BasePermissions) []byte { +func effectivePermBytes(basePerms permission.BasePermissions, + globalPerms permission.BasePermissions) []byte { return permBytes(basePerms.ResultantPerms() | globalPerms.ResultantPerms()) } -func permBytes(basePerms ptypes.PermFlag) []byte { +func permBytes(basePerms permission.PermFlag) []byte { return Uint64ToWord256(uint64(basePerms)).Bytes() } diff --git a/execution/evm/snative_test.go b/execution/evm/snative_test.go index e9b4150db7256f160dede1eaab8e73962fae5cb1..ed02ab80ad498d0888a0fa81a1f81912c820a5e0 100644 --- a/execution/evm/snative_test.go +++ b/execution/evm/snative_test.go @@ -20,15 +20,14 @@ import ( "strings" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" . "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/errors" "github.com/hyperledger/burrow/execution/evm/abi" "github.com/hyperledger/burrow/execution/evm/asm/bc" "github.com/hyperledger/burrow/execution/evm/sha3" - permission "github.com/hyperledger/burrow/permission/types" - ptypes "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" "github.com/stretchr/testify/assert" ) @@ -128,13 +127,13 @@ func funcIDFromHex(t *testing.T, hexString string) abi.FunctionSelector { return abi.FirstFourBytes(bs) } -func permFlagToWord256(permFlag ptypes.PermFlag) Word256 { +func permFlagToWord256(permFlag permission.PermFlag) Word256 { return Uint64ToWord256(uint64(permFlag)) } -func allAccountPermissions() ptypes.AccountPermissions { - return ptypes.AccountPermissions{ - Base: ptypes.BasePermissions{ +func allAccountPermissions() permission.AccountPermissions { + return permission.AccountPermissions{ + Base: permission.BasePermissions{ Perms: permission.AllPermFlags, SetBit: permission.AllPermFlags, }, diff --git a/execution/evm/vm.go b/execution/evm/vm.go index dda39f001067077667307c895ba50cdd76cc4db1..53d9b1ebc68667bd5955e2af2aa49dea279dae64 100644 --- a/execution/evm/vm.go +++ b/execution/evm/vm.go @@ -21,17 +21,16 @@ import ( "math/big" "strings" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" . "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution/errors" - "github.com/hyperledger/burrow/execution/events" . "github.com/hyperledger/burrow/execution/evm/asm" "github.com/hyperledger/burrow/execution/evm/sha3" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/logging" - ptypes "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" "github.com/hyperledger/burrow/txs" ) @@ -40,6 +39,16 @@ const ( callStackCapacity = 100 // TODO ensure usage. ) +type EventSink interface { + Call(call *exec.CallEvent, exception *errors.Exception) + Log(log *exec.LogEvent) +} + +type noopEventSink struct{} + +func (*noopEventSink) Call(call *exec.CallEvent, exception *errors.Exception) {} +func (*noopEventSink) Log(log *exec.LogEvent) {} + type Params struct { BlockHeight uint64 BlockHash Word256 @@ -54,7 +63,7 @@ type VM struct { tx *txs.Tx stackDepth uint64 nestedCallErrors []errors.NestedCall - publisher event.Publisher + eventSink EventSink logger *logging.Logger returnData []byte debugOpcodes bool @@ -68,6 +77,7 @@ func NewVM(params Params, origin crypto.Address, tx *txs.Tx, logger *logging.Log origin: origin, stackDepth: 0, tx: tx, + eventSink: &noopEventSink{}, logger: logger.WithScope("NewVM"), } for _, option := range options { @@ -82,9 +92,9 @@ func (vm *VM) Debugf(format string, a ...interface{}) { } } -// satisfies go_events.Eventable -func (vm *VM) SetPublisher(publisher event.Publisher) { - vm.publisher = publisher +// Set EventSink destination for events - can be unset if events generation is not required +func (vm *VM) SetEventSink(em EventSink) { + vm.eventSink = em } // CONTRACT: it is the duty of the contract writer to call known permissions @@ -93,29 +103,25 @@ func (vm *VM) SetPublisher(publisher event.Publisher) { // on known permissions and panics else) // If the perm is not defined in the acc nor set by default in GlobalPermissions, // this function returns false. -func HasPermission(stateWriter state.ReaderWriter, acc acm.Account, perm ptypes.PermFlag) bool { +func HasPermission(stateWriter state.ReaderWriter, acc acm.Account, perm permission.PermFlag) bool { value, _ := acc.Permissions().Base.Compose(state.GlobalAccountPermissions(stateWriter).Base).Get(perm) return value } func (vm *VM) fireCallEvent(exception *errors.CodedError, output *[]byte, callerAddress, calleeAddress crypto.Address, input []byte, value uint64, gas *uint64) { // fire the post call event (including exception if applicable) - if vm.publisher != nil { - events.PublishAccountCall(vm.publisher, vm.tx, vm.params.BlockHeight, - &events.EventDataCall{ - CallData: &events.CallData{ - Caller: callerAddress, - Callee: calleeAddress, - Data: input, - Value: value, - Gas: *gas, - }, - Origin: vm.origin, - StackDepth: vm.stackDepth, - Return: *output, - Exception: errors.AsCodedError(*exception), - }) - } + vm.eventSink.Call(&exec.CallEvent{ + CallData: &exec.CallData{ + Caller: callerAddress, + Callee: calleeAddress, + Data: input, + Value: value, + Gas: *gas, + }, + Origin: vm.origin, + StackDepth: vm.stackDepth, + Return: *output, + }, errors.AsException(*exception)) } // CONTRACT state is aware of caller and callee, so we can just mutate them. @@ -124,7 +130,7 @@ func (vm *VM) fireCallEvent(exception *errors.CodedError, output *[]byte, caller // value: To be transferred from caller to callee. Refunded upon errors.CodedError. // gas: Available gas. No refunds for gas. // code: May be nil, since the CALL opcode may be used to send value from contracts to accounts -func (vm *VM) Call(callState *state.Cache, caller, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) { +func (vm *VM) Call(callState *state.Cache, caller, callee *acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) { exception := new(errors.CodedError) // fire the post call event (including exception if applicable) @@ -168,7 +174,7 @@ func (vm *VM) Call(callState *state.Cache, caller, callee acm.MutableAccount, co // The intent of delegate call is to run the code of the callee in the storage context of the caller; // while preserving the original caller to the previous callee. // Different to the normal CALL or CALLCODE, the value does not need to be transferred to the callee. -func (vm *VM) DelegateCall(callState *state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) { +func (vm *VM) DelegateCall(callState *state.Cache, caller acm.Account, callee *acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) { exception := new(string) // fire the post call event (including exception if applicable) @@ -208,7 +214,7 @@ func useGasNegative(gasLeft *uint64, gasToUse uint64, err *errors.CodedError) bo } // Just like Call() but does not transfer 'value' or modify the callDepth. -func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) { +func (vm *VM) call(callState *state.Cache, caller acm.Account, callee *acm.MutableAccount, code, input []byte, value uint64, gas *uint64) (output []byte, err errors.CodedError) { vm.Debugf("(%d) (%X) %X (code=%d) gas: %v (d) %X\n", vm.stackDepth, caller.Address().Bytes()[:4], callee.Address(), len(callee.Code()), *gas, input) @@ -838,25 +844,18 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl vm.Debugf(" => Memory err: %s", memErr) return nil, firstErr(err, errors.ErrorCodeMemoryOutOfBounds) } - if vm.publisher != nil { - publishErr := events.PublishLogEvent(vm.publisher, vm.tx, &events.EventDataLog{ - Height: vm.params.BlockHeight, - Address: callee.Address(), - Topics: topics, - Data: data, - }) - if publishErr != nil { - vm.Debugf(" => Log event publish err: %s", publishErr) - return nil, firstErr(err, errors.ErrorCodeEventPublish) - } - } + vm.eventSink.Log(&exec.LogEvent{ + Address: callee.Address(), + Topics: topics, + Data: data, + }) vm.Debugf(" => T:%X D:%X\n", topics, data) case CREATE: // 0xF0 vm.returnData = nil - if !HasPermission(callState, callee, ptypes.CreateContract) { - return nil, errors.PermissionDenied{Perm: ptypes.CreateContract} + if !HasPermission(callState, callee, permission.CreateContract) { + return nil, errors.PermissionDenied{Perm: permission.CreateContract} } contractValue, popErr := stack.PopU64() if popErr != nil { @@ -902,8 +901,8 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl case CALL, CALLCODE, DELEGATECALL: // 0xF1, 0xF2, 0xF4 vm.returnData = nil - if !HasPermission(callState, callee, ptypes.Call) { - return nil, errors.PermissionDenied{Perm: ptypes.Call} + if !HasPermission(callState, callee, permission.Call) { + return nil, errors.PermissionDenied{Perm: permission.Call} } gasLimit, popErr := stack.PopU64() if popErr != nil { @@ -982,8 +981,8 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl } else { // nil account means we're sending funds to a new account if acc == nil { - if !HasPermission(callState, caller, ptypes.CreateAccount) { - return nil, errors.PermissionDenied{Perm: ptypes.CreateAccount} + if !HasPermission(callState, caller, permission.CreateAccount) { + return nil, errors.PermissionDenied{Perm: permission.CreateAccount} } acc = acm.ConcreteAccount{Address: crypto.AddressFromWord256(addr)}.MutableAccount() } @@ -1077,8 +1076,8 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl if useGasNegative(gas, GasCreateAccount, &gasErr) { return nil, firstErr(err, gasErr) } - if !HasPermission(callState, callee, ptypes.CreateContract) { - return nil, firstErr(err, errors.PermissionDenied{Perm: ptypes.CreateContract}) + if !HasPermission(callState, callee, permission.CreateContract) { + return nil, firstErr(err, errors.PermissionDenied{Perm: permission.CreateContract}) } var createErr errors.CodedError receiver, createErr = vm.createAccount(callState, callee, logger) @@ -1088,7 +1087,7 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl } - receiver, errAdd := receiver.AddToBalance(callee.Balance()) + errAdd := receiver.AddToBalance(callee.Balance()) if errAdd != nil { return nil, firstErr(err, errAdd) } @@ -1101,25 +1100,25 @@ func (vm *VM) call(callState *state.Cache, caller acm.Account, callee acm.Mutabl return nil, nil case STATICCALL, CREATE2: - return nil, errors.Errorf("%s not yet implemented", op.Name()) + return nil, errors.Errorf("%v not yet implemented", op) default: - vm.Debugf("(pc) %-3v Unknown opcode %X\n", pc, op) - return nil, errors.Errorf("unknown opcode %X", op) + vm.Debugf("(pc) %-3v Unknown opcode %v\n", pc, op) + return nil, errors.Errorf("unknown opcode %v", op) } pc++ } } -func (vm *VM) createAccount(callState *state.Cache, callee acm.MutableAccount, logger *logging.Logger) (acm.MutableAccount, errors.CodedError) { +func (vm *VM) createAccount(callState *state.Cache, callee *acm.MutableAccount, logger *logging.Logger) (*acm.MutableAccount, errors.CodedError) { newAccount := DeriveNewAccount(callee, state.GlobalAccountPermissions(callState), logger) err := callState.UpdateAccount(newAccount) if err != nil { - return nil, errors.AsCodedError(err) + return nil, errors.AsException(err) } err = callState.UpdateAccount(callee) if err != nil { - return nil, errors.AsCodedError(err) + return nil, errors.AsException(err) } return newAccount, nil } @@ -1168,20 +1167,20 @@ func (vm *VM) jump(code []byte, to int64, pc *int64) (err errors.CodedError) { func firstErr(errA, errB error) errors.CodedError { if errA != nil { - return errors.AsCodedError(errA) + return errors.AsException(errA) } else { - return errors.AsCodedError(errB) + return errors.AsException(errB) } } -func transfer(from, to acm.MutableAccount, amount uint64) errors.CodedError { +func transfer(from, to *acm.MutableAccount, amount uint64) errors.CodedError { if from.Balance() < amount { return errors.ErrorCodeInsufficientBalance } else { from.SubtractFromBalance(amount) - _, err := to.AddToBalance(amount) + err := to.AddToBalance(amount) if err != nil { - return errors.AsCodedError(err) + return errors.AsException(err) } } return nil diff --git a/execution/evm/vm_test.go b/execution/evm/vm_test.go index 62d1ca3b816631af52709aa0eb0ea6f5eefec4db..5b7224d1765f08d34a9bde7c5b4b8a6dbf8af550 100644 --- a/execution/evm/vm_test.go +++ b/execution/evm/vm_test.go @@ -15,25 +15,22 @@ package evm import ( - "context" "encoding/hex" "fmt" "strconv" "testing" "time" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" . "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution/errors" - "github.com/hyperledger/burrow/execution/events" . "github.com/hyperledger/burrow/execution/evm/asm" . "github.com/hyperledger/burrow/execution/evm/asm/bc" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/permission" - ptypes "github.com/hyperledger/burrow/permission/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/crypto/ripemd160" @@ -65,7 +62,7 @@ func newParams() Params { } } -func newAccount(seed ...byte) acm.MutableAccount { +func newAccount(seed ...byte) *acm.MutableAccount { hasher := ripemd160.New() hasher.Write(seed) return acm.ConcreteAccount{ @@ -697,14 +694,16 @@ func TestSendCall(t *testing.T) { //---------------------------------------------- // give account2 sufficient balance, should pass - account2, err = newAccount(2).AddToBalance(100000) + account2 = newAccount(2) + err = account2.AddToBalance(100000) require.NoError(t, err) _, err = runVMWaitError(cache, ourVm, account1, account2, addr, contractCode, 1000) assert.NoError(t, err, "Should have sufficient balance") //---------------------------------------------- // insufficient gas, should fail - account2, err = newAccount(2).AddToBalance(100000) + account2 = newAccount(2) + err = account2.AddToBalance(100000) require.NoError(t, err) _, err = runVMWaitError(cache, ourVm, account1, account2, addr, contractCode, 100) assert.NoError(t, err, "Expected insufficient gas error") @@ -996,7 +995,7 @@ func returnWord() []byte { } func makeAccountWithCode(accountUpdater state.AccountUpdater, name string, - code []byte) (acm.MutableAccount, crypto.Address) { + code []byte) (*acm.MutableAccount, crypto.Address) { address, _ := crypto.AddressFromBytes([]byte(name)) account := acm.ConcreteAccount{ Address: address, @@ -1012,43 +1011,34 @@ func makeAccountWithCode(accountUpdater state.AccountUpdater, name string, // and then waits for any exceptions transmitted by Data in the AccCall // event (in the case of no direct error from call we will block waiting for // at least 1 AccCall event) -func runVMWaitError(vmCache *state.Cache, ourVm *VM, caller, callee acm.MutableAccount, subscribeAddr crypto.Address, +func runVMWaitError(vmCache *state.Cache, ourVm *VM, caller, callee *acm.MutableAccount, subscribeAddr crypto.Address, contractCode []byte, gas uint64) ([]byte, error) { - eventCh := make(chan *events.EventDataCall) - output, err := runVM(eventCh, vmCache, ourVm, caller, callee, subscribeAddr, contractCode, gas) + txe := new(exec.TxExecution) + output, err := runVM(txe, vmCache, ourVm, caller, callee, subscribeAddr, contractCode, gas) if err != nil { return output, err } - select { - case eventDataCall := <-eventCh: - if eventDataCall.Exception != nil { - return output, eventDataCall.Exception + if len(txe.Events) > 0 { + ex := txe.Events[0].Header.Exception + if ex != nil { + return output, ex } - return output, nil } + return output, nil } // Subscribes to an AccCall, runs the vm, returns the output and any direct // exception -func runVM(eventCh chan<- *events.EventDataCall, vmCache *state.Cache, ourVm *VM, caller, callee acm.MutableAccount, +func runVM(sink EventSink, vmCache *state.Cache, ourVm *VM, caller, callee *acm.MutableAccount, subscribeAddr crypto.Address, contractCode []byte, gas uint64) ([]byte, error) { - // we need to catch the event from the CALL to check for exceptions - em := event.NewEmitter(logging.NewNoopLogger()) fmt.Printf("subscribe to %s\n", subscribeAddr) - err := events.SubscribeAccountCall(context.Background(), em, "test", subscribeAddr, - nil, -1, eventCh) - if err != nil { - return nil, err - } - evc := event.NewCache() - ourVm.SetPublisher(evc) + ourVm.SetEventSink(sink) start := time.Now() output, err := ourVm.Call(vmCache, caller, callee, contractCode, []byte{}, 0, &gas) fmt.Printf("Output: %v Error: %v\n", output, err) fmt.Println("Call took:", time.Since(start)) - evc.Flush(em) return output, err } @@ -1155,7 +1145,7 @@ func TestSubslice(t *testing.T) { func TestHasPermission(t *testing.T) { st := newAppState() acc := acm.ConcreteAccount{ - Permissions: ptypes.AccountPermissions{ + Permissions: permission.AccountPermissions{ Base: BasePermissionsFromStrings(t, "00100001000111", "11011110111000"), @@ -1165,15 +1155,15 @@ func TestHasPermission(t *testing.T) { assert.True(t, HasPermission(st, acc, PermFlagFromString(t, "100001000110"))) } -func BasePermissionsFromStrings(t *testing.T, perms, setBit string) ptypes.BasePermissions { - return ptypes.BasePermissions{ +func BasePermissionsFromStrings(t *testing.T, perms, setBit string) permission.BasePermissions { + return permission.BasePermissions{ Perms: PermFlagFromString(t, perms), SetBit: PermFlagFromString(t, setBit), } } -func PermFlagFromString(t *testing.T, binaryString string) ptypes.PermFlag { +func PermFlagFromString(t *testing.T, binaryString string) permission.PermFlag { permFlag, err := strconv.ParseUint(binaryString, 2, 64) require.NoError(t, err) - return ptypes.PermFlag(permFlag) + return permission.PermFlag(permFlag) } diff --git a/execution/exec/block_execution.go b/execution/exec/block_execution.go new file mode 100644 index 0000000000000000000000000000000000000000..3fc8a905de6d74e5177928981e1ddeb89d6f4b2a --- /dev/null +++ b/execution/exec/block_execution.go @@ -0,0 +1,99 @@ +package exec + +import ( + "fmt" + + "encoding/json" + + "github.com/gogo/protobuf/proto" + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/event/query" + "github.com/hyperledger/burrow/txs" + abciTypes "github.com/tendermint/abci/types" +) + +func EventStringBlockExecution(height uint64) string { return fmt.Sprintf("Execution/Block/%v", height) } + +func DecodeBlockExecution(bs []byte) (*BlockExecution, error) { + be := new(BlockExecution) + err := cdc.UnmarshalBinary(bs, be) + if err != nil { + return nil, err + } + return be, nil +} + +func (be *BlockExecution) Encode() ([]byte, error) { + return cdc.MarshalBinary(be) +} + +func (*BlockExecution) EventType() EventType { + return TypeBlockExecution +} + +func (be *BlockExecution) Tx(txEnv *txs.Envelope) *TxExecution { + txe := NewTxExecution(txEnv) + be.Append(txe) + return txe +} + +func (be *BlockExecution) Append(tail ...*TxExecution) { + for i, txe := range tail { + txe.Index = uint64(len(be.TxExecutions) + i) + txe.Height = be.Height + } + be.TxExecutions = append(be.TxExecutions, tail...) +} + +// Tags +type TaggedBlockExecution struct { + query.Tagged + *BlockExecution +} + +func (be *BlockExecution) Tagged() *TaggedBlockExecution { + return &TaggedBlockExecution{ + Tagged: query.MergeTags( + query.TagMap{ + event.EventIDKey: EventStringBlockExecution(be.Height), + event.EventTypeKey: be.EventType(), + }, + query.MustReflectTags(be), + query.MustReflectTags(be.BlockHeader), + ), + BlockExecution: be, + } +} + +// TODO remove when Header gogo protobuf fixed in Tendermint +func BlockHeaderFromHeader(header *abciTypes.Header) *BlockHeader { + if header == nil { + return nil + } + bs, _ := json.Marshal(header) + return &BlockHeader{ + JSON: string(bs), + NumTxs: header.NumTxs, + } +} + +type ABCIHeader struct { + *abciTypes.Header +} + +// Gogo proto support +func (h *ABCIHeader) Marshal() ([]byte, error) { + return proto.Marshal(h.Header) +} + +func (h *ABCIHeader) Unmarshal(data []byte) error { + return proto.Unmarshal(data, h.Header) +} + +func QueryForBlockExecutionFromHeight(height uint64) *query.Builder { + return QueryForBlockExecution().AndGreaterThanOrEqual(event.HeightKey, height) +} + +func QueryForBlockExecution() *query.Builder { + return query.NewBuilder().AndEquals(event.EventTypeKey, TypeBlockExecution) +} diff --git a/execution/exec/block_execution_test.go b/execution/exec/block_execution_test.go new file mode 100644 index 0000000000000000000000000000000000000000..5a02fd56416ee18d49ae9ef5d59c8d07ed92ab94 --- /dev/null +++ b/execution/exec/block_execution_test.go @@ -0,0 +1,24 @@ +package exec + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestBlockExecution_Marshal(t *testing.T) { + be := &BlockExecution{ + // TODO: reenable when tendermint Header works GRPC + //BlockHeader: &abciTypes.Header{ + // Height: 3, + // AppHash: []byte{2}, + // Proposer: abciTypes.Validator{ + // Power: 34, + // }, + //}, + } + bs, err := be.Marshal() + require.NoError(t, err) + beOut := new(BlockExecution) + require.NoError(t, beOut.Unmarshal(bs)) +} diff --git a/execution/exec/codec.go b/execution/exec/codec.go new file mode 100644 index 0000000000000000000000000000000000000000..beb9d32a79998e585b37aec9c3d7abd0acf620c3 --- /dev/null +++ b/execution/exec/codec.go @@ -0,0 +1,5 @@ +package exec + +import "github.com/hyperledger/burrow/txs" + +var cdc = txs.NewAminoCodec() diff --git a/execution/exec/event.go b/execution/exec/event.go new file mode 100644 index 0000000000000000000000000000000000000000..b629a265ce93a9cee8f22ce9037bfe9cdb30260c --- /dev/null +++ b/execution/exec/event.go @@ -0,0 +1,120 @@ +package exec + +import ( + "reflect" + + "fmt" + + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/event/query" +) + +var eventMessageTag = query.TagMap{event.MessageTypeKey: reflect.TypeOf(&Event{}).String()} + +type EventType uint32 + +// Execution event types +const ( + TypeCall = EventType(0x00) + TypeLog = EventType(0x01) + TypeAccountInput = EventType(0x02) + TypeAccountOutput = EventType(0x03) + TypeTxExecution = EventType(0x04) + TypeBlockExecution = EventType(0x05) +) + +var nameFromType = map[EventType]string{ + TypeCall: "CallEvent", + TypeLog: "LogEvent", + TypeAccountInput: "AccountInputEvent", + TypeAccountOutput: "AccountOutputEvent", + TypeTxExecution: "TxExecutionEvent", + TypeBlockExecution: "BlockExecutionEvent", +} + +var typeFromName = make(map[string]EventType) + +func init() { + for t, n := range nameFromType { + typeFromName[n] = t + } +} + +func EventTypeFromString(name string) EventType { + return typeFromName[name] +} + +func (ev *Event) EventType() EventType { + return ev.Header.EventType +} + +func (typ EventType) String() string { + name, ok := nameFromType[typ] + if ok { + return name + } + return "UnknownTx" +} + +func (typ EventType) MarshalText() ([]byte, error) { + return []byte(typ.String()), nil +} + +func (typ *EventType) UnmarshalText(data []byte) error { + *typ = EventTypeFromString(string(data)) + return nil +} + +// Event + +func (ev *Event) String() string { + return fmt.Sprintf("ExecutionEvent{%v: %s}", ev.Header.String(), ev.Body()) +} + +func (ev *Event) Body() string { + if ev.Input != nil { + return ev.Input.String() + } + if ev.Output != nil { + return ev.Output.String() + } + if ev.Log != nil { + return ev.Log.String() + } + if ev.Call != nil { + return ev.Call.String() + } + return "<empty>" +} + +// Tags +type TaggedEvent struct { + query.Tagged + *Event +} + +type TaggedEvents []*TaggedEvent + +func (ev *Event) Tagged() *TaggedEvent { + return &TaggedEvent{ + Tagged: query.MergeTags( + query.MustReflectTags(ev.Header), + eventMessageTag, + query.MustReflectTags(ev.Input), + query.MustReflectTags(ev.Output), + query.MustReflectTags(ev.Call), + ev.Log, + ), + Event: ev, + } +} + +func (tevs TaggedEvents) Filter(qry query.Query) TaggedEvents { + var filtered TaggedEvents + for _, tev := range tevs { + if qry.Matches(tev) { + filtered = append(filtered, tev) + } + } + return filtered +} diff --git a/execution/exec/event_test.go b/execution/exec/event_test.go new file mode 100644 index 0000000000000000000000000000000000000000..e1e12072f2f6f6d45bd439f320cb5c1ce60582d9 --- /dev/null +++ b/execution/exec/event_test.go @@ -0,0 +1,72 @@ +package exec + +import ( + "testing" + + "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/event/query" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tmthrgd/go-hex" +) + +func TestEventTagQueries(t *testing.T) { + addressHex := "DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF" + address, err := crypto.AddressFromHexString(addressHex) + require.NoError(t, err) + ev := &Event{ + Header: &Header{ + EventType: TypeLog, + EventID: "foo/bar", + TxHash: []byte{2, 3, 4}, + Height: 34, + Index: 2, + }, + Log: &LogEvent{ + Address: address, + Topics: []binary.Word256{binary.RightPadWord256([]byte("marmot"))}, + }, + } + + tev := ev.Tagged() + + qb := query.NewBuilder().AndEquals(event.EventTypeKey, TypeLog.String()) + qry, err := qb.Query() + require.NoError(t, err) + assert.True(t, qry.Matches(tev)) + + qb = qb.AndContains(event.EventIDKey, "bar") + qry, err = qb.Query() + require.NoError(t, err) + assert.True(t, qry.Matches(tev)) + + qb = qb.AndEquals(event.TxHashKey, hex.EncodeUpperToString(tev.Header.TxHash)) + qry, err = qb.Query() + require.NoError(t, err) + assert.True(t, qry.Matches(tev)) + + qb = qb.AndGreaterThanOrEqual(event.HeightKey, tev.Header.Height) + qry, err = qb.Query() + require.NoError(t, err) + assert.True(t, qry.Matches(tev)) + + qb = qb.AndStrictlyLessThan(event.IndexKey, tev.Header.Index+1) + qry, err = qb.Query() + require.NoError(t, err) + assert.True(t, qry.Matches(tev)) + + qb = qb.AndEquals(event.AddressKey, addressHex) + qry, err = qb.Query() + require.NoError(t, err) + assert.True(t, qry.Matches(tev)) + + qb = qb.AndEquals(LogNTextKey(0), "marmot") + qry, err = qb.Query() + require.NoError(t, err) + assert.True(t, qry.Matches(tev)) + + t.Logf("Query: %v", qry) + t.Logf("Keys: %v", tev.Keys()) +} diff --git a/execution/exec/exec.pb.go b/execution/exec/exec.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..6c7cfe26c6fb967a2b217cc76ed5d08fcf0d45e0 --- /dev/null +++ b/execution/exec/exec.pb.go @@ -0,0 +1,3216 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: exec.proto + +/* + Package exec is a generated protocol buffer package. + + It is generated from these files: + exec.proto + + It has these top-level messages: + BlockExecution + BlockHeader + TxExecution + Header + Event + Result + LogEvent + CallEvent + InputEvent + OutputEvent + CallData +*/ +package exec + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import _ "github.com/tendermint/abci/types" +import errors "github.com/hyperledger/burrow/execution/errors" +import names "github.com/hyperledger/burrow/execution/names" +import txs "github.com/hyperledger/burrow/txs" +import permission "github.com/hyperledger/burrow/permission" + +import github_com_hyperledger_burrow_txs_payload "github.com/hyperledger/burrow/txs/payload" +import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" +import github_com_hyperledger_burrow_txs "github.com/hyperledger/burrow/txs" +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type BlockExecution struct { + // The height of this block + Height uint64 `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"` + // TODO: reintroduce this when upstream merges: https://github.com/tendermint/tendermint/pull/1987 + // types.Header BlockHeader = 2; + BlockHeader *BlockHeader `protobuf:"bytes,2,opt,name=BlockHeader" json:"BlockHeader,omitempty"` + TxExecutions []*TxExecution `protobuf:"bytes,3,rep,name=TxExecutions" json:"TxExecutions,omitempty"` +} + +func (m *BlockExecution) Reset() { *m = BlockExecution{} } +func (m *BlockExecution) String() string { return proto.CompactTextString(m) } +func (*BlockExecution) ProtoMessage() {} +func (*BlockExecution) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{0} } + +func (m *BlockExecution) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *BlockExecution) GetBlockHeader() *BlockHeader { + if m != nil { + return m.BlockHeader + } + return nil +} + +func (m *BlockExecution) GetTxExecutions() []*TxExecution { + if m != nil { + return m.TxExecutions + } + return nil +} + +func (*BlockExecution) XXX_MessageName() string { + return "exec.BlockExecution" +} + +type BlockHeader struct { + JSON string `protobuf:"bytes,1,opt,name=JSON,proto3" json:"JSON,omitempty"` + NumTxs int32 `protobuf:"varint,2,opt,name=NumTxs,proto3" json:"NumTxs,omitempty"` +} + +func (m *BlockHeader) Reset() { *m = BlockHeader{} } +func (m *BlockHeader) String() string { return proto.CompactTextString(m) } +func (*BlockHeader) ProtoMessage() {} +func (*BlockHeader) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{1} } + +func (m *BlockHeader) GetJSON() string { + if m != nil { + return m.JSON + } + return "" +} + +func (m *BlockHeader) GetNumTxs() int32 { + if m != nil { + return m.NumTxs + } + return 0 +} + +func (*BlockHeader) XXX_MessageName() string { + return "exec.BlockHeader" +} + +type TxExecution struct { + // Transaction type + TxType github_com_hyperledger_burrow_txs_payload.Type `protobuf:"varint,2,opt,name=TxType,proto3,casttype=github.com/hyperledger/burrow/txs/payload.Type" json:"TxType,omitempty"` + // The hash of the transaction that caused this event to be generated + TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,3,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"` + // The block height at which this Tx was included + Height uint64 `protobuf:"varint,4,opt,name=Height,proto3" json:"Height,omitempty"` + // The index of this transaction within the block + Index uint64 `protobuf:"varint,5,opt,name=Index,proto3" json:"Index,omitempty"` + // Signed Tx that triggered this execution + Envelope *github_com_hyperledger_burrow_txs.Envelope `protobuf:"bytes,6,opt,name=Envelope,customtype=github.com/hyperledger/burrow/txs.Envelope" json:"Envelope,omitempty"` + // Execution events + Events []*Event `protobuf:"bytes,7,rep,name=Events" json:"Events,omitempty"` + // The execution results + Result *Result `protobuf:"bytes,8,opt,name=Result" json:"Result,omitempty"` + // The transaction receipt + Receipt *txs.Receipt `protobuf:"bytes,9,opt,name=Receipt" json:"Receipt,omitempty"` + // If execution was an exception + Exception *errors.Exception `protobuf:"bytes,10,opt,name=Exception" json:"Exception,omitempty"` +} + +func (m *TxExecution) Reset() { *m = TxExecution{} } +func (m *TxExecution) String() string { return proto.CompactTextString(m) } +func (*TxExecution) ProtoMessage() {} +func (*TxExecution) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{2} } + +func (m *TxExecution) GetTxType() github_com_hyperledger_burrow_txs_payload.Type { + if m != nil { + return m.TxType + } + return 0 +} + +func (m *TxExecution) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *TxExecution) GetIndex() uint64 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *TxExecution) GetEvents() []*Event { + if m != nil { + return m.Events + } + return nil +} + +func (m *TxExecution) GetResult() *Result { + if m != nil { + return m.Result + } + return nil +} + +func (m *TxExecution) GetReceipt() *txs.Receipt { + if m != nil { + return m.Receipt + } + return nil +} + +func (m *TxExecution) GetException() *errors.Exception { + if m != nil { + return m.Exception + } + return nil +} + +func (*TxExecution) XXX_MessageName() string { + return "exec.TxExecution" +} + +type Header struct { + // Transaction type + TxType github_com_hyperledger_burrow_txs_payload.Type `protobuf:"varint,1,opt,name=TxType,proto3,casttype=github.com/hyperledger/burrow/txs/payload.Type" json:"TxType,omitempty"` + // The hash of the transaction that caused this event to be generated + TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,2,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"` + // The type of event + EventType EventType `protobuf:"varint,3,opt,name=EventType,proto3,casttype=EventType" json:"EventType,omitempty"` + // EventID published with event + EventID string `protobuf:"bytes,4,opt,name=EventID,proto3" json:"EventID,omitempty"` + // The block height at which this event was emitted + Height uint64 `protobuf:"varint,5,opt,name=Height,proto3" json:"Height,omitempty"` + // The index of this event relative to other events generated by the same transaction + Index uint64 `protobuf:"varint,6,opt,name=Index,proto3" json:"Index,omitempty"` + // If event is exception + Exception *errors.Exception `protobuf:"bytes,7,opt,name=Exception" json:"Exception,omitempty"` +} + +func (m *Header) Reset() { *m = Header{} } +func (*Header) ProtoMessage() {} +func (*Header) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{3} } + +func (m *Header) GetTxType() github_com_hyperledger_burrow_txs_payload.Type { + if m != nil { + return m.TxType + } + return 0 +} + +func (m *Header) GetEventType() EventType { + if m != nil { + return m.EventType + } + return 0 +} + +func (m *Header) GetEventID() string { + if m != nil { + return m.EventID + } + return "" +} + +func (m *Header) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *Header) GetIndex() uint64 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *Header) GetException() *errors.Exception { + if m != nil { + return m.Exception + } + return nil +} + +func (*Header) XXX_MessageName() string { + return "exec.Header" +} + +type Event struct { + Header *Header `protobuf:"bytes,1,opt,name=Header" json:"Header,omitempty"` + Input *InputEvent `protobuf:"bytes,2,opt,name=Input" json:"Input,omitempty"` + Output *OutputEvent `protobuf:"bytes,3,opt,name=Output" json:"Output,omitempty"` + Call *CallEvent `protobuf:"bytes,4,opt,name=Call" json:"Call,omitempty"` + Log *LogEvent `protobuf:"bytes,5,opt,name=Log" json:"Log,omitempty"` +} + +func (m *Event) Reset() { *m = Event{} } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{4} } + +func (m *Event) GetHeader() *Header { + if m != nil { + return m.Header + } + return nil +} + +func (m *Event) GetInput() *InputEvent { + if m != nil { + return m.Input + } + return nil +} + +func (m *Event) GetOutput() *OutputEvent { + if m != nil { + return m.Output + } + return nil +} + +func (m *Event) GetCall() *CallEvent { + if m != nil { + return m.Call + } + return nil +} + +func (m *Event) GetLog() *LogEvent { + if m != nil { + return m.Log + } + return nil +} + +func (*Event) XXX_MessageName() string { + return "exec.Event" +} + +// Could structure this further if needed - sum type of various results relevant to different transaction types +type Result struct { + // EVM execution return + Return []byte `protobuf:"bytes,1,opt,name=Return,proto3" json:"Return,omitempty"` + // Gas used in computation + GasUsed uint64 `protobuf:"varint,2,opt,name=GasUsed,proto3" json:"GasUsed,omitempty"` + // Name entry created + NameEntry *names.Entry `protobuf:"bytes,3,opt,name=NameEntry" json:"NameEntry,omitempty"` + // Permission update performed + PermArgs *permission.PermArgs `protobuf:"bytes,4,opt,name=PermArgs" json:"PermArgs,omitempty"` +} + +func (m *Result) Reset() { *m = Result{} } +func (m *Result) String() string { return proto.CompactTextString(m) } +func (*Result) ProtoMessage() {} +func (*Result) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{5} } + +func (m *Result) GetReturn() []byte { + if m != nil { + return m.Return + } + return nil +} + +func (m *Result) GetGasUsed() uint64 { + if m != nil { + return m.GasUsed + } + return 0 +} + +func (m *Result) GetNameEntry() *names.Entry { + if m != nil { + return m.NameEntry + } + return nil +} + +func (m *Result) GetPermArgs() *permission.PermArgs { + if m != nil { + return m.PermArgs + } + return nil +} + +func (*Result) XXX_MessageName() string { + return "exec.Result" +} + +type LogEvent struct { + Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"` + Data github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,2,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"` + Topics []github_com_hyperledger_burrow_binary.Word256 `protobuf:"bytes,3,rep,name=Topics,customtype=github.com/hyperledger/burrow/binary.Word256" json:"Topics"` +} + +func (m *LogEvent) Reset() { *m = LogEvent{} } +func (m *LogEvent) String() string { return proto.CompactTextString(m) } +func (*LogEvent) ProtoMessage() {} +func (*LogEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{6} } + +func (*LogEvent) XXX_MessageName() string { + return "exec.LogEvent" +} + +type CallEvent struct { + CallData *CallData `protobuf:"bytes,1,opt,name=CallData" json:"CallData,omitempty"` + Origin github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Origin,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Origin"` + StackDepth uint64 `protobuf:"varint,3,opt,name=StackDepth,proto3" json:"StackDepth,omitempty"` + Return github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,4,opt,name=Return,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Return"` +} + +func (m *CallEvent) Reset() { *m = CallEvent{} } +func (m *CallEvent) String() string { return proto.CompactTextString(m) } +func (*CallEvent) ProtoMessage() {} +func (*CallEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{7} } + +func (m *CallEvent) GetCallData() *CallData { + if m != nil { + return m.CallData + } + return nil +} + +func (m *CallEvent) GetStackDepth() uint64 { + if m != nil { + return m.StackDepth + } + return 0 +} + +func (*CallEvent) XXX_MessageName() string { + return "exec.CallEvent" +} + +type InputEvent struct { + Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"` +} + +func (m *InputEvent) Reset() { *m = InputEvent{} } +func (m *InputEvent) String() string { return proto.CompactTextString(m) } +func (*InputEvent) ProtoMessage() {} +func (*InputEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{8} } + +func (*InputEvent) XXX_MessageName() string { + return "exec.InputEvent" +} + +type OutputEvent struct { + Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"` +} + +func (m *OutputEvent) Reset() { *m = OutputEvent{} } +func (m *OutputEvent) String() string { return proto.CompactTextString(m) } +func (*OutputEvent) ProtoMessage() {} +func (*OutputEvent) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{9} } + +func (*OutputEvent) XXX_MessageName() string { + return "exec.OutputEvent" +} + +type CallData struct { + Caller github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Caller,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Caller"` + Callee github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Callee,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Callee"` + Data github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,3,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"` + Value uint64 `protobuf:"varint,4,opt,name=Value,proto3" json:"Value,omitempty"` + Gas uint64 `protobuf:"varint,5,opt,name=Gas,proto3" json:"Gas,omitempty"` +} + +func (m *CallData) Reset() { *m = CallData{} } +func (m *CallData) String() string { return proto.CompactTextString(m) } +func (*CallData) ProtoMessage() {} +func (*CallData) Descriptor() ([]byte, []int) { return fileDescriptorExec, []int{10} } + +func (m *CallData) GetValue() uint64 { + if m != nil { + return m.Value + } + return 0 +} + +func (m *CallData) GetGas() uint64 { + if m != nil { + return m.Gas + } + return 0 +} + +func (*CallData) XXX_MessageName() string { + return "exec.CallData" +} +func init() { + proto.RegisterType((*BlockExecution)(nil), "exec.BlockExecution") + golang_proto.RegisterType((*BlockExecution)(nil), "exec.BlockExecution") + proto.RegisterType((*BlockHeader)(nil), "exec.BlockHeader") + golang_proto.RegisterType((*BlockHeader)(nil), "exec.BlockHeader") + proto.RegisterType((*TxExecution)(nil), "exec.TxExecution") + golang_proto.RegisterType((*TxExecution)(nil), "exec.TxExecution") + proto.RegisterType((*Header)(nil), "exec.Header") + golang_proto.RegisterType((*Header)(nil), "exec.Header") + proto.RegisterType((*Event)(nil), "exec.Event") + golang_proto.RegisterType((*Event)(nil), "exec.Event") + proto.RegisterType((*Result)(nil), "exec.Result") + golang_proto.RegisterType((*Result)(nil), "exec.Result") + proto.RegisterType((*LogEvent)(nil), "exec.LogEvent") + golang_proto.RegisterType((*LogEvent)(nil), "exec.LogEvent") + proto.RegisterType((*CallEvent)(nil), "exec.CallEvent") + golang_proto.RegisterType((*CallEvent)(nil), "exec.CallEvent") + proto.RegisterType((*InputEvent)(nil), "exec.InputEvent") + golang_proto.RegisterType((*InputEvent)(nil), "exec.InputEvent") + proto.RegisterType((*OutputEvent)(nil), "exec.OutputEvent") + golang_proto.RegisterType((*OutputEvent)(nil), "exec.OutputEvent") + proto.RegisterType((*CallData)(nil), "exec.CallData") + golang_proto.RegisterType((*CallData)(nil), "exec.CallData") +} +func (m *BlockExecution) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlockExecution) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Height != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Height)) + } + if m.BlockHeader != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.BlockHeader.Size())) + n1, err := m.BlockHeader.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if len(m.TxExecutions) > 0 { + for _, msg := range m.TxExecutions { + dAtA[i] = 0x1a + i++ + i = encodeVarintExec(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *BlockHeader) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlockHeader) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.JSON) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(len(m.JSON))) + i += copy(dAtA[i:], m.JSON) + } + if m.NumTxs != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.NumTxs)) + } + return i, nil +} + +func (m *TxExecution) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TxExecution) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TxType != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.TxType)) + } + dAtA[i] = 0x1a + i++ + i = encodeVarintExec(dAtA, i, uint64(m.TxHash.Size())) + n2, err := m.TxHash.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + if m.Height != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Height)) + } + if m.Index != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Index)) + } + if m.Envelope != nil { + dAtA[i] = 0x32 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Envelope.Size())) + n3, err := m.Envelope.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if len(m.Events) > 0 { + for _, msg := range m.Events { + dAtA[i] = 0x3a + i++ + i = encodeVarintExec(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.Result != nil { + dAtA[i] = 0x42 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Result.Size())) + n4, err := m.Result.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + if m.Receipt != nil { + dAtA[i] = 0x4a + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Receipt.Size())) + n5, err := m.Receipt.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + if m.Exception != nil { + dAtA[i] = 0x52 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Exception.Size())) + n6, err := m.Exception.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n6 + } + return i, nil +} + +func (m *Header) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Header) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TxType != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.TxType)) + } + dAtA[i] = 0x12 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.TxHash.Size())) + n7, err := m.TxHash.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n7 + if m.EventType != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.EventType)) + } + if len(m.EventID) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintExec(dAtA, i, uint64(len(m.EventID))) + i += copy(dAtA[i:], m.EventID) + } + if m.Height != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Height)) + } + if m.Index != 0 { + dAtA[i] = 0x30 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Index)) + } + if m.Exception != nil { + dAtA[i] = 0x3a + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Exception.Size())) + n8, err := m.Exception.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n8 + } + return i, nil +} + +func (m *Event) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Event) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Header.Size())) + n9, err := m.Header.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n9 + } + if m.Input != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Input.Size())) + n10, err := m.Input.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n10 + } + if m.Output != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Output.Size())) + n11, err := m.Output.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 + } + if m.Call != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Call.Size())) + n12, err := m.Call.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n12 + } + if m.Log != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Log.Size())) + n13, err := m.Log.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n13 + } + return i, nil +} + +func (m *Result) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Result) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Return) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(len(m.Return))) + i += copy(dAtA[i:], m.Return) + } + if m.GasUsed != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.GasUsed)) + } + if m.NameEntry != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintExec(dAtA, i, uint64(m.NameEntry.Size())) + n14, err := m.NameEntry.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n14 + } + if m.PermArgs != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.PermArgs.Size())) + n15, err := m.PermArgs.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n15 + } + return i, nil +} + +func (m *LogEvent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LogEvent) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Address.Size())) + n16, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n16 + dAtA[i] = 0x12 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Data.Size())) + n17, err := m.Data.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n17 + if len(m.Topics) > 0 { + for _, msg := range m.Topics { + dAtA[i] = 0x1a + i++ + i = encodeVarintExec(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *CallEvent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CallEvent) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.CallData != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(m.CallData.Size())) + n18, err := m.CallData.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n18 + } + dAtA[i] = 0x12 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Origin.Size())) + n19, err := m.Origin.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n19 + if m.StackDepth != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.StackDepth)) + } + dAtA[i] = 0x22 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Return.Size())) + n20, err := m.Return.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n20 + return i, nil +} + +func (m *InputEvent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *InputEvent) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Address.Size())) + n21, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n21 + return i, nil +} + +func (m *OutputEvent) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *OutputEvent) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Address.Size())) + n22, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n22 + return i, nil +} + +func (m *CallData) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CallData) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Caller.Size())) + n23, err := m.Caller.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n23 + dAtA[i] = 0x12 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Callee.Size())) + n24, err := m.Callee.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n24 + dAtA[i] = 0x1a + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Data.Size())) + n25, err := m.Data.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n25 + if m.Value != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Value)) + } + if m.Gas != 0 { + dAtA[i] = 0x28 + i++ + i = encodeVarintExec(dAtA, i, uint64(m.Gas)) + } + return i, nil +} + +func encodeVarintExec(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *BlockExecution) Size() (n int) { + var l int + _ = l + if m.Height != 0 { + n += 1 + sovExec(uint64(m.Height)) + } + if m.BlockHeader != nil { + l = m.BlockHeader.Size() + n += 1 + l + sovExec(uint64(l)) + } + if len(m.TxExecutions) > 0 { + for _, e := range m.TxExecutions { + l = e.Size() + n += 1 + l + sovExec(uint64(l)) + } + } + return n +} + +func (m *BlockHeader) Size() (n int) { + var l int + _ = l + l = len(m.JSON) + if l > 0 { + n += 1 + l + sovExec(uint64(l)) + } + if m.NumTxs != 0 { + n += 1 + sovExec(uint64(m.NumTxs)) + } + return n +} + +func (m *TxExecution) Size() (n int) { + var l int + _ = l + if m.TxType != 0 { + n += 1 + sovExec(uint64(m.TxType)) + } + l = m.TxHash.Size() + n += 1 + l + sovExec(uint64(l)) + if m.Height != 0 { + n += 1 + sovExec(uint64(m.Height)) + } + if m.Index != 0 { + n += 1 + sovExec(uint64(m.Index)) + } + if m.Envelope != nil { + l = m.Envelope.Size() + n += 1 + l + sovExec(uint64(l)) + } + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovExec(uint64(l)) + } + } + if m.Result != nil { + l = m.Result.Size() + n += 1 + l + sovExec(uint64(l)) + } + if m.Receipt != nil { + l = m.Receipt.Size() + n += 1 + l + sovExec(uint64(l)) + } + if m.Exception != nil { + l = m.Exception.Size() + n += 1 + l + sovExec(uint64(l)) + } + return n +} + +func (m *Header) Size() (n int) { + var l int + _ = l + if m.TxType != 0 { + n += 1 + sovExec(uint64(m.TxType)) + } + l = m.TxHash.Size() + n += 1 + l + sovExec(uint64(l)) + if m.EventType != 0 { + n += 1 + sovExec(uint64(m.EventType)) + } + l = len(m.EventID) + if l > 0 { + n += 1 + l + sovExec(uint64(l)) + } + if m.Height != 0 { + n += 1 + sovExec(uint64(m.Height)) + } + if m.Index != 0 { + n += 1 + sovExec(uint64(m.Index)) + } + if m.Exception != nil { + l = m.Exception.Size() + n += 1 + l + sovExec(uint64(l)) + } + return n +} + +func (m *Event) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovExec(uint64(l)) + } + if m.Input != nil { + l = m.Input.Size() + n += 1 + l + sovExec(uint64(l)) + } + if m.Output != nil { + l = m.Output.Size() + n += 1 + l + sovExec(uint64(l)) + } + if m.Call != nil { + l = m.Call.Size() + n += 1 + l + sovExec(uint64(l)) + } + if m.Log != nil { + l = m.Log.Size() + n += 1 + l + sovExec(uint64(l)) + } + return n +} + +func (m *Result) Size() (n int) { + var l int + _ = l + l = len(m.Return) + if l > 0 { + n += 1 + l + sovExec(uint64(l)) + } + if m.GasUsed != 0 { + n += 1 + sovExec(uint64(m.GasUsed)) + } + if m.NameEntry != nil { + l = m.NameEntry.Size() + n += 1 + l + sovExec(uint64(l)) + } + if m.PermArgs != nil { + l = m.PermArgs.Size() + n += 1 + l + sovExec(uint64(l)) + } + return n +} + +func (m *LogEvent) Size() (n int) { + var l int + _ = l + l = m.Address.Size() + n += 1 + l + sovExec(uint64(l)) + l = m.Data.Size() + n += 1 + l + sovExec(uint64(l)) + if len(m.Topics) > 0 { + for _, e := range m.Topics { + l = e.Size() + n += 1 + l + sovExec(uint64(l)) + } + } + return n +} + +func (m *CallEvent) Size() (n int) { + var l int + _ = l + if m.CallData != nil { + l = m.CallData.Size() + n += 1 + l + sovExec(uint64(l)) + } + l = m.Origin.Size() + n += 1 + l + sovExec(uint64(l)) + if m.StackDepth != 0 { + n += 1 + sovExec(uint64(m.StackDepth)) + } + l = m.Return.Size() + n += 1 + l + sovExec(uint64(l)) + return n +} + +func (m *InputEvent) Size() (n int) { + var l int + _ = l + l = m.Address.Size() + n += 1 + l + sovExec(uint64(l)) + return n +} + +func (m *OutputEvent) Size() (n int) { + var l int + _ = l + l = m.Address.Size() + n += 1 + l + sovExec(uint64(l)) + return n +} + +func (m *CallData) Size() (n int) { + var l int + _ = l + l = m.Caller.Size() + n += 1 + l + sovExec(uint64(l)) + l = m.Callee.Size() + n += 1 + l + sovExec(uint64(l)) + l = m.Data.Size() + n += 1 + l + sovExec(uint64(l)) + if m.Value != 0 { + n += 1 + sovExec(uint64(m.Value)) + } + if m.Gas != 0 { + n += 1 + sovExec(uint64(m.Gas)) + } + return n +} + +func sovExec(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozExec(x uint64) (n int) { + return sovExec(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *BlockExecution) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BlockExecution: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlockExecution: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockHeader", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BlockHeader == nil { + m.BlockHeader = &BlockHeader{} + } + if err := m.BlockHeader.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxExecutions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TxExecutions = append(m.TxExecutions, &TxExecution{}) + if err := m.TxExecutions[len(m.TxExecutions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BlockHeader) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BlockHeader: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlockHeader: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JSON", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JSON = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumTxs", wireType) + } + m.NumTxs = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumTxs |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TxExecution) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxExecution: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxExecution: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxType", wireType) + } + m.TxType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxType |= (github_com_hyperledger_burrow_txs_payload.Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Envelope", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Envelope == nil { + m.Envelope = &github_com_hyperledger_burrow_txs.Envelope{} + } + if err := m.Envelope.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, &Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Result == nil { + m.Result = &Result{} + } + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Receipt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Receipt == nil { + m.Receipt = &txs.Receipt{} + } + if err := m.Receipt.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Exception", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Exception == nil { + m.Exception = &errors.Exception{} + } + if err := m.Exception.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Header) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Header: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Header: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxType", wireType) + } + m.TxType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxType |= (github_com_hyperledger_burrow_txs_payload.Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EventType", wireType) + } + m.EventType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EventType |= (EventType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EventID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EventID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Exception", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Exception == nil { + m.Exception = &errors.Exception{} + } + if err := m.Exception.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Event) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Event: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &Header{} + } + if err := m.Header.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Input == nil { + m.Input = &InputEvent{} + } + if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Output", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Output == nil { + m.Output = &OutputEvent{} + } + if err := m.Output.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Call", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Call == nil { + m.Call = &CallEvent{} + } + if err := m.Call.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Log", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Log == nil { + m.Log = &LogEvent{} + } + if err := m.Log.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Result) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Result: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Result: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Return", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Return = append(m.Return[:0], dAtA[iNdEx:postIndex]...) + if m.Return == nil { + m.Return = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GasUsed", wireType) + } + m.GasUsed = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GasUsed |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NameEntry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NameEntry == nil { + m.NameEntry = &names.Entry{} + } + if err := m.NameEntry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PermArgs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PermArgs == nil { + m.PermArgs = &permission.PermArgs{} + } + if err := m.PermArgs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LogEvent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LogEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LogEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Topics", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_hyperledger_burrow_binary.Word256 + m.Topics = append(m.Topics, v) + if err := m.Topics[len(m.Topics)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CallEvent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CallEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CallEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CallData", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CallData == nil { + m.CallData = &CallData{} + } + if err := m.CallData.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Origin", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Origin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StackDepth", wireType) + } + m.StackDepth = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StackDepth |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Return", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Return.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *InputEvent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: InputEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: InputEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OutputEvent) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: OutputEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OutputEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CallData) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CallData: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CallData: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Caller", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Caller.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Callee", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Callee.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthExec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Value |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Gas", wireType) + } + m.Gas = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowExec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Gas |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipExec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthExec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipExec(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowExec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowExec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowExec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthExec + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowExec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipExec(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthExec = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowExec = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("exec.proto", fileDescriptorExec) } +func init() { golang_proto.RegisterFile("exec.proto", fileDescriptorExec) } + +var fileDescriptorExec = []byte{ + // 963 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcd, 0x6f, 0x1b, 0x45, + 0x14, 0xef, 0xf8, 0x63, 0x6d, 0x3f, 0x3b, 0x25, 0x8c, 0x22, 0xb4, 0xea, 0xc1, 0x6b, 0xa5, 0xa8, + 0x0a, 0xa1, 0x5d, 0x23, 0x97, 0x20, 0xc1, 0xad, 0x26, 0x56, 0x93, 0x2a, 0x24, 0x68, 0x6a, 0x40, + 0x70, 0x5b, 0xef, 0x0e, 0x9b, 0x25, 0xf6, 0xee, 0x6a, 0x76, 0xb6, 0xac, 0x8f, 0x70, 0xe2, 0xc8, + 0x81, 0x03, 0xc7, 0xe6, 0x02, 0xff, 0x06, 0xc7, 0x1c, 0xb9, 0x52, 0x24, 0x0b, 0x25, 0xff, 0x45, + 0x4f, 0x68, 0x3e, 0x76, 0xbd, 0x8e, 0xaa, 0xb6, 0x6a, 0xd2, 0x4b, 0x34, 0xef, 0xbd, 0xdf, 0xfe, + 0xe6, 0x7d, 0xfc, 0xe6, 0xc5, 0x00, 0x34, 0xa3, 0xae, 0x1d, 0xb3, 0x88, 0x47, 0xb8, 0x26, 0xce, + 0xb7, 0xee, 0xf9, 0x01, 0x3f, 0x4e, 0x27, 0xb6, 0x1b, 0xcd, 0xfa, 0x7e, 0xe4, 0x47, 0x7d, 0x19, + 0x9c, 0xa4, 0xdf, 0x4b, 0x4b, 0x1a, 0xf2, 0xa4, 0x3e, 0xba, 0x75, 0xb7, 0x04, 0xe7, 0x34, 0xf4, + 0x28, 0x9b, 0x05, 0x21, 0xef, 0x3b, 0x13, 0x37, 0xe8, 0xf3, 0x79, 0x4c, 0x13, 0xf5, 0x57, 0xa3, + 0x3b, 0x94, 0xb1, 0x88, 0xe5, 0x56, 0x3b, 0x74, 0x66, 0x45, 0xa8, 0xc5, 0xb3, 0xfc, 0xb8, 0x1e, + 0x0b, 0x96, 0x24, 0x09, 0xa2, 0x50, 0x79, 0x36, 0x7f, 0x43, 0x70, 0x73, 0x38, 0x8d, 0xdc, 0x93, + 0x51, 0x46, 0xdd, 0x94, 0x07, 0x51, 0x88, 0xdf, 0x03, 0x63, 0x8f, 0x06, 0xfe, 0x31, 0x37, 0x51, + 0x0f, 0x6d, 0xd5, 0x88, 0xb6, 0xf0, 0x7d, 0x68, 0x4b, 0xe4, 0x1e, 0x75, 0x3c, 0xca, 0xcc, 0x4a, + 0x0f, 0x6d, 0xb5, 0x07, 0xef, 0xda, 0xb2, 0xce, 0x52, 0x80, 0x94, 0x51, 0x78, 0x07, 0x3a, 0xe3, + 0xac, 0xe0, 0x4e, 0xcc, 0x6a, 0xaf, 0xba, 0xfc, 0xaa, 0x14, 0x21, 0x2b, 0xb0, 0xcd, 0x4f, 0x57, + 0xee, 0xc2, 0x18, 0x6a, 0x8f, 0x1e, 0x1f, 0x1d, 0xca, 0x84, 0x5a, 0x44, 0x9e, 0x45, 0x9a, 0x87, + 0xe9, 0x6c, 0x9c, 0x25, 0x32, 0x93, 0x3a, 0xd1, 0xd6, 0xe6, 0x45, 0x15, 0xda, 0x25, 0x2e, 0xfc, + 0x08, 0x8c, 0x71, 0x36, 0x9e, 0xc7, 0x54, 0xe2, 0xd6, 0x86, 0x83, 0xe7, 0x0b, 0xcb, 0x2e, 0xf5, + 0xf6, 0x78, 0x1e, 0x53, 0x36, 0xa5, 0x9e, 0x4f, 0x59, 0x7f, 0x92, 0x32, 0x16, 0xfd, 0xd8, 0xe7, + 0x59, 0xd2, 0x8f, 0x9d, 0xf9, 0x34, 0x72, 0x3c, 0x5b, 0x7c, 0x49, 0x34, 0x03, 0xfe, 0x42, 0x70, + 0xed, 0x39, 0xc9, 0xb1, 0x59, 0xed, 0xa1, 0xad, 0xce, 0x70, 0xe7, 0x6c, 0x61, 0xdd, 0x78, 0xb6, + 0xb0, 0xee, 0xbd, 0x9c, 0x6f, 0x12, 0x84, 0x0e, 0x9b, 0xdb, 0x7b, 0x34, 0x1b, 0xce, 0x39, 0x4d, + 0x88, 0x26, 0x29, 0x75, 0xba, 0xb6, 0xd2, 0xe9, 0x0d, 0xa8, 0xef, 0x87, 0x1e, 0xcd, 0xcc, 0xba, + 0x74, 0x2b, 0x03, 0x7f, 0x0b, 0xcd, 0x51, 0xf8, 0x84, 0x4e, 0xa3, 0x98, 0x9a, 0x86, 0x6c, 0xfe, + 0x9a, 0x2d, 0x46, 0x9b, 0x3b, 0x87, 0xf6, 0xb3, 0x85, 0xb5, 0xfd, 0xca, 0xca, 0x0a, 0x3c, 0x29, + 0xe8, 0xf0, 0x6d, 0x30, 0x46, 0x4f, 0x68, 0xc8, 0x13, 0xb3, 0x21, 0xe7, 0xd3, 0x56, 0xf3, 0x91, + 0x3e, 0xa2, 0x43, 0xf8, 0x7d, 0x30, 0x08, 0x4d, 0xd2, 0x29, 0x37, 0x9b, 0xf2, 0xf6, 0x8e, 0x02, + 0x29, 0x1f, 0xd1, 0x31, 0x7c, 0x07, 0x1a, 0x84, 0xba, 0x34, 0x88, 0xb9, 0xd9, 0xd2, 0x30, 0x71, + 0xa9, 0xf6, 0x91, 0x3c, 0x88, 0xfb, 0xd0, 0x1a, 0x65, 0x2e, 0x8d, 0xc5, 0x8c, 0x4c, 0xc8, 0xb5, + 0xa4, 0x44, 0x5c, 0x04, 0xc8, 0x12, 0xf3, 0x59, 0xe7, 0x97, 0x53, 0x0b, 0xfd, 0x7a, 0x6a, 0xa1, + 0xa7, 0xa7, 0x16, 0xda, 0xfc, 0xb7, 0x22, 0x7a, 0x27, 0xc5, 0xb1, 0x1c, 0x30, 0xba, 0xc6, 0x01, + 0x57, 0xae, 0x63, 0xc0, 0x1f, 0x42, 0x4b, 0x36, 0x4f, 0x66, 0x57, 0x95, 0xd9, 0xad, 0x3d, 0x5f, + 0x58, 0x4b, 0x27, 0x59, 0x1e, 0xb1, 0x09, 0x0d, 0x69, 0xec, 0xef, 0x4a, 0x39, 0xb4, 0x48, 0x6e, + 0x96, 0x74, 0x52, 0x7f, 0xb1, 0x4e, 0x8c, 0xb2, 0x4e, 0x56, 0x3a, 0xdb, 0x78, 0x8d, 0xce, 0xae, + 0xff, 0xfe, 0xd4, 0xba, 0xb1, 0xd2, 0xdd, 0x7f, 0x10, 0xd4, 0xe5, 0xe5, 0x62, 0xe8, 0xfa, 0xbd, + 0xa3, 0xf2, 0xd0, 0xf5, 0x53, 0xcf, 0x47, 0x70, 0x47, 0x24, 0x12, 0xa7, 0x5c, 0x2f, 0x85, 0x75, + 0x05, 0x92, 0x2e, 0xa5, 0x21, 0x15, 0xc6, 0x1f, 0x80, 0x71, 0x94, 0x72, 0x01, 0xac, 0x96, 0xb7, + 0x87, 0xf2, 0x69, 0xb5, 0x29, 0x03, 0xdf, 0x86, 0xda, 0xe7, 0xce, 0x74, 0x2a, 0x5b, 0xd1, 0x1e, + 0xbc, 0xa3, 0x80, 0xc2, 0xa3, 0x60, 0x32, 0x88, 0x7b, 0x50, 0x3d, 0x88, 0x7c, 0xd9, 0x95, 0xf6, + 0xe0, 0xa6, 0xc2, 0x1c, 0x44, 0xbe, 0x82, 0x88, 0xd0, 0x0b, 0x6a, 0xfb, 0x03, 0xe5, 0x3a, 0x16, + 0x7d, 0x25, 0x94, 0xa7, 0x2c, 0x94, 0xc5, 0x75, 0x88, 0xb6, 0xc4, 0x24, 0x1e, 0x3a, 0xc9, 0x57, + 0x09, 0xf5, 0x64, 0x41, 0x35, 0x92, 0x9b, 0x78, 0x1b, 0x5a, 0x87, 0xce, 0x8c, 0x8e, 0x42, 0xce, + 0xe6, 0xba, 0x86, 0x8e, 0xad, 0x96, 0xad, 0xf4, 0x91, 0x65, 0x18, 0x7f, 0x04, 0xcd, 0x2f, 0x29, + 0x9b, 0x3d, 0x60, 0x7e, 0xa2, 0xab, 0xd8, 0xb0, 0x4b, 0xfb, 0x37, 0x8f, 0x91, 0x02, 0x75, 0x49, + 0xe2, 0x3f, 0x55, 0xa0, 0x99, 0x17, 0x83, 0x0f, 0xa1, 0xf1, 0xc0, 0xf3, 0x18, 0x4d, 0x12, 0x95, + 0xeb, 0xf0, 0x63, 0xad, 0xcc, 0xbb, 0x2f, 0x57, 0xa6, 0xcb, 0xe6, 0x31, 0x8f, 0x6c, 0xfd, 0x2d, + 0xc9, 0x49, 0xf0, 0x3e, 0xd4, 0x76, 0x1d, 0xee, 0x5c, 0x4d, 0xe6, 0x92, 0x02, 0x1f, 0x80, 0x31, + 0x8e, 0xe2, 0xc0, 0x55, 0xcb, 0xfd, 0xb5, 0x33, 0xd3, 0x64, 0xdf, 0x44, 0xcc, 0x1b, 0xec, 0x7c, + 0x42, 0x34, 0xc7, 0xa5, 0x1e, 0xfc, 0x5c, 0x81, 0x56, 0x31, 0x74, 0xbc, 0x0d, 0x4d, 0x61, 0xc8, + 0xc4, 0x51, 0x79, 0xe6, 0xb9, 0x97, 0x14, 0x71, 0x91, 0xd5, 0x11, 0x0b, 0xfc, 0x20, 0xd4, 0x25, + 0xbe, 0x59, 0xbf, 0x34, 0x07, 0xee, 0x02, 0x3c, 0xe6, 0x8e, 0x7b, 0xb2, 0x4b, 0x63, 0xae, 0x96, + 0x7f, 0x8d, 0x94, 0x3c, 0x62, 0x6f, 0x68, 0x25, 0xd5, 0xae, 0xb4, 0x37, 0x14, 0xc9, 0xa5, 0x26, + 0xfc, 0x00, 0xb0, 0x7c, 0x4a, 0xd7, 0xad, 0x84, 0x4b, 0x77, 0x9d, 0x40, 0xbb, 0xf4, 0x1a, 0xdf, + 0xf2, 0x65, 0x7f, 0x56, 0x60, 0x65, 0x60, 0xe2, 0xac, 0x37, 0xcd, 0x1b, 0x0f, 0x4c, 0x71, 0x14, + 0x6c, 0xf4, 0x6a, 0xe3, 0x57, 0x1c, 0xc5, 0x6b, 0xa9, 0x5e, 0xfd, 0xb5, 0x6c, 0x40, 0xfd, 0x6b, + 0x67, 0x9a, 0x52, 0xfd, 0x2f, 0x5f, 0x19, 0x78, 0x1d, 0xaa, 0x0f, 0x9d, 0x44, 0xaf, 0x77, 0x71, + 0x5c, 0xed, 0xd4, 0x70, 0x78, 0x76, 0xde, 0x45, 0x7f, 0x9f, 0x77, 0xd1, 0x7f, 0xe7, 0x5d, 0xf4, + 0xd7, 0x45, 0x17, 0x9d, 0x5d, 0x74, 0xd1, 0x77, 0xaf, 0x28, 0x86, 0xe6, 0xbf, 0x81, 0xe4, 0x69, + 0x62, 0xc8, 0x5f, 0x7c, 0xf7, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x4c, 0xf0, 0xd7, 0x87, 0x9a, + 0x0a, 0x00, 0x00, +} diff --git a/execution/exec/header.go b/execution/exec/header.go new file mode 100644 index 0000000000000000000000000000000000000000..1ed0b5aac01e7748a56256e93612241a78ed945f --- /dev/null +++ b/execution/exec/header.go @@ -0,0 +1,13 @@ +package exec + +import ( + "fmt" +) + +func (h *Header) String() string { + if h == nil { + return fmt.Sprintf("Header{<Empty>}") + } + return fmt.Sprintf("Header{Tx{%v}: %v; Event{%v}: %v; Height: %v; Index: %v}", + h.TxType, h.TxHash, h.EventType, h.EventID, h.Height, h.Index) +} diff --git a/execution/events/log.go b/execution/exec/log_event.go similarity index 51% rename from execution/events/log.go rename to execution/exec/log_event.go index b41fad89fcc24db4a431e64fdf4dd8013bd8b30a..ea1aa02295844c0397fd7ee44c1d0bc504bedc54 100644 --- a/execution/events/log.go +++ b/execution/exec/log_event.go @@ -12,78 +12,39 @@ // See the License for the specific language governing permissions and // limitations under the License. -package events +package exec import ( - "context" - "fmt" - "strings" - "github.com/hyperledger/burrow/binary" + "fmt" + . "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/txs" "github.com/tmthrgd/go-hex" ) -// Functions to generate eventId strings - -func EventStringLogEvent(addr crypto.Address) string { return fmt.Sprintf("Log/%s", addr) } - -//---------------------------------------- - -// EventDataLog fires when a contract executes the LOG opcode -type EventDataLog struct { - Height uint64 - Address crypto.Address - Topics []Word256 - Data binary.HexBytes -} +const logNTextTopicCutset = "\x00" +const LogNKeyPrefix = "Log" -// Publish/Subscribe -func PublishLogEvent(publisher event.Publisher, tx *txs.Tx, log *EventDataLog) error { - ev := &Event{ - Header: &Header{ - TxType: tx.Type(), - TxHash: tx.Hash(), - EventType: TypeLog, - EventID: EventStringLogEvent(log.Address), - Height: log.Height, - }, - Log: log, - } - return publisher.Publish(context.Background(), ev, ev.Tags()) +func LogNKey(topic int) string { + return fmt.Sprintf("%s%d", LogNKeyPrefix, topic) } -func SubscribeLogEvent(ctx context.Context, subscribable event.Subscribable, subscriber string, address crypto.Address, - ch chan<- *EventDataLog) error { - - qry := event.QueryForEventID(EventStringLogEvent(address)) - - return event.SubscribeCallback(ctx, subscribable, subscriber, qry, func(message interface{}) (stop bool) { - ev, ok := message.(*Event) - if ok && ev.Log != nil { - ch <- ev.Log - } - return - }) +func LogNTextKey(topic int) string { + return fmt.Sprintf("%s%dText", LogNKeyPrefix, topic) } -// Tags -const logNTextTopicCutset = "\x00" - var logTagKeys []string var logNTopicIndex = make(map[string]int, 5) var logNTextTopicIndex = make(map[string]int, 5) func init() { for i := 0; i <= 4; i++ { - logN := event.LogNKey(i) - logTagKeys = append(logTagKeys, event.LogNKey(i)) - logNText := event.LogNTextKey(i) + logN := LogNKey(i) + logTagKeys = append(logTagKeys, LogNKey(i)) + logNText := LogNTextKey(i) logTagKeys = append(logTagKeys, logNText) logNTopicIndex[logN] = i logNTextTopicIndex[logNText] = i @@ -91,7 +52,7 @@ func init() { logTagKeys = append(logTagKeys, event.AddressKey) } -func (log *EventDataLog) Get(key string) (string, bool) { +func (log *LogEvent) Get(key string) (string, bool) { var value interface{} switch key { case event.AddressKey: @@ -108,17 +69,17 @@ func (log *EventDataLog) Get(key string) (string, bool) { return query.StringFromValue(value), true } -func (log *EventDataLog) GetTopic(i int) Word256 { +func (log *LogEvent) GetTopic(i int) Word256 { if i < len(log.Topics) { return log.Topics[i] } return Word256{} } -func (log *EventDataLog) Len() int { +func (log *LogEvent) Len() int { return len(logTagKeys) } -func (log *EventDataLog) Keys() []string { +func (log *LogEvent) Keys() []string { return logTagKeys } diff --git a/execution/exec/tx_execution.go b/execution/exec/tx_execution.go new file mode 100644 index 0000000000000000000000000000000000000000..493af29207bd8bf63f40c1091f6cae7c41cd91c9 --- /dev/null +++ b/execution/exec/tx_execution.go @@ -0,0 +1,154 @@ +package exec + +import ( + "fmt" + + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/event/query" + "github.com/hyperledger/burrow/execution/errors" + "github.com/hyperledger/burrow/execution/names" + "github.com/hyperledger/burrow/permission" + "github.com/hyperledger/burrow/txs" +) + +func EventStringAccountInput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Input", addr) } +func EventStringAccountOutput(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Output", addr) } + +func EventStringAccountCall(addr crypto.Address) string { return fmt.Sprintf("Acc/%s/Call", addr) } +func EventStringLogEvent(addr crypto.Address) string { return fmt.Sprintf("Log/%s", addr) } +func EventStringTxExecution(txHash []byte) string { return fmt.Sprintf("Execution/Tx/%X", txHash) } + +func NewTxExecution(txEnv *txs.Envelope) *TxExecution { + return &TxExecution{ + TxHash: txEnv.Tx.Hash(), + TxType: txEnv.Tx.Type(), + Envelope: txEnv, + Receipt: txEnv.Tx.GenerateReceipt(), + } +} + +func DecodeTxExecution(bs []byte) (*TxExecution, error) { + txe := new(TxExecution) + err := cdc.UnmarshalBinary(bs, txe) + if err != nil { + return nil, err + } + return txe, nil +} + +func (txe *TxExecution) Encode() ([]byte, error) { + return cdc.MarshalBinary(txe) +} + +func (*TxExecution) EventType() EventType { + return TypeTxExecution +} + +func (txe *TxExecution) Header(eventType EventType, eventID string, exception *errors.Exception) *Header { + return &Header{ + TxType: txe.TxType, + TxHash: txe.TxHash, + EventType: eventType, + EventID: eventID, + Height: txe.Height, + Exception: exception, + } +} + +// Emit events +func (txe *TxExecution) Input(address crypto.Address, exception *errors.Exception) { + txe.Append(&Event{ + Header: txe.Header(TypeAccountInput, EventStringAccountInput(address), exception), + Input: &InputEvent{ + Address: address, + }, + }) +} + +func (txe *TxExecution) Output(address crypto.Address, exception *errors.Exception) { + txe.Append(&Event{ + Header: txe.Header(TypeAccountOutput, EventStringAccountOutput(address), exception), + Output: &OutputEvent{ + Address: address, + }, + }) +} + +func (txe *TxExecution) Log(log *LogEvent) { + txe.Append(&Event{ + Header: txe.Header(TypeLog, EventStringLogEvent(log.Address), nil), + Log: log, + }) +} + +func (txe *TxExecution) Call(call *CallEvent, exception *errors.Exception) { + txe.Append(&Event{ + Header: txe.Header(TypeCall, EventStringAccountCall(call.CallData.Callee), exception), + Call: call, + }) +} + +// Set result +func (txe *TxExecution) Return(returnValue []byte, gasUsed uint64) { + if txe.Result == nil { + txe.Result = &Result{} + } + txe.Result.Return = returnValue + txe.Result.GasUsed = gasUsed +} + +func (txe *TxExecution) Name(entry *names.Entry) { + if txe.Result == nil { + txe.Result = &Result{} + } + txe.Result.NameEntry = entry +} + +func (txe *TxExecution) Permission(permArgs *permission.PermArgs) { + if txe.Result == nil { + txe.Result = &Result{} + } + txe.Result.PermArgs = permArgs +} + +func (txe *TxExecution) Append(tail ...*Event) { + for i, ev := range tail { + if ev != nil && ev.Header != nil { + ev.Header.Index = uint64(len(txe.Events) + i) + ev.Header.Height = txe.Height + } + } + txe.Events = append(txe.Events, tail...) +} + +// Tags +type TaggedTxExecution struct { + query.Tagged + *TxExecution +} + +func (txe *TxExecution) Tagged() *TaggedTxExecution { + return &TaggedTxExecution{ + Tagged: query.MergeTags( + query.TagMap{ + event.EventIDKey: EventStringTxExecution(txe.TxHash), + event.EventTypeKey: txe.EventType()}, + query.MustReflectTags(txe), + txe.Envelope.Tagged(), + ), + TxExecution: txe, + } +} + +func (txe *TxExecution) TaggedEvents() TaggedEvents { + tevs := make(TaggedEvents, len(txe.Events)) + for i, ev := range txe.Events { + tevs[i] = ev.Tagged() + } + return tevs +} + +func QueryForTxExecution(txHash []byte) query.Queryable { + return query.NewBuilder().AndEquals(event.EventIDKey, EventStringTxExecution(txHash)) +} diff --git a/execution/execution.go b/execution/execution.go index 22eff6e9b33dc219c5ddbd90e267533a2bd2dcf8..23412014eddc452a9260e697a073403f8e87c123 100644 --- a/execution/execution.go +++ b/execution/execution.go @@ -19,23 +19,31 @@ import ( "runtime/debug" "sync" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "context" + + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/binary" bcm "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution/evm" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/execution/executors" "github.com/hyperledger/burrow/execution/names" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/txs" "github.com/hyperledger/burrow/txs/payload" + abciTypes "github.com/tendermint/abci/types" ) type Executor interface { - Execute(txEnv *txs.Envelope) error + Execute(txEnv *txs.Envelope) (*exec.TxExecution, error) +} + +type Context interface { + Execute(txe *exec.TxExecution) error } type ExecutorState interface { @@ -59,20 +67,21 @@ type BatchCommitter interface { BatchExecutor // Commit execution results to underlying State and provide opportunity // to mutate state before it is saved - Commit() (stateHash []byte, err error) + Commit(*abciTypes.Header) (stateHash []byte, err error) } type executor struct { sync.RWMutex - runCall bool - publisher event.Publisher - state ExecutorState - stateCache *state.Cache - nameRegCache *names.Cache - eventCache *event.Cache - logger *logging.Logger - vmOptions []func(*evm.VM) - txExecutors map[payload.Type]Executor + runCall bool + tip bcm.TipInfo + state ExecutorState + stateCache *state.Cache + nameRegCache *names.Cache + publisher event.Publisher + blockExecution *exec.BlockExecution + logger *logging.Logger + vmOptions []func(*evm.VM) + txExecutors map[payload.Type]Context } var _ BatchExecutor = (*executor)(nil) @@ -85,10 +94,10 @@ func NewBatchChecker(backend ExecutorState, tip bcm.TipInfo, logger *logging.Log logger.WithScope("NewBatchExecutor"), options...) } -func NewBatchCommitter(backend ExecutorState, tip bcm.TipInfo, publisher event.Publisher, logger *logging.Logger, +func NewBatchCommitter(backend ExecutorState, tip bcm.TipInfo, emitter event.Publisher, logger *logging.Logger, options ...ExecutionOption) BatchCommitter { - return newExecutor("CommitCache", true, backend, tip, publisher, + return newExecutor("CommitCache", true, backend, tip, emitter, logger.WithScope("NewBatchCommitter"), options...) } @@ -98,42 +107,41 @@ func newExecutor(name string, runCall bool, backend ExecutorState, tip bcm.TipIn exe := &executor{ runCall: runCall, state: backend, - publisher: publisher, + tip: tip, stateCache: state.NewCache(backend, state.Name(name)), - eventCache: event.NewCache(), nameRegCache: names.NewCache(backend), - logger: logger.With(structure.ComponentKey, "Executor"), + publisher: publisher, + blockExecution: &exec.BlockExecution{ + Height: tip.LastBlockHeight() + 1, + }, + logger: logger.With(structure.ComponentKey, "Executor"), } for _, option := range options { option(exe) } - exe.txExecutors = map[payload.Type]Executor{ + exe.txExecutors = map[payload.Type]Context{ payload.TypeSend: &executors.SendContext{ - Tip: tip, - StateWriter: exe.stateCache, - EventPublisher: exe.eventCache, - Logger: exe.logger, + Tip: tip, + StateWriter: exe.stateCache, + Logger: exe.logger, }, payload.TypeCall: &executors.CallContext{ - Tip: tip, - StateWriter: exe.stateCache, - EventPublisher: exe.eventCache, - RunCall: runCall, - VMOptions: exe.vmOptions, - Logger: exe.logger, + Tip: tip, + StateWriter: exe.stateCache, + RunCall: runCall, + VMOptions: exe.vmOptions, + Logger: exe.logger, }, payload.TypeName: &executors.NameContext{ - Tip: tip, - StateWriter: exe.stateCache, - EventPublisher: exe.eventCache, - NameReg: exe.nameRegCache, - Logger: exe.logger, + Tip: tip, + StateWriter: exe.stateCache, + NameReg: exe.nameRegCache, + Logger: exe.logger, }, payload.TypePermissions: &executors.PermissionsContext{ - Tip: tip, - StateWriter: exe.stateCache, - EventPublisher: exe.eventCache, - Logger: exe.logger, + Tip: tip, + StateWriter: exe.stateCache, + Logger: exe.logger, }, } return exe @@ -141,7 +149,7 @@ func newExecutor(name string, runCall bool, backend ExecutorState, tip bcm.TipIn // If the tx is invalid, an error will be returned. // Unlike ExecBlock(), state will not be altered. -func (exe *executor) Execute(txEnv *txs.Envelope) (err error) { +func (exe *executor) Execute(txEnv *txs.Envelope) (txe *exec.TxExecution, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("recovered from panic in executor.Execute(%s): %v\n%s", txEnv.String(), r, @@ -158,24 +166,53 @@ func (exe *executor) Execute(txEnv *txs.Envelope) (err error) { // Verify transaction signature against inputs err = txEnv.Verify(exe.stateCache) if err != nil { - return err + return nil, err } if txExecutor, ok := exe.txExecutors[txEnv.Tx.Type()]; ok { - return txExecutor.Execute(txEnv) + // Establish new TxExecution + txe := exe.blockExecution.Tx(txEnv) + err = txExecutor.Execute(txe) + if err != nil { + return nil, err + } + // Return execution for this tx + return txe, err + } + return nil, fmt.Errorf("unknown transaction type: %v", txEnv.Tx.Type()) +} + +func (exe *executor) finaliseBlockExecution(header *abciTypes.Header) (*exec.BlockExecution, error) { + if header != nil && uint64(header.Height) != exe.blockExecution.Height { + return nil, fmt.Errorf("trying to finalise block execution with height %v but passed Tendermint"+ + "block header at height %v", exe.blockExecution.Height, header.Height) + } + // Capture BlockExecution to return + be := exe.blockExecution + // Set the header when provided + be.BlockHeader = exec.BlockHeaderFromHeader(header) + // Start new execution for the next height + exe.blockExecution = &exec.BlockExecution{ + Height: exe.blockExecution.Height + 1, } - return fmt.Errorf("unknown transaction type: %v", txEnv.Tx.Type()) + return be, nil } -func (exe *executor) Commit() (_ []byte, err error) { +func (exe *executor) Commit(header *abciTypes.Header) (_ []byte, err error) { // The write lock to the executor is controlled by the caller (e.g. abci.App) so we do not acquire it here to avoid // deadlock defer func() { if r := recover(); r != nil { - err = fmt.Errorf("recovered from panic in executor.Commit(): %v\n%v", r, debug.Stack()) + err = fmt.Errorf("recovered from panic in executor.Commit(): %v\n%s", r, debug.Stack()) } }() - return exe.state.Update(func(ws Updatable) error { + exe.logger.InfoMsg("Executor committing", "height", exe.blockExecution.Height) + // Form BlockExecution for this block from TxExecutions and Tendermint block header + blockExecution, err := exe.finaliseBlockExecution(header) + if err != nil { + return nil, err + } + hash, err := exe.state.Update(func(ws Updatable) error { // flush the caches err := exe.stateCache.Flush(ws, exe.state) if err != nil { @@ -185,17 +222,27 @@ func (exe *executor) Commit() (_ []byte, err error) { if err != nil { return err } - err = exe.eventCache.Sync(ws) - if err != nil { - return err - } - // flush events to listeners - err = exe.eventCache.Flush(exe.publisher) + err = ws.AddBlock(blockExecution) if err != nil { return err } return nil }) + if err != nil { + return nil, err + } + // Now state is committed publish events + for _, txe := range blockExecution.TxExecutions { + publishErr := exe.publisher.Publish(context.Background(), txe, txe.Tagged()) + exe.logger.InfoMsg("Error publishing TxExecution", + "tx_hash", txe.TxHash, + structure.ErrorKey, publishErr) + } + publishErr := exe.publisher.Publish(context.Background(), blockExecution, blockExecution.Tagged()) + exe.logger.InfoMsg("Error publishing TxExecution", + "height", blockExecution.Height, + structure.ErrorKey, publishErr) + return hash, nil } func (exe *executor) Reset() error { diff --git a/execution/execution_test.go b/execution/execution_test.go index 74e5689ccf1f447032e88dd2b0eac57d09bc06c5..608da343cfbfdb99750fc30f747d7007ff0530a0 100644 --- a/execution/execution_test.go +++ b/execution/execution_test.go @@ -16,7 +16,6 @@ package execution import ( "bytes" - "context" "fmt" "strconv" "testing" @@ -24,24 +23,22 @@ import ( "runtime/debug" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" . "github.com/hyperledger/burrow/binary" bcm "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution/errors" - "github.com/hyperledger/burrow/execution/events" "github.com/hyperledger/burrow/execution/evm" . "github.com/hyperledger/burrow/execution/evm/asm" "github.com/hyperledger/burrow/execution/evm/asm/bc" "github.com/hyperledger/burrow/execution/evm/sha3" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/execution/names" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/permission" - "github.com/hyperledger/burrow/permission/snatives" - ptypes "github.com/hyperledger/burrow/permission/types" "github.com/hyperledger/burrow/txs" "github.com/hyperledger/burrow/txs/payload" "github.com/stretchr/testify/require" @@ -127,7 +124,32 @@ var testChainID = testGenesisDoc.ChainID() type testExecutor struct { *executor blockchain *bcm.Blockchain - event.Emitter +} + +func makeExecutor(state *State) *testExecutor { + blockchain := newBlockchain(testGenesisDoc) + return &testExecutor{ + executor: newExecutor("makeExecutorCache", true, state, blockchain.Tip, event.NewNoOpPublisher(), + logger), + blockchain: blockchain, + } +} + +func (te *testExecutor) signExecuteCommit(tx payload.Payload, signer acm.AddressableSigner) error { + txEnv := txs.Enclose(testChainID, tx) + err := txEnv.Sign(signer) + if err != nil { + return err + } + _, err = te.Execute(txEnv) + if err != nil { + return err + } + appHash, err := te.Commit(nil) + if err != nil { + return err + } + return te.blockchain.CommitBlock(time.Now(), nil, appHash) } func makeUsers(n int) []acm.AddressableSigner { @@ -145,17 +167,7 @@ func newBlockchain(genesisDoc *genesis.GenesisDoc) *bcm.Blockchain { return bc } -func makeExecutor(state *State) *testExecutor { - emitter := event.NewEmitter(logger) - blockchain := newBlockchain(testGenesisDoc) - return &testExecutor{ - executor: newExecutor("makeExecutorCache", true, state, blockchain.Tip, emitter, logger), - blockchain: blockchain, - Emitter: emitter, - } -} - -func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) genesis.GenesisDoc { +func newBaseGenDoc(globalPerm, accountPerm permission.AccountPermissions) genesis.GenesisDoc { var genAccounts []genesis.Account for _, user := range users[:5] { accountPermCopy := accountPerm // Create new instance for custom overridability. @@ -189,18 +201,13 @@ func newBaseGenDoc(globalPerm, accountPerm ptypes.AccountPermissions) genesis.Ge } } -//func getAccount(state state.AccountGetter, address acm.Address) acm.MutableAccount { -// acc, _ := state.GetMutableAccount(state, address) -// return acc -//} - func TestSendFails(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) - genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true) - genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true) + genDoc.Accounts[1].Permissions.Base.Set(permission.Send, true) + genDoc.Accounts[2].Permissions.Base.Set(permission.Call, true) + genDoc.Accounts[3].Permissions.Base.Set(permission.CreateContract, true) st, err := MakeGenesisState(stateDB, &genDoc) require.NoError(t, err) exe := makeExecutor(st) @@ -235,7 +242,7 @@ func TestSendFails(t *testing.T) { // simple send tx to unknown account without create_account perm should fail acc := getAccount(exe.stateCache, users[3].Address()) - acc.MutablePermissions().Base.Set(ptypes.Send, true) + acc.MutablePermissions().Base.Set(permission.Send, true) exe.stateCache.UpdateAccount(acc) tx = payload.NewSendTx() if err := tx.AddInput(exe.stateCache, users[3].PublicKey(), 5); err != nil { @@ -249,8 +256,8 @@ func TestName(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Name, true) + genDoc.Accounts[0].Permissions.Base.Set(permission.Send, true) + genDoc.Accounts[1].Permissions.Base.Set(permission.Name, true) st, err := MakeGenesisState(stateDB, &genDoc) require.NoError(t, err) batchCommitter := makeExecutor(st) @@ -277,9 +284,9 @@ func TestCallFails(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) - genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true) - genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true) + genDoc.Accounts[1].Permissions.Base.Set(permission.Send, true) + genDoc.Accounts[2].Permissions.Base.Set(permission.Call, true) + genDoc.Accounts[3].Permissions.Base.Set(permission.CreateContract, true) st, err := MakeGenesisState(stateDB, &genDoc) require.NoError(t, err) batchCommitter := makeExecutor(st) @@ -320,7 +327,7 @@ func TestSendPermission(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission + genDoc.Accounts[0].Permissions.Base.Set(permission.Send, true) // give the 0 account permission st, err := MakeGenesisState(stateDB, &genDoc) require.NoError(t, err) batchCommitter := makeExecutor(st) @@ -345,7 +352,7 @@ func TestCallPermission(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission + genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true) // give the 0 account permission st, err := MakeGenesisState(stateDB, &genDoc) require.NoError(t, err) exe := makeExecutor(st) @@ -361,7 +368,6 @@ func TestCallPermission(t *testing.T) { Balance: 0, Code: []byte{0x60}, Sequence: 0, - StorageRoot: Zero256.Bytes(), Permissions: permission.ZeroAccountPermissions, }.MutableAccount() st.writeState.UpdateAccount(simpleAcc) @@ -382,7 +388,6 @@ func TestCallPermission(t *testing.T) { Balance: 10000, Code: contractCode, Sequence: 0, - StorageRoot: Zero256.Bytes(), Permissions: permission.ZeroAccountPermissions, }.MutableAccount() exe.stateCache.UpdateAccount(caller1Acc) @@ -401,14 +406,14 @@ func TestCallPermission(t *testing.T) { fmt.Println("\n##### CALL TO SIMPLE CONTRACT (PASS)") // A single input, having the permission, and the contract has permission - caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true) + caller1Acc.MutablePermissions().Base.Set(permission.Call, true) exe.stateCache.UpdateAccount(caller1Acc) tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100) txEnv = txs.Enclose(testChainID, tx) require.NoError(t, txEnv.Sign(users[0])) // we need to subscribe to the Call event to detect the exception - _, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr) // + _, err = execTxWaitAccountCall(t, exe, txEnv, caller1ContractAddr) require.NoError(t, err) //---------------------------------------------------------- @@ -424,11 +429,10 @@ func TestCallPermission(t *testing.T) { Balance: 1000, Code: contractCode2, Sequence: 0, - StorageRoot: Zero256.Bytes(), Permissions: permission.ZeroAccountPermissions, }.MutableAccount() - caller1Acc.MutablePermissions().Base.Set(ptypes.Call, false) - caller2Acc.MutablePermissions().Base.Set(ptypes.Call, true) + caller1Acc.MutablePermissions().Base.Set(permission.Call, false) + caller2Acc.MutablePermissions().Base.Set(permission.Call, true) exe.stateCache.UpdateAccount(caller1Acc) exe.stateCache.UpdateAccount(caller2Acc) @@ -445,7 +449,7 @@ func TestCallPermission(t *testing.T) { // both caller1 and caller2 have permission fmt.Println("\n##### CALL TO CONTRACT CALLING SIMPLE CONTRACT (PASS)") - caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true) + caller1Acc.MutablePermissions().Base.Set(permission.Call, true) exe.stateCache.UpdateAccount(caller1Acc) tx, _ = payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &caller2ContractAddr, nil, 100, 10000, 100) @@ -461,8 +465,8 @@ func TestCreatePermission(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateContract, true) // give the 0 account permission - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission + genDoc.Accounts[0].Permissions.Base.Set(permission.CreateContract, true) // give the 0 account permission + genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true) // give the 0 account permission st, err := MakeGenesisState(stateDB, &genDoc) require.NoError(t, err) exe := makeExecutor(st) @@ -527,7 +531,7 @@ func TestCreatePermission(t *testing.T) { // call the contract (should PASS) fmt.Println("\n###### CALL THE FACTORY (PASS)") - contractAcc.MutablePermissions().Base.Set(ptypes.CreateContract, true) + contractAcc.MutablePermissions().Base.Set(permission.CreateContract, true) exe.stateCache.UpdateAccount(contractAcc) // A single input, having the permission, should succeed @@ -548,11 +552,10 @@ func TestCreatePermission(t *testing.T) { Balance: 1000, Code: code, Sequence: 0, - StorageRoot: Zero256.Bytes(), Permissions: permission.ZeroAccountPermissions, }.MutableAccount() - contractAcc.MutablePermissions().Base.Set(ptypes.Call, true) - contractAcc.MutablePermissions().Base.Set(ptypes.CreateContract, true) + contractAcc.MutablePermissions().Base.Set(permission.Call, true) + contractAcc.MutablePermissions().Base.Set(permission.CreateContract, true) exe.stateCache.UpdateAccount(contractAcc) // this should call the 0 address but not create ... @@ -572,9 +575,9 @@ func TestCreateAccountPermission(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission - genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission - genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateAccount, true) // give the 0 account permission + genDoc.Accounts[0].Permissions.Base.Set(permission.Send, true) // give the 0 account permission + genDoc.Accounts[1].Permissions.Base.Set(permission.Send, true) // give the 0 account permission + genDoc.Accounts[0].Permissions.Base.Set(permission.CreateAccount, true) // give the 0 account permission st, err := MakeGenesisState(stateDB, &genDoc) require.NoError(t, err) batchCommitter := makeExecutor(st) @@ -615,7 +618,7 @@ func TestCreateAccountPermission(t *testing.T) { // Two inputs, both with send, both with create, should pass acc := getAccount(batchCommitter.stateCache, users[1].Address()) - acc.MutablePermissions().Base.Set(ptypes.CreateAccount, true) + acc.MutablePermissions().Base.Set(permission.CreateAccount, true) batchCommitter.stateCache.UpdateAccount(acc) tx = payload.NewSendTx() if err := tx.AddInput(batchCommitter.stateCache, users[0].PublicKey(), 5); err != nil { @@ -643,7 +646,7 @@ func TestCreateAccountPermission(t *testing.T) { // CALL to unknown account acc = getAccount(batchCommitter.stateCache, users[0].Address()) - acc.MutablePermissions().Base.Set(ptypes.Call, true) + acc.MutablePermissions().Base.Set(permission.Call, true) batchCommitter.stateCache.UpdateAccount(acc) // call to contract that calls unknown account - without create_account perm @@ -655,7 +658,6 @@ func TestCreateAccountPermission(t *testing.T) { Balance: 0, Code: contractCode, Sequence: 0, - StorageRoot: Zero256.Bytes(), Permissions: permission.ZeroAccountPermissions, }.MutableAccount() batchCommitter.stateCache.UpdateAccount(caller1Acc) @@ -671,8 +673,8 @@ func TestCreateAccountPermission(t *testing.T) { // NOTE: for a contract to be able to CreateAccount, it must be able to call // NOTE: for a users to be able to CreateAccount, it must be able to send! - caller1Acc.MutablePermissions().Base.Set(ptypes.CreateAccount, true) - caller1Acc.MutablePermissions().Base.Set(ptypes.Call, true) + caller1Acc.MutablePermissions().Base.Set(permission.CreateAccount, true) + caller1Acc.MutablePermissions().Base.Set(permission.Call, true) batchCommitter.stateCache.UpdateAccount(caller1Acc) // A single input, having the permission, but the contract doesn't have permission txCall, _ = payload.NewCallTx(batchCommitter.stateCache, users[0].PublicKey(), &caller1ContractAddr, nil, 100, 10000, 100) @@ -696,8 +698,8 @@ func TestSNativeCALL(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission - genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with + genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true) // give the 0 account permission + genDoc.Accounts[3].Permissions.Base.Set(permission.Bond, true) // some arbitrary permission to play with genDoc.Accounts[3].Permissions.AddRole("bumble") genDoc.Accounts[3].Permissions.AddRole("bee") st, err := MakeGenesisState(stateDB, &genDoc) @@ -713,17 +715,16 @@ func TestSNativeCALL(t *testing.T) { Balance: 0, Code: nil, Sequence: 0, - StorageRoot: Zero256.Bytes(), Permissions: permission.ZeroAccountPermissions, }.MutableAccount() - doug.MutablePermissions().Base.Set(ptypes.Call, true) + doug.MutablePermissions().Base.Set(permission.Call, true) //doug.Permissions.Base.Set(permission.HasBase, true) exe.stateCache.UpdateAccount(doug) fmt.Println("\n#### HasBase") // HasBase - snativeAddress, pF, data := snativePermTestInputCALL("hasBase", users[3], ptypes.Bond, false) + snativeAddress, pF, data := snativePermTestInputCALL("hasBase", users[3], permission.Bond, false) testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { // return value should be true or false as a 32 byte array... @@ -735,10 +736,10 @@ func TestSNativeCALL(t *testing.T) { fmt.Println("\n#### SetBase") // SetBase - snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], ptypes.Bond, false) + snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], permission.Bond, false) testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.Bond, false) + snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.Bond, false) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { // return value should be true or false as a 32 byte array... if !IsZeros(ret) { @@ -746,9 +747,9 @@ func TestSNativeCALL(t *testing.T) { } return nil }) - snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], ptypes.CreateContract, true) + snativeAddress, pF, data = snativePermTestInputCALL("setBase", users[3], permission.CreateContract, true) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false) + snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.CreateContract, false) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { // return value should be true or false as a 32 byte array... if !IsZeros(ret[:31]) || ret[31] != byte(1) { @@ -759,10 +760,10 @@ func TestSNativeCALL(t *testing.T) { fmt.Println("\n#### UnsetBase") // UnsetBase - snativeAddress, pF, data = snativePermTestInputCALL("unsetBase", users[3], ptypes.CreateContract, false) + snativeAddress, pF, data = snativePermTestInputCALL("unsetBase", users[3], permission.CreateContract, false) testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false) + snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.CreateContract, false) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { if !IsZeros(ret) { return fmt.Errorf("Expected 0. Got %X", ret) @@ -772,10 +773,10 @@ func TestSNativeCALL(t *testing.T) { fmt.Println("\n#### SetGlobal") // SetGlobalPerm - snativeAddress, pF, data = snativePermTestInputCALL("setGlobal", users[3], ptypes.CreateContract, true) + snativeAddress, pF, data = snativePermTestInputCALL("setGlobal", users[3], permission.CreateContract, true) testSNativeCALLExpectFail(t, exe, doug, snativeAddress, data) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { return nil }) - snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], ptypes.CreateContract, false) + snativeAddress, pF, data = snativePermTestInputCALL("hasBase", users[3], permission.CreateContract, false) testSNativeCALLExpectPass(t, exe, doug, pF, snativeAddress, data, func(ret []byte) error { // return value should be true or false as a 32 byte array... if !IsZeros(ret[:31]) || ret[31] != byte(1) { @@ -833,8 +834,8 @@ func TestSNativeTx(t *testing.T) { stateDB := dbm.NewDB("state", dbBackend, dbDir) defer stateDB.Close() genDoc := newBaseGenDoc(permission.ZeroAccountPermissions, permission.ZeroAccountPermissions) - genDoc.Accounts[0].Permissions.Base.Set(ptypes.Call, true) // give the 0 account permission - genDoc.Accounts[3].Permissions.Base.Set(ptypes.Bond, true) // some arbitrary permission to play with + genDoc.Accounts[0].Permissions.Base.Set(permission.Call, true) // give the 0 account permission + genDoc.Accounts[3].Permissions.Base.Set(permission.Bond, true) // some arbitrary permission to play with genDoc.Accounts[3].Permissions.AddRole("bumble") genDoc.Accounts[3].Permissions.AddRole("bee") st, err := MakeGenesisState(stateDB, &genDoc) @@ -846,37 +847,37 @@ func TestSNativeTx(t *testing.T) { fmt.Println("\n#### SetBase") // SetBase - snativeArgs := snativePermTestInputTx("setBase", users[3], ptypes.Bond, false) + snativeArgs := snativePermTestInputTx("setBase", users[3], permission.Bond, false) testSNativeTxExpectFail(t, batchCommitter, snativeArgs) - testSNativeTxExpectPass(t, batchCommitter, ptypes.SetBase, snativeArgs) + testSNativeTxExpectPass(t, batchCommitter, permission.SetBase, snativeArgs) acc := getAccount(batchCommitter.stateCache, users[3].Address()) - if v, _ := acc.MutablePermissions().Base.Get(ptypes.Bond); v { + if v, _ := acc.MutablePermissions().Base.Get(permission.Bond); v { t.Fatal("expected permission to be set false") } - snativeArgs = snativePermTestInputTx("setBase", users[3], ptypes.CreateContract, true) - testSNativeTxExpectPass(t, batchCommitter, ptypes.SetBase, snativeArgs) + snativeArgs = snativePermTestInputTx("setBase", users[3], permission.CreateContract, true) + testSNativeTxExpectPass(t, batchCommitter, permission.SetBase, snativeArgs) acc = getAccount(batchCommitter.stateCache, users[3].Address()) - if v, _ := acc.MutablePermissions().Base.Get(ptypes.CreateContract); !v { + if v, _ := acc.MutablePermissions().Base.Get(permission.CreateContract); !v { t.Fatal("expected permission to be set true") } fmt.Println("\n#### UnsetBase") // UnsetBase - snativeArgs = snativePermTestInputTx("unsetBase", users[3], ptypes.CreateContract, false) + snativeArgs = snativePermTestInputTx("unsetBase", users[3], permission.CreateContract, false) testSNativeTxExpectFail(t, batchCommitter, snativeArgs) - testSNativeTxExpectPass(t, batchCommitter, ptypes.UnsetBase, snativeArgs) + testSNativeTxExpectPass(t, batchCommitter, permission.UnsetBase, snativeArgs) acc = getAccount(batchCommitter.stateCache, users[3].Address()) - if v, _ := acc.MutablePermissions().Base.Get(ptypes.CreateContract); v { + if v, _ := acc.MutablePermissions().Base.Get(permission.CreateContract); v { t.Fatal("expected permission to be set false") } fmt.Println("\n#### SetGlobal") // SetGlobalPerm - snativeArgs = snativePermTestInputTx("setGlobal", users[3], ptypes.CreateContract, true) + snativeArgs = snativePermTestInputTx("setGlobal", users[3], permission.CreateContract, true) testSNativeTxExpectFail(t, batchCommitter, snativeArgs) - testSNativeTxExpectPass(t, batchCommitter, ptypes.SetGlobal, snativeArgs) + testSNativeTxExpectPass(t, batchCommitter, permission.SetGlobal, snativeArgs) acc = getAccount(batchCommitter.stateCache, acm.GlobalPermissionsAddress) - if v, _ := acc.MutablePermissions().Base.Get(ptypes.CreateContract); !v { + if v, _ := acc.MutablePermissions().Base.Get(permission.CreateContract); !v { t.Fatal("expected permission to be set true") } @@ -884,7 +885,7 @@ func TestSNativeTx(t *testing.T) { // AddRole snativeArgs = snativeRoleTestInputTx("addRole", users[3], "chuck") testSNativeTxExpectFail(t, batchCommitter, snativeArgs) - testSNativeTxExpectPass(t, batchCommitter, ptypes.AddRole, snativeArgs) + testSNativeTxExpectPass(t, batchCommitter, permission.AddRole, snativeArgs) acc = getAccount(batchCommitter.stateCache, users[3].Address()) if v := acc.Permissions().HasRole("chuck"); !v { t.Fatal("expected role to be added") @@ -894,7 +895,7 @@ func TestSNativeTx(t *testing.T) { // RemoveRole snativeArgs = snativeRoleTestInputTx("removeRole", users[3], "chuck") testSNativeTxExpectFail(t, batchCommitter, snativeArgs) - testSNativeTxExpectPass(t, batchCommitter, ptypes.RemoveRole, snativeArgs) + testSNativeTxExpectPass(t, batchCommitter, permission.RemoveRole, snativeArgs) acc = getAccount(batchCommitter.stateCache, users[3].Address()) if v := acc.Permissions().HasRole("chuck"); v { t.Fatal("expected role to be removed") @@ -951,8 +952,8 @@ func TestNameTxs(t *testing.T) { st.writeState.save() names.MinNameRegistrationPeriod = 5 - blockchain := newBlockchain(testGenesisDoc) - startingBlock := blockchain.LastBlockHeight() + exe := makeExecutor(st) + startingBlock := exe.blockchain.LastBlockHeight() // try some bad names. these should all fail nameStrings := []string{"", "\n", "123#$%", "\x00", string([]byte{20, 40, 60, 80}), @@ -964,10 +965,8 @@ func TestNameTxs(t *testing.T) { amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier* names.NameBaseCost(name, data) tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee) - txEnv := txs.Enclose(testChainID, tx) - txEnv.Sign(testPrivAccounts[0]) - if err := execTxWithState(st, txEnv); err == nil { + if err = exe.signExecuteCommit(tx, testPrivAccounts[0]); err == nil { t.Fatalf("Expected invalid name error from %s", name) } } @@ -979,10 +978,8 @@ func TestNameTxs(t *testing.T) { amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier* names.NameBaseCost(name, data) tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee) - txEnv := txs.Enclose(testChainID, tx) - txEnv.Sign(testPrivAccounts[0]) - if err := execTxWithState(st, txEnv); err == nil { + if err = exe.signExecuteCommit(tx, testPrivAccounts[0]); err == nil { t.Fatalf("Expected invalid data error from %s", data) } } @@ -1010,68 +1007,50 @@ func TestNameTxs(t *testing.T) { data = "on this side of neptune there are 1234567890 people: first is OMNIVORE+-3. Or is it. Ok this is pretty restrictive. No exclamations :(. Faces tho :')" amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data) tx, _ := payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee) - txEnv := txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[0])) - if err := execTxWithState(st, txEnv); err != nil { - t.Fatal(err) - } - entry, err := st.GetNameEntry(name) + + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0])) + + entry, err := st.GetName(name) require.NoError(t, err) validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks) // fail to update it as non-owner, in same block tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[1])) - if err := execTxWithState(st, txEnv); err == nil { - t.Fatal("Expected error") - } + require.Error(t, exe.signExecuteCommit(tx, testPrivAccounts[1])) // update it as owner, just to increase expiry, in same block // NOTE: we have to resend the data or it will clear it (is this what we want?) tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[0])) - if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil { - t.Fatal(err) - } - entry, err = st.GetNameEntry(name) + + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0])) + + entry, err = st.GetName(name) require.NoError(t, err) validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks*2) // update it as owner, just to increase expiry, in next block tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[0])) - if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil { - t.Fatal(err) - } - entry, err = st.GetNameEntry(name) + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0])) + + entry, err = st.GetName(name) require.NoError(t, err) validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks*3) // fail to update it as non-owner // Fast forward - for blockchain.Tip.LastBlockHeight() < entry.Expires-1 { - commitNewBlock(st, blockchain) + for exe.blockchain.Tip.LastBlockHeight() < entry.Expires-1 { + commitNewBlock(st, exe.blockchain) } tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[1])) - if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err == nil { - t.Fatal("Expected error") - } - commitNewBlock(st, blockchain) + require.Error(t, exe.signExecuteCommit(tx, testPrivAccounts[1])) + commitNewBlock(st, exe.blockchain) // once expires, non-owner succeeds - startingBlock = blockchain.LastBlockHeight() + startingBlock = exe.blockchain.LastBlockHeight() tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[1])) - if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil { - t.Fatal(err) - } - entry, err = st.GetNameEntry(name) + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1])) + + entry, err = st.GetName(name) require.NoError(t, err) validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), startingBlock+numDesiredBlocks) @@ -1081,12 +1060,9 @@ func TestNameTxs(t *testing.T) { numDesiredBlocks = 10 amt = fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data) - oldCredit tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[1])) - if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil { - t.Fatal(err) - } - entry, err = st.GetNameEntry(name) + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1])) + + entry, err = st.GetName(name) require.NoError(t, err) validateEntry(t, entry, name, data, testPrivAccounts[1].Address(), startingBlock+numDesiredBlocks) @@ -1094,12 +1070,9 @@ func TestNameTxs(t *testing.T) { amt = fee data = "" tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[1])) - if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil { - t.Fatal(err) - } - entry, err = st.GetNameEntry(name) + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1])) + + entry, err = st.GetName(name) require.NoError(t, err) if entry != nil { t.Fatal("Expected removed entry to be nil") @@ -1107,33 +1080,27 @@ func TestNameTxs(t *testing.T) { // create entry by key0, // test removal by key1 after expiry - startingBlock = blockchain.LastBlockHeight() + startingBlock = exe.blockchain.LastBlockHeight() name = "looking_good/karaoke_bar" data = "some data" amt = fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data) tx, _ = payload.NewNameTx(st, testPrivAccounts[0].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[0])) - if err := execTxWithStateAndBlockchain(st, blockchain, txEnv); err != nil { - t.Fatal(err) - } - entry, err = st.GetNameEntry(name) + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[0])) + + entry, err = st.GetName(name) require.NoError(t, err) validateEntry(t, entry, name, data, testPrivAccounts[0].Address(), startingBlock+numDesiredBlocks) // Fast forward - for blockchain.Tip.LastBlockHeight() < entry.Expires { - commitNewBlock(st, blockchain) + for exe.blockchain.Tip.LastBlockHeight() < entry.Expires { + commitNewBlock(st, exe.blockchain) } amt = fee data = "" tx, _ = payload.NewNameTx(st, testPrivAccounts[1].PublicKey(), name, data, amt, fee) - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(testPrivAccounts[1])) - if err := execTxWithStateNewBlock(st, blockchain, txEnv); err != nil { - t.Fatal(err) - } - entry, err = st.GetNameEntry(name) + require.NoError(t, exe.signExecuteCommit(tx, testPrivAccounts[1])) + + entry, err = st.GetName(name) require.NoError(t, err) if entry != nil { t.Fatal("Expected removed entry to be nil") @@ -1166,20 +1133,22 @@ var createData, _ = hex.DecodeString("9ed93318") func TestCreates(t *testing.T) { //evm.SetDebug(true) - state, privAccounts := makeGenesisState(3, true, 1000, 1, true, 1000) + st, privAccounts := makeGenesisState(3, true, 1000, 1, true, 1000) //val0 := state.GetValidatorInfo(privValidators[0].Address()) - acc0 := getAccount(state, privAccounts[0].Address()) - acc1 := getAccount(state, privAccounts[1].Address()) - acc2 := getAccount(state, privAccounts[2].Address()) + acc0 := getAccount(st, privAccounts[0].Address()) + acc1 := getAccount(st, privAccounts[1].Address()) + acc2 := getAccount(st, privAccounts[2].Address()) - newAcc1 := getAccount(state, acc1.Address()) + exe := makeExecutor(st) + + newAcc1 := getAccount(st, acc1.Address()) newAcc1.SetCode(preFactoryCode) - newAcc2 := getAccount(state, acc2.Address()) + newAcc2 := getAccount(st, acc2.Address()) newAcc2.SetCode(factoryCode) - state.writeState.UpdateAccount(newAcc1) - state.writeState.UpdateAccount(newAcc2) + st.writeState.UpdateAccount(newAcc1) + st.writeState.UpdateAccount(newAcc2) createData = append(createData, acc2.Address().Word256().Bytes()...) @@ -1195,39 +1164,29 @@ func TestCreates(t *testing.T) { Data: createData, } - txEnv := txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(privAccounts[0])) - err := execTxWithState(state, txEnv) - if err != nil { - t.Errorf("Got error in executing call transaction, %v", err) - } + require.NoError(t, exe.signExecuteCommit(tx, privAccounts[0])) - acc1 = getAccount(state, acc1.Address()) - firstCreatedAddress, err := state.GetStorage(acc1.Address(), LeftPadWord256(nil)) + acc1 = getAccount(st, acc1.Address()) + firstCreatedAddress, err := st.GetStorage(acc1.Address(), LeftPadWord256(nil)) require.NoError(t, err) - acc0 = getAccount(state, acc0.Address()) + acc0 = getAccount(st, acc0.Address()) // call the pre-factory, triggering the factory to run a create tx = &payload.CallTx{ Input: &payload.TxInput{ Address: acc0.Address(), Amount: 1, - Sequence: acc0.Sequence() + 1, + Sequence: tx.Input.Sequence + 1, }, Address: addressPtr(acc1), GasLimit: 100000, Data: createData, } - txEnv = txs.Enclose(testChainID, tx) - require.NoError(t, txEnv.Sign(privAccounts[0])) - err = execTxWithState(state, txEnv) - if err != nil { - t.Errorf("Got error in executing call transaction, %v", err) - } + require.NoError(t, exe.signExecuteCommit(tx, privAccounts[0])) - acc1 = getAccount(state, acc1.Address()) - secondCreatedAddress, err := state.GetStorage(acc1.Address(), LeftPadWord256(nil)) + acc1 = getAccount(st, acc1.Address()) + secondCreatedAddress, err := st.GetStorage(acc1.Address(), LeftPadWord256(nil)) require.NoError(t, err) if firstCreatedAddress == secondCreatedAddress { @@ -1487,7 +1446,7 @@ proof-of-work chain as proof of what happened while they were gone ` t.Errorf("Unexpected newAcc0 balance. Expected %v, got %v", acc0.Balance()-entryAmount, newAcc0.Balance()) } - entry, err := stateNameTx.GetNameEntry(entryName) + entry, err := stateNameTx.GetName(entryName) require.NoError(t, err) if entry == nil { t.Errorf("Expected an entry but got nil") @@ -1502,8 +1461,8 @@ proof-of-work chain as proof of what happened while they were gone ` txEnv = txs.Enclose(testChainID, tx) require.NoError(t, txEnv.Sign(privAccounts[0])) err = execTxWithState(stateNameTx, txEnv) - if _, ok := err.(payload.ErrTxInvalidString); !ok { - t.Errorf("Expected invalid string error. Got: %s", err.Error()) + if errors.AsException(err).ErrorCode() != errors.ErrorCodeInvalidString { + t.Errorf("Expected invalid string error. Got: %v", err) } } @@ -1596,7 +1555,7 @@ func TestSelfDestruct(t *testing.T) { signAndExecute(t, false, exe, testChainID, tx, privAccounts[0]) // commit the block - exe.Commit() + exe.Commit(nil) // acc2 should receive the sent funds and the contracts balance newAcc2 := getAccount(st, acc2.Address()) @@ -1616,10 +1575,11 @@ func signAndExecute(t *testing.T, shouldFail bool, exe BatchExecutor, chainID st env := txs.Enclose(chainID, tx) require.NoError(t, env.Sign(signers...), "Could not sign tx in call: %s", debug.Stack()) + _, err := exe.Execute(env) if shouldFail { - require.Error(t, exe.Execute(env), "Tx should fail in call: %s", debug.Stack()) + require.Error(t, err, "Tx should fail in call: %s", debug.Stack()) } else { - require.NoError(t, exe.Execute(env), "Could not execute tx in call: %s", debug.Stack()) + require.NoError(t, err, "Could not execute tx in call: %s", debug.Stack()) } return env } @@ -1627,10 +1587,13 @@ func signAndExecute(t *testing.T, shouldFail bool, exe BatchExecutor, chainID st func execTxWithStateAndBlockchain(state *State, blockchain *bcm.Blockchain, txEnv *txs.Envelope) error { exe := newExecutor("execTxWithStateAndBlockchainCache", true, state, blockchain.Tip, event.NewNoOpPublisher(), logger) - if err := exe.Execute(txEnv); err != nil { + if _, err := exe.Execute(txEnv); err != nil { return err } else { - exe.Commit() + _, err := exe.Commit(nil) + if err != nil { + return err + } commitNewBlock(state, blockchain) return nil } @@ -1665,7 +1628,7 @@ func makeGenesisState(numAccounts int, randBalance bool, minBalance uint64, numV return s0, privAccounts } -func getAccount(accountGetter state.AccountGetter, address crypto.Address) acm.MutableAccount { +func getAccount(accountGetter state.AccountGetter, address crypto.Address) *acm.MutableAccount { acc, _ := state.GetMutableAccount(accountGetter, address) return acc } @@ -1686,46 +1649,44 @@ var ExceptionTimeOut = errors.NewCodedError(errors.ErrorCodeGeneric, "timed out // run ExecTx and wait for the Call event on given addr // returns the msg data and an error/exception func execTxWaitAccountCall(t *testing.T, exe *testExecutor, txEnv *txs.Envelope, - address crypto.Address) (*events.EventDataCall, error) { - - ch := make(chan *events.EventDataCall) - ctx := context.Background() - const subscriber = "execTxWaitEvent" - events.SubscribeAccountCall(ctx, exe, subscriber, address, txEnv.Tx.Hash(), -1, ch) - defer exe.UnsubscribeAll(ctx, subscriber) - err := exe.Execute(txEnv) + address crypto.Address) (*exec.CallEvent, error) { + + qry, err := event.QueryForEventID(exec.EventStringAccountCall(address)). + AndEquals(event.TxHashKey, txEnv.Tx.Hash()).Query() if err != nil { return nil, err } - exe.Commit() - exe.blockchain.CommitBlock(time.Time{}, nil, nil) - ticker := time.NewTicker(5 * time.Second) - - select { - case eventDataCall := <-ch: - fmt.Println("MSG: ", eventDataCall) - return eventDataCall, eventDataCall.Exception.AsError() - - case <-ticker.C: - return nil, ExceptionTimeOut + evs, err := exe.Execute(txEnv) + if err != nil { + return nil, err } + _, err = exe.Commit(nil) + require.NoError(t, err) + err = exe.blockchain.CommitBlock(time.Time{}, nil, nil) + require.NoError(t, err) + for _, ev := range evs.TaggedEvents().Filter(qry) { + if ev.Call != nil { + return ev.Call, ev.Header.Exception.AsError() + } + } + return nil, fmt.Errorf("did not receive EventDataCall execution event from execTxWaitAccountCall") } // give a contract perms for an snative, call it, it calls the snative, but shouldn't have permission -func testSNativeCALLExpectFail(t *testing.T, exe *testExecutor, doug acm.MutableAccount, +func testSNativeCALLExpectFail(t *testing.T, exe *testExecutor, doug *acm.MutableAccount, snativeAddress crypto.Address, data []byte) { testSNativeCALL(t, false, exe, doug, 0, snativeAddress, data, nil) } // give a contract perms for an snative, call it, it calls the snative, ensure the check funciton (f) succeeds -func testSNativeCALLExpectPass(t *testing.T, exe *testExecutor, doug acm.MutableAccount, snativePerm ptypes.PermFlag, +func testSNativeCALLExpectPass(t *testing.T, exe *testExecutor, doug *acm.MutableAccount, snativePerm permission.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) { testSNativeCALL(t, true, exe, doug, snativePerm, snativeAddress, data, f) } -func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug acm.MutableAccount, - snativePerm ptypes.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) { +func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug *acm.MutableAccount, + snativePerm permission.PermFlag, snativeAddress crypto.Address, data []byte, f func([]byte) error) { if expectPass { doug.MutablePermissions().Base.Set(snativePerm, true) } @@ -1737,7 +1698,6 @@ func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug acm. tx, _ := payload.NewCallTx(exe.stateCache, users[0].PublicKey(), &dougAddress, data, 100, 10000, 100) txEnv := txs.Enclose(testChainID, tx) require.NoError(t, txEnv.Sign(users[0])) - t.Logf("subscribing to %v", events.EventStringAccountCall(snativeAddress)) ev, err := execTxWaitAccountCall(t, exe, txEnv, snativeAddress) if err == ExceptionTimeOut { t.Fatal("Timed out waiting for event") @@ -1753,17 +1713,17 @@ func testSNativeCALL(t *testing.T, expectPass bool, exe *testExecutor, doug acm. } } -func testSNativeTxExpectFail(t *testing.T, batchCommitter *testExecutor, snativeArgs snatives.PermArgs) { +func testSNativeTxExpectFail(t *testing.T, batchCommitter *testExecutor, snativeArgs permission.PermArgs) { testSNativeTx(t, false, batchCommitter, 0, snativeArgs) } -func testSNativeTxExpectPass(t *testing.T, batchCommitter *testExecutor, perm ptypes.PermFlag, - snativeArgs snatives.PermArgs) { +func testSNativeTxExpectPass(t *testing.T, batchCommitter *testExecutor, perm permission.PermFlag, + snativeArgs permission.PermArgs) { testSNativeTx(t, true, batchCommitter, perm, snativeArgs) } -func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *testExecutor, perm ptypes.PermFlag, - snativeArgs snatives.PermArgs) { +func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *testExecutor, perm permission.PermFlag, + snativeArgs permission.PermArgs) { if expectPass { acc := getAccount(batchCommitter.stateCache, users[0].Address()) acc.MutablePermissions().Base.Set(perm, true) @@ -1772,7 +1732,7 @@ func testSNativeTx(t *testing.T, expectPass bool, batchCommitter *testExecutor, tx, _ := payload.NewPermissionsTx(batchCommitter.stateCache, users[0].PublicKey(), snativeArgs) txEnv := txs.Enclose(testChainID, tx) require.NoError(t, txEnv.Sign(users[0])) - err := batchCommitter.Execute(txEnv) + _, err := batchCommitter.Execute(txEnv) if expectPass { if err != nil { t.Fatal("Unexpected exception", err) @@ -1803,8 +1763,8 @@ func permNameToFuncID(name string) []byte { return id[:] } -func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm ptypes.PermFlag, - val bool) (addr crypto.Address, pF ptypes.PermFlag, data []byte) { +func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm permission.PermFlag, + val bool) (addr crypto.Address, pF permission.PermFlag, data []byte) { addr = permissionsContract.Address() switch name { case "hasBase", "unsetBase": @@ -1820,50 +1780,50 @@ func snativePermTestInputCALL(name string, user acm.AddressableSigner, perm ptyp } data = append(permNameToFuncID(name), data...) var err error - if pF, err = ptypes.PermStringToFlag(name); err != nil { + if pF, err = permission.PermStringToFlag(name); err != nil { panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name)) } return } -func snativePermTestInputTx(name string, user acm.AddressableSigner, perm ptypes.PermFlag, - val bool) (snativeArgs snatives.PermArgs) { +func snativePermTestInputTx(name string, user acm.AddressableSigner, perm permission.PermFlag, + val bool) (snativeArgs permission.PermArgs) { switch name { case "hasBase": - snativeArgs = snatives.HasBaseArgs(user.Address(), perm) + snativeArgs = permission.HasBaseArgs(user.Address(), perm) case "unsetBase": - snativeArgs = snatives.UnsetBaseArgs(user.Address(), perm) + snativeArgs = permission.UnsetBaseArgs(user.Address(), perm) case "setBase": - snativeArgs = snatives.SetBaseArgs(user.Address(), perm, val) + snativeArgs = permission.SetBaseArgs(user.Address(), perm, val) case "setGlobal": - snativeArgs = snatives.SetGlobalArgs(perm, val) + snativeArgs = permission.SetGlobalArgs(perm, val) } return } func snativeRoleTestInputCALL(name string, user acm.AddressableSigner, - role string) (addr crypto.Address, pF ptypes.PermFlag, data []byte) { + role string) (addr crypto.Address, pF permission.PermFlag, data []byte) { addr = permissionsContract.Address() data = user.Address().Word256().Bytes() data = append(data, RightPadBytes([]byte(role), 32)...) data = append(permNameToFuncID(name), data...) var err error - if pF, err = ptypes.PermStringToFlag(name); err != nil { + if pF, err = permission.PermStringToFlag(name); err != nil { panic(fmt.Sprintf("failed to convert perm string (%s) to flag", name)) } return } -func snativeRoleTestInputTx(name string, user acm.AddressableSigner, role string) (snativeArgs snatives.PermArgs) { +func snativeRoleTestInputTx(name string, user acm.AddressableSigner, role string) (snativeArgs permission.PermArgs) { switch name { case "hasRole": - snativeArgs = snatives.HasRoleArgs(user.Address(), role) + snativeArgs = permission.HasRoleArgs(user.Address(), role) case "addRole": - snativeArgs = snatives.AddRoleArgs(user.Address(), role) + snativeArgs = permission.AddRoleArgs(user.Address(), role) case "removeRole": - snativeArgs = snatives.RemoveRoleArgs(user.Address(), role) + snativeArgs = permission.RemoveRoleArgs(user.Address(), role) } return } diff --git a/execution/executors/call.go b/execution/executors/call_context.go similarity index 73% rename from execution/executors/call.go rename to execution/executors/call_context.go index ce79fc5c2a6ddaecca585f3c2a21ec8761dcc4a1..78fa25e4a7218770693655e267da7a433d428bfd 100644 --- a/execution/executors/call.go +++ b/execution/executors/call_context.go @@ -3,17 +3,15 @@ package executors import ( "fmt" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/blockchain" - "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution/errors" - "github.com/hyperledger/burrow/execution/events" "github.com/hyperledger/burrow/execution/evm" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" - "github.com/hyperledger/burrow/txs" "github.com/hyperledger/burrow/txs/payload" ) @@ -21,23 +19,22 @@ import ( const GasLimit = uint64(1000000) type CallContext struct { - Tip blockchain.TipInfo - StateWriter state.ReaderWriter - EventPublisher event.Publisher - RunCall bool - VMOptions []func(*evm.VM) - Logger *logging.Logger - tx *payload.CallTx - txEnv *txs.Envelope + Tip blockchain.TipInfo + StateWriter state.ReaderWriter + RunCall bool + VMOptions []func(*evm.VM) + Logger *logging.Logger + tx *payload.CallTx + txe *exec.TxExecution } -func (ctx *CallContext) Execute(txEnv *txs.Envelope) error { +func (ctx *CallContext) Execute(txe *exec.TxExecution) error { var ok bool - ctx.tx, ok = txEnv.Tx.Payload.(*payload.CallTx) + ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.CallTx) if !ok { - return fmt.Errorf("payload must be CallTx, but is: %v", txEnv.Tx.Payload) + return fmt.Errorf("payload must be CallTx, but is: %v", txe.Envelope.Tx.Payload) } - ctx.txEnv = txEnv + ctx.txe = txe inAcc, outAcc, err := ctx.Precheck() if err != nil { return err @@ -46,15 +43,12 @@ func (ctx *CallContext) Execute(txEnv *txs.Envelope) error { value := ctx.tx.Input.Amount - ctx.tx.Fee if ctx.RunCall { - ctx.Deliver(inAcc, outAcc, value) - } else { - ctx.Check(inAcc, value) + return ctx.Deliver(inAcc, outAcc, value) } - - return nil + return ctx.Check(inAcc, value) } -func (ctx *CallContext) Precheck() (acm.MutableAccount, acm.Account, error) { +func (ctx *CallContext) Precheck() (*acm.MutableAccount, acm.Account, error) { var outAcc acm.Account // Validate input inAcc, err := state.GetMutableAccount(ctx.StateWriter, ctx.tx.Input.Address) @@ -85,7 +79,8 @@ func (ctx *CallContext) Precheck() (acm.MutableAccount, acm.Account, error) { "old_sequence", inAcc.Sequence(), "new_sequence", inAcc.Sequence()+1) - inAcc, err = inAcc.IncSequence().SubtractFromBalance(ctx.tx.Fee) + inAcc.IncSequence() + err = inAcc.SubtractFromBalance(ctx.tx.Fee) if err != nil { return nil, nil, err } @@ -126,13 +121,13 @@ func (ctx *CallContext) Precheck() (acm.MutableAccount, acm.Account, error) { return inAcc, outAcc, nil } -func (ctx *CallContext) Check(inAcc acm.MutableAccount, value uint64) error { +func (ctx *CallContext) Check(inAcc *acm.MutableAccount, value uint64) error { createContract := ctx.tx.Address == nil // The mempool does not call txs until // the proposer determines the order of txs. // So mempool will skip the actual .Call(), // and only deduct from the caller's balance. - inAcc, err := inAcc.SubtractFromBalance(value) + err := inAcc.SubtractFromBalance(value) if err != nil { return err } @@ -145,20 +140,24 @@ func (ctx *CallContext) Check(inAcc acm.MutableAccount, value uint64) error { "new_sequence", inAcc.Sequence()+1) inAcc.IncSequence() } - return ctx.StateWriter.UpdateAccount(inAcc) + err = ctx.StateWriter.UpdateAccount(inAcc) + if err != nil { + return err + } + return nil } func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error { createContract := ctx.tx.Address == nil // VM call variables var ( - gas uint64 = ctx.tx.GasLimit - caller acm.MutableAccount = acm.AsMutableAccount(inAcc) - callee acm.MutableAccount = nil // initialized below - code []byte = nil - ret []byte = nil - txCache = state.NewCache(ctx.StateWriter, state.Name("TxCache")) - params = evm.Params{ + gas uint64 = ctx.tx.GasLimit + caller *acm.MutableAccount = acm.AsMutableAccount(inAcc) + callee *acm.MutableAccount = nil // initialized below + code []byte = nil + ret []byte = nil + txCache = state.NewCache(ctx.StateWriter, state.Name("TxCache")) + params = evm.Params{ BlockHeight: ctx.Tip.LastBlockHeight(), BlockHash: binary.LeftPadWord256(ctx.Tip.LastBlockHash()), BlockTime: ctx.Tip.LastBlockTime().Unix(), @@ -192,7 +191,7 @@ func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error { "caller_address", inAcc.Address(), "callee_address", ctx.tx.Address) } - ctx.FireCallEvents(nil, payload.ErrTxInvalidAddress) + ctx.CallEvents(payload.ErrTxInvalidAddress) return nil } callee = acm.AsMutableAccount(outAcc) @@ -206,8 +205,8 @@ func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error { txCache.UpdateAccount(caller) txCache.UpdateAccount(callee) - vmach := evm.NewVM(params, caller.Address(), ctx.txEnv.Tx, ctx.Logger, ctx.VMOptions...) - vmach.SetPublisher(ctx.EventPublisher) + vmach := evm.NewVM(params, caller.Address(), ctx.txe.Envelope.Tx, ctx.Logger, ctx.VMOptions...) + vmach.SetEventSink(ctx.txe) // NOTE: Call() transfers the value from caller to callee iff call succeeds. ret, exception := vmach.Call(txCache, caller, callee, code, ctx.tx.Data, value, &gas) if exception != nil { @@ -224,25 +223,21 @@ func (ctx *CallContext) Deliver(inAcc, outAcc acm.Account, value uint64) error { return err } } + ctx.CallEvents(exception) + ctx.txe.Return(ret, ctx.tx.GasLimit-gas) // Create a receipt from the ret and whether it erred. ctx.Logger.TraceMsg("VM call complete", "caller", caller, "callee", callee, "return", ret, structure.ErrorKey, exception) - ctx.FireCallEvents(ret, exception) return nil } -func (ctx *CallContext) FireCallEvents(ret []byte, err error) { - // Fire Events for sender and receiver - // a separate event will be fired from vm for each additional call - if ctx.EventPublisher != nil { - events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, ctx.txEnv.Tx, - ret, errors.AsCodedError(err)) - if ctx.tx.Address != nil { - events.PublishAccountOutput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), *ctx.tx.Address, ctx.txEnv.Tx, - ret, errors.AsCodedError(err)) - } +func (ctx *CallContext) CallEvents(err error) { + // Fire Events for sender and receiver a separate event will be fired from vm for each additional call + ctx.txe.Input(ctx.tx.Input.Address, errors.AsException(err)) + if ctx.tx.Address != nil { + ctx.txe.Input(*ctx.tx.Address, errors.AsException(err)) } } diff --git a/execution/executors/name.go b/execution/executors/name_context.go similarity index 67% rename from execution/executors/name.go rename to execution/executors/name_context.go index 658992d5331687450cf34fe524ddbde96a9f9583..ce8396704b35f75b58d536f017282ecaab9589d6 100644 --- a/execution/executors/name.go +++ b/execution/executors/name_context.go @@ -3,31 +3,36 @@ package executors import ( "fmt" - "github.com/hyperledger/burrow/account/state" + "regexp" + + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/blockchain" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/events" + "github.com/hyperledger/burrow/execution/errors" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/execution/names" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" - "github.com/hyperledger/burrow/txs" "github.com/hyperledger/burrow/txs/payload" ) +// Name should be file system like +// Data should be anything permitted in JSON +var regexpAlphaNum = regexp.MustCompile("^[a-zA-Z0-9._/-@]*$") +var regexpJSON = regexp.MustCompile(`^[a-zA-Z0-9_/ \-+"':,\n\t.{}()\[\]]*$`) + type NameContext struct { - Tip blockchain.TipInfo - StateWriter state.ReaderWriter - EventPublisher event.Publisher - NameReg names.ReaderWriter - Logger *logging.Logger - tx *payload.NameTx + Tip blockchain.TipInfo + StateWriter state.ReaderWriter + NameReg names.ReaderWriter + Logger *logging.Logger + tx *payload.NameTx } -func (ctx *NameContext) Execute(txEnv *txs.Envelope) error { +func (ctx *NameContext) Execute(txe *exec.TxExecution) error { var ok bool - ctx.tx, ok = txEnv.Tx.Payload.(*payload.NameTx) + ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.NameTx) if !ok { - return fmt.Errorf("payload must be NameTx, but is: %v", txEnv.Tx.Payload) + return fmt.Errorf("payload must be NameTx, but is: %v", txe.Envelope.Tx.Payload) } // Validate input inAcc, err := state.GetMutableAccount(ctx.StateWriter, ctx.tx.Input.Address) @@ -56,7 +61,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error { } // validate the input strings - if err := ctx.tx.ValidateStrings(); err != nil { + if err := validateStrings(ctx.tx); err != nil { return err } @@ -74,7 +79,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error { "last_block_height", lastBlockHeight) // check if the name exists - entry, err := ctx.NameReg.GetNameEntry(ctx.tx.Name) + entry, err := ctx.NameReg.GetName(ctx.tx.Name) if err != nil { return err } @@ -99,7 +104,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error { // (owners if not expired, anyone if expired) ctx.Logger.TraceMsg("Removing NameReg entry (no value and empty data in tx requests this)", "name", entry.Name) - err := ctx.NameReg.RemoveNameEntry(entry.Name) + err := ctx.NameReg.RemoveName(entry.Name) if err != nil { return err } @@ -134,7 +139,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error { "credit", credit) } entry.Data = ctx.tx.Data - err := ctx.NameReg.UpdateNameEntry(entry) + err := ctx.NameReg.UpdateName(entry) if err != nil { return err } @@ -153,7 +158,7 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error { ctx.Logger.TraceMsg("Creating NameReg entry", "name", entry.Name, "expires_in", expiresIn) - err := ctx.NameReg.UpdateNameEntry(entry) + err := ctx.NameReg.UpdateName(entry) if err != nil { return err } @@ -168,18 +173,51 @@ func (ctx *NameContext) Execute(txEnv *txs.Envelope) error { "old_sequence", inAcc.Sequence(), "new_sequence", inAcc.Sequence()+1) inAcc.IncSequence() - inAcc, err = inAcc.SubtractFromBalance(value) + err = inAcc.SubtractFromBalance(value) + if err != nil { + return err + } + err = ctx.StateWriter.UpdateAccount(inAcc) if err != nil { return err } - ctx.StateWriter.UpdateAccount(inAcc) // TODO: maybe we want to take funds on error and allow txs in that don't do anythingi? - if ctx.EventPublisher != nil { - events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, txEnv.Tx, nil, nil) - events.PublishNameReg(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), txEnv.Tx) + txe.Input(ctx.tx.Input.Address, nil) + txe.Name(entry) + return nil +} + +func validateStrings(tx *payload.NameTx) error { + if len(tx.Name) == 0 { + return errors.ErrorCodef(errors.ErrorCodeInvalidString, "name must not be empty") + } + if len(tx.Name) > names.MaxNameLength { + return errors.ErrorCodef(errors.ErrorCodeInvalidString, "Name is too long. Max %d bytes", names.MaxNameLength) + } + if len(tx.Data) > names.MaxDataLength { + return errors.ErrorCodef(errors.ErrorCodeInvalidString, "Data is too long. Max %d bytes", names.MaxDataLength) + } + + if !validateNameRegEntryName(tx.Name) { + return errors.ErrorCodef(errors.ErrorCodeInvalidString, + "Invalid characters found in NameTx.Name (%s). Only alphanumeric, underscores, dashes, forward slashes, and @ are allowed", tx.Name) + } + + if !validateNameRegEntryData(tx.Data) { + return errors.ErrorCodef(errors.ErrorCodeInvalidString, + "Invalid characters found in NameTx.Data (%s). Only the kind of things found in a JSON file are allowed", tx.Data) } return nil } + +// filter strings +func validateNameRegEntryName(name string) bool { + return regexpAlphaNum.Match([]byte(name)) +} + +func validateNameRegEntryData(data string) bool { + return regexpJSON.Match([]byte(data)) +} diff --git a/execution/executors/permissions.go b/execution/executors/permissions_context.go similarity index 72% rename from execution/executors/permissions.go rename to execution/executors/permissions_context.go index 0ccc62040da5a695c1ceaaac7c59074af793e9f0..39292a3b0f8cd20c74cb1b0d78ad4c54b0f02f88 100644 --- a/execution/executors/permissions.go +++ b/execution/executors/permissions_context.go @@ -3,32 +3,29 @@ package executors import ( "fmt" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/events" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" - ptypes "github.com/hyperledger/burrow/permission/types" - "github.com/hyperledger/burrow/txs" + "github.com/hyperledger/burrow/permission" "github.com/hyperledger/burrow/txs/payload" ) type PermissionsContext struct { - Tip blockchain.TipInfo - StateWriter state.ReaderWriter - EventPublisher event.Publisher - Logger *logging.Logger - tx *payload.PermissionsTx + Tip blockchain.TipInfo + StateWriter state.ReaderWriter + Logger *logging.Logger + tx *payload.PermissionsTx } -func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error { +func (ctx *PermissionsContext) Execute(txe *exec.TxExecution) error { var ok bool - ctx.tx, ok = txEnv.Tx.Payload.(*payload.PermissionsTx) + ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.PermissionsTx) if !ok { - return fmt.Errorf("payload must be PermissionsTx, but is: %v", txEnv.Tx.Payload) + return fmt.Errorf("payload must be PermissionsTx, but is: %v", txe.Envelope.Tx.Payload) } // Validate input inAcc, err := state.GetMutableAccount(ctx.StateWriter, ctx.tx.Input.Address) @@ -68,38 +65,38 @@ func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error { var permAcc acm.Account switch ctx.tx.PermArgs.PermFlag { - case ptypes.HasBase: + case permission.HasBase: // this one doesn't make sense from txs return fmt.Errorf("HasBase is for contracts, not humans. Just look at the blockchain") - case ptypes.SetBase: + case permission.SetBase: permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, - func(perms *ptypes.AccountPermissions) error { + func(perms *permission.AccountPermissions) error { return perms.Base.Set(*ctx.tx.PermArgs.Permission, *ctx.tx.PermArgs.Value) }) - case ptypes.UnsetBase: + case permission.UnsetBase: permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, - func(perms *ptypes.AccountPermissions) error { + func(perms *permission.AccountPermissions) error { return perms.Base.Unset(*ctx.tx.PermArgs.Permission) }) - case ptypes.SetGlobal: + case permission.SetGlobal: permAcc, err = mutatePermissions(ctx.StateWriter, acm.GlobalPermissionsAddress, - func(perms *ptypes.AccountPermissions) error { + func(perms *permission.AccountPermissions) error { return perms.Base.Set(*ctx.tx.PermArgs.Permission, *ctx.tx.PermArgs.Value) }) - case ptypes.HasRole: + case permission.HasRole: return fmt.Errorf("HasRole is for contracts, not humans. Just look at the blockchain") - case ptypes.AddRole: + case permission.AddRole: permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, - func(perms *ptypes.AccountPermissions) error { + func(perms *permission.AccountPermissions) error { if !perms.AddRole(*ctx.tx.PermArgs.Role) { return fmt.Errorf("role (%s) already exists for account %s", *ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address) } return nil }) - case ptypes.RemoveRole: + case permission.RemoveRole: permAcc, err = mutatePermissions(ctx.StateWriter, *ctx.tx.PermArgs.Address, - func(perms *ptypes.AccountPermissions) error { + func(perms *permission.AccountPermissions) error { if !perms.RmRole(*ctx.tx.PermArgs.Role) { return fmt.Errorf("role (%s) does not exist for account %s", *ctx.tx.PermArgs.Role, *ctx.tx.PermArgs.Address) @@ -122,7 +119,7 @@ func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error { "old_sequence", inAcc.Sequence(), "new_sequence", inAcc.Sequence()+1) inAcc.IncSequence() - inAcc, err = inAcc.SubtractFromBalance(value) + err = inAcc.SubtractFromBalance(value) if err != nil { return err } @@ -131,16 +128,13 @@ func (ctx *PermissionsContext) Execute(txEnv *txs.Envelope) error { ctx.StateWriter.UpdateAccount(permAcc) } - if ctx.EventPublisher != nil { - events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), ctx.tx.Input.Address, txEnv.Tx, nil, nil) - events.PublishPermissions(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), txEnv.Tx) - } - + txe.Input(ctx.tx.Input.Address, nil) + txe.Permission(&ctx.tx.PermArgs) return nil } func mutatePermissions(stateReader state.Reader, address crypto.Address, - mutator func(*ptypes.AccountPermissions) error) (acm.Account, error) { + mutator func(*permission.AccountPermissions) error) (acm.Account, error) { account, err := stateReader.GetAccount(address) if err != nil { diff --git a/execution/executors/send.go b/execution/executors/send_context.go similarity index 59% rename from execution/executors/send.go rename to execution/executors/send_context.go index f7e9f752b0bfbf7ea7aaac0fa97609b987a670ad..5cad86303d48049084e716abb33c803233a3c5f3 100644 --- a/execution/executors/send.go +++ b/execution/executors/send_context.go @@ -3,28 +3,25 @@ package executors import ( "fmt" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/blockchain" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/events" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/txs" "github.com/hyperledger/burrow/txs/payload" ) type SendContext struct { - Tip blockchain.TipInfo - StateWriter state.ReaderWriter - EventPublisher event.Publisher - Logger *logging.Logger - tx *payload.SendTx + Tip blockchain.TipInfo + StateWriter state.ReaderWriter + Logger *logging.Logger + tx *payload.SendTx } -func (ctx *SendContext) Execute(txEnv *txs.Envelope) error { +func (ctx *SendContext) Execute(txe *exec.TxExecution) error { var ok bool - ctx.tx, ok = txEnv.Tx.Payload.(*payload.SendTx) + ctx.tx, ok = txe.Envelope.Tx.Payload.(*payload.SendTx) if !ok { - return fmt.Errorf("payload must be NameTx, but is: %v", txEnv.Tx.Payload) + return fmt.Errorf("payload must be NameTx, but is: %v", txe.Envelope.Tx.Payload) } accounts, err := getInputs(ctx.StateWriter, ctx.tx.Inputs) if err != nil { @@ -70,14 +67,13 @@ func (ctx *SendContext) Execute(txEnv *txs.Envelope) error { ctx.StateWriter.UpdateAccount(acc) } - if ctx.EventPublisher != nil { - for _, i := range ctx.tx.Inputs { - events.PublishAccountInput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), i.Address, txEnv.Tx, nil, nil) - } + for _, i := range ctx.tx.Inputs { + txe.Input(i.Address, nil) + } - for _, o := range ctx.tx.Outputs { - events.PublishAccountOutput(ctx.EventPublisher, ctx.Tip.LastBlockHeight(), o.Address, txEnv.Tx, nil, nil) - } + for _, o := range ctx.tx.Outputs { + txe.Output(o.Address, nil) } + return nil } diff --git a/execution/executors/shared.go b/execution/executors/shared.go index 8843249b1eaa488400db617ea18676deed2ea647..58904bb98efddc27cd0df9e2a4e3ef7cbc6e94da 100644 --- a/execution/executors/shared.go +++ b/execution/executors/shared.go @@ -3,13 +3,12 @@ package executors import ( "fmt" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/permission" - ptypes "github.com/hyperledger/burrow/permission/types" "github.com/hyperledger/burrow/txs/payload" ) @@ -18,9 +17,9 @@ import ( // or it must be specified in the TxInput. If redeclared, // the TxInput is modified and input.PublicKey() set to nil. func getInputs(accountGetter state.AccountGetter, - ins []*payload.TxInput) (map[crypto.Address]acm.MutableAccount, error) { + ins []*payload.TxInput) (map[crypto.Address]*acm.MutableAccount, error) { - accounts := map[crypto.Address]acm.MutableAccount{} + accounts := map[crypto.Address]*acm.MutableAccount{} for _, in := range ins { // Account shouldn't be duplicated if _, ok := accounts[in.Address]; ok { @@ -38,10 +37,10 @@ func getInputs(accountGetter state.AccountGetter, return accounts, nil } -func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount, - outs []*payload.TxOutput, logger *logging.Logger) (map[crypto.Address]acm.MutableAccount, error) { +func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address]*acm.MutableAccount, + outs []*payload.TxOutput, logger *logging.Logger) (map[crypto.Address]*acm.MutableAccount, error) { if accs == nil { - accs = make(map[crypto.Address]acm.MutableAccount) + accs = make(map[crypto.Address]*acm.MutableAccount) } // we should err if an account is being created but the inputs don't have permission @@ -75,7 +74,7 @@ func getOrMakeOutputs(accountGetter state.AccountGetter, accs map[crypto.Address return accs, nil } -func validateInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.TxInput) (uint64, error) { +func validateInputs(accs map[crypto.Address]*acm.MutableAccount, ins []*payload.TxInput) (uint64, error) { total := uint64(0) for _, in := range ins { acc := accs[in.Address] @@ -92,7 +91,7 @@ func validateInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.T return total, nil } -func validateInput(acc acm.MutableAccount, in *payload.TxInput) error { +func validateInput(acc *acm.MutableAccount, in *payload.TxInput) error { // Check TxInput basic if err := in.ValidateBasic(); err != nil { return err @@ -124,7 +123,7 @@ func validateOutputs(outs []*payload.TxOutput) (uint64, error) { return total, nil } -func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.TxInput, logger *logging.Logger) error { +func adjustByInputs(accs map[crypto.Address]*acm.MutableAccount, ins []*payload.TxInput, logger *logging.Logger) error { for _, in := range ins { acc := accs[in.Address] if acc == nil { @@ -135,7 +134,7 @@ func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.T return fmt.Errorf("adjustByInputs() expects sufficient funds but account %s only has balance %v and "+ "we are deducting %v", in.Address, acc.Balance(), in.Amount) } - acc, err := acc.SubtractFromBalance(in.Amount) + err := acc.SubtractFromBalance(in.Amount) if err != nil { return err } @@ -149,14 +148,14 @@ func adjustByInputs(accs map[crypto.Address]acm.MutableAccount, ins []*payload.T return nil } -func adjustByOutputs(accs map[crypto.Address]acm.MutableAccount, outs []*payload.TxOutput) error { +func adjustByOutputs(accs map[crypto.Address]*acm.MutableAccount, outs []*payload.TxOutput) error { for _, out := range outs { acc := accs[out.Address] if acc == nil { return fmt.Errorf("adjustByOutputs() expects account in accounts, but account %s not found", out.Address) } - _, err := acc.AddToBalance(out.Amount) + err := acc.AddToBalance(out.Amount) if err != nil { return err } @@ -167,13 +166,13 @@ func adjustByOutputs(accs map[crypto.Address]acm.MutableAccount, outs []*payload //--------------------------------------------------------------- // Get permission on an account or fall back to global value -func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm ptypes.PermFlag, logger *logging.Logger) bool { - if perm > ptypes.AllPermFlags { +func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm permission.PermFlag, logger *logging.Logger) bool { + if perm > permission.AllPermFlags { logger.InfoMsg( fmt.Sprintf("HasPermission called on invalid permission 0b%b (invalid) > 0b%b (maximum) ", - perm, ptypes.AllPermFlags), + perm, permission.AllPermFlags), "invalid_permission", perm, - "maximum_permission", ptypes.AllPermFlags) + "maximum_permission", permission.AllPermFlags) return false } @@ -197,10 +196,10 @@ func HasPermission(accountGetter state.AccountGetter, acc acm.Account, perm ptyp } // TODO: for debug log the failed accounts -func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount, +func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]*acm.MutableAccount, logger *logging.Logger) bool { for _, acc := range accs { - if !HasPermission(accountGetter, acc, ptypes.Send, logger) { + if !HasPermission(accountGetter, acc, permission.Send, logger) { return false } } @@ -209,23 +208,23 @@ func hasSendPermission(accountGetter state.AccountGetter, accs map[crypto.Addres func hasNamePermission(accountGetter state.AccountGetter, acc acm.Account, logger *logging.Logger) bool { - return HasPermission(accountGetter, acc, ptypes.Name, logger) + return HasPermission(accountGetter, acc, permission.Name, logger) } func hasCallPermission(accountGetter state.AccountGetter, acc acm.Account, logger *logging.Logger) bool { - return HasPermission(accountGetter, acc, ptypes.Call, logger) + return HasPermission(accountGetter, acc, permission.Call, logger) } func hasCreateContractPermission(accountGetter state.AccountGetter, acc acm.Account, logger *logging.Logger) bool { - return HasPermission(accountGetter, acc, ptypes.CreateContract, logger) + return HasPermission(accountGetter, acc, permission.CreateContract, logger) } -func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.MutableAccount, +func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[crypto.Address]*acm.MutableAccount, logger *logging.Logger) bool { for _, acc := range accs { - if !HasPermission(accountGetter, acc, ptypes.CreateAccount, logger) { + if !HasPermission(accountGetter, acc, permission.CreateAccount, logger) { return false } } @@ -234,14 +233,14 @@ func hasCreateAccountPermission(accountGetter state.AccountGetter, accs map[cryp func hasBondPermission(accountGetter state.AccountGetter, acc acm.Account, logger *logging.Logger) bool { - return HasPermission(accountGetter, acc, ptypes.Bond, logger) + return HasPermission(accountGetter, acc, permission.Bond, logger) } func hasBondOrSendPermission(accountGetter state.AccountGetter, accs map[crypto.Address]acm.Account, logger *logging.Logger) bool { for _, acc := range accs { - if !HasPermission(accountGetter, acc, ptypes.Bond, logger) { - if !HasPermission(accountGetter, acc, ptypes.Send, logger) { + if !HasPermission(accountGetter, acc, permission.Bond, logger) { + if !HasPermission(accountGetter, acc, permission.Send, logger) { return false } } diff --git a/execution/names/cache.go b/execution/names/cache.go index 7b8e060f1fa1ebe1b4095ad77c6c928598d2ef2a..6513f702ecb0eeb26c8ec80332c01116d3b66134 100644 --- a/execution/names/cache.go +++ b/execution/names/cache.go @@ -46,7 +46,7 @@ func NewCache(backend Reader) *Cache { } } -func (cache *Cache) GetNameEntry(name string) (*Entry, error) { +func (cache *Cache) GetName(name string) (*Entry, error) { nameInfo, err := cache.get(name) if err != nil { return nil, err @@ -59,7 +59,7 @@ func (cache *Cache) GetNameEntry(name string) (*Entry, error) { return nameInfo.entry, nil } -func (cache *Cache) UpdateNameEntry(entry *Entry) error { +func (cache *Cache) UpdateName(entry *Entry) error { nameInfo, err := cache.get(entry.Name) if err != nil { return err @@ -67,7 +67,7 @@ func (cache *Cache) UpdateNameEntry(entry *Entry) error { nameInfo.Lock() defer nameInfo.Unlock() if nameInfo.removed { - return fmt.Errorf("UpdateNameEntry on a removed name: %s", nameInfo.entry.Name) + return fmt.Errorf("UpdateName on a removed name: %s", nameInfo.entry.Name) } nameInfo.entry = entry @@ -75,7 +75,7 @@ func (cache *Cache) UpdateNameEntry(entry *Entry) error { return nil } -func (cache *Cache) RemoveNameEntry(name string) error { +func (cache *Cache) RemoveName(name string) error { nameInfo, err := cache.get(name) if err != nil { return err @@ -83,7 +83,7 @@ func (cache *Cache) RemoveNameEntry(name string) error { nameInfo.Lock() defer nameInfo.Unlock() if nameInfo.removed { - return fmt.Errorf("RemoveNameEntry on removed name: %s", name) + return fmt.Errorf("RemoveName on removed name: %s", name) } nameInfo.removed = true return nil @@ -107,13 +107,13 @@ func (cache *Cache) Sync(state Writer) error { nameInfo := cache.names[name] nameInfo.RLock() if nameInfo.removed { - err := state.RemoveNameEntry(name) + err := state.RemoveName(name) if err != nil { nameInfo.RUnlock() return err } } else if nameInfo.updated { - err := state.UpdateNameEntry(nameInfo.entry) + err := state.UpdateName(nameInfo.entry) if err != nil { nameInfo.RUnlock() return err @@ -156,7 +156,7 @@ func (cache *Cache) get(name string) (*nameInfo, error) { defer cache.Unlock() nmeInfo = cache.names[name] if nmeInfo == nil { - entry, err := cache.backend.GetNameEntry(name) + entry, err := cache.backend.GetName(name) if err != nil { return nil, err } diff --git a/execution/names/names.go b/execution/names/names.go index 1732575f0351c50e94cb80c69aead84e706bfde0..81d83b1764bb872b261ffc5a0a297f90286b47ba 100644 --- a/execution/names/names.go +++ b/execution/names/names.go @@ -15,12 +15,15 @@ package names import ( - "github.com/hyperledger/burrow/crypto" + "fmt" + + "github.com/hyperledger/burrow/event/query" "github.com/tendermint/go-amino" ) -var ( - MinNameRegistrationPeriod uint64 = 5 +var MinNameRegistrationPeriod uint64 = 5 + +const ( // NOTE: base costs and validity checks are here so clients // can use them without importing state @@ -34,25 +37,28 @@ var ( MaxDataLength = 1 << 16 ) -// NameReg provides a global key value store based on Name, Data pairs that are subject to expiry and ownership by an -// account. -type Entry struct { - // registered name for the entry - Name string - // address that created the entry - Owner crypto.Address - // data to store under this name - Data string - // block at which this entry expires - Expires uint64 -} - var cdc = amino.NewCodec() func (e *Entry) Encode() ([]byte, error) { return cdc.MarshalBinary(e) } +func (e *Entry) String() string { + return fmt.Sprintf("NameEntry{%v -> %v; Expires: %v, Owner: %v}", e.Name, e.Data, e.Expires, e.Owner) +} + +type TaggedEntry struct { + *Entry + query.Tagged +} + +func (e *Entry) Tagged() *TaggedEntry { + return &TaggedEntry{ + Entry: e, + Tagged: query.MustReflectTags(e), + } +} + func DecodeEntry(entryBytes []byte) (*Entry, error) { entry := new(Entry) err := cdc.UnmarshalBinary(entryBytes, entry) @@ -63,14 +69,14 @@ func DecodeEntry(entryBytes []byte) (*Entry, error) { } type Reader interface { - GetNameEntry(name string) (*Entry, error) + GetName(name string) (*Entry, error) } type Writer interface { // Updates the name entry creating it if it does not exist - UpdateNameEntry(entry *Entry) error + UpdateName(entry *Entry) error // Remove the name entry - RemoveNameEntry(name string) error + RemoveName(name string) error } type ReaderWriter interface { @@ -79,7 +85,7 @@ type ReaderWriter interface { } type Iterable interface { - IterateNameEntries(consumer func(*Entry) (stop bool)) (stopped bool, err error) + IterateNames(consumer func(*Entry) (stop bool)) (stopped bool, err error) } type IterableReader interface { @@ -100,3 +106,7 @@ func NameBaseCost(name, data string) uint64 { func NameCostPerBlock(baseCost uint64) uint64 { return NameBlockCostMultiplier * NameByteCostMultiplier * baseCost } + +func NameCostForExpiryIn(name, data string, expiresIn uint64) uint64 { + return NameCostPerBlock(NameBaseCost(name, data)) * expiresIn +} diff --git a/execution/names/names.pb.go b/execution/names/names.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..64cd40e92694559809ea9d8f0e1311a454466afa --- /dev/null +++ b/execution/names/names.pb.go @@ -0,0 +1,449 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: names.proto + +/* + Package names is a generated protocol buffer package. + + It is generated from these files: + names.proto + + It has these top-level messages: + Entry +*/ +package names + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" + +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +// NameReg provides a global key value store based on Name, Data pairs that are subject to expiry and ownership by an +// account. +type Entry struct { + // registered name for the entry + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + // address that created the entry + Owner github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Owner,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Owner"` + // data to store under this name + Data string `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"` + // block at which this entry expires + Expires uint64 `protobuf:"varint,4,opt,name=Expires,proto3" json:"Expires,omitempty"` +} + +func (m *Entry) Reset() { *m = Entry{} } +func (*Entry) ProtoMessage() {} +func (*Entry) Descriptor() ([]byte, []int) { return fileDescriptorNames, []int{0} } + +func (m *Entry) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Entry) GetData() string { + if m != nil { + return m.Data + } + return "" +} + +func (m *Entry) GetExpires() uint64 { + if m != nil { + return m.Expires + } + return 0 +} + +func (*Entry) XXX_MessageName() string { + return "names.Entry" +} +func init() { + proto.RegisterType((*Entry)(nil), "names.Entry") + golang_proto.RegisterType((*Entry)(nil), "names.Entry") +} +func (m *Entry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Entry) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintNames(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + dAtA[i] = 0x12 + i++ + i = encodeVarintNames(dAtA, i, uint64(m.Owner.Size())) + n1, err := m.Owner.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + if len(m.Data) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintNames(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + if m.Expires != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintNames(dAtA, i, uint64(m.Expires)) + } + return i, nil +} + +func encodeVarintNames(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Entry) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovNames(uint64(l)) + } + l = m.Owner.Size() + n += 1 + l + sovNames(uint64(l)) + l = len(m.Data) + if l > 0 { + n += 1 + l + sovNames(uint64(l)) + } + if m.Expires != 0 { + n += 1 + sovNames(uint64(m.Expires)) + } + return n +} + +func sovNames(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozNames(x uint64) (n int) { + return sovNames(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Entry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNames + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Entry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Entry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNames + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNames + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNames + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthNames + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Owner.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNames + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNames + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + m.Expires = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNames + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Expires |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipNames(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNames + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipNames(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowNames + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowNames + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowNames + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthNames + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowNames + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipNames(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthNames = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowNames = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("names.proto", fileDescriptorNames) } +func init() { golang_proto.RegisterFile("names.proto", fileDescriptorNames) } + +var fileDescriptorNames = []byte{ + // 245 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0x4b, 0xcc, 0x4d, + 0x2d, 0xd6, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x73, 0xa4, 0x74, 0xd3, 0x33, 0x4b, + 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, 0xb2, 0x49, + 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0x74, 0x29, 0xcd, 0x66, 0xe4, 0x62, 0x75, 0xcd, + 0x2b, 0x29, 0xaa, 0x14, 0x12, 0xe2, 0x62, 0xf1, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60, 0xd4, + 0xe0, 0x0c, 0x02, 0xb3, 0x85, 0xbc, 0xb8, 0x58, 0xfd, 0xcb, 0xf3, 0x52, 0x8b, 0x24, 0x98, 0x14, + 0x18, 0x35, 0x78, 0x9c, 0x4c, 0x4e, 0xdc, 0x93, 0x67, 0xb8, 0x75, 0x4f, 0x5e, 0x07, 0xc9, 0x8e, + 0x8c, 0xca, 0x82, 0xd4, 0xa2, 0x9c, 0xd4, 0x94, 0xf4, 0xd4, 0x22, 0xfd, 0xa4, 0xd2, 0xa2, 0xa2, + 0xfc, 0x72, 0xfd, 0xe4, 0xa2, 0xca, 0x82, 0x92, 0x7c, 0x3d, 0xc7, 0x94, 0x94, 0xa2, 0xd4, 0xe2, + 0xe2, 0x20, 0x88, 0x11, 0x20, 0xf3, 0x5d, 0x12, 0x4b, 0x12, 0x25, 0x98, 0x21, 0xe6, 0x83, 0xd8, + 0x42, 0x12, 0x5c, 0xec, 0xae, 0x15, 0x05, 0x99, 0x45, 0xa9, 0xc5, 0x12, 0x2c, 0x0a, 0x8c, 0x1a, + 0x2c, 0x41, 0x30, 0xae, 0x15, 0xcb, 0x8c, 0x05, 0xf2, 0x0c, 0x4e, 0xce, 0x27, 0x1e, 0xc9, 0x31, + 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x81, 0xc7, 0x72, 0x8c, 0x27, 0x1e, 0xcb, + 0x31, 0x46, 0xe9, 0xe2, 0xb7, 0x3e, 0xb5, 0x22, 0x35, 0xb9, 0xb4, 0x24, 0x33, 0x3f, 0x4f, 0x1f, + 0x1c, 0x22, 0x49, 0x6c, 0x60, 0x9f, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x03, 0xd1, 0x42, + 0x7f, 0x2e, 0x01, 0x00, 0x00, +} diff --git a/execution/names/names_test.go b/execution/names/names_test.go new file mode 100644 index 0000000000000000000000000000000000000000..3ee467ddc947f44827450acde24d4bb70a2f4e57 --- /dev/null +++ b/execution/names/names_test.go @@ -0,0 +1,39 @@ +package names + +import ( + "testing" + + "github.com/gogo/protobuf/proto" + "github.com/hyperledger/burrow/crypto" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestEncodeAmino(t *testing.T) { + entry := &Entry{ + Name: "Foo", + Data: "oh noes", + Expires: 24423432, + Owner: crypto.Address{1, 2, 0, 9, 8, 8, 1, 2}, + } + encoded, err := entry.Encode() + require.NoError(t, err) + entryOut, err := DecodeEntry(encoded) + require.NoError(t, err) + assert.Equal(t, entry, entryOut) +} + +func TestEncodeProtobuf(t *testing.T) { + entry := &Entry{ + Name: "Foo", + Data: "oh noes", + Expires: 24423432, + Owner: crypto.Address{1, 2, 0, 9, 8, 8, 1, 2}, + } + encoded, err := proto.Marshal(entry) + require.NoError(t, err) + entryOut := new(Entry) + err = proto.Unmarshal(encoded, entryOut) + require.NoError(t, err) + assert.Equal(t, entry, entryOut) +} diff --git a/execution/options.go b/execution/options.go deleted file mode 100644 index 8b6e458b890a5ce9dd1e07e24b0806634541b77f..0000000000000000000000000000000000000000 --- a/execution/options.go +++ /dev/null @@ -1,11 +0,0 @@ -package execution - -import "github.com/hyperledger/burrow/execution/evm" - -type ExecutionOption func(*executor) - -func VMOptions(vmOptions ...func(*evm.VM)) func(*executor) { - return func(exe *executor) { - exe.vmOptions = vmOptions - } -} diff --git a/execution/pbtransactor/transactor.pb.go b/execution/pbtransactor/transactor.pb.go deleted file mode 100644 index e5c7a89349d7c3430b3047d9c207ebbef3fd6d1c..0000000000000000000000000000000000000000 --- a/execution/pbtransactor/transactor.pb.go +++ /dev/null @@ -1,960 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/hyperledger/burrow/execution/pbtransactor/transactor.proto - -package pbtransactor // import "github.com/hyperledger/burrow/execution/pbtransactor" - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import pbevents "github.com/hyperledger/burrow/execution/events/pbevents" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// Params -type CallParam struct { - From []byte `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` - Address []byte `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CallParam) Reset() { *m = CallParam{} } -func (m *CallParam) String() string { return proto.CompactTextString(m) } -func (*CallParam) ProtoMessage() {} -func (*CallParam) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{0} -} -func (m *CallParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CallParam.Unmarshal(m, b) -} -func (m *CallParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CallParam.Marshal(b, m, deterministic) -} -func (dst *CallParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_CallParam.Merge(dst, src) -} -func (m *CallParam) XXX_Size() int { - return xxx_messageInfo_CallParam.Size(m) -} -func (m *CallParam) XXX_DiscardUnknown() { - xxx_messageInfo_CallParam.DiscardUnknown(m) -} - -var xxx_messageInfo_CallParam proto.InternalMessageInfo - -func (m *CallParam) GetFrom() []byte { - if m != nil { - return m.From - } - return nil -} - -func (m *CallParam) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *CallParam) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -type CallCodeParam struct { - From []byte `protobuf:"bytes,1,opt,name=from,proto3" json:"from,omitempty"` - Code []byte `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"` - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CallCodeParam) Reset() { *m = CallCodeParam{} } -func (m *CallCodeParam) String() string { return proto.CompactTextString(m) } -func (*CallCodeParam) ProtoMessage() {} -func (*CallCodeParam) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{1} -} -func (m *CallCodeParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CallCodeParam.Unmarshal(m, b) -} -func (m *CallCodeParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CallCodeParam.Marshal(b, m, deterministic) -} -func (dst *CallCodeParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_CallCodeParam.Merge(dst, src) -} -func (m *CallCodeParam) XXX_Size() int { - return xxx_messageInfo_CallCodeParam.Size(m) -} -func (m *CallCodeParam) XXX_DiscardUnknown() { - xxx_messageInfo_CallCodeParam.DiscardUnknown(m) -} - -var xxx_messageInfo_CallCodeParam proto.InternalMessageInfo - -func (m *CallCodeParam) GetFrom() []byte { - if m != nil { - return m.From - } - return nil -} - -func (m *CallCodeParam) GetCode() []byte { - if m != nil { - return m.Code - } - return nil -} - -func (m *CallCodeParam) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -type TransactParam struct { - // The input account to sign with - InputAccount *InputAccount `protobuf:"bytes,1,opt,name=inputAccount,proto3" json:"inputAccount,omitempty"` - // The address of the contract to call, or omitted if creating a new contract - Address []byte `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - // EVM bytecode payload to deliver - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` - // The maximum gas to provide to the EVM when running any code - provided in order to bound the computation time - GasLimit uint64 `protobuf:"varint,4,opt,name=gasLimit,proto3" json:"gasLimit,omitempty"` - // Value to transfer, where amount = value + fee - Value uint64 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"` - // Fee to offer validators for processing transaction - Fee uint64 `protobuf:"varint,6,opt,name=fee,proto3" json:"fee,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TransactParam) Reset() { *m = TransactParam{} } -func (m *TransactParam) String() string { return proto.CompactTextString(m) } -func (*TransactParam) ProtoMessage() {} -func (*TransactParam) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{2} -} -func (m *TransactParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TransactParam.Unmarshal(m, b) -} -func (m *TransactParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TransactParam.Marshal(b, m, deterministic) -} -func (dst *TransactParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_TransactParam.Merge(dst, src) -} -func (m *TransactParam) XXX_Size() int { - return xxx_messageInfo_TransactParam.Size(m) -} -func (m *TransactParam) XXX_DiscardUnknown() { - xxx_messageInfo_TransactParam.DiscardUnknown(m) -} - -var xxx_messageInfo_TransactParam proto.InternalMessageInfo - -func (m *TransactParam) GetInputAccount() *InputAccount { - if m != nil { - return m.InputAccount - } - return nil -} - -func (m *TransactParam) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *TransactParam) GetData() []byte { - if m != nil { - return m.Data - } - return nil -} - -func (m *TransactParam) GetGasLimit() uint64 { - if m != nil { - return m.GasLimit - } - return 0 -} - -func (m *TransactParam) GetValue() uint64 { - if m != nil { - return m.Value - } - return 0 -} - -func (m *TransactParam) GetFee() uint64 { - if m != nil { - return m.Fee - } - return 0 -} - -type SendParam struct { - InputAccount *InputAccount `protobuf:"bytes,1,opt,name=inputAccount,proto3" json:"inputAccount,omitempty"` - ToAddress []byte `protobuf:"bytes,2,opt,name=toAddress,proto3" json:"toAddress,omitempty"` - Amount uint64 `protobuf:"varint,3,opt,name=amount,proto3" json:"amount,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SendParam) Reset() { *m = SendParam{} } -func (m *SendParam) String() string { return proto.CompactTextString(m) } -func (*SendParam) ProtoMessage() {} -func (*SendParam) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{3} -} -func (m *SendParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SendParam.Unmarshal(m, b) -} -func (m *SendParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SendParam.Marshal(b, m, deterministic) -} -func (dst *SendParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_SendParam.Merge(dst, src) -} -func (m *SendParam) XXX_Size() int { - return xxx_messageInfo_SendParam.Size(m) -} -func (m *SendParam) XXX_DiscardUnknown() { - xxx_messageInfo_SendParam.DiscardUnknown(m) -} - -var xxx_messageInfo_SendParam proto.InternalMessageInfo - -func (m *SendParam) GetInputAccount() *InputAccount { - if m != nil { - return m.InputAccount - } - return nil -} - -func (m *SendParam) GetToAddress() []byte { - if m != nil { - return m.ToAddress - } - return nil -} - -func (m *SendParam) GetAmount() uint64 { - if m != nil { - return m.Amount - } - return 0 -} - -type TxParam struct { - Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxParam) Reset() { *m = TxParam{} } -func (m *TxParam) String() string { return proto.CompactTextString(m) } -func (*TxParam) ProtoMessage() {} -func (*TxParam) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{4} -} -func (m *TxParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxParam.Unmarshal(m, b) -} -func (m *TxParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxParam.Marshal(b, m, deterministic) -} -func (dst *TxParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxParam.Merge(dst, src) -} -func (m *TxParam) XXX_Size() int { - return xxx_messageInfo_TxParam.Size(m) -} -func (m *TxParam) XXX_DiscardUnknown() { - xxx_messageInfo_TxParam.DiscardUnknown(m) -} - -var xxx_messageInfo_TxParam proto.InternalMessageInfo - -func (m *TxParam) GetTx() []byte { - if m != nil { - return m.Tx - } - return nil -} - -type SignTxParam struct { - Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` - PrivateAccounts []*PrivateAccount `protobuf:"bytes,2,rep,name=privateAccounts,proto3" json:"privateAccounts,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignTxParam) Reset() { *m = SignTxParam{} } -func (m *SignTxParam) String() string { return proto.CompactTextString(m) } -func (*SignTxParam) ProtoMessage() {} -func (*SignTxParam) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{5} -} -func (m *SignTxParam) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignTxParam.Unmarshal(m, b) -} -func (m *SignTxParam) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignTxParam.Marshal(b, m, deterministic) -} -func (dst *SignTxParam) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignTxParam.Merge(dst, src) -} -func (m *SignTxParam) XXX_Size() int { - return xxx_messageInfo_SignTxParam.Size(m) -} -func (m *SignTxParam) XXX_DiscardUnknown() { - xxx_messageInfo_SignTxParam.DiscardUnknown(m) -} - -var xxx_messageInfo_SignTxParam proto.InternalMessageInfo - -func (m *SignTxParam) GetTx() []byte { - if m != nil { - return m.Tx - } - return nil -} - -func (m *SignTxParam) GetPrivateAccounts() []*PrivateAccount { - if m != nil { - return m.PrivateAccounts - } - return nil -} - -// Results -type SignedTx struct { - Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignedTx) Reset() { *m = SignedTx{} } -func (m *SignedTx) String() string { return proto.CompactTextString(m) } -func (*SignedTx) ProtoMessage() {} -func (*SignedTx) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{6} -} -func (m *SignedTx) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignedTx.Unmarshal(m, b) -} -func (m *SignedTx) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignedTx.Marshal(b, m, deterministic) -} -func (dst *SignedTx) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignedTx.Merge(dst, src) -} -func (m *SignedTx) XXX_Size() int { - return xxx_messageInfo_SignedTx.Size(m) -} -func (m *SignedTx) XXX_DiscardUnknown() { - xxx_messageInfo_SignedTx.DiscardUnknown(m) -} - -var xxx_messageInfo_SignedTx proto.InternalMessageInfo - -func (m *SignedTx) GetTx() []byte { - if m != nil { - return m.Tx - } - return nil -} - -type CallResult struct { - Return []byte `protobuf:"bytes,1,opt,name=Return,proto3" json:"Return,omitempty"` - GasUsed uint64 `protobuf:"varint,2,opt,name=GasUsed,proto3" json:"GasUsed,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CallResult) Reset() { *m = CallResult{} } -func (m *CallResult) String() string { return proto.CompactTextString(m) } -func (*CallResult) ProtoMessage() {} -func (*CallResult) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{7} -} -func (m *CallResult) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CallResult.Unmarshal(m, b) -} -func (m *CallResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CallResult.Marshal(b, m, deterministic) -} -func (dst *CallResult) XXX_Merge(src proto.Message) { - xxx_messageInfo_CallResult.Merge(dst, src) -} -func (m *CallResult) XXX_Size() int { - return xxx_messageInfo_CallResult.Size(m) -} -func (m *CallResult) XXX_DiscardUnknown() { - xxx_messageInfo_CallResult.DiscardUnknown(m) -} - -var xxx_messageInfo_CallResult proto.InternalMessageInfo - -func (m *CallResult) GetReturn() []byte { - if m != nil { - return m.Return - } - return nil -} - -func (m *CallResult) GetGasUsed() uint64 { - if m != nil { - return m.GasUsed - } - return 0 -} - -type TxReceipt struct { - TxHash []byte `protobuf:"bytes,1,opt,name=TxHash,proto3" json:"TxHash,omitempty"` - CreatesContract bool `protobuf:"varint,2,opt,name=CreatesContract,proto3" json:"CreatesContract,omitempty"` - ContractAddress []byte `protobuf:"bytes,3,opt,name=ContractAddress,proto3" json:"ContractAddress,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *TxReceipt) Reset() { *m = TxReceipt{} } -func (m *TxReceipt) String() string { return proto.CompactTextString(m) } -func (*TxReceipt) ProtoMessage() {} -func (*TxReceipt) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{8} -} -func (m *TxReceipt) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_TxReceipt.Unmarshal(m, b) -} -func (m *TxReceipt) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_TxReceipt.Marshal(b, m, deterministic) -} -func (dst *TxReceipt) XXX_Merge(src proto.Message) { - xxx_messageInfo_TxReceipt.Merge(dst, src) -} -func (m *TxReceipt) XXX_Size() int { - return xxx_messageInfo_TxReceipt.Size(m) -} -func (m *TxReceipt) XXX_DiscardUnknown() { - xxx_messageInfo_TxReceipt.DiscardUnknown(m) -} - -var xxx_messageInfo_TxReceipt proto.InternalMessageInfo - -func (m *TxReceipt) GetTxHash() []byte { - if m != nil { - return m.TxHash - } - return nil -} - -func (m *TxReceipt) GetCreatesContract() bool { - if m != nil { - return m.CreatesContract - } - return false -} - -func (m *TxReceipt) GetContractAddress() []byte { - if m != nil { - return m.ContractAddress - } - return nil -} - -type InputAccount struct { - PrivateKey []byte `protobuf:"bytes,1,opt,name=privateKey,proto3" json:"privateKey,omitempty"` - Address []byte `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *InputAccount) Reset() { *m = InputAccount{} } -func (m *InputAccount) String() string { return proto.CompactTextString(m) } -func (*InputAccount) ProtoMessage() {} -func (*InputAccount) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{9} -} -func (m *InputAccount) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_InputAccount.Unmarshal(m, b) -} -func (m *InputAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_InputAccount.Marshal(b, m, deterministic) -} -func (dst *InputAccount) XXX_Merge(src proto.Message) { - xxx_messageInfo_InputAccount.Merge(dst, src) -} -func (m *InputAccount) XXX_Size() int { - return xxx_messageInfo_InputAccount.Size(m) -} -func (m *InputAccount) XXX_DiscardUnknown() { - xxx_messageInfo_InputAccount.DiscardUnknown(m) -} - -var xxx_messageInfo_InputAccount proto.InternalMessageInfo - -func (m *InputAccount) GetPrivateKey() []byte { - if m != nil { - return m.PrivateKey - } - return nil -} - -func (m *InputAccount) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -type PrivateAccount struct { - PrivateKey []byte `protobuf:"bytes,1,opt,name=PrivateKey,proto3" json:"PrivateKey,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PrivateAccount) Reset() { *m = PrivateAccount{} } -func (m *PrivateAccount) String() string { return proto.CompactTextString(m) } -func (*PrivateAccount) ProtoMessage() {} -func (*PrivateAccount) Descriptor() ([]byte, []int) { - return fileDescriptor_transactor_97142763aca9e238, []int{10} -} -func (m *PrivateAccount) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PrivateAccount.Unmarshal(m, b) -} -func (m *PrivateAccount) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PrivateAccount.Marshal(b, m, deterministic) -} -func (dst *PrivateAccount) XXX_Merge(src proto.Message) { - xxx_messageInfo_PrivateAccount.Merge(dst, src) -} -func (m *PrivateAccount) XXX_Size() int { - return xxx_messageInfo_PrivateAccount.Size(m) -} -func (m *PrivateAccount) XXX_DiscardUnknown() { - xxx_messageInfo_PrivateAccount.DiscardUnknown(m) -} - -var xxx_messageInfo_PrivateAccount proto.InternalMessageInfo - -func (m *PrivateAccount) GetPrivateKey() []byte { - if m != nil { - return m.PrivateKey - } - return nil -} - -func init() { - proto.RegisterType((*CallParam)(nil), "pbtransactor.CallParam") - proto.RegisterType((*CallCodeParam)(nil), "pbtransactor.CallCodeParam") - proto.RegisterType((*TransactParam)(nil), "pbtransactor.TransactParam") - proto.RegisterType((*SendParam)(nil), "pbtransactor.SendParam") - proto.RegisterType((*TxParam)(nil), "pbtransactor.TxParam") - proto.RegisterType((*SignTxParam)(nil), "pbtransactor.SignTxParam") - proto.RegisterType((*SignedTx)(nil), "pbtransactor.SignedTx") - proto.RegisterType((*CallResult)(nil), "pbtransactor.CallResult") - proto.RegisterType((*TxReceipt)(nil), "pbtransactor.TxReceipt") - proto.RegisterType((*InputAccount)(nil), "pbtransactor.InputAccount") - proto.RegisterType((*PrivateAccount)(nil), "pbtransactor.PrivateAccount") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// TransactorClient is the client API for Transactor service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type TransactorClient interface { - // Broadcast a signed and serialised transaction to the mempool - BroadcastTx(ctx context.Context, in *TxParam, opts ...grpc.CallOption) (*TxReceipt, error) - // Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved - Call(ctx context.Context, in *CallParam, opts ...grpc.CallOption) (*CallResult, error) - // Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved - CallCode(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*CallResult, error) - // Formulate a CallTx transaction signed server-side - Transact(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*TxReceipt, error) - // Formulate a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response - TransactAndHold(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*pbevents.EventDataCall, error) - // Formulate a SendTx transaction signed server-side - Send(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error) - // Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response - SendAndHold(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error) - // Sign a transaction server-side - SignTx(ctx context.Context, in *SignTxParam, opts ...grpc.CallOption) (*SignedTx, error) -} - -type transactorClient struct { - cc *grpc.ClientConn -} - -func NewTransactorClient(cc *grpc.ClientConn) TransactorClient { - return &transactorClient{cc} -} - -func (c *transactorClient) BroadcastTx(ctx context.Context, in *TxParam, opts ...grpc.CallOption) (*TxReceipt, error) { - out := new(TxReceipt) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/BroadcastTx", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *transactorClient) Call(ctx context.Context, in *CallParam, opts ...grpc.CallOption) (*CallResult, error) { - out := new(CallResult) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/Call", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *transactorClient) CallCode(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*CallResult, error) { - out := new(CallResult) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/CallCode", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *transactorClient) Transact(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*TxReceipt, error) { - out := new(TxReceipt) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/Transact", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *transactorClient) TransactAndHold(ctx context.Context, in *TransactParam, opts ...grpc.CallOption) (*pbevents.EventDataCall, error) { - out := new(pbevents.EventDataCall) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/TransactAndHold", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *transactorClient) Send(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error) { - out := new(TxReceipt) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/Send", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *transactorClient) SendAndHold(ctx context.Context, in *SendParam, opts ...grpc.CallOption) (*TxReceipt, error) { - out := new(TxReceipt) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/SendAndHold", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *transactorClient) SignTx(ctx context.Context, in *SignTxParam, opts ...grpc.CallOption) (*SignedTx, error) { - out := new(SignedTx) - err := c.cc.Invoke(ctx, "/pbtransactor.Transactor/SignTx", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// TransactorServer is the server API for Transactor service. -type TransactorServer interface { - // Broadcast a signed and serialised transaction to the mempool - BroadcastTx(context.Context, *TxParam) (*TxReceipt, error) - // Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved - Call(context.Context, *CallParam) (*CallResult, error) - // Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved - CallCode(context.Context, *CallCodeParam) (*CallResult, error) - // Formulate a CallTx transaction signed server-side - Transact(context.Context, *TransactParam) (*TxReceipt, error) - // Formulate a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response - TransactAndHold(context.Context, *TransactParam) (*pbevents.EventDataCall, error) - // Formulate a SendTx transaction signed server-side - Send(context.Context, *SendParam) (*TxReceipt, error) - // Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response - SendAndHold(context.Context, *SendParam) (*TxReceipt, error) - // Sign a transaction server-side - SignTx(context.Context, *SignTxParam) (*SignedTx, error) -} - -func RegisterTransactorServer(s *grpc.Server, srv TransactorServer) { - s.RegisterService(&_Transactor_serviceDesc, srv) -} - -func _Transactor_BroadcastTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TxParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).BroadcastTx(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/BroadcastTx", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).BroadcastTx(ctx, req.(*TxParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Transactor_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CallParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).Call(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/Call", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).Call(ctx, req.(*CallParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Transactor_CallCode_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CallCodeParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).CallCode(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/CallCode", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).CallCode(ctx, req.(*CallCodeParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Transactor_Transact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TransactParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).Transact(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/Transact", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).Transact(ctx, req.(*TransactParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Transactor_TransactAndHold_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TransactParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).TransactAndHold(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/TransactAndHold", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).TransactAndHold(ctx, req.(*TransactParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Transactor_Send_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SendParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).Send(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/Send", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).Send(ctx, req.(*SendParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Transactor_SendAndHold_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SendParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).SendAndHold(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/SendAndHold", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).SendAndHold(ctx, req.(*SendParam)) - } - return interceptor(ctx, in, info, handler) -} - -func _Transactor_SignTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SignTxParam) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TransactorServer).SignTx(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbtransactor.Transactor/SignTx", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TransactorServer).SignTx(ctx, req.(*SignTxParam)) - } - return interceptor(ctx, in, info, handler) -} - -var _Transactor_serviceDesc = grpc.ServiceDesc{ - ServiceName: "pbtransactor.Transactor", - HandlerType: (*TransactorServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "BroadcastTx", - Handler: _Transactor_BroadcastTx_Handler, - }, - { - MethodName: "Call", - Handler: _Transactor_Call_Handler, - }, - { - MethodName: "CallCode", - Handler: _Transactor_CallCode_Handler, - }, - { - MethodName: "Transact", - Handler: _Transactor_Transact_Handler, - }, - { - MethodName: "TransactAndHold", - Handler: _Transactor_TransactAndHold_Handler, - }, - { - MethodName: "Send", - Handler: _Transactor_Send_Handler, - }, - { - MethodName: "SendAndHold", - Handler: _Transactor_SendAndHold_Handler, - }, - { - MethodName: "SignTx", - Handler: _Transactor_SignTx_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "github.com/hyperledger/burrow/execution/pbtransactor/transactor.proto", -} - -func init() { - proto.RegisterFile("github.com/hyperledger/burrow/execution/pbtransactor/transactor.proto", fileDescriptor_transactor_97142763aca9e238) -} - -var fileDescriptor_transactor_97142763aca9e238 = []byte{ - // 625 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x4f, 0x6f, 0xd3, 0x30, - 0x14, 0x57, 0xd7, 0xac, 0x6b, 0x5f, 0xbb, 0x0d, 0x59, 0x30, 0xb2, 0x30, 0xa1, 0x29, 0xa7, 0x9e, - 0x5a, 0x34, 0x10, 0x02, 0x21, 0x06, 0x5d, 0x37, 0x36, 0x34, 0x90, 0xa6, 0x2c, 0x5c, 0xb8, 0xb9, - 0xf1, 0x5b, 0x17, 0xa9, 0x8d, 0x23, 0xc7, 0xd9, 0xb2, 0x23, 0x77, 0xbe, 0x14, 0xdf, 0x0c, 0xd9, - 0x71, 0xda, 0x26, 0xa5, 0xc0, 0x10, 0xa7, 0xbc, 0x3f, 0x3f, 0xff, 0xde, 0x3f, 0x3f, 0x07, 0x4e, - 0xc6, 0xa1, 0xbc, 0x4e, 0x47, 0xbd, 0x80, 0x4f, 0xfb, 0xd7, 0x77, 0x31, 0x8a, 0x09, 0xb2, 0x31, - 0x8a, 0xfe, 0x28, 0x15, 0x82, 0xdf, 0xf6, 0x31, 0xc3, 0x20, 0x95, 0x21, 0x8f, 0xfa, 0xf1, 0x48, - 0x0a, 0x1a, 0x25, 0x34, 0x90, 0x5c, 0xf4, 0xe7, 0x62, 0x2f, 0x16, 0x5c, 0x72, 0xd2, 0x59, 0x74, - 0x3b, 0xc7, 0x7f, 0x4b, 0x8a, 0x37, 0x18, 0xc9, 0xa4, 0x1f, 0x8f, 0x8c, 0x90, 0x7f, 0x72, 0x4e, - 0xf7, 0x33, 0xb4, 0x86, 0x74, 0x32, 0xb9, 0xa0, 0x82, 0x4e, 0x09, 0x01, 0xeb, 0x4a, 0xf0, 0xa9, - 0x5d, 0xdb, 0xaf, 0x75, 0x3b, 0x9e, 0x96, 0x89, 0x0d, 0x1b, 0x94, 0x31, 0x81, 0x49, 0x62, 0xaf, - 0x69, 0x73, 0xa1, 0x2a, 0x34, 0xa3, 0x92, 0xda, 0xf5, 0x1c, 0xad, 0x64, 0xf7, 0x1c, 0x36, 0x15, - 0xdd, 0x90, 0x33, 0x5c, 0x4d, 0x49, 0xc0, 0x0a, 0x38, 0x43, 0xc3, 0xa7, 0xe5, 0x5f, 0x92, 0xfd, - 0xa8, 0xc1, 0xa6, 0x6f, 0x0a, 0xce, 0xd9, 0x0e, 0xa1, 0x13, 0x46, 0x71, 0x2a, 0x07, 0x41, 0xc0, - 0xd3, 0x48, 0x6a, 0xd6, 0xf6, 0x81, 0xd3, 0x5b, 0x6c, 0x4c, 0xef, 0xe3, 0x02, 0xc2, 0x2b, 0xe1, - 0xef, 0x57, 0x0c, 0x71, 0xa0, 0x39, 0xa6, 0xc9, 0xa7, 0x70, 0x1a, 0x4a, 0xdb, 0xda, 0xaf, 0x75, - 0x2d, 0x6f, 0xa6, 0x93, 0x87, 0xb0, 0x7e, 0x43, 0x27, 0x29, 0xda, 0xeb, 0xda, 0x91, 0x2b, 0xe4, - 0x01, 0xd4, 0xaf, 0x10, 0xed, 0x86, 0xb6, 0x29, 0xd1, 0xfd, 0x56, 0x83, 0xd6, 0x25, 0x46, 0xec, - 0xff, 0xe4, 0xbf, 0x07, 0x2d, 0xc9, 0x07, 0xa5, 0x0a, 0xe6, 0x06, 0xb2, 0x03, 0x0d, 0x3a, 0xd5, - 0xbc, 0x75, 0x9d, 0x80, 0xd1, 0xdc, 0x5d, 0xd8, 0xf0, 0xb3, 0x3c, 0x81, 0x2d, 0x58, 0x93, 0x99, - 0x19, 0xc6, 0x9a, 0xcc, 0x5c, 0x84, 0xf6, 0x65, 0x38, 0x8e, 0x56, 0xb8, 0xc9, 0x07, 0xd8, 0x8e, - 0x45, 0x78, 0x43, 0x25, 0x9a, 0x0c, 0x54, 0xd4, 0x7a, 0xb7, 0x7d, 0xb0, 0x57, 0x4e, 0xf9, 0xa2, - 0x04, 0xf2, 0xaa, 0x87, 0x5c, 0x07, 0x9a, 0x2a, 0x0c, 0x32, 0x3f, 0x5b, 0x4a, 0xe1, 0x10, 0x40, - 0x5d, 0x19, 0x0f, 0x93, 0x74, 0x22, 0x55, 0x0d, 0x1e, 0xca, 0x54, 0x44, 0x06, 0x61, 0x34, 0x35, - 0xb9, 0x53, 0x9a, 0x7c, 0x49, 0x90, 0xe9, 0xba, 0x2d, 0xaf, 0x50, 0xdd, 0x5b, 0x68, 0xf9, 0x99, - 0x87, 0x01, 0x86, 0xb1, 0x3e, 0xee, 0x67, 0x67, 0x34, 0xb9, 0x2e, 0x8e, 0xe7, 0x1a, 0xe9, 0xc2, - 0xf6, 0x50, 0x20, 0x95, 0x98, 0x0c, 0x79, 0x24, 0x05, 0x0d, 0xa4, 0xa6, 0x69, 0x7a, 0x55, 0xb3, - 0x46, 0x1a, 0xb9, 0x68, 0x74, 0x7e, 0x27, 0xaa, 0x66, 0xf7, 0x0c, 0x3a, 0x8b, 0xa3, 0x22, 0x4f, - 0x01, 0x4c, 0xdd, 0xe7, 0x78, 0x67, 0xe2, 0x2f, 0x58, 0x56, 0x5f, 0x3e, 0xf7, 0x19, 0x6c, 0x95, - 0x3b, 0xa8, 0xb8, 0x2e, 0x96, 0xb8, 0xe6, 0x96, 0x83, 0xef, 0x16, 0x80, 0x3f, 0xeb, 0x3f, 0x79, - 0x0b, 0xed, 0x23, 0xc1, 0x29, 0x0b, 0x68, 0x22, 0xfd, 0x8c, 0x3c, 0x2a, 0x4f, 0xc7, 0x4c, 0xd7, - 0x79, 0x5c, 0x35, 0x17, 0x5d, 0x7b, 0x0d, 0x96, 0x1a, 0x01, 0xa9, 0x00, 0x66, 0x0f, 0x83, 0x63, - 0x2f, 0x3b, 0xcc, 0xbc, 0x06, 0xd0, 0x2c, 0x16, 0x9e, 0x3c, 0x59, 0x46, 0xcd, 0x1e, 0x82, 0xdf, - 0x50, 0xbc, 0x87, 0x66, 0x51, 0x4a, 0x95, 0xa2, 0xb4, 0xfd, 0xab, 0xf3, 0x3f, 0x85, 0xed, 0x02, - 0x39, 0x88, 0xd8, 0x19, 0x9f, 0xb0, 0x3f, 0x13, 0x99, 0x57, 0xf0, 0x44, 0x7d, 0x8e, 0xa9, 0xa4, - 0xba, 0x01, 0xaf, 0xc0, 0x52, 0xcb, 0x5a, 0x6d, 0xc4, 0x6c, 0x81, 0x57, 0xa7, 0xf0, 0x0e, 0xda, - 0x0a, 0x55, 0x84, 0xbf, 0x3f, 0xc1, 0x1b, 0x68, 0xe4, 0x9b, 0x48, 0x76, 0x2b, 0x67, 0xe7, 0xfb, - 0xe9, 0xec, 0x2c, 0xbb, 0xd4, 0x4e, 0x1d, 0xbd, 0xfc, 0xfa, 0xe2, 0x5f, 0x7e, 0x31, 0xa3, 0x86, - 0xfe, 0x09, 0x3c, 0xff, 0x19, 0x00, 0x00, 0xff, 0xff, 0x51, 0xbd, 0x3d, 0xf0, 0xa1, 0x06, 0x00, - 0x00, -} diff --git a/execution/pbtransactor/transactor.proto b/execution/pbtransactor/transactor.proto deleted file mode 100644 index dd058388d94e87214adcb2880ce098e8c2f0c223..0000000000000000000000000000000000000000 --- a/execution/pbtransactor/transactor.proto +++ /dev/null @@ -1,96 +0,0 @@ -syntax = 'proto3'; - -package pbtransactor; - -option go_package = "github.com/hyperledger/burrow/execution/pbtransactor"; - -import "github.com/hyperledger/burrow/execution/events/pbevents/events.proto"; - -// Transaction Service Definition -service Transactor { - // Broadcast a signed and serialised transaction to the mempool - rpc BroadcastTx (TxParam) returns (TxReceipt); - // Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved - rpc Call (CallParam) returns (CallResult); - // Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved - rpc CallCode (CallCodeParam) returns (CallResult); - // Formulate a CallTx transaction signed server-side - rpc Transact (TransactParam) returns (TxReceipt); - // Formulate a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response - rpc TransactAndHold (TransactParam) returns (pbevents.EventDataCall); - // Formulate a SendTx transaction signed server-side - rpc Send (SendParam) returns (TxReceipt); - // Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response - rpc SendAndHold (SendParam) returns (TxReceipt); - // Sign a transaction server-side - rpc SignTx (SignTxParam) returns (SignedTx); -} - -// Params -message CallParam { - bytes from = 1; - bytes address = 2; - bytes data = 3; -} - -message CallCodeParam { - bytes from = 1; - bytes code = 2; - bytes data = 3; -} - -message TransactParam { - // The input account to sign with - InputAccount inputAccount = 1; - // The address of the contract to call, or omitted if creating a new contract - bytes address = 2; - // EVM bytecode payload to deliver - bytes data = 3; - // The maximum gas to provide to the EVM when running any code - provided in order to bound the computation time - uint64 gasLimit = 4; - // Value to transfer, where amount = value + fee - uint64 value = 5; - // Fee to offer validators for processing transaction - uint64 fee = 6; -} - -message SendParam { - InputAccount inputAccount = 1; - bytes toAddress = 2; - uint64 amount = 3; -} - -message TxParam { - bytes tx = 1; -} - -message SignTxParam { - bytes tx = 1; - repeated PrivateAccount privateAccounts = 2; -} - -// Results -message SignedTx { - bytes tx = 1; -} - -message CallResult { - bytes Return = 1; - uint64 GasUsed = 2; -} - -message TxReceipt { - bytes TxHash = 1; - bool CreatesContract = 2; - bytes ContractAddress = 3; -} - -message InputAccount { - bytes privateKey = 1; - bytes address = 2; -} - -message PrivateAccount { - bytes PrivateKey = 1; -} -//-------------------------------------------------- \ No newline at end of file diff --git a/execution/simulated_call.go b/execution/simulated_call.go new file mode 100644 index 0000000000000000000000000000000000000000..fc7156a41678477afcbfcdbda062376b648e7b71 --- /dev/null +++ b/execution/simulated_call.go @@ -0,0 +1,75 @@ +package execution + +import ( + "fmt" + "runtime/debug" + + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" + "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/blockchain" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/execution/evm" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/execution/executors" + "github.com/hyperledger/burrow/logging" +) + +// Run a contract's code on an isolated and unpersisted state +// Cannot be used to create new contracts +func CallSim(reader state.Reader, tip blockchain.TipInfo, fromAddress, address crypto.Address, data []byte, + logger *logging.Logger) (*exec.TxExecution, error) { + + if evm.IsRegisteredNativeContract(address.Word256()) { + return nil, fmt.Errorf("attempt to call native contract at address "+ + "%X, but native contracts can not be called directly. Use a deployed "+ + "contract that calls the native function instead", address) + } + // This was being run against CheckTx cache, need to understand the reasoning + callee, err := state.GetMutableAccount(reader, address) + if err != nil { + return nil, err + } + if callee == nil { + return nil, fmt.Errorf("account %s does not exist", address) + } + return CallCodeSim(reader, tip, fromAddress, address, callee.Code(), data, logger) +} + +// Run the given code on an isolated and unpersisted state +// Cannot be used to create new contracts. +func CallCodeSim(reader state.Reader, tip blockchain.TipInfo, fromAddress, address crypto.Address, code, data []byte, + logger *logging.Logger) (_ *exec.TxExecution, err error) { + // This was being run against CheckTx cache, need to understand the reasoning + caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount() + callee := acm.ConcreteAccount{Address: address}.MutableAccount() + + txCache := state.NewCache(reader) + + params := vmParams(tip) + vmach := evm.NewVM(params, caller.Address(), nil, logger.WithScope("CallCode")) + + txe := &exec.TxExecution{} + vmach.SetEventSink(txe) + gas := params.GasLimit + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic from VM in simulated call: %v\n%s", r, debug.Stack()) + } + }() + ret, err := vmach.Call(txCache, caller, callee, code, data, 0, &gas) + if err != nil { + return nil, err + } + txe.Return(ret, params.GasLimit-gas) + return txe, nil +} + +func vmParams(tip blockchain.TipInfo) evm.Params { + return evm.Params{ + BlockHeight: tip.LastBlockHeight(), + BlockHash: binary.LeftPadWord256(tip.LastBlockHash()), + BlockTime: tip.LastBlockTime().Unix(), + GasLimit: executors.GasLimit, + } +} diff --git a/execution/state.go b/execution/state.go index 8418c836fdadca65c923fd81b71010451c573e86..12460d7837b8e62c74da7a8b7314b3b99dc3db7b 100644 --- a/execution/state.go +++ b/execution/state.go @@ -15,22 +15,19 @@ package execution import ( - "context" "fmt" "sync" "time" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/events" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/execution/names" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/permission" - ptypes "github.com/hyperledger/burrow/permission/types" "github.com/tendermint/iavl" dbm "github.com/tendermint/tmlibs/db" ) @@ -49,13 +46,15 @@ const ( accountsPrefix = "a/" storagePrefix = "s/" nameRegPrefix = "n/" - eventPrefix = "e/" + blockPrefix = "b/" + txPrefix = "t/" ) var ( accountsStart, accountsEnd []byte = prefixKeyRange(accountsPrefix) storageStart, storageEnd []byte = prefixKeyRange(storagePrefix) nameRegStart, nameRegEnd []byte = prefixKeyRange(nameRegPrefix) + lastBlockHeightKey = []byte("h") ) // Implements account and blockchain state @@ -66,7 +65,7 @@ var _ Updatable = &writeState{} type Updatable interface { state.Writer names.Writer - event.Publisher + AddBlock(blockExecution *exec.BlockExecution) error } // Wraps state to give access to writer methods @@ -86,8 +85,6 @@ type State struct { // Values may be reassigned (mutex protected) // Previous version of IAVL tree for concurrent read-only access readTree *iavl.Tree - // High water mark for height/index - make sure we do not overwrite events - should only increase - eventKeyHighWatermark events.Key // Last state hash hash []byte } @@ -139,7 +136,7 @@ func MakeGenesisState(db dbm.DB, genesisDoc *genesis.GenesisDoc) (*State, error) globalPerms = genesisDoc.GlobalPermissions // XXX: make sure the set bits are all true // Without it the HasPermission() functions will fail - globalPerms.Base.SetBit = ptypes.AllPermFlags + globalPerms.Base.SetBit = permission.AllPermFlags permsAcc := &acm.ConcreteAccount{ Address: acm.GlobalPermissionsAddress, @@ -195,7 +192,10 @@ func LoadState(db dbm.DB, hash []byte) (*State, error) { func (s *State) Update(updater func(up Updatable) error) ([]byte, error) { s.Lock() defer s.Unlock() - updater(s.writeState) + err := updater(s.writeState) + if err != nil { + return nil, err + } return s.writeState.save() } @@ -244,12 +244,12 @@ func (s *State) GetAccount(address crypto.Address) (acm.Account, error) { func (ws *writeState) UpdateAccount(account acm.Account) error { if account == nil { - return fmt.Errorf("UpdateAccount passed nil account in execution.State") + return fmt.Errorf("UpdateAccount passed nil account in State") } // TODO: find a way to implement something equivalent to this so we can set the account StorageRoot //storageRoot := s.tree.SubTreeHash(prefixedKey(storagePrefix, account.Address().Bytes())) // Alternatively just abandon and - accountWithStorageRoot := acm.AsMutableAccount(account).SetStorageRoot(nil) + accountWithStorageRoot := acm.AsMutableAccount(account) encodedAccount, err := accountWithStorageRoot.Encode() if err != nil { return err @@ -313,40 +313,68 @@ func (s *State) IterateStorage(address crypto.Address, // Events // Execution events -func (ws *writeState) Publish(ctx context.Context, msg interface{}, tags event.Tags) error { - if exeEvent, ok := msg.(*events.Event); ok { - key := exeEvent.Header.Key() - if !key.IsSuccessorOf(ws.state.eventKeyHighWatermark) { - return fmt.Errorf("received event with non-increasing key compared with current high watermark %v: %v", - ws.state.eventKeyHighWatermark, exeEvent) - } - ws.state.eventKeyHighWatermark = key - if exeEvent.Tx != nil { - // Don't serialise the tx (for now) we should normalise and store against tx hash - exeEvent = exeEvent.Copy() - // The header still contains the tx hash - exeEvent.Tx.Tx = nil - } - bs, err := exeEvent.Encode() - if err != nil { - return err - } - ws.state.tree.Set(eventKey(key), bs) +func (ws *writeState) AddBlock(be *exec.BlockExecution) error { + lastBlockHeight, ok := ws.lastBlockHeight() + if ok && be.Height != lastBlockHeight+1 { + return fmt.Errorf("AddBlock received block for height %v but last block height was %v", + be.Height, lastBlockHeight) + } + ws.setLastBlockHeight(be.Height) + // Index transactions so they can be retrieved by their TxHash + for i, txe := range be.TxExecutions { + ws.addTx(txe.TxHash, be.Height, uint64(i)) + } + bs, err := be.Encode() + if err != nil { + return err } + key := blockKey(be.Height) + ws.state.tree.Set(key, bs) return nil } -func (s *State) GetEvents(startKey, endKey events.Key, consumer func(ev *events.Event) (stop bool)) (stopped bool, err error) { - return s.tree.IterateRange(eventKey(startKey), eventKey(endKey), true, +func (ws *writeState) addTx(txHash []byte, height, index uint64) { + ws.state.tree.Set(txKey(txHash), encodeTxRef(height, index)) +} + +func (s *State) GetTx(txHash []byte) (*exec.TxExecution, error) { + _, bs := s.readTree.Get(txKey(txHash)) + if len(bs) == 0 { + return nil, nil + } + height, index, err := decodeTxRef(bs) + if err != nil { + return nil, fmt.Errorf("error decoding database reference to tx %X: %v", txHash, err) + } + be, err := s.GetBlock(height) + if err != nil { + return nil, fmt.Errorf("error getting block %v containing tx %X", height, txHash) + } + if index < uint64(len(be.TxExecutions)) { + return be.TxExecutions[index], nil + } + return nil, fmt.Errorf("retrieved index %v in block %v for tx %X but block only contains %v TxExecutions", + index, height, txHash, len(be.TxExecutions)) +} + +func (s *State) GetBlock(height uint64) (*exec.BlockExecution, error) { + _, bs := s.readTree.Get(blockKey(height)) + if len(bs) == 0 { + return nil, nil + } + return exec.DecodeBlockExecution(bs) +} + +func (s *State) GetBlocks(startHeight, endHeight uint64, consumer func(*exec.BlockExecution) (stop bool)) (stopped bool, err error) { + return s.readTree.IterateRange(blockKey(startHeight), blockKey(endHeight), true, func(_, value []byte) bool { - var exeEvent *events.Event - exeEvent, err = events.DecodeEvent(value) + block, err := exec.DecodeBlockExecution(value) if err != nil { err = fmt.Errorf("error unmarshalling ExecutionEvent in GetEvents: %v", err) // stop iteration on error return true } - return consumer(exeEvent) + return consumer(block) }), err } @@ -356,10 +384,18 @@ func (s *State) Hash() []byte { return s.hash } -func (s *State) LatestEventKey() events.Key { - s.RLock() - defer s.RUnlock() - return s.eventKeyHighWatermark +func (s *writeState) lastBlockHeight() (uint64, bool) { + _, bs := s.state.tree.Get(lastBlockHeightKey) + if len(bs) == 0 { + return 0, false + } + return binary.GetUint64BE(bs), true +} + +func (s *writeState) setLastBlockHeight(height uint64) { + bs := make([]byte, 8) + binary.PutUint64BE(bs, height) + s.state.tree.Set(lastBlockHeightKey, bs) } // Events @@ -368,7 +404,7 @@ func (s *State) LatestEventKey() events.Key { var _ names.IterableReader = &State{} -func (s *State) GetNameEntry(name string) (*names.Entry, error) { +func (s *State) GetName(name string) (*names.Entry, error) { _, entryBytes := s.readTree.Get(prefixedKey(nameRegPrefix, []byte(name))) if entryBytes == nil { return nil, nil @@ -377,7 +413,7 @@ func (s *State) GetNameEntry(name string) (*names.Entry, error) { return names.DecodeEntry(entryBytes) } -func (s *State) IterateNameEntries(consumer func(*names.Entry) (stop bool)) (stopped bool, err error) { +func (s *State) IterateNames(consumer func(*names.Entry) (stop bool)) (stopped bool, err error) { return s.readTree.IterateRange(nameRegStart, nameRegEnd, true, func(key []byte, value []byte) (stop bool) { var entry *names.Entry entry, err = names.DecodeEntry(value) @@ -388,7 +424,7 @@ func (s *State) IterateNameEntries(consumer func(*names.Entry) (stop bool)) (sto }), err } -func (ws *writeState) UpdateNameEntry(entry *names.Entry) error { +func (ws *writeState) UpdateName(entry *names.Entry) error { bs, err := entry.Encode() if err != nil { return err @@ -397,7 +433,7 @@ func (ws *writeState) UpdateNameEntry(entry *names.Entry) error { return nil } -func (ws *writeState) RemoveNameEntry(name string) error { +func (ws *writeState) RemoveName(name string) error { ws.state.tree.Remove(prefixedKey(nameRegPrefix, []byte(name))) return nil } @@ -416,8 +452,32 @@ func (s *State) Copy(db dbm.DB) (*State, error) { return stateCopy, nil } -func eventKey(key events.Key) []byte { - return prefixedKey(eventPrefix, key) +// Key and value helpers + +func encodeTxRef(height, index uint64) []byte { + bs := make([]byte, 16) + binary.PutUint64BE(bs[:8], height) + binary.PutUint64BE(bs[8:], index) + return bs +} + +func decodeTxRef(bs []byte) (height, index uint64, _ error) { + if len(bs) != 16 { + return 0, 0, fmt.Errorf("tx reference must have 16 bytes but '%X' does not", bs) + } + height = binary.GetUint64BE(bs[:8]) + index = binary.GetUint64BE(bs[8:]) + return +} + +func txKey(txHash []byte) []byte { + return prefixedKey(txPrefix, txHash) +} + +func blockKey(height uint64) []byte { + bs := make([]byte, 8) + binary.PutUint64BE(bs, height) + return prefixedKey(blockPrefix, bs) } func prefixedKey(prefix string, suffices ...[]byte) []byte { diff --git a/execution/state_test.go b/execution/state_test.go index 360910ba9021aa0c719b75d8b6b150833667cc23..7a821c340c16fa4a63c2830344c491ce008bde8f 100644 --- a/execution/state_test.go +++ b/execution/state_test.go @@ -15,21 +15,16 @@ package execution import ( - "context" "encoding/json" "fmt" "testing" - "github.com/golang/protobuf/proto" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/execution/events/pbevents" "github.com/hyperledger/burrow/execution/evm/sha3" - permission "github.com/hyperledger/burrow/permission/types" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/permission" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tmlibs/db" @@ -50,63 +45,58 @@ func TestState_UpdateAccount(t *testing.T) { assert.Equal(t, account, accountOut) } -func TestState_Publish(t *testing.T) { +func TestWriteState_AddBlock(t *testing.T) { s := NewState(db.NewMemDB()) - ctx := context.Background() - evs := []*events.Event{ - mkEvent(100, 0), - mkEvent(100, 1), - } + height := uint64(100) + txs := uint64(5) + events := uint64(10) _, err := s.Update(func(ws Updatable) error { - for _, ev := range evs { - require.NoError(t, ws.Publish(ctx, ev, nil)) - } - return nil + return ws.AddBlock(mkBlock(height, txs, events)) }) require.NoError(t, err) - i := 0 - _, err = s.GetEvents(events.NewKey(100, 0), events.NewKey(100, 0), - func(ev *events.Event) (stop bool) { - assert.Equal(t, evs[i], ev) - i++ + _, err = s.GetBlocks(height, height+1, + func(be *exec.BlockExecution) (stop bool) { + for ti := uint64(0); ti < txs; ti++ { + for e := uint64(0); e < events; e++ { + assert.Equal(t, mkEvent(height, ti, e).Header.TxHash.String(), + be.TxExecutions[ti].Events[e].Header.TxHash.String()) + } + } return false }) require.NoError(t, err) // non-increasing events _, err = s.Update(func(ws Updatable) error { - require.Error(t, ws.Publish(ctx, mkEvent(100, 0), nil)) - require.Error(t, ws.Publish(ctx, mkEvent(100, 1), nil)) - require.Error(t, ws.Publish(ctx, mkEvent(99, 1324234), nil)) - require.NoError(t, ws.Publish(ctx, mkEvent(100, 2), nil)) - require.NoError(t, ws.Publish(ctx, mkEvent(101, 0), nil)) return nil }) require.NoError(t, err) } -func TestProtobufEventSerialisation(t *testing.T) { - ev := mkEvent(112, 23) - pbEvent := pbevents.GetExecutionEvent(ev) - bs, err := proto.Marshal(pbEvent) - require.NoError(t, err) - pbEventOut := new(pbevents.ExecutionEvent) - require.NoError(t, proto.Unmarshal(bs, pbEventOut)) - fmt.Println(pbEventOut) - assert.Equal(t, asJSON(t, pbEvent), asJSON(t, pbEventOut)) +func mkBlock(height, txs, events uint64) *exec.BlockExecution { + be := &exec.BlockExecution{ + Height: height, + } + for ti := uint64(0); ti < txs; ti++ { + txe := &exec.TxExecution{ + Height: height, + } + for e := uint64(0); e < events; e++ { + txe.Events = append(txe.Events, mkEvent(height, ti, e)) + } + be.TxExecutions = append(be.TxExecutions, txe) + } + return be } -func mkEvent(height, index uint64) *events.Event { - return &events.Event{ - Header: &events.Header{ +func mkEvent(height, tx, index uint64) *exec.Event { + return &exec.Event{ + Header: &exec.Header{ Height: height, Index: index, - TxHash: sha3.Sha3([]byte(fmt.Sprintf("txhash%v%v", height, index))), - EventID: fmt.Sprintf("eventID: %v%v", height, index), - }, - Tx: &events.EventDataTx{ - Tx: txs.Enclose("foo", &payload.CallTx{}).Tx, + TxHash: sha3.Sha3([]byte(fmt.Sprintf("txhash%v%v%v", height, tx, index))), + EventID: fmt.Sprintf("eventID: %v%v%v", height, tx, index), }, - Log: &events.EventDataLog{ + Log: &exec.LogEvent{ Address: crypto.Address{byte(height), byte(index)}, Topics: []binary.Word256{{1, 2, 3}}, }, diff --git a/execution/transactor.go b/execution/transactor.go index c4d57bba192210072240583ad4700526727236d6..3a5cbd2743f598dc1421c153df1373dc9c177354 100644 --- a/execution/transactor.go +++ b/execution/transactor.go @@ -15,414 +15,232 @@ package execution import ( - "bytes" "context" - "encoding/json" "fmt" - "runtime/debug" "time" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" - "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/consensus/tendermint/codes" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/errors" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/execution/evm" - "github.com/hyperledger/burrow/execution/executors" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" abciTypes "github.com/tendermint/abci/types" tmTypes "github.com/tendermint/tendermint/types" ) -const BlockingTimeoutSeconds = 30 - -type Call struct { - Return binary.HexBytes - GasUsed uint64 -} +const ( + BlockingTimeout = 10 * time.Second + SubscribeBufferSize = 10 +) -// Transactor is the controller/middleware for the v0 RPC +// Transactor is responsible for helping to formulate, sign, and broadcast transactions to tendermint +// +// The BroadcastTx* methods are able to work against the mempool Accounts (pending) state rather than the +// committed (final) Accounts state and can assign a sequence number based on all of the txs +// seen since the last block - provided these transactions are successfully committed (via DeliverTx) then +// subsequent transactions will have valid sequence numbers. This allows Burrow to coordinate sequencing and signing +// for a key it holds or is provided - it is down to the key-holder to manage the mutual information between transactions +// concurrent within a new block window. type Transactor struct { - tip *blockchain.Tip - eventEmitter event.Emitter - broadcastTxAsync func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error - txEncoder txs.Encoder - logger *logging.Logger + Tip blockchain.TipInfo + Subscribable event.Subscribable + MempoolAccounts *Accounts + checkTxAsync func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error + txEncoder txs.Encoder + logger *logging.Logger } -func NewTransactor(tip *blockchain.Tip, eventEmitter event.Emitter, - broadcastTxAsync func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error, txEncoder txs.Encoder, +func NewTransactor(tip blockchain.TipInfo, subscribable event.Subscribable, mempoolAccounts *Accounts, + checkTxAsync func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error, txEncoder txs.Encoder, logger *logging.Logger) *Transactor { return &Transactor{ - tip: tip, - eventEmitter: eventEmitter, - broadcastTxAsync: broadcastTxAsync, - txEncoder: txEncoder, - logger: logger.With(structure.ComponentKey, "Transactor"), - } -} - -// Run a contract's code on an isolated and unpersisted state -// Cannot be used to create new contracts -func (trans *Transactor) Call(reader state.Reader, fromAddress, address crypto.Address, - data []byte) (call *Call, err error) { - - if evm.IsRegisteredNativeContract(address.Word256()) { - return nil, fmt.Errorf("attempt to call native contract at address "+ - "%X, but native contracts can not be called directly. Use a deployed "+ - "contract that calls the native function instead", address) - } - // This was being run against CheckTx cache, need to understand the reasoning - callee, err := state.GetMutableAccount(reader, address) - if err != nil { - return nil, err - } - if callee == nil { - return nil, fmt.Errorf("account %s does not exist", address) - } - caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount() - txCache := state.NewCache(reader) - params := vmParams(trans.tip) - - vmach := evm.NewVM(params, caller.Address(), nil, trans.logger.WithScope("Call")) - vmach.SetPublisher(trans.eventEmitter) - - gas := params.GasLimit - defer func() { - if r := recover(); r != nil { - err = fmt.Errorf("panic from VM in simulated call: %v\n%s", r, debug.Stack()) - } - }() - ret, err := vmach.Call(txCache, caller, callee, callee.Code(), data, 0, &gas) - if err != nil { - return nil, err - } - gasUsed := params.GasLimit - gas - return &Call{Return: ret, GasUsed: gasUsed}, nil -} - -// Run the given code on an isolated and unpersisted state -// Cannot be used to create new contracts. -func (trans *Transactor) CallCode(reader state.Reader, fromAddress crypto.Address, code, data []byte) (*Call, error) { - // This was being run against CheckTx cache, need to understand the reasoning - callee := acm.ConcreteAccount{Address: fromAddress}.MutableAccount() - caller := acm.ConcreteAccount{Address: fromAddress}.MutableAccount() - txCache := state.NewCache(reader) - params := vmParams(trans.tip) - - vmach := evm.NewVM(params, caller.Address(), nil, trans.logger.WithScope("CallCode")) - gas := params.GasLimit - ret, err := vmach.Call(txCache, caller, callee, code, data, 0, &gas) - if err != nil { - return nil, err - } - gasUsed := params.GasLimit - gas - return &Call{Return: ret, GasUsed: gasUsed}, nil -} - -func (trans *Transactor) BroadcastTxAsyncRaw(txBytes []byte, callback func(res *abciTypes.Response)) error { - return trans.broadcastTxAsync(txBytes, callback) -} - -func (trans *Transactor) BroadcastTxAsync(txEnv *txs.Envelope, callback func(res *abciTypes.Response)) error { - err := txEnv.Validate() - if err != nil { - return err - } - txBytes, err := trans.txEncoder.EncodeTx(txEnv) - if err != nil { - return fmt.Errorf("error encoding transaction: %v", err) - } - return trans.BroadcastTxAsyncRaw(txBytes, callback) -} - -// Broadcast a transaction and waits for a response from the mempool. Transactions to BroadcastTx will block during -// various mempool operations (managed by Tendermint) including mempool Reap, Commit, and recheckTx. -func (trans *Transactor) BroadcastTx(txEnv *txs.Envelope) (*txs.Receipt, error) { - trans.logger.Trace.Log("method", "BroadcastTx", - "tx_hash", txEnv.Tx.Hash(), - "tx", txEnv.String()) - err := txEnv.Validate() - if err != nil { - return nil, err - } - txBytes, err := trans.txEncoder.EncodeTx(txEnv) - if err != nil { - return nil, err - } - return trans.BroadcastTxRaw(txBytes) -} - -func (trans *Transactor) BroadcastTxRaw(txBytes []byte) (*txs.Receipt, error) { - responseCh := make(chan *abciTypes.Response, 1) - err := trans.BroadcastTxAsyncRaw(txBytes, func(res *abciTypes.Response) { - responseCh <- res - }) - - if err != nil { - return nil, err - } - response := <-responseCh - checkTxResponse := response.GetCheckTx() - if checkTxResponse == nil { - return nil, fmt.Errorf("application did not return CheckTx response") - } - - switch checkTxResponse.Code { - case codes.TxExecutionSuccessCode: - receipt := new(txs.Receipt) - err := json.Unmarshal(checkTxResponse.Data, receipt) + Tip: tip, + Subscribable: subscribable, + MempoolAccounts: mempoolAccounts, + checkTxAsync: checkTxAsync, + txEncoder: txEncoder, + logger: logger.With(structure.ComponentKey, "Transactor"), + } +} + +func (trans *Transactor) BroadcastTxSync(ctx context.Context, txEnv *txs.Envelope) (*exec.TxExecution, error) { + // Subscribe to TX + // Sign if needed - must do before we sign in order to get correct TxHash + if len(txEnv.Signatories) == 0 { + var err error + var unlock UnlockFunc + txEnv, unlock, err = trans.SignTxMempool(txEnv) if err != nil { - return nil, fmt.Errorf("could not deserialise transaction receipt: %s", err) + return nil, fmt.Errorf("error signing trnasction: %v", err) } - return receipt, nil - default: - return nil, fmt.Errorf("error returned by Tendermint in BroadcastTxSync "+ - "ABCI code: %v, ABCI log: %v", checkTxResponse.Code, checkTxResponse.Log) - } -} - -// Orders calls to BroadcastTx using lock (waits for response from core before releasing) -func (trans *Transactor) Transact(sequentialSigningAccount *SequentialSigningAccount, address *crypto.Address, data []byte, - gasLimit, value, fee uint64) (*txs.Receipt, error) { - - // Use the get the freshest sequence numbers from mempool state and hold the lock until we get a response from - // CheckTx - inputAccount, unlock, err := sequentialSigningAccount.Lock() - if err != nil { - return nil, err - } - defer unlock() - if binary.IsUint64SumOverflow(value, fee) { - return nil, fmt.Errorf("amount to transfer overflows uint64 amount = %v (value) + %v (fee)", value, fee) - } - txEnv, err := trans.formulateCallTx(inputAccount, address, data, gasLimit, value+fee, fee) - if err != nil { - return nil, err - } - return trans.BroadcastTx(txEnv) -} - -func (trans *Transactor) TransactAndHold(ctx context.Context, sequentialSigningAccount *SequentialSigningAccount, - address *crypto.Address, data []byte, gasLimit, value, fee uint64) (*events.EventDataCall, error) { - - inputAccount, unlock, err := sequentialSigningAccount.Lock() - if err != nil { - return nil, err - } - defer unlock() - if binary.IsUint64SumOverflow(value, fee) { - return nil, fmt.Errorf("amount to transfer overflows uint64 amount = %v (value) + %v (fee)", value, fee) - } - callTxEnv, err := trans.formulateCallTx(inputAccount, address, data, gasLimit, value+fee, fee) - if err != nil { - return nil, err + defer unlock() } - expectedReceipt := callTxEnv.Tx.GenerateReceipt() - - subID, err := event.GenerateSubscriptionID() + txHash := txEnv.Tx.Hash() + subID := event.GenSubID() + out, err := trans.Subscribable.Subscribe(ctx, subID, exec.QueryForTxExecution(txHash), SubscribeBufferSize) if err != nil { return nil, err } + defer trans.Subscribable.UnsubscribeAll(context.Background(), subID) - // We want non-blocking on the first event received (but buffer the value), - // after which we want to block (and then discard the value - see below) - ch := make(chan *events.EventDataCall, 1) - - err = events.SubscribeAccountCall(context.Background(), trans.eventEmitter, subID, expectedReceipt.ContractAddress, - expectedReceipt.TxHash, 0, ch) + checkTxReceipt, err := trans.CheckTxSync(txEnv) if err != nil { return nil, err } - // Will clean up callback goroutine and subscription in pubsub - defer trans.eventEmitter.UnsubscribeAll(context.Background(), subID) - - receipt, err := trans.BroadcastTx(callTxEnv) - if err != nil { - return nil, err - } - if !bytes.Equal(receipt.TxHash, expectedReceipt.TxHash) { - return nil, fmt.Errorf("BroadcastTx received TxHash %X but %X was expected", - receipt.TxHash, expectedReceipt.TxHash) - } - - timer := time.NewTimer(BlockingTimeoutSeconds * time.Second) + // Wait for all responses + timer := time.NewTimer(BlockingTimeout) defer timer.Stop() + // Get all the execution events for this Tx select { case <-ctx.Done(): return nil, ctx.Err() case <-timer.C: - return nil, fmt.Errorf("transaction timed out TxHash: %X", expectedReceipt.TxHash) - case eventDataCall := <-ch: - if eventDataCall.Exception != nil && eventDataCall.Exception.ErrorCode() != errors.ErrorCodeExecutionReverted { - return nil, fmt.Errorf("error when transacting: %v", eventDataCall.Exception) - } else { - return eventDataCall, nil - } + return nil, fmt.Errorf("timed out waiting for transaction with hash %v timed out after %v", + checkTxReceipt.TxHash, BlockingTimeout) + case msg := <-out: + return msg.(*exec.TxExecution), nil } } -func (trans *Transactor) formulateCallTx(inputAccount *SigningAccount, address *crypto.Address, data []byte, - gasLimit, amount, fee uint64) (*txs.Envelope, error) { - - txInput := &payload.TxInput{ - Address: inputAccount.Address(), - Amount: amount, - Sequence: inputAccount.Sequence() + 1, - } - tx := &payload.CallTx{ - Input: txInput, - Address: address, - GasLimit: gasLimit, - Fee: fee, - Data: data, - } - env := txs.Enclose(trans.tip.ChainID(), tx) - // Got ourselves a tx. - err := env.Sign(inputAccount) - if err != nil { - return nil, err +// Broadcast a transaction without waiting for confirmation - will attempt to sign server-side and set sequence numbers +// if no signatures are provided +func (trans *Transactor) BroadcastTxAsync(txEnv *txs.Envelope) (*txs.Receipt, error) { + // Attempt to sign unless signatures provided + if len(txEnv.Signatories) == 0 { + var err error + var unlock UnlockFunc + txEnv, unlock, err = trans.SignTxMempool(txEnv) + if err != nil { + return nil, err + } + defer unlock() } - return env, nil + return trans.CheckTxSync(txEnv) } -func (trans *Transactor) Send(sequentialSigningAccount *SequentialSigningAccount, toAddress crypto.Address, - amount uint64) (*txs.Receipt, error) { - - inputAccount, unlock, err := sequentialSigningAccount.Lock() - if err != nil { - return nil, err +func (trans *Transactor) SignTxMempool(txEnv *txs.Envelope) (*txs.Envelope, UnlockFunc, error) { + inputs := txEnv.Tx.GetInputs() + signers := make([]acm.AddressableSigner, len(inputs)) + unlockers := make([]UnlockFunc, len(inputs)) + for i, input := range inputs { + ssa, err := trans.MempoolAccounts.SequentialSigningAccount(input.Address) + if err != nil { + return nil, nil, err + } + sa, unlock, err := ssa.Lock() + if err != nil { + return nil, nil, err + } + // Hold lock until safely in mempool - important that this is held until after CheckTxSync returns + unlockers[i] = unlock + signers[i] = sa + // Set sequence number consecutively from mempool + input.Sequence = sa.Sequence() + 1 } - defer unlock() - sendTxEnv, err := trans.formulateSendTx(inputAccount, toAddress, amount) + err := txEnv.Sign(signers...) if err != nil { - return nil, err + return nil, nil, err } - - return trans.BroadcastTx(sendTxEnv) + return txEnv, UnlockFunc(func() { + for _, unlock := range unlockers { + defer unlock() + } + }), nil } -func (trans *Transactor) SendAndHold(ctx context.Context, sequentialSigningAccount *SequentialSigningAccount, - toAddress crypto.Address, amount uint64) (*txs.Receipt, error) { - - inputAccount, unlock, err := sequentialSigningAccount.Lock() - if err != nil { - return nil, err +func (trans *Transactor) SignTx(txEnv *txs.Envelope) (*txs.Envelope, error) { + var err error + inputs := txEnv.Tx.GetInputs() + signers := make([]acm.AddressableSigner, len(inputs)) + for i, input := range inputs { + signers[i], err = trans.MempoolAccounts.SigningAccount(input.Address) } - defer unlock() - - sendTxEnv, err := trans.formulateSendTx(inputAccount, toAddress, amount) + err = txEnv.Sign(signers...) if err != nil { return nil, err } - expectedReceipt := sendTxEnv.Tx.GenerateReceipt() + return txEnv, nil +} - subID, err := event.GenerateSubscriptionID() +// Broadcast a transaction and waits for a response from the mempool. Transactions to BroadcastTx will block during +// various mempool operations (managed by Tendermint) including mempool Reap, Commit, and recheckTx. +func (trans *Transactor) CheckTxSync(txEnv *txs.Envelope) (*txs.Receipt, error) { + trans.logger.Trace.Log("method", "CheckTxSync", + "tx_hash", txEnv.Tx.Hash(), + "tx", txEnv.String()) + err := txEnv.Validate() if err != nil { return nil, err } - - wc := make(chan *payload.SendTx) - err = events.SubscribeAccountOutputSendTx(context.Background(), trans.eventEmitter, subID, toAddress, - expectedReceipt.TxHash, wc) + txBytes, err := trans.txEncoder.EncodeTx(txEnv) if err != nil { return nil, err } - defer trans.eventEmitter.UnsubscribeAll(context.Background(), subID) + return trans.CheckTxSyncRaw(txBytes) +} - receipt, err := trans.BroadcastTx(sendTxEnv) +func (trans *Transactor) CheckTxSyncRaw(txBytes []byte) (*txs.Receipt, error) { + responseCh := make(chan *abciTypes.Response, 1) + err := trans.CheckTxAsyncRaw(txBytes, func(res *abciTypes.Response) { + responseCh <- res + }) if err != nil { return nil, err } - if !bytes.Equal(receipt.TxHash, expectedReceipt.TxHash) { - return nil, fmt.Errorf("BroadcastTx received TxHash %X but %X was expected", - receipt.TxHash, expectedReceipt.TxHash) - } - - timer := time.NewTimer(BlockingTimeoutSeconds * time.Second) + timer := time.NewTimer(BlockingTimeout) defer timer.Stop() select { - case <-ctx.Done(): - return nil, ctx.Err() case <-timer.C: - return nil, fmt.Errorf("transaction timed out TxHash: %X", expectedReceipt.TxHash) - case sendTx := <-wc: - // This is a double check - we subscribed to this tx's hash so something has gone wrong if the amounts don't match - if sendTx.Inputs[0].Amount == amount { - return expectedReceipt, nil + return nil, fmt.Errorf("timed out waiting for CheckTx response in CheckTxSyncRaw") + case response := <-responseCh: + checkTxResponse := response.GetCheckTx() + if checkTxResponse == nil { + return nil, fmt.Errorf("application did not return CheckTx response") } - return nil, fmt.Errorf("received SendTx but hash doesn't seem to match what we subscribed to, "+ - "received SendTx: %v which does not match receipt on sending: %v", sendTx, expectedReceipt) - } -} - -func (trans *Transactor) formulateSendTx(inputAccount *SigningAccount, toAddress crypto.Address, - amount uint64) (*txs.Envelope, error) { - sendTx := payload.NewSendTx() - txInput := &payload.TxInput{ - Address: inputAccount.Address(), - Amount: amount, - Sequence: inputAccount.Sequence() + 1, - } - sendTx.Inputs = append(sendTx.Inputs, txInput) - txOutput := &payload.TxOutput{Address: toAddress, Amount: amount} - sendTx.Outputs = append(sendTx.Outputs, txOutput) - - env := txs.Enclose(trans.tip.ChainID(), sendTx) - err := env.Sign(inputAccount) - if err != nil { - return nil, err + switch checkTxResponse.Code { + case codes.TxExecutionSuccessCode: + receipt, err := txs.DecodeReceipt(checkTxResponse.Data) + if err != nil { + return nil, fmt.Errorf("could not deserialise transaction receipt: %s", err) + } + return receipt, nil + default: + return nil, fmt.Errorf("error returned by Tendermint in BroadcastTxSync "+ + "ABCI code: %v, ABCI log: %v", checkTxResponse.Code, checkTxResponse.Log) + } } - - return env, nil } -func (trans *Transactor) TransactNameReg(sequentialSigningAccount *SequentialSigningAccount, name, data string, amount, - fee uint64) (*txs.Receipt, error) { +func (trans *Transactor) CheckTxAsyncRaw(txBytes []byte, callback func(res *abciTypes.Response)) error { + return trans.checkTxAsync(txBytes, callback) +} - inputAccount, unlock, err := sequentialSigningAccount.Lock() +func (trans *Transactor) CheckTxAsync(txEnv *txs.Envelope, callback func(res *abciTypes.Response)) error { + err := txEnv.Validate() if err != nil { - return nil, err + return err } - defer unlock() - // Formulate and sign - tx := payload.NewNameTxWithSequence(inputAccount.PublicKey(), name, data, amount, fee, inputAccount.Sequence()+1) - env := txs.Enclose(trans.tip.ChainID(), tx) - err = env.Sign(inputAccount) + txBytes, err := trans.txEncoder.EncodeTx(txEnv) if err != nil { - return nil, err + return fmt.Errorf("error encoding transaction: %v", err) } - return trans.BroadcastTx(env) + return trans.CheckTxAsyncRaw(txBytes, callback) } -// Sign a transaction -func (trans *Transactor) SignTx(txEnv *txs.Envelope, signingAccounts []acm.AddressableSigner) (*txs.Envelope, error) { - // more checks? - err := txEnv.Sign(signingAccounts...) - if err != nil { - return nil, err - } - return txEnv, nil +func (trans *Transactor) CallCodeSim(fromAddress crypto.Address, code, data []byte) (*exec.TxExecution, error) { + return CallCodeSim(trans.MempoolAccounts, trans.Tip, fromAddress, fromAddress, code, data, trans.logger) } -func vmParams(tip *blockchain.Tip) evm.Params { - return evm.Params{ - BlockHeight: tip.LastBlockHeight(), - BlockHash: binary.LeftPadWord256(tip.LastBlockHash()), - BlockTime: tip.LastBlockTime().Unix(), - GasLimit: executors.GasLimit, - } +func (trans *Transactor) CallSim(fromAddress, address crypto.Address, data []byte) (*exec.TxExecution, error) { + return CallSim(trans.MempoolAccounts, trans.Tip, fromAddress, address, data, trans.logger) } diff --git a/execution/transactor_test.go b/execution/transactor_test.go new file mode 100644 index 0000000000000000000000000000000000000000..f8c6389544d60ff422c52f4293b1a890a0e6a26d --- /dev/null +++ b/execution/transactor_test.go @@ -0,0 +1,77 @@ +// Copyright 2017 Monax Industries Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package execution + +import ( + "context" + "testing" + "time" + + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" + "github.com/hyperledger/burrow/blockchain" + "github.com/hyperledger/burrow/consensus/tendermint/codes" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/keys/mock" + "github.com/hyperledger/burrow/logging" + "github.com/hyperledger/burrow/txs" + "github.com/hyperledger/burrow/txs/payload" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + abciTypes "github.com/tendermint/abci/types" + tmTypes "github.com/tendermint/tendermint/types" +) + +func TestTransactor_BroadcastTxSync(t *testing.T) { + chainID := "TestChain" + tip := blockchain.NewTip(chainID, time.Time{}, []byte("genesis")) + logger := logging.NewNoopLogger() + evc := event.NewEmitter(logger) + txCodec := txs.NewAminoCodec() + privAccount := acm.GeneratePrivateAccountFromSecret("frogs") + tx := &payload.CallTx{ + Input: &payload.TxInput{ + Address: privAccount.Address(), + }, + Address: &crypto.Address{1, 2, 3}, + } + txEnv := txs.Enclose(chainID, tx) + err := txEnv.Sign(privAccount) + require.NoError(t, err) + height := uint64(35) + trans := NewTransactor(tip, evc, NewAccounts(state.NewMemoryState(), mock.NewKeyClient(privAccount), 100), + func(tx tmTypes.Tx, cb func(*abciTypes.Response)) error { + txe := exec.NewTxExecution(txEnv) + txe.Height = height + err := evc.Publish(context.Background(), txe, txe.Tagged()) + if err != nil { + return err + } + bs, err := txe.Receipt.Encode() + if err != nil { + return err + } + cb(abciTypes.ToResponseCheckTx(abciTypes.ResponseCheckTx{ + Code: codes.TxExecutionSuccessCode, + Data: bs, + })) + return nil + }, txCodec, logger) + txe, err := trans.BroadcastTxSync(context.Background(), txEnv) + require.NoError(t, err) + assert.Equal(t, height, txe.Height) +} diff --git a/genesis/deterministic_genesis.go b/genesis/deterministic_genesis.go index ca023f2617dad40d527ec32e078b7718618f6531..6c4e6a2090209fbe60a503ab5dbc0425d3b0fe18 100644 --- a/genesis/deterministic_genesis.go +++ b/genesis/deterministic_genesis.go @@ -5,7 +5,7 @@ import ( "math/rand" "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/permission" ) diff --git a/genesis/genesis.go b/genesis/genesis.go index d60564415ea851eb85cbcc7d4e0154121a848d5c..6d91fd472710b9be879090eb63f55e74cf886c17 100644 --- a/genesis/genesis.go +++ b/genesis/genesis.go @@ -21,10 +21,9 @@ import ( "sort" "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/permission" - ptypes "github.com/hyperledger/burrow/permission/types" ) // How many bytes to take from the front of the GenesisDoc hash to append @@ -45,7 +44,7 @@ type BasicAccount struct { type Account struct { BasicAccount Name string - Permissions ptypes.AccountPermissions + Permissions permission.AccountPermissions } type Validator struct { @@ -62,7 +61,7 @@ type GenesisDoc struct { GenesisTime time.Time ChainName string Salt []byte `json:",omitempty" toml:",omitempty"` - GlobalPermissions ptypes.AccountPermissions + GlobalPermissions permission.AccountPermissions Accounts []Account Validators []Validator } diff --git a/genesis/genesis_test.go b/genesis/genesis_test.go index 0c5021bb0a0b07f3ad6d10a96e003d807cbbf305..640bf18d975c07102436609a01159c79c11ec18a 100644 --- a/genesis/genesis_test.go +++ b/genesis/genesis_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/permission" "github.com/stretchr/testify/assert" ) diff --git a/genesis/spec/genesis_spec.go b/genesis/spec/genesis_spec.go index 3f3aba5f387e92a26a00221ea3f9412cf9c8d42c..cb4fb76cfb3a9d8f4e1f4c30ad4b1ac29bcc4347 100644 --- a/genesis/spec/genesis_spec.go +++ b/genesis/spec/genesis_spec.go @@ -10,7 +10,6 @@ import ( "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/permission" - ptypes "github.com/hyperledger/burrow/permission/types" ) const DefaultAmount uint64 = 1000000 @@ -62,7 +61,7 @@ func (gs *GenesisSpec) GenesisDoc(keyClient keys.KeyClient, generateNodeKeys boo if err != nil { return nil, err } - genesisDoc.GlobalPermissions = ptypes.AccountPermissions{ + genesisDoc.GlobalPermissions = permission.AccountPermissions{ Base: basePerms, } } diff --git a/genesis/spec/genesis_spec_test.go b/genesis/spec/genesis_spec_test.go index 0a9aeb7af802c71f93f3fa755c9740ddd5d6a01a..98665055d9ef3c1d0b4e6ed4f13bb386c2cce92b 100644 --- a/genesis/spec/genesis_spec_test.go +++ b/genesis/spec/genesis_spec_test.go @@ -5,7 +5,7 @@ import ( "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys/mock" - permission "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/genesis/spec/presets.go b/genesis/spec/presets.go index 30e6c08a186cb14fb5c02e9797194568737051b0..3025d98c0f4b9e9a3f995f8aea33c91f9e77f82f 100644 --- a/genesis/spec/presets.go +++ b/genesis/spec/presets.go @@ -3,7 +3,7 @@ package spec import ( "sort" - permission "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" ) // Files here can be used as starting points for building various 'chain types' but are otherwise diff --git a/genesis/spec/presets_test.go b/genesis/spec/presets_test.go index df77f9bdba93339754ef237cf503f292e1cf13c9..762e397bd3154b6368e4ae01fe5f7532632d81d5 100644 --- a/genesis/spec/presets_test.go +++ b/genesis/spec/presets_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/hyperledger/burrow/keys/mock" - permission "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/permission" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/genesis/spec/spec.pb.go b/genesis/spec/spec.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..9d568bfd4db830e6f7a3ab147d301289699a3b46 --- /dev/null +++ b/genesis/spec/spec.pb.go @@ -0,0 +1,662 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: spec.proto + +/* + Package spec is a generated protocol buffer package. + + It is generated from these files: + spec.proto + + It has these top-level messages: + TemplateAccount +*/ +package spec + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import crypto "github.com/hyperledger/burrow/crypto" + +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type TemplateAccount struct { + Name string `protobuf:"bytes,1,opt,name=Name" json:"Name"` + Address *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,customtype=github.com/hyperledger/burrow/crypto.Address" json:",omitempty" toml:",omitempty"` + NodeAddress *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,3,opt,name=NodeAddress,customtype=github.com/hyperledger/burrow/crypto.Address" json:",omitempty" toml:",omitempty"` + PublicKey *crypto.PublicKey `protobuf:"bytes,4,opt,name=PublicKey" json:",omitempty" toml:",omitempty"` + Amount *uint64 `protobuf:"varint,5,opt,name=Amount" json:",omitempty" toml:",omitempty"` + Power *uint64 `protobuf:"varint,6,opt,name=Power" json:",omitempty" toml:",omitempty"` + Permissions []string `protobuf:"bytes,7,rep,name=Permissions" json:",omitempty" toml:",omitempty"` + Roles []string `protobuf:"bytes,8,rep,name=Roles" json:",omitempty" toml:",omitempty"` +} + +func (m *TemplateAccount) Reset() { *m = TemplateAccount{} } +func (m *TemplateAccount) String() string { return proto.CompactTextString(m) } +func (*TemplateAccount) ProtoMessage() {} +func (*TemplateAccount) Descriptor() ([]byte, []int) { return fileDescriptorSpec, []int{0} } + +func (m *TemplateAccount) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *TemplateAccount) GetPublicKey() *crypto.PublicKey { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *TemplateAccount) GetAmount() uint64 { + if m != nil && m.Amount != nil { + return *m.Amount + } + return 0 +} + +func (m *TemplateAccount) GetPower() uint64 { + if m != nil && m.Power != nil { + return *m.Power + } + return 0 +} + +func (m *TemplateAccount) GetPermissions() []string { + if m != nil { + return m.Permissions + } + return nil +} + +func (m *TemplateAccount) GetRoles() []string { + if m != nil { + return m.Roles + } + return nil +} + +func (*TemplateAccount) XXX_MessageName() string { + return "spec.TemplateAccount" +} +func init() { + proto.RegisterType((*TemplateAccount)(nil), "spec.TemplateAccount") + golang_proto.RegisterType((*TemplateAccount)(nil), "spec.TemplateAccount") +} +func (m *TemplateAccount) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TemplateAccount) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintSpec(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + if m.Address != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintSpec(dAtA, i, uint64(m.Address.Size())) + n1, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if m.NodeAddress != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintSpec(dAtA, i, uint64(m.NodeAddress.Size())) + n2, err := m.NodeAddress.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.PublicKey != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintSpec(dAtA, i, uint64(m.PublicKey.Size())) + n3, err := m.PublicKey.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.Amount != nil { + dAtA[i] = 0x28 + i++ + i = encodeVarintSpec(dAtA, i, uint64(*m.Amount)) + } + if m.Power != nil { + dAtA[i] = 0x30 + i++ + i = encodeVarintSpec(dAtA, i, uint64(*m.Power)) + } + if len(m.Permissions) > 0 { + for _, s := range m.Permissions { + dAtA[i] = 0x3a + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + dAtA[i] = 0x42 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + return i, nil +} + +func encodeVarintSpec(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *TemplateAccount) Size() (n int) { + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovSpec(uint64(l)) + if m.Address != nil { + l = m.Address.Size() + n += 1 + l + sovSpec(uint64(l)) + } + if m.NodeAddress != nil { + l = m.NodeAddress.Size() + n += 1 + l + sovSpec(uint64(l)) + } + if m.PublicKey != nil { + l = m.PublicKey.Size() + n += 1 + l + sovSpec(uint64(l)) + } + if m.Amount != nil { + n += 1 + sovSpec(uint64(*m.Amount)) + } + if m.Power != nil { + n += 1 + sovSpec(uint64(*m.Power)) + } + if len(m.Permissions) > 0 { + for _, s := range m.Permissions { + l = len(s) + n += 1 + l + sovSpec(uint64(l)) + } + } + if len(m.Roles) > 0 { + for _, s := range m.Roles { + l = len(s) + n += 1 + l + sovSpec(uint64(l)) + } + } + return n +} + +func sovSpec(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozSpec(x uint64) (n int) { + return sovSpec(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *TemplateAccount) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TemplateAccount: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TemplateAccount: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpec + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_hyperledger_burrow_crypto.Address + m.Address = &v + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeAddress", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthSpec + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_hyperledger_burrow_crypto.Address + m.NodeAddress = &v + if err := m.NodeAddress.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSpec + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PublicKey == nil { + m.PublicKey = &crypto.PublicKey{} + } + if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Amount = &v + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType) + } + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Power = &v + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpec + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Permissions = append(m.Permissions, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSpec + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSpec + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSpec(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthSpec + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSpec(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthSpec + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSpec + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipSpec(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthSpec = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSpec = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("spec.proto", fileDescriptorSpec) } +func init() { golang_proto.RegisterFile("spec.proto", fileDescriptorSpec) } + +var fileDescriptorSpec = []byte{ + // 359 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x92, 0x3f, 0x6f, 0xe2, 0x30, + 0x18, 0x87, 0xf1, 0x11, 0xe0, 0x30, 0x48, 0x27, 0x3c, 0x59, 0x0c, 0x49, 0xc4, 0x2d, 0xd1, 0x89, + 0x23, 0xd2, 0x6d, 0x47, 0x97, 0x12, 0xa9, 0x53, 0x25, 0x84, 0x28, 0x53, 0x37, 0x92, 0xbc, 0x0d, + 0x91, 0x62, 0x1c, 0xd9, 0x8e, 0x50, 0x3e, 0x4e, 0xbf, 0x49, 0x47, 0x46, 0xe6, 0x0e, 0x51, 0x05, + 0x43, 0xa5, 0x8e, 0xfd, 0x04, 0x55, 0x42, 0x28, 0x4c, 0x55, 0x96, 0x6e, 0xef, 0x1f, 0x3d, 0xbf, + 0xc7, 0xb2, 0x8d, 0xb1, 0x8c, 0xc1, 0x1b, 0xc5, 0x82, 0x2b, 0x4e, 0xb4, 0xbc, 0xee, 0xff, 0x0d, + 0x42, 0xb5, 0x4a, 0xdc, 0x91, 0xc7, 0x99, 0x1d, 0xf0, 0x80, 0xdb, 0xc5, 0xd2, 0x4d, 0x1e, 0x8a, + 0xae, 0x68, 0x8a, 0xea, 0x08, 0xf5, 0xbb, 0x9e, 0x48, 0x63, 0x55, 0x76, 0x83, 0x57, 0x0d, 0xff, + 0x5a, 0x00, 0x8b, 0xa3, 0xa5, 0x82, 0x89, 0xe7, 0xf1, 0x64, 0xad, 0x08, 0xc5, 0xda, 0x74, 0xc9, + 0x80, 0x22, 0x13, 0x59, 0x6d, 0x47, 0xdb, 0x66, 0x46, 0x6d, 0x5e, 0x4c, 0x08, 0xc3, 0xad, 0x89, + 0xef, 0x0b, 0x90, 0x92, 0xfe, 0x30, 0x91, 0xd5, 0x75, 0xee, 0x9e, 0x33, 0x63, 0x78, 0xe1, 0x5f, + 0xa5, 0x31, 0x88, 0x08, 0xfc, 0x00, 0x84, 0xed, 0x26, 0x42, 0xf0, 0x8d, 0x5d, 0xea, 0x4a, 0xee, + 0x2d, 0x33, 0xf0, 0x90, 0xb3, 0x50, 0x01, 0x8b, 0x55, 0xfa, 0x9e, 0x19, 0x3d, 0xc5, 0x59, 0x34, + 0x1e, 0x9c, 0x67, 0x83, 0xf9, 0xc9, 0x41, 0x12, 0xdc, 0x99, 0x72, 0x1f, 0x4e, 0xca, 0xfa, 0xf7, + 0x29, 0x2f, 0x3d, 0x64, 0x81, 0xdb, 0xb3, 0xc4, 0x8d, 0x42, 0xef, 0x16, 0x52, 0xaa, 0x99, 0xc8, + 0xea, 0xfc, 0xeb, 0x8d, 0xca, 0xcc, 0xcf, 0x85, 0xf3, 0xbb, 0x4a, 0xee, 0x39, 0x88, 0x5c, 0xe1, + 0xe6, 0x84, 0xe5, 0xf7, 0x4b, 0x1b, 0x26, 0xb2, 0xb4, 0x6a, 0x7c, 0x89, 0x90, 0xff, 0xb8, 0x31, + 0xe3, 0x1b, 0x10, 0xb4, 0x59, 0x9d, 0x3d, 0x12, 0xe4, 0x06, 0x77, 0x66, 0x20, 0x58, 0x28, 0x65, + 0xc8, 0xd7, 0x92, 0xb6, 0xcc, 0xba, 0xd5, 0xae, 0x16, 0x70, 0xc9, 0xe5, 0x27, 0x98, 0xf3, 0x08, + 0x24, 0xfd, 0x59, 0x3d, 0xe0, 0x48, 0x8c, 0xb5, 0xdd, 0xa3, 0x51, 0x73, 0xae, 0xb7, 0x7b, 0x1d, + 0xed, 0xf6, 0x3a, 0x7a, 0xd9, 0xeb, 0xe8, 0xe9, 0xa0, 0xa3, 0xed, 0x41, 0x47, 0xf7, 0x7f, 0xbe, + 0x7e, 0xc9, 0x00, 0xd6, 0x20, 0x43, 0x69, 0xe7, 0x1f, 0xfd, 0x23, 0x00, 0x00, 0xff, 0xff, 0x4b, + 0xcc, 0xe3, 0x66, 0xfb, 0x02, 0x00, 0x00, +} diff --git a/genesis/spec/template_account.go b/genesis/spec/template_account.go index 9d3c2acc4d60bbcc4465ef250b94335260bac715..1362ec117623dcd038f82460883ccecfb378bf15 100644 --- a/genesis/spec/template_account.go +++ b/genesis/spec/template_account.go @@ -7,22 +7,8 @@ import ( "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/permission" - ptypes "github.com/hyperledger/burrow/permission/types" ) -type TemplateAccount struct { - // Template accounts sharing a name will be merged when merging genesis specs - Name string `json:",omitempty" toml:",omitempty"` - // Address is convenient to have in file for reference, but otherwise ignored since derived from PublicKey - Address *crypto.Address `json:",omitempty" toml:",omitempty"` - NodeAddress *crypto.Address `json:",omitempty" toml:",omitempty"` - PublicKey *crypto.PublicKey `json:",omitempty" toml:",omitempty"` - Amount *uint64 `json:",omitempty" toml:",omitempty"` - Power *uint64 `json:",omitempty" toml:",omitempty"` - Permissions []string `json:",omitempty" toml:",omitempty"` - Roles []string `json:",omitempty" toml:",omitempty"` -} - func (ta TemplateAccount) Validator(keyClient keys.KeyClient, index int, generateNodeKeys bool) (*genesis.Validator, error) { var err error gv := new(genesis.Validator) @@ -58,12 +44,12 @@ func (ta TemplateAccount) Validator(keyClient keys.KeyClient, index int, generat return gv, nil } -func (ta TemplateAccount) AccountPermissions() (ptypes.AccountPermissions, error) { +func (ta TemplateAccount) AccountPermissions() (permission.AccountPermissions, error) { basePerms, err := permission.BasePermissionsFromStringList(ta.Permissions) if err != nil { return permission.ZeroAccountPermissions, nil } - return ptypes.AccountPermissions{ + return permission.AccountPermissions{ Base: basePerms, Roles: ta.Roles, }, nil diff --git a/core/kernel_test.go b/integration/core/kernel_test.go similarity index 61% rename from core/kernel_test.go rename to integration/core/kernel_test.go index be0c5106875518518a4c53cf95c4f04d465c7f35..d4003e2127c916b97fd2bc9bf5feae91e6f7b928 100644 --- a/core/kernel_test.go +++ b/integration/core/kernel_test.go @@ -1,3 +1,5 @@ +// +build integration + package core import ( @@ -7,12 +9,15 @@ import ( "testing" "time" - "github.com/hyperledger/burrow/consensus/tendermint" + "github.com/hyperledger/burrow/config" "github.com/hyperledger/burrow/consensus/tendermint/validator" + "github.com/hyperledger/burrow/core" + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/execution/exec" "github.com/hyperledger/burrow/genesis" + "github.com/hyperledger/burrow/integration" "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/rpc" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" tmConfig "github.com/tendermint/tendermint/config" @@ -30,7 +35,7 @@ func TestBootThenShutdown(t *testing.T) { logger := logging.NewNoopLogger() genesisDoc, _, privateValidators := genesis.NewDeterministicGenesis(123).GenesisDoc(1, true, 1000, 1, true, 1000) privValidator := validator.NewPrivValidatorMemory(privateValidators[0], privateValidators[0]) - assert.NoError(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, nil)) + assert.NoError(t, bootWaitBlocksShutdown(privValidator, integration.NewTestConfig(genesisDoc), tmConf, logger, nil)) } func TestBootShutdownResume(t *testing.T) { @@ -43,31 +48,36 @@ func TestBootShutdownResume(t *testing.T) { genesisDoc, _, privateValidators := genesis.NewDeterministicGenesis(123).GenesisDoc(1, true, 1000, 1, true, 1000) privValidator := validator.NewPrivValidatorMemory(privateValidators[0], privateValidators[0]) - i := int64(0) + i := uint64(0) // asserts we get a consecutive run of blocks - blockChecker := func(block *tmTypes.EventDataNewBlock) bool { - assert.Equal(t, i+1, block.Block.Height) + blockChecker := func(block *exec.BlockExecution) bool { + assert.Equal(t, i+1, block.Height) i++ // stop every third block return i%3 != 0 } + testConfig := integration.NewTestConfig(genesisDoc) // First run - require.NoError(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, blockChecker)) + require.NoError(t, bootWaitBlocksShutdown(privValidator, testConfig, tmConf, logger, blockChecker)) // Resume and check we pick up where we left off - require.NoError(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, blockChecker)) + require.NoError(t, bootWaitBlocksShutdown(privValidator, testConfig, tmConf, logger, blockChecker)) // Resuming with mismatched genesis should fail genesisDoc.Salt = []byte("foo") - assert.Error(t, bootWaitBlocksShutdown(privValidator, genesisDoc, tmConf, logger, blockChecker)) + assert.Error(t, bootWaitBlocksShutdown(privValidator, testConfig, tmConf, logger, blockChecker)) } -func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, genesisDoc *genesis.GenesisDoc, +func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, testConfig *config.BurrowConfig, tmConf *tmConfig.Config, logger *logging.Logger, - blockChecker func(block *tmTypes.EventDataNewBlock) (cont bool)) error { + blockChecker func(block *exec.BlockExecution) (cont bool)) error { keyStore := keys.NewKeyStore(keys.DefaultKeysDir, false, logger) keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger()) - kern, err := NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, - rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), keyStore, nil, logger) + kern, err := core.NewKernel(context.Background(), keyClient, privValidator, + testConfig.GenesisDoc, + testConfig.Tendermint.TendermintConfig(), + testConfig.RPC, + testConfig.Keys, + keyStore, nil, logger) if err != nil { return err } @@ -77,10 +87,12 @@ func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, genesisDoc *gen return err } - ch, err := tendermint.SubscribeNewBlock(context.Background(), kern.Emitter) + subID := event.GenSubID() + ch, err := kern.Emitter.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 10) if err != nil { return err } + defer kern.Emitter.UnsubscribeAll(context.Background(), subID) cont := true for cont { select { @@ -88,11 +100,11 @@ func bootWaitBlocksShutdown(privValidator tmTypes.PrivValidator, genesisDoc *gen if err != nil { return fmt.Errorf("timed out waiting for block") } - case ednb := <-ch: + case msg := <-ch: if blockChecker == nil { cont = false } else { - cont = blockChecker(ednb) + cont = blockChecker(msg.(*exec.BlockExecution)) } } } diff --git a/rpc/tm/integration/main_test.go b/integration/core/main_test.go similarity index 75% rename from rpc/tm/integration/main_test.go rename to integration/core/main_test.go index 9833d45c9668313b8104da27c639286373b376d0..af90e852e37a5aed272ec671b8b192ba8e17d27f 100644 --- a/rpc/tm/integration/main_test.go +++ b/integration/core/main_test.go @@ -15,23 +15,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package integration +package core import ( "os" "testing" - "time" - "github.com/hyperledger/burrow/core" - "github.com/hyperledger/burrow/core/integration" + "github.com/hyperledger/burrow/integration" ) +var _ = integration.ClaimPorts() + // Needs to be in a _test.go file to be picked up func TestMain(m *testing.M) { - returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(*core.Kernel) int { - return m.Run() - }) - - time.Sleep(3 * time.Second) + returnValue := m.Run() os.Exit(returnValue) } diff --git a/core/integration/test_wrapper.go b/integration/integration.go similarity index 53% rename from core/integration/test_wrapper.go rename to integration/integration.go index 79b5db460b908c8c5f8f387a5194efa95578cecd..388cae7d617b7b366195479fc85357c404616894 100644 --- a/core/integration/test_wrapper.go +++ b/integration/integration.go @@ -1,6 +1,3 @@ -// +build integration - -// Space above here matters // Copyright 2017 Monax Industries Limited // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,24 +16,26 @@ package integration import ( "context" + "encoding/binary" "fmt" "os" + "runtime" "strconv" + "sync/atomic" "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/config" "github.com/hyperledger/burrow/consensus/tendermint/validator" "github.com/hyperledger/burrow/core" + "github.com/hyperledger/burrow/execution/evm/sha3" "github.com/hyperledger/burrow/genesis" - "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/keys/mock" "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/logging/config" + lConfig "github.com/hyperledger/burrow/logging/config" "github.com/hyperledger/burrow/logging/lifecycle" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/permission" - "github.com/hyperledger/burrow/rpc" - tm_config "github.com/tendermint/tendermint/config" ) const ( @@ -48,31 +47,42 @@ const ( //var debugLogging = true var debugLogging = false +// Starting point for assigning range of ports for tests +// Start at unprivileged port (hoping for the best) +const startingPort uint16 = 1024 + +// For each port claimant assign a bucket +const startingPortSeparation uint16 = 10 +const startingPortBuckets = 1000 + +// Mutable port to assign to next claimant +var port = uint32(startingPort) + // We use this to wrap tests -func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.GenesisDoc, runner func(*core.Kernel) int) int { - fmt.Println("Running with integration TestWrapper (core/integration/test_wrapper.go)...") +func TestWrapper(privateAccounts []*acm.PrivateAccount, testConfig *config.BurrowConfig, runner func(*core.Kernel) int) int { + fmt.Println("Running with integration TestWrapper (core/integration/integration.go)...") os.RemoveAll(testDir) os.MkdirAll(testDir, 0777) os.Chdir(testDir) - tmConf := tm_config.DefaultConfig() os.MkdirAll("config", 0777) + logger := logging.NewNoopLogger() if debugLogging { var err error // Change config as needed - logger, err = lifecycle.NewLoggerFromLoggingConfig(&config.LoggingConfig{ + logger, err = lifecycle.NewLoggerFromLoggingConfig(&lConfig.LoggingConfig{ ExcludeTrace: false, - RootSink: config.Sink(). - SetTransform(config.FilterTransform(config.IncludeWhenAnyMatches, + RootSink: lConfig.Sink(). + SetTransform(lConfig.FilterTransform(lConfig.IncludeWhenAnyMatches, structure.ComponentKey, "Tendermint", structure.ScopeKey, "executor.Execute\\(tx txs.Tx\\)", )). //AddSinks(config.Sink().SetTransform(config.FilterTransform(config.ExcludeWhenAnyMatches, "run_call", "false")). - AddSinks(config.Sink().SetTransform(config.PruneTransform("log_channel", "trace", "scope", "returns", "run_id", "args")). - AddSinks(config.Sink().SetTransform(config.SortTransform("tx_hash", "time", "message", "method")). - SetOutput(config.StdoutOutput()))), + AddSinks(lConfig.Sink().SetTransform(lConfig.PruneTransform("log_channel", "trace", "scope", "returns", "run_id", "args")). + AddSinks(lConfig.Sink().SetTransform(lConfig.SortTransform("tx_hash", "time", "message", "method")). + SetOutput(lConfig.StdoutOutput()))), }) if err != nil { panic(err) @@ -82,14 +92,18 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes validatorAccount := privateAccounts[0] privValidator := validator.NewPrivValidatorMemory(validatorAccount, validatorAccount) keyClient := mock.NewKeyClient(privateAccounts...) - kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), + kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, + testConfig.GenesisDoc, + testConfig.Tendermint.TendermintConfig(), + testConfig.RPC, + testConfig.Keys, nil, nil, logger) if err != nil { panic(err) } // Sometimes better to not shutdown as logging errors on shutdown may obscure real issue defer func() { - //kernel.Shutdown(context.Background()) + kernel.Shutdown(context.Background()) }() err = kernel.Boot() @@ -100,7 +114,7 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes return runner(kernel) } -func TestGenesisDoc(addressables []acm.PrivateAccount) *genesis.GenesisDoc { +func TestGenesisDoc(addressables []*acm.PrivateAccount) *genesis.GenesisDoc { accounts := make(map[string]acm.Account, len(addressables)) for i, pa := range addressables { account := acm.FromAddressable(pa) @@ -119,10 +133,48 @@ func TestGenesisDoc(addressables []acm.PrivateAccount) *genesis.GenesisDoc { } // Deterministic account generation helper. Pass number of accounts to make -func MakePrivateAccounts(n int) []acm.PrivateAccount { - accounts := make([]acm.PrivateAccount, n) +func MakePrivateAccounts(n int) []*acm.PrivateAccount { + accounts := make([]*acm.PrivateAccount, n) for i := 0; i < n; i++ { accounts[i] = acm.GeneratePrivateAccountFromSecret("mysecret" + strconv.Itoa(i)) } return accounts } + +// Some helpers for setting Burrow's various ports in non-colliding ranges for tests +func ClaimPorts() uint16 { + _, file, _, _ := runtime.Caller(1) + startIndex := uint16(binary.LittleEndian.Uint16(sha3.Sha3([]byte(file)))) % startingPortBuckets + newPort := startingPort + startIndex*startingPortSeparation + // In case overflow + if newPort < startingPort { + newPort += startingPort + } + if !atomic.CompareAndSwapUint32(&port, uint32(startingPort), uint32(newPort)) { + panic("GetPort() called before ClaimPorts() or ClaimPorts() called twice") + } + return uint16(atomic.LoadUint32(&port)) +} + +func GetPort() uint16 { + return uint16(atomic.AddUint32(&port, 1)) +} + +func GetLocalAddress() string { + return fmt.Sprintf("localhost:%v", GetPort()) +} + +func GetTCPLocalAddress() string { + return fmt.Sprintf("tcp://localhost:%v", GetPort()) +} + +func NewTestConfig(genesisDoc *genesis.GenesisDoc) *config.BurrowConfig { + cnf := config.DefaultBurrowConfig() + cnf.GenesisDoc = genesisDoc + cnf.Tendermint.ListenAddress = GetTCPLocalAddress() + cnf.RPC.GRPC.ListenAddress = GetLocalAddress() + cnf.RPC.Metrics.ListenAddress = GetTCPLocalAddress() + cnf.RPC.TM.ListenAddress = GetTCPLocalAddress() + cnf.Keys.RemoteAddress = "" + return cnf +} diff --git a/integration/rpcevents/execution_events_server_test.go b/integration/rpcevents/execution_events_server_test.go new file mode 100644 index 0000000000000000000000000000000000000000..19c96d3bbe4cbbfe4fb762789ef309e4c0ac93dd --- /dev/null +++ b/integration/rpcevents/execution_events_server_test.go @@ -0,0 +1,192 @@ +// +build integration + +// Space above here matters +// Copyright 2017 Monax Industries Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rpcevents + +import ( + "context" + "io" + "testing" + + "time" + + "strconv" + + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/event/query" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/integration/rpctest" + "github.com/hyperledger/burrow/rpc/rpcevents" + "github.com/hyperledger/burrow/rpc/rpctransact" + "github.com/hyperledger/burrow/txs/payload" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetBlocks(t *testing.T) { + request := &rpcevents.BlocksRequest{ + BlockRange: rpcevents.NewBlockRange(rpcevents.LatestBound(), rpcevents.StreamBound()), + } + tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress) + stream, err := ecli.GetBlocks(context.Background(), request) + require.NoError(t, err) + pulls := 3 + sendsPerPull := 4 + var blocks []*exec.BlockExecution + for i := 0; i < pulls; i++ { + doSends(t, sendsPerPull, tcli) + block, err := stream.Recv() + require.NoError(t, err) + blocks = append(blocks, block) + } + assert.True(t, len(blocks) > 0, "should see at least one block (height 2)") + var height uint64 + for _, b := range blocks { + if height > 0 { + assert.Equal(t, height+1, b.Height) + } + height = b.Height + } + require.NoError(t, stream.CloseSend()) +} +func TestGetBlocksContains2(t *testing.T) { + request := &rpcevents.BlocksRequest{ + BlockRange: rpcevents.NewBlockRange(rpcevents.LatestBound(), rpcevents.StreamBound()), + Query: "Height CONTAINS '2'", + } + tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress) + stream, err := ecli.GetBlocks(context.Background(), request) + require.NoError(t, err) + pulls := 2 + sendsPerPull := 4 + var blocks []*exec.BlockExecution + for i := 0; i < pulls; i++ { + doSends(t, sendsPerPull, tcli) + block, err := stream.Recv() + require.NoError(t, err) + blocks = append(blocks, block) + assert.Contains(t, strconv.FormatUint(block.Height, 10), "2") + } + assert.True(t, len(blocks) > 0, "should see at least one block (height 2)") + require.NoError(t, stream.CloseSend()) +} + +func TestGetEventsSend(t *testing.T) { + request := &rpcevents.BlocksRequest{ + BlockRange: rpcevents.NewBlockRange(rpcevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()), + rpcevents.LatestBound()), + } + numSends := 1100 + responses := testGetEventsSend(t, numSends, request) + assert.Equal(t, numSends*2, countEventsAndCheckConsecutive(t, responses), + "should receive 1 input, 1 output per send") +} + +func TestGetEventsSendContainsAA(t *testing.T) { + request := &rpcevents.BlocksRequest{ + BlockRange: rpcevents.NewBlockRange(rpcevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()), + rpcevents.LatestBound()), + Query: "TxHash CONTAINS 'AA'", + } + numSends := 1100 + responses := testGetEventsSend(t, numSends, request) + for _, response := range responses { + for _, ev := range response.Events { + require.Contains(t, ev.Header.TxHash.String(), "AA") + } + } +} + +func TestGetEventsSendFiltered(t *testing.T) { + request := &rpcevents.BlocksRequest{ + BlockRange: rpcevents.NewBlockRange(rpcevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()), + rpcevents.LatestBound()), + Query: query.NewBuilder().AndEquals(event.EventTypeKey, exec.TypeAccountInput.String()).String(), + } + numSends := 500 + responses := testGetEventsSend(t, numSends, request) + assert.Equal(t, numSends, countEventsAndCheckConsecutive(t, responses), "should receive a single input event per send") +} + +func testGetEventsSend(t *testing.T, numSends int, request *rpcevents.BlocksRequest) []*rpcevents.GetEventsResponse { + + doSends(t, numSends, rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress)) + ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress) + evs, err := ecli.GetEvents(context.Background(), request) + require.NoError(t, err) + var responses []*rpcevents.GetEventsResponse + for { + resp, err := evs.Recv() + if err != nil { + if err == io.EOF { + break + } + require.NoError(t, err) + } + responses = append(responses, resp) + } + return responses +} + +func doSends(t *testing.T, numSends int, cli rpctransact.TransactClient) { + countCh := rpctest.CommittedTxCount(t, kern.Emitter) + amt := uint64(2004) + for i := 0; i < numSends; i++ { + // Slow us down a bit to ensure spread across blocks + time.Sleep(time.Millisecond) + receipt, err := cli.SendTxAsync(context.Background(), + &payload.SendTx{ + Inputs: []*payload.TxInput{{ + Address: inputAddress, + Amount: amt, + }}, + Outputs: []*payload.TxOutput{{ + Address: rpctest.PrivateAccounts[4].Address(), + Amount: amt, + }}, + }) + require.NoError(t, err) + assert.False(t, receipt.CreatesContract) + } + require.Equal(t, numSends, <-countCh) +} + +func countEventsAndCheckConsecutive(t *testing.T, respones []*rpcevents.GetEventsResponse) int { + i := 0 + var height uint64 + var index uint64 + txHash := "" + for _, resp := range respones { + require.True(t, resp.Height > height, "must not receive multiple GetEventsResponses for the same block") + height := resp.Height + for _, ev := range resp.Events { + require.Equal(t, ev.Header.Height, height, "height of event headers much match height of GetEventsResponse") + if txHash != ev.Header.TxHash.String() { + txHash = ev.Header.TxHash.String() + index = 0 + } + if ev.Header.Index > index { + require.Equal(t, index+1, ev.Header.Index) + index++ + } + i++ + } + } + return i +} diff --git a/rpc/rpcevents/integration/main_test.go b/integration/rpcevents/main_test.go similarity index 62% rename from rpc/rpcevents/integration/main_test.go rename to integration/rpcevents/main_test.go index 338b533457def710c8e5d9e6895a8606d8d49c97..8418fbd740cffae49f2d109dbfadad1a6f739f15 100644 --- a/rpc/rpcevents/integration/main_test.go +++ b/integration/rpcevents/main_test.go @@ -15,30 +15,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -package integration +package rpcevents import ( "os" "testing" - "time" "github.com/hyperledger/burrow/core" - "github.com/hyperledger/burrow/core/integration" - "github.com/hyperledger/burrow/execution/pbtransactor" + "github.com/hyperledger/burrow/integration" + "github.com/hyperledger/burrow/integration/rpctest" ) -var privateAccounts = integration.MakePrivateAccounts(5) // make keys -var genesisDoc = integration.TestGenesisDoc(privateAccounts) -var inputAccount = &pbtransactor.InputAccount{Address: privateAccounts[0].Address().Bytes()} +var _ = integration.ClaimPorts() +var inputAddress = rpctest.PrivateAccounts[0].Address() +var testConfig = integration.NewTestConfig(rpctest.GenesisDoc) var kern *core.Kernel // Needs to be in a _test.go file to be picked up func TestMain(m *testing.M) { - returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int { - kern = k - return m.Run() - }) + returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig, + func(k *core.Kernel) int { + kern = k + return m.Run() + }) - time.Sleep(3 * time.Second) os.Exit(returnValue) } diff --git a/rpc/rpctransactor/integration/main_test.go b/integration/rpcquery/main_test.go similarity index 69% rename from rpc/rpctransactor/integration/main_test.go rename to integration/rpcquery/main_test.go index a83a08b5158c70bc5236c3a042e1e6ceab4eb827..423a22bd5b0791222a3733bdf84e54c44d8c9b62 100644 --- a/rpc/rpctransactor/integration/main_test.go +++ b/integration/rpcquery/main_test.go @@ -15,28 +15,28 @@ // See the License for the specific language governing permissions and // limitations under the License. -package integration +package rpcquery import ( "os" "testing" - "time" "github.com/hyperledger/burrow/core" - "github.com/hyperledger/burrow/core/integration" + "github.com/hyperledger/burrow/integration" + "github.com/hyperledger/burrow/integration/rpctest" ) -var privateAccounts = integration.MakePrivateAccounts(5) // make keys -var genesisDoc = integration.TestGenesisDoc(privateAccounts) +var _ = integration.ClaimPorts() +var testConfig = integration.NewTestConfig(rpctest.GenesisDoc) var kern *core.Kernel // Needs to be in a _test.go file to be picked up func TestMain(m *testing.M) { - returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int { - kern = k - return m.Run() - }) + returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig, + func(k *core.Kernel) int { + kern = k + return m.Run() + }) - time.Sleep(3 * time.Second) os.Exit(returnValue) } diff --git a/integration/rpcquery/query_server_test.go b/integration/rpcquery/query_server_test.go new file mode 100644 index 0000000000000000000000000000000000000000..05bb7e858e712a2868d6da4f24a89a3b3e4a620c --- /dev/null +++ b/integration/rpcquery/query_server_test.go @@ -0,0 +1,87 @@ +// +build integration + +package rpcquery + +import ( + "context" + "fmt" + "io" + "testing" + + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/event/query" + "github.com/hyperledger/burrow/execution/names" + "github.com/hyperledger/burrow/genesis" + "github.com/hyperledger/burrow/integration/rpctest" + "github.com/hyperledger/burrow/rpc/rpcquery" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGetAccount(t *testing.T) { + cli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress) + ca, err := cli.GetAccount(context.Background(), &rpcquery.GetAccountParam{ + Address: rpctest.PrivateAccounts[2].Address(), + }) + require.NoError(t, err) + genAcc := rpctest.GenesisDoc.Accounts[2] + genAccOut := genesis.GenesisAccountFromAccount(rpctest.GenesisDoc.Accounts[2].Name, ca.Account()) + // Normalise + genAcc.Permissions.Roles = nil + genAccOut.Permissions.Roles = nil + assert.Equal(t, genAcc, genAccOut) +} + +func TestListAccounts(t *testing.T) { + cli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress) + stream, err := cli.ListAccounts(context.Background(), &rpcquery.ListAccountsParam{}) + require.NoError(t, err) + var accs []acm.Account + acc, err := stream.Recv() + for err == nil { + accs = append(accs, acc.Account()) + acc, err = stream.Recv() + } + if err != nil && err != io.EOF { + t.Fatalf("unexpected error: %v", err) + } + assert.Len(t, accs, len(rpctest.GenesisDoc.Accounts)+1) +} + +func TestListNames(t *testing.T) { + tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + dataA, dataB := "NO TAMBOURINES", "ELEPHANTS WELCOME" + n := 8 + for i := 0; i < n; i++ { + name := fmt.Sprintf("Flub/%v", i) + if i%2 == 0 { + rpctest.UpdateName(t, tcli, rpctest.PrivateAccounts[0].Address(), name, dataA, 200) + } else { + rpctest.UpdateName(t, tcli, rpctest.PrivateAccounts[1].Address(), name, dataB, 200) + } + } + qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress) + entries := receiveNames(t, qcli, "") + assert.Len(t, entries, n) + entries = receiveNames(t, qcli, query.NewBuilder().AndEquals("Data", dataA).String()) + if assert.Len(t, entries, n/2) { + assert.Equal(t, dataA, entries[0].Data) + } +} + +func receiveNames(t testing.TB, qcli rpcquery.QueryClient, query string) []*names.Entry { + stream, err := qcli.ListNames(context.Background(), &rpcquery.ListNamesParam{ + Query: query, + }) + require.NoError(t, err) + var entries []*names.Entry + entry, err := stream.Recv() + for err == nil { + entries = append(entries, entry) + entry, err = stream.Recv() + } + if err != nil && err != io.EOF { + t.Fatalf("unexpected error: %v", err) + } + return entries +} diff --git a/integration/rpctest/helpers.go b/integration/rpctest/helpers.go new file mode 100644 index 0000000000000000000000000000000000000000..9fb660f0dabf03be6e181f4b0514c43964224f28 --- /dev/null +++ b/integration/rpctest/helpers.go @@ -0,0 +1,188 @@ +package rpctest + +import ( + "context" + "fmt" + "testing" + + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/execution/evm/abi" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/execution/names" + "github.com/hyperledger/burrow/integration" + "github.com/hyperledger/burrow/rpc" + "github.com/hyperledger/burrow/rpc/rpcevents" + "github.com/hyperledger/burrow/rpc/rpcquery" + "github.com/hyperledger/burrow/rpc/rpctransact" + "github.com/hyperledger/burrow/rpc/tm/tmclient" + "github.com/hyperledger/burrow/txs" + "github.com/hyperledger/burrow/txs/payload" + "github.com/stretchr/testify/require" + "google.golang.org/grpc" +) + +// Recursive call count for UpsieDownsie() function call from strange_loop.sol +// Equals initial call, then depth from 17 -> 34, one for the bounce, then depth from 34 -> 23, +// so... (I didn't say it had to make sense): +const UpsieDownsieCallCount = 1 + (34 - 17) + 1 + (34 - 23) + +var i = UpsieDownsieCallCount + +var PrivateAccounts = integration.MakePrivateAccounts(10) // make keys +var GenesisDoc = integration.TestGenesisDoc(PrivateAccounts) + +// Helpers +func NewTransactClient(t testing.TB, listenAddress string) rpctransact.TransactClient { + conn, err := grpc.Dial(listenAddress, grpc.WithInsecure()) + require.NoError(t, err) + return rpctransact.NewTransactClient(conn) +} + +func NewExecutionEventsClient(t testing.TB, listenAddress string) rpcevents.ExecutionEventsClient { + conn, err := grpc.Dial(listenAddress, grpc.WithInsecure()) + require.NoError(t, err) + return rpcevents.NewExecutionEventsClient(conn) +} + +func NewQueryClient(t testing.TB, listenAddress string) rpcquery.QueryClient { + conn, err := grpc.Dial(listenAddress, grpc.WithInsecure()) + require.NoError(t, err) + return rpcquery.NewQueryClient(conn) +} + +func CommittedTxCount(t *testing.T, em event.Emitter) chan int { + var numTxs int32 + emptyBlocks := 0 + maxEmptyBlocks := 2 + outCh := make(chan int) + subID := event.GenSubID() + ch, err := em.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 1) + require.NoError(t, err) + + go func() { + defer em.UnsubscribeAll(context.Background(), subID) + for msg := range ch { + be := msg.(*exec.BlockExecution) + if be.BlockHeader.NumTxs == 0 { + emptyBlocks++ + } else { + emptyBlocks = 0 + } + if emptyBlocks > maxEmptyBlocks { + break + } + numTxs += be.BlockHeader.NumTxs + fmt.Printf("Total TXs committed at block %v: %v (+%v)\n", be.Height, numTxs, be.BlockHeader.NumTxs) + } + outCh <- int(numTxs) + }() + return outCh +} + +func CreateContract(t testing.TB, cli rpctransact.TransactClient, inputAddress crypto.Address) *exec.TxExecution { + txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: 2, + }, + Address: nil, + Data: Bytecode_strange_loop, + Fee: 2, + GasLimit: 10000, + }) + require.NoError(t, err) + return txe +} + +func CallContract(t testing.TB, cli rpctransact.TransactClient, inputAddress, + contractAddress crypto.Address) *exec.TxExecution { + + functionID := abi.FunctionID("UpsieDownsie()") + txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: 2, + }, + Address: &contractAddress, + Data: functionID[:], + Fee: 2, + GasLimit: 10000, + }) + require.NoError(t, err) + return txe +} + +func UpdateName(t testing.TB, cli rpctransact.TransactClient, inputAddress crypto.Address, name, data string, + expiresIn uint64) *exec.TxExecution { + + txe, err := cli.NameTxSync(context.Background(), &payload.NameTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: names.NameCostForExpiryIn(name, data, expiresIn), + }, + Name: name, + Data: data, + }) + require.NoError(t, err) + return txe +} + +//------------------------------------------------------------------------------- +// some default transaction functions + +func MakeDefaultCallTx(t *testing.T, client tmclient.RPCClient, addr *crypto.Address, code []byte, amt, gasLim, + fee uint64) *txs.Envelope { + sequence := GetSequence(t, client, PrivateAccounts[0].Address()) + tx := payload.NewCallTxWithSequence(PrivateAccounts[0].PublicKey(), addr, code, amt, gasLim, fee, sequence+1) + txEnv := txs.Enclose(GenesisDoc.ChainID(), tx) + require.NoError(t, txEnv.Sign(PrivateAccounts[0])) + return txEnv +} + +//------------------------------------------------------------------------------- +// rpc call wrappers (fail on err) + +// get an account's sequence number +func GetSequence(t *testing.T, client tmclient.RPCClient, addr crypto.Address) uint64 { + acc, err := tmclient.GetAccount(client, addr) + if err != nil { + t.Fatal(err) + } + if acc == nil { + return 0 + } + return acc.Sequence() +} + +// get the account +func GetAccount(t *testing.T, client tmclient.RPCClient, addr crypto.Address) acm.Account { + ac, err := tmclient.GetAccount(client, addr) + if err != nil { + t.Fatal(err) + } + return ac +} + +// dump all storage for an account. currently unused +func DumpStorage(t *testing.T, client tmclient.RPCClient, addr crypto.Address) *rpc.ResultDumpStorage { + resp, err := tmclient.DumpStorage(client, addr) + if err != nil { + t.Fatal(err) + } + return resp +} + +func GetStorage(t *testing.T, client tmclient.RPCClient, addr crypto.Address, key []byte) []byte { + resp, err := tmclient.GetStorage(client, addr, key) + if err != nil { + t.Fatal(err) + } + return resp +} + +//-------------------------------------------------------------------------------- +// utility verification function + +// simple call contract calls another contract diff --git a/rpc/test/strange_loop.sol b/integration/rpctest/strange_loop.sol similarity index 100% rename from rpc/test/strange_loop.sol rename to integration/rpctest/strange_loop.sol diff --git a/rpc/test/strange_loop.sol.go b/integration/rpctest/strange_loop.sol.go similarity index 99% rename from rpc/test/strange_loop.sol.go rename to integration/rpctest/strange_loop.sol.go index 57a1f061fb43f6474291a716e6bda51d0c5f28c2..d01c57b636113bfcfb1aa5d6554dadb9ea4fbb95 100644 --- a/rpc/test/strange_loop.sol.go +++ b/integration/rpctest/strange_loop.sol.go @@ -1,4 +1,4 @@ -package test +package rpctest import "github.com/tmthrgd/go-hex" diff --git a/integration/rpctransact/call_test.go b/integration/rpctransact/call_test.go new file mode 100644 index 0000000000000000000000000000000000000000..fca4a232d37f858c09d265e7f75542a33b766666 --- /dev/null +++ b/integration/rpctransact/call_test.go @@ -0,0 +1,343 @@ +// +build integration + +package rpctransact + +import ( + "context" + "sync" + "testing" + + "strings" + + "fmt" + + "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/execution/evm/asm" + "github.com/hyperledger/burrow/execution/evm/asm/bc" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/integration/rpctest" + "github.com/hyperledger/burrow/rpc/rpctransact" + "github.com/hyperledger/burrow/txs/payload" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestCallTxNoCode(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + + // Flip flops between sending private key and input address to test private key and address based signing + toAddress := rpctest.PrivateAccounts[2].Address() + + numCreates := 1000 + countCh := rpctest.CommittedTxCount(t, kern.Emitter) + for i := 0; i < numCreates; i++ { + receipt, err := cli.CallTxAsync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: 2, + }, + Address: &toAddress, + Data: []byte{}, + Fee: 2, + GasLimit: 10000 + uint64(i), + }) + require.NoError(t, err) + assert.False(t, receipt.CreatesContract) + assert.Equal(t, toAddress, receipt.ContractAddress) + } + require.Equal(t, numCreates, <-countCh) +} + +func TestCreateContract(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + numGoroutines := 100 + numCreates := 50 + wg := new(sync.WaitGroup) + wg.Add(numGoroutines) + countCh := rpctest.CommittedTxCount(t, kern.Emitter) + for i := 0; i < numGoroutines; i++ { + go func() { + for j := 0; j < numCreates; j++ { + receipt, err := cli.CallTxAsync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: 2, + }, + Address: nil, + Data: rpctest.Bytecode_strange_loop, + Fee: 2, + GasLimit: 10000, + }) + if assert.NoError(t, err) { + assert.True(t, receipt.CreatesContract) + } + } + wg.Done() + }() + } + wg.Wait() + + require.Equal(t, numGoroutines*numCreates, <-countCh) +} + +func BenchmarkCreateContract(b *testing.B) { + cli := rpctest.NewTransactClient(b, testConfig.RPC.GRPC.ListenAddress) + for i := 0; i < b.N; i++ { + create, err := cli.CallTxAsync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: 2, + }, + Address: nil, + Data: rpctest.Bytecode_strange_loop, + Fee: 2, + GasLimit: 10000, + }) + require.NoError(b, err) + assert.True(b, create.CreatesContract) + } +} + +func TestCallTxSync(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + numGoroutines := 3 + numRuns := 2 + countCh := rpctest.CommittedTxCount(t, kern.Emitter) + for i := 0; i < numGoroutines; i++ { + for j := 0; j < numRuns; j++ { + createTxe := rpctest.CreateContract(t, cli, inputAddress) + callTxe := rpctest.CallContract(t, cli, inputAddress, lastCall(createTxe.Events).CallData.Callee) + depth := binary.Uint64FromWord256(binary.LeftPadWord256(lastCall(callTxe.Events).Return)) + // Would give 23 if taken from wrong frame (i.e. not the outer stackdepth == 0 one) + assert.Equal(t, 18, int(depth)) + } + } + require.Equal(t, numGoroutines*numRuns*2, <-countCh) +} + +func TestSendTxAsync(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + numSends := 1000 + countCh := rpctest.CommittedTxCount(t, kern.Emitter) + for i := 0; i < numSends; i++ { + receipt, err := cli.SendTxAsync(context.Background(), &payload.SendTx{ + Inputs: []*payload.TxInput{{ + Address: inputAddress, + Amount: 2003, + }}, + Outputs: []*payload.TxOutput{{ + Address: rpctest.PrivateAccounts[3].Address(), + Amount: 2003, + }}, + }) + require.NoError(t, err) + assert.False(t, receipt.CreatesContract) + } + require.Equal(t, numSends, <-countCh) +} + +func TestCallCode(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + // add two integers and return the result + var i, j byte = 123, 21 + _, contractCode, expectedReturn := simpleContract(i, j) + txe, err := cli.CallCodeSim(context.Background(), &rpctransact.CallCodeParam{ + FromAddress: inputAddress, + Code: contractCode, + }) + require.NoError(t, err) + assert.Equal(t, expectedReturn, txe.Result.Return) + + // pass two ints as calldata, add, and return the result + txe, err = cli.CallCodeSim(context.Background(), &rpctransact.CallCodeParam{ + FromAddress: inputAddress, + Code: bc.MustSplice(asm.PUSH1, 0x0, asm.CALLDATALOAD, asm.PUSH1, 0x20, asm.CALLDATALOAD, asm.ADD, asm.PUSH1, + 0x0, asm.MSTORE, asm.PUSH1, 0x20, asm.PUSH1, 0x0, asm.RETURN), + Data: bc.MustSplice(binary.LeftPadWord256([]byte{i}), binary.LeftPadWord256([]byte{j})), + }) + require.NoError(t, err) + assert.Equal(t, expectedReturn, txe.Result.Return) +} + +func TestCallContract(t *testing.T) { + initCode, _, expectedReturn := simpleContract(43, 1) + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: uint64(6969), + }, + Address: nil, + Data: initCode, + Fee: uint64(1000), + GasLimit: uint64(1000), + }) + require.NoError(t, err) + assert.Equal(t, true, txe.Receipt.CreatesContract, "This transaction should"+ + " create a contract") + assert.NotEqual(t, 0, len(txe.TxHash), "Receipt should contain a"+ + " transaction hash") + contractAddress := txe.Receipt.ContractAddress + assert.NotEqual(t, 0, len(contractAddress), "Transactions claims to have"+ + " created a contract but the contract address is empty") + + txe, err = cli.CallTxSync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: uint64(6969), + }, + Address: &contractAddress, + Fee: uint64(1000), + GasLimit: uint64(1000), + }) + require.NoError(t, err) + + assert.Equal(t, expectedReturn, txe.Result.Return) +} + +// create two contracts, one of which calls the other +func TestNestedCall(t *testing.T) { + code, _, expectedReturn := simpleContract(5, 6) + + // Deploy callee contract + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: uint64(6969), + }, + Data: code, + GasLimit: 10000, + }) + require.NoError(t, err) + assert.True(t, txe.Receipt.CreatesContract) + calleeContractAddress := txe.Receipt.ContractAddress + + // Deploy caller contract + code, _, _ = simpleCallContract(calleeContractAddress) + txe, err = cli.CallTxSync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: uint64(6969), + }, + Data: code, + GasLimit: 10000, + }) + require.NoError(t, err) + assert.True(t, txe.Receipt.CreatesContract) + callerContractAddress := txe.Receipt.ContractAddress + + // Call caller contract + txe, err = cli.CallTxSync(context.Background(), &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: uint64(6969), + }, + Address: &callerContractAddress, + GasLimit: 10000, + }) + require.NoError(t, err) + assert.Equal(t, expectedReturn, txe.Result.Return) +} + +func TestCallEvents(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + createTxe := rpctest.CreateContract(t, cli, inputAddress) + address := lastCall(createTxe.Events).CallData.Callee + callTxe := rpctest.CallContract(t, cli, inputAddress, address) + callEvents := filterCalls(callTxe.Events) + require.Len(t, callEvents, rpctest.UpsieDownsieCallCount, "should see 30 recursive call events") + for i, ev := range callEvents { + assert.Equal(t, uint64(rpctest.UpsieDownsieCallCount-i-1), ev.StackDepth) + } +} + +func TestLogEvents(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + createTxe := rpctest.CreateContract(t, cli, inputAddress) + address := lastCall(createTxe.Events).CallData.Callee + callTxe := rpctest.CallContract(t, cli, inputAddress, address) + evs := filterLogs(callTxe.Events) + require.Len(t, evs, rpctest.UpsieDownsieCallCount-2) + log := evs[0] + depth := binary.Int64FromWord256(log.Topics[2]) + direction := strings.TrimRight(string(log.Topics[1][:]), "\x00") + assert.Equal(t, int64(18), depth) + assert.Equal(t, "Upsie!", direction) +} + +func filterCalls(evs []*exec.Event) []*exec.CallEvent { + var callEvs []*exec.CallEvent + for _, ev := range evs { + if ev.Call != nil { + callEvs = append(callEvs, ev.Call) + } + } + return callEvs +} + +func filterLogs(evs []*exec.Event) []*exec.LogEvent { + var logEvs []*exec.LogEvent + for _, ev := range evs { + if ev.Log != nil { + logEvs = append(logEvs, ev.Log) + } + } + return logEvs +} + +func lastCall(evs []*exec.Event) *exec.CallEvent { + callEvs := filterCalls(evs) + return callEvs[len(callEvs)-1] +} + +func TestName(t *testing.T) { + initcode, contractcode, returncode := simpleContract(5, 6) + fmt.Println(asm.OpCode(0x7f).Name(), initcode, contractcode, returncode) + +} + +// simple contract returns 5 + 6 = 0xb +func simpleContract(i, j byte) ([]byte, []byte, []byte) { + // this is the code we want to run when the contract is called + contractCode := bc.MustSplice(asm.PUSH1, i, asm.PUSH1, j, asm.ADD, asm.PUSH1, 0x0, asm.MSTORE, asm.PUSH1, 0x20, asm.PUSH1, + 0x0, asm.RETURN) + // the is the code we need to return the contractCode when the contract is initialized + lenCode := len(contractCode) + // push code to the stack + initCode := bc.MustSplice(asm.PUSH32, binary.RightPadWord256(contractCode), + // store it in memory + asm.PUSH1, 0x0, asm.MSTORE, + // return whats in memory + asm.PUSH1, lenCode, asm.PUSH1, 0x0, asm.RETURN) + // return init code, contract code, expected return + return initCode, contractCode, binary.LeftPadBytes([]byte{i + j}, 32) +} + +func simpleCallContract(address crypto.Address) ([]byte, []byte, []byte) { + gas1, gas2 := byte(0x1), byte(0x1) + value := byte(0x1) + inOff, inSize := byte(0x0), byte(0x0) // no call data + retOff, retSize := byte(0x0), byte(0x20) + // this is the code we want to run (call a contract and return) + contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, + 0x60, value, 0x73} + contractCode = append(contractCode, address.Bytes()...) + contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, + 0x60, 0x0, 0xf3}...) + + // the is the code we need to return; the contractCode when the contract is initialized + // it should copy the code from the input into memory + lenCode := len(contractCode) + memOff := byte(0x0) + inOff = byte(0xc) // length of code before codeContract + length := byte(lenCode) + + code := []byte{0x60, length, 0x60, inOff, 0x60, memOff, 0x37} + // return whats in memory + code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) + code = append(code, contractCode...) + // return init code, contract code, expected return + return code, contractCode, binary.LeftPadBytes([]byte{0xb}, 32) +} diff --git a/rpc/v0/integration/main_test.go b/integration/rpctransact/main_test.go similarity index 69% rename from rpc/v0/integration/main_test.go rename to integration/rpctransact/main_test.go index a83a08b5158c70bc5236c3a042e1e6ceab4eb827..bda89290e649e0046a1564904829e1072ffee103 100644 --- a/rpc/v0/integration/main_test.go +++ b/integration/rpctransact/main_test.go @@ -15,28 +15,28 @@ // See the License for the specific language governing permissions and // limitations under the License. -package integration +package rpctransact import ( "os" "testing" - "time" "github.com/hyperledger/burrow/core" - "github.com/hyperledger/burrow/core/integration" + "github.com/hyperledger/burrow/integration" + "github.com/hyperledger/burrow/integration/rpctest" ) -var privateAccounts = integration.MakePrivateAccounts(5) // make keys -var genesisDoc = integration.TestGenesisDoc(privateAccounts) +var _ = integration.ClaimPorts() +var testConfig = integration.NewTestConfig(rpctest.GenesisDoc) var kern *core.Kernel // Needs to be in a _test.go file to be picked up func TestMain(m *testing.M) { - returnValue := integration.TestWrapper(privateAccounts, genesisDoc, func(k *core.Kernel) int { - kern = k - return m.Run() - }) + returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig, + func(k *core.Kernel) int { + kern = k + return m.Run() + }) - time.Sleep(3 * time.Second) os.Exit(returnValue) } diff --git a/integration/rpctransact/name_test.go b/integration/rpctransact/name_test.go new file mode 100644 index 0000000000000000000000000000000000000000..3ba4a77f5bdebbf4953a8534d32528de00a32984 --- /dev/null +++ b/integration/rpctransact/name_test.go @@ -0,0 +1,117 @@ +// +build integration + +package rpctransact + +import ( + "context" + "testing" + + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/execution/names" + "github.com/hyperledger/burrow/integration/rpctest" + "github.com/hyperledger/burrow/rpc/rpcquery" + "github.com/hyperledger/burrow/txs/payload" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNameTxSync(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + name := "Flub" + data := "floooo" + expiresIn := uint64(100) + _, err := cli.NameTxSync(context.Background(), &payload.NameTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: names.NameCostForExpiryIn(name, data, expiresIn), + }, + Name: name, + Data: data, + }) + require.NoError(t, err) + + qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress) + entry, err := qcli.GetName(context.Background(), &rpcquery.GetNameParam{ + Name: name, + }) + require.NoError(t, err) + assert.Equal(t, name, entry.Name) + assert.Equal(t, data, entry.Data) + assert.Equal(t, inputAddress, entry.Owner) + assert.True(t, entry.Expires >= expiresIn, "expiry should be later than expiresIn") +} + +func TestNameReg(t *testing.T) { + tcli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress) + names.MinNameRegistrationPeriod = 1 + + // register a new name, check if its there + // since entries ought to be unique and these run against different clients, we append the client + name := "ye_old_domain_name" + const data = "if not now, when" + numDesiredBlocks := uint64(2) + + txe := rpctest.UpdateName(t, tcli, inputAddress, name, data, numDesiredBlocks) + + entry := txe.Result.NameEntry + assert.NotNil(t, entry, "name shoudl return") + _, ok := txe.Envelope.Tx.Payload.(*payload.NameTx) + require.True(t, ok, "should be NameTx: %v", txe.Envelope.Tx.Payload) + + assert.Equal(t, name, entry.Name) + assert.Equal(t, data, entry.Data) + + entryQuery, err := qcli.GetName(context.Background(), &rpcquery.GetNameParam{Name: name}) + require.NoError(t, err) + + assert.Equal(t, entry, entryQuery) + + // update the data as the owner, make sure still there + numDesiredBlocks = uint64(3) + const updatedData = "these are amongst the things I wish to bestow upon " + + "the youth of generations come: a safe supply of honey, and a better " + + "money. For what else shall they need" + rpctest.UpdateName(t, tcli, inputAddress, name, updatedData, numDesiredBlocks) + + entry, err = qcli.GetName(context.Background(), &rpcquery.GetNameParam{Name: name}) + require.NoError(t, err) + + assert.Equal(t, updatedData, entry.Data) + + // try to update as non owner, should fail + txe, err = tcli.NameTxSync(context.Background(), &payload.NameTx{ + Input: &payload.TxInput{ + Address: rpctest.PrivateAccounts[1].Address(), + Amount: names.NameCostForExpiryIn(name, data, numDesiredBlocks), + }, + Name: name, + Data: "flub flub floo", + }) + require.Error(t, err, "updating as non-owner on non-expired name should fail") + assert.Contains(t, err.Error(), "permission denied") + + waitNBlocks(t, numDesiredBlocks) + //now the entry should be expired, so we can update as non owner + const data2 = "this is not my beautiful house" + owner := rpctest.PrivateAccounts[3].Address() + txe = rpctest.UpdateName(t, tcli, owner, name, data2, numDesiredBlocks) + entry = txe.Result.NameEntry + + entryQuery, err = qcli.GetName(context.Background(), &rpcquery.GetNameParam{Name: name}) + require.NoError(t, err) + assert.Equal(t, entry, entryQuery) + assert.Equal(t, data2, entry.Data) + assert.Equal(t, owner, entry.Owner) +} + +func waitNBlocks(t testing.TB, n uint64) { + subID := event.GenSubID() + ch, err := kern.Emitter.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 10) + require.NoError(t, err) + defer kern.Emitter.UnsubscribeAll(context.Background(), subID) + for i := uint64(0); i < n; i++ { + <-ch + } +} diff --git a/integration/rpctransact/send_test.go b/integration/rpctransact/send_test.go new file mode 100644 index 0000000000000000000000000000000000000000..4b465dbc9d9cc922bc6d7f65ad17e175ba110700 --- /dev/null +++ b/integration/rpctransact/send_test.go @@ -0,0 +1,31 @@ +// +build integration + +package rpctransact + +import ( + "context" + "testing" + + "github.com/hyperledger/burrow/integration/rpctest" + "github.com/hyperledger/burrow/txs/payload" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSendTxSync(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + for i := 0; i < 2; i++ { + txe, err := cli.SendTxSync(context.Background(), &payload.SendTx{ + Inputs: []*payload.TxInput{{ + Address: inputAddress, + Amount: 2003, + }}, + Outputs: []*payload.TxOutput{{ + Address: rpctest.PrivateAccounts[3].Address(), + Amount: 2003, + }}, + }) + require.NoError(t, err) + assert.False(t, txe.Receipt.CreatesContract) + } +} diff --git a/integration/rpctransact/transact_server_test.go b/integration/rpctransact/transact_server_test.go new file mode 100644 index 0000000000000000000000000000000000000000..6ab30c545161e70bafbab0efaf558776399e8a23 --- /dev/null +++ b/integration/rpctransact/transact_server_test.go @@ -0,0 +1,109 @@ +// +build integration + +// Space above here matters +// Copyright 2017 Monax Industries Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package rpctransact + +import ( + "context" + "fmt" + "testing" + + "time" + + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/integration/rpctest" + "github.com/hyperledger/burrow/rpc/rpcevents" + "github.com/hyperledger/burrow/rpc/rpcquery" + "github.com/hyperledger/burrow/rpc/rpctransact" + "github.com/hyperledger/burrow/txs" + "github.com/hyperledger/burrow/txs/payload" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var inputAccount = rpctest.PrivateAccounts[0] +var inputAddress = inputAccount.Address() + +func TestBroadcastTxLocallySigned(t *testing.T) { + qcli := rpctest.NewQueryClient(t, testConfig.RPC.GRPC.ListenAddress) + acc, err := qcli.GetAccount(context.Background(), &rpcquery.GetAccountParam{ + Address: inputAddress, + }) + require.NoError(t, err) + amount := uint64(2123) + txEnv := txs.Enclose(rpctest.GenesisDoc.ChainID(), &payload.SendTx{ + Inputs: []*payload.TxInput{{ + Address: inputAddress, + Sequence: acc.Sequence + 1, + Amount: amount, + }}, + Outputs: []*payload.TxOutput{{ + Address: rpctest.PrivateAccounts[1].Address(), + Amount: amount, + }}, + }) + require.NoError(t, txEnv.Sign(inputAccount)) + + // Test subscribing to transaction before sending it + ch := make(chan *exec.TxExecution) + go func() { + ecli := rpctest.NewExecutionEventsClient(t, testConfig.RPC.GRPC.ListenAddress) + txe, err := ecli.GetTx(context.Background(), &rpcevents.GetTxRequest{ + TxHash: txEnv.Tx.Hash(), + Wait: true, + }) + require.NoError(t, err) + ch <- txe + }() + + // Make it wait + time.Sleep(time.Second) + + // No broadcast + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + receipt, err := cli.BroadcastTxAsync(context.Background(), &rpctransact.TxEnvelopeParam{Envelope: txEnv}) + require.NoError(t, err) + assert.False(t, receipt.CreatesContract, "This tx should not create a contract") + require.NotEmpty(t, receipt.TxHash, "Failed to compute tx hash") + assert.Equal(t, txEnv.Tx.Hash(), receipt.TxHash) + + txe := <-ch + require.True(t, len(txe.Events) > 0) + assert.NotNil(t, txe.Events[0].Input) +} + +func TestFormulateTx(t *testing.T) { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + txEnv, err := cli.FormulateTx(context.Background(), &rpctransact.PayloadParam{ + CallTx: &payload.CallTx{ + Input: &payload.TxInput{ + Address: inputAddress, + Amount: 230, + }, + Data: []byte{2, 3, 6, 4, 3}, + }, + }) + require.NoError(t, err) + bs, err := txEnv.Marshal() + require.NoError(t, err) + // We should see the sign bytes embedded + if !assert.Contains(t, string(bs), fmt.Sprintf("{\"ChainID\":\"%s\",\"Type\":\"CallTx\","+ + "\"Payload\":{\"Input\":{\"Address\":\"4A6DFB649EF0D50780998A686BD69AB175C08E26\",\"Amount\":230},"+ + "\"Data\":\"0203060403\"}}", rpctest.GenesisDoc.ChainID())) { + fmt.Println(string(bs)) + } +} diff --git a/integration/tm/main_test.go b/integration/tm/main_test.go new file mode 100644 index 0000000000000000000000000000000000000000..cdee8c090e6460240c21842b944fc1116daf8f4d --- /dev/null +++ b/integration/tm/main_test.go @@ -0,0 +1,49 @@ +// +build integration + +// Space above here matters +// Copyright 2017 Monax Industries Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tm + +import ( + "os" + "testing" + + "github.com/hyperledger/burrow/core" + "github.com/hyperledger/burrow/integration" + "github.com/hyperledger/burrow/integration/rpctest" + rpcClient "github.com/hyperledger/burrow/rpc/lib/client" + tmClient "github.com/hyperledger/burrow/rpc/tm/tmclient" +) + +var kern *core.Kernel +var _ = integration.ClaimPorts() +var testConfig = integration.NewTestConfig(rpctest.GenesisDoc) +var jsonRpcClient = rpcClient.NewJSONRPCClient(testConfig.RPC.TM.ListenAddress) +var httpClient = rpcClient.NewURIClient(testConfig.RPC.TM.ListenAddress) +var clients = map[string]tmClient.RPCClient{ + "JSONRPC": jsonRpcClient, + "HTTP": httpClient, +} + +// Needs to be in a _test.go file to be picked up +func TestMain(m *testing.M) { + returnValue := integration.TestWrapper(rpctest.PrivateAccounts, testConfig, func(k *core.Kernel) int { + kern = k + return m.Run() + }) + + os.Exit(returnValue) +} diff --git a/integration/tm/tm_server_test.go b/integration/tm/tm_server_test.go new file mode 100644 index 0000000000000000000000000000000000000000..09ce3b5815876e70f2018ea31c54b955c0e7532b --- /dev/null +++ b/integration/tm/tm_server_test.go @@ -0,0 +1,224 @@ +// +build integration + +// Space above here matters +// Copyright 2017 Monax Industries Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tm + +import ( + "context" + "fmt" + "strings" + "testing" + "time" + + "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/event" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/integration/rpctest" + "github.com/hyperledger/burrow/rpc/rpctransact" + "github.com/hyperledger/burrow/rpc/tm/tmclient" + "github.com/hyperledger/burrow/txs" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/consensus/types" +) + +const timeout = 5 * time.Second + +func testWithAllClients(t *testing.T, testFunction func(*testing.T, string, tmclient.RPCClient)) { + for clientName, client := range clients { + testFunction(t, clientName, client) + } +} + +//-------------------------------------------------------------------------------- +func TestStatus(t *testing.T) { + testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) { + resp, err := tmclient.Status(client) + assert.NoError(t, err) + assert.Equal(t, rpctest.GenesisDoc.ChainID(), resp.NodeInfo.Network, + "ChainID should match NodeInfo.Network") + }) +} + +func TestGetAccount(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } + testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) { + acc := rpctest.GetAccount(t, client, rpctest.PrivateAccounts[0].Address()) + if acc == nil { + t.Fatal("Account was nil") + } + if acc.Address() != rpctest.PrivateAccounts[0].Address() { + t.Fatalf("Failed to get correct account. Got %s, expected %s", acc.Address(), + rpctest.PrivateAccounts[0].Address()) + } + }) +} + +func TestGetStorage(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } + testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) { + amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000) + code := []byte{0x60, 0x5, 0x60, 0x1, 0x55} + // Call with nil address will create a contract + tx := rpctest.MakeDefaultCallTx(t, client, nil, code, amt, gasLim, fee) + txe := broadcastTxSync(t, tx) + assert.Equal(t, true, txe.Receipt.CreatesContract, "This transaction should"+ + " create a contract") + assert.NotEqual(t, 0, len(txe.TxHash), "Receipt should contain a"+ + " transaction hash") + contractAddr := txe.Receipt.ContractAddress + assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+ + " created a contract but the contract address is empty") + + v := rpctest.GetStorage(t, client, contractAddr, []byte{0x1}) + got := binary.LeftPadWord256(v) + expected := binary.LeftPadWord256([]byte{0x5}) + if got.Compare(expected) != 0 { + t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(), + expected.Bytes()) + } + }) +} + +func TestWaitBlocks(t *testing.T) { + waitNBlocks(t, 5) +} + +func TestBlockchainInfo(t *testing.T) { + testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) { + // wait a mimimal number of blocks to ensure that the later query for block + // headers has a non-trivial length + nBlocks := 4 + waitNBlocks(t, nBlocks) + + resp, err := tmclient.ListBlocks(client, 0, 0) + if err != nil { + t.Fatalf("Failed to get blockchain info: %v", err) + } + lastBlockHeight := resp.LastHeight + nMetaBlocks := len(resp.BlockMetas) + assert.True(t, uint64(nMetaBlocks) <= lastBlockHeight, + "Logically number of block metas should be equal or less than block height.") + assert.True(t, nBlocks <= len(resp.BlockMetas), + "Should see at least %v BlockMetas after waiting for %v blocks but saw %v", + nBlocks, nBlocks, len(resp.BlockMetas)) + // For the maximum number (default to 20) of retrieved block headers, + // check that they correctly chain to each other. + lastBlockHash := resp.BlockMetas[nMetaBlocks-1].Header.Hash() + for i := nMetaBlocks - 2; i >= 0; i-- { + // the blockhash in header of height h should be identical to the hash + // in the LastBlockID of the header of block height h+1. + assert.Equal(t, lastBlockHash, resp.BlockMetas[i].Header.LastBlockID.Hash, + "Blockchain should be a hash tree!") + lastBlockHash = resp.BlockMetas[i].Header.Hash() + } + + // Now retrieve only two blockheaders (h=1, and h=2) and check that we got + // two results. + resp, err = tmclient.ListBlocks(client, 1, 2) + assert.NoError(t, err) + assert.Equal(t, 2, len(resp.BlockMetas), + "Should see 2 BlockMetas after extracting 2 blocks") + }) +} + +func TestListUnconfirmedTxs(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } + testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) { + amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000) + code := []byte{0x60, 0x5, 0x60, 0x1, 0x55} + // Call with nil address will create a contract + txEnv := rpctest.MakeDefaultCallTx(t, client, nil, code, amt, gasLim, fee) + txChan := make(chan []*txs.Envelope) + + // We want to catch the Tx in mempool before it gets reaped by tendermint + // consensus. We should be able to do this almost always if we broadcast our + // transaction immediately after a block has been committed. There is about + // 1 second between blocks, and we will have the lock on Reap + // So we wait for a block here + waitNBlocks(t, 1) + + go func() { + for { + resp, err := tmclient.ListUnconfirmedTxs(client, -1) + if err != nil { + // We get an error on exit + return + } + if resp.NumTxs > 0 { + txChan <- resp.Txs + } + } + }() + + broadcastTxSync(t, txEnv) + select { + case <-time.After(time.Second * timeout): + t.Fatal("Timeout out waiting for unconfirmed transactions to appear") + case transactions := <-txChan: + assert.Len(t, transactions, 1, "There should only be a single transaction in the "+ + "mempool during this test (previous txs should have made it into a block)") + assert.Contains(t, transactions, txEnv, "Transaction should be returned by ListUnconfirmedTxs") + } + }) +} + +func TestListValidators(t *testing.T) { + testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) { + resp, err := tmclient.ListValidators(client) + assert.NoError(t, err) + assert.Len(t, resp.BondedValidators, 1) + validator := resp.BondedValidators[0] + assert.Equal(t, rpctest.GenesisDoc.Validators[0].PublicKey, validator.PublicKey) + }) +} + +func TestDumpConsensusState(t *testing.T) { + startTime := time.Now() + testWithAllClients(t, func(t *testing.T, clientName string, client tmclient.RPCClient) { + resp, err := tmclient.DumpConsensusState(client) + assert.NoError(t, err) + assert.NotZero(t, startTime) + assert.Equal(t, fmt.Sprintf("/0/%d", types.RoundStepNewHeight), + strings.TrimLeft(resp.RoundState.HeightRoundStep, "0123456789")) + }) +} + +func waitNBlocks(t testing.TB, n int) { + subID := event.GenSubID() + ch, err := kern.Emitter.Subscribe(context.Background(), subID, exec.QueryForBlockExecution(), 10) + require.NoError(t, err) + defer kern.Emitter.UnsubscribeAll(context.Background(), subID) + for i := 0; i < n; i++ { + <-ch + } +} + +func broadcastTxSync(t testing.TB, txEnv *txs.Envelope) *exec.TxExecution { + cli := rpctest.NewTransactClient(t, testConfig.RPC.GRPC.ListenAddress) + txe, err := cli.BroadcastTxSync(context.Background(), &rpctransact.TxEnvelopeParam{ + Envelope: txEnv, + }) + require.NoError(t, err) + return txe +} diff --git a/keys/key_client.go b/keys/key_client.go index bae1d0ae70d4cf987f856204b96f8e0d465dbb8a..ae6a92c7aef1a8bff974be885f0a513d2f157ac7 100644 --- a/keys/key_client.go +++ b/keys/key_client.go @@ -20,7 +20,6 @@ import ( "time" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging" "google.golang.org/grpc" ) @@ -49,16 +48,16 @@ type localKeyClient struct { type remoteKeyClient struct { rpcAddress string - kc pbkeys.KeysClient + kc KeysClient logger *logging.Logger } func (l *localKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) { - resp, err := l.ks.Sign(nil, &pbkeys.SignRequest{Address: signAddress.String(), Message: message}) + resp, err := l.ks.Sign(nil, &SignRequest{Address: signAddress.String(), Message: message}) if err != nil { return crypto.Signature{}, err } - curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + curveType, err := crypto.CurveTypeFromString(resp.GetCurveType()) if err != nil { return crypto.Signature{}, err } @@ -66,20 +65,20 @@ func (l *localKeyClient) Sign(signAddress crypto.Address, message []byte) (signa } func (l *localKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) { - resp, err := l.ks.PublicKey(nil, &pbkeys.PubRequest{Address: address.String()}) + resp, err := l.ks.PublicKey(nil, &PubRequest{Address: address.String()}) if err != nil { return crypto.PublicKey{}, err } - curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + curveType, err := crypto.CurveTypeFromString(resp.GetCurveType()) if err != nil { return crypto.PublicKey{}, err } - return crypto.PublicKeyFromBytes(resp.GetPub(), curveType) + return crypto.PublicKeyFromBytes(resp.GetPublicKey(), curveType) } // Generate requests that a key be generate within the keys instance and returns the address func (l *localKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) { - resp, err := l.ks.GenerateKey(nil, &pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()}) + resp, err := l.ks.GenerateKey(nil, &GenRequest{KeyName: keyName, CurveType: curveType.String()}) if err != nil { return crypto.Address{}, err } @@ -94,7 +93,7 @@ func (l *localKeyClient) HealthCheck() error { func (l *remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - req := pbkeys.SignRequest{Address: signAddress.String(), Message: message} + req := SignRequest{Address: signAddress.String(), Message: message} l.logger.TraceMsg("Sending Sign request to remote key server: ", fmt.Sprintf("%v", req)) resp, err := l.kc.Sign(ctx, &req) if err != nil { @@ -102,7 +101,7 @@ func (l *remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (sign return crypto.Signature{}, err } l.logger.TraceMsg("Received Sign response to remote key server: %v", resp) - curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + curveType, err := crypto.CurveTypeFromString(resp.GetCurveType()) if err != nil { return crypto.Signature{}, err } @@ -112,26 +111,26 @@ func (l *remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (sign func (l *remoteKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - req := pbkeys.PubRequest{Address: address.String()} + req := PubRequest{Address: address.String()} l.logger.TraceMsg("Sending PublicKey request to remote key server: ", fmt.Sprintf("%v", req)) resp, err := l.kc.PublicKey(ctx, &req) if err != nil { l.logger.TraceMsg("Received PublicKey error response: ", err) return crypto.PublicKey{}, err } - curveType, err := crypto.CurveTypeFromString(resp.GetCurvetype()) + curveType, err := crypto.CurveTypeFromString(resp.GetCurveType()) if err != nil { return crypto.PublicKey{}, err } l.logger.TraceMsg("Received PublicKey response to remote key server: ", fmt.Sprintf("%v", resp)) - return crypto.PublicKeyFromBytes(resp.GetPub(), curveType) + return crypto.PublicKeyFromBytes(resp.GetPublicKey(), curveType) } // Generate requests that a key be generate within the keys instance and returns the address func (l *remoteKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - req := pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()} + req := GenRequest{KeyName: keyName, CurveType: curveType.String()} l.logger.TraceMsg("Sending Generate request to remote key server: ", fmt.Sprintf("%v", req)) resp, err := l.kc.GenerateKey(ctx, &req) if err != nil { @@ -146,7 +145,7 @@ func (l *remoteKeyClient) Generate(keyName string, curveType crypto.CurveType) ( func (l *remoteKeyClient) HealthCheck() error { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, err := l.kc.List(ctx, &pbkeys.ListRequest{}) + _, err := l.kc.List(ctx, &ListRequest{}) return err } @@ -160,7 +159,7 @@ func NewRemoteKeyClient(rpcAddress string, logger *logging.Logger) (KeyClient, e if err != nil { return nil, err } - kc := pbkeys.NewKeysClient(conn) + kc := NewKeysClient(conn) return &remoteKeyClient{kc: kc, rpcAddress: rpcAddress, logger: logger}, nil } diff --git a/keys/key_store.go b/keys/key_store.go index 0a8a1cf5a338698ab0f3ebaebfcfcfe3c50dea30..c2326cf382c45286edfa0f7bffe12a1ed1993702 100644 --- a/keys/key_store.go +++ b/keys/key_store.go @@ -15,8 +15,8 @@ import ( "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" - "github.com/tmthrgd/go-hex" + "github.com/tmthrgd/go-hex" "golang.org/x/crypto/scrypt" ) diff --git a/keys/keys.pb.go b/keys/keys.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..6d8212e6a3e934c5440e5a519d8b11e83cc584dd --- /dev/null +++ b/keys/keys.pb.go @@ -0,0 +1,4538 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: keys.proto + +/* + Package keys is a generated protocol buffer package. + + It is generated from these files: + keys.proto + + It has these top-level messages: + ListRequest + VerifyResponse + RemoveNameResponse + AddNameResponse + RemoveNameRequest + GenRequest + GenResponse + PubRequest + PubResponse + ImportJSONRequest + ImportResponse + ImportRequest + ExportRequest + ExportResponse + SignRequest + SignResponse + VerifyRequest + HashRequest + HashResponse + KeyID + ListResponse + AddNameRequest +*/ +package keys + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" + +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type ListRequest struct { +} + +func (m *ListRequest) Reset() { *m = ListRequest{} } +func (m *ListRequest) String() string { return proto.CompactTextString(m) } +func (*ListRequest) ProtoMessage() {} +func (*ListRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{0} } + +func (*ListRequest) XXX_MessageName() string { + return "keys.ListRequest" +} + +type VerifyResponse struct { +} + +func (m *VerifyResponse) Reset() { *m = VerifyResponse{} } +func (m *VerifyResponse) String() string { return proto.CompactTextString(m) } +func (*VerifyResponse) ProtoMessage() {} +func (*VerifyResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{1} } + +func (*VerifyResponse) XXX_MessageName() string { + return "keys.VerifyResponse" +} + +type RemoveNameResponse struct { +} + +func (m *RemoveNameResponse) Reset() { *m = RemoveNameResponse{} } +func (m *RemoveNameResponse) String() string { return proto.CompactTextString(m) } +func (*RemoveNameResponse) ProtoMessage() {} +func (*RemoveNameResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{2} } + +func (*RemoveNameResponse) XXX_MessageName() string { + return "keys.RemoveNameResponse" +} + +type AddNameResponse struct { +} + +func (m *AddNameResponse) Reset() { *m = AddNameResponse{} } +func (m *AddNameResponse) String() string { return proto.CompactTextString(m) } +func (*AddNameResponse) ProtoMessage() {} +func (*AddNameResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{3} } + +func (*AddNameResponse) XXX_MessageName() string { + return "keys.AddNameResponse" +} + +type RemoveNameRequest struct { + KeyName string `protobuf:"bytes,1,opt,name=KeyName,proto3" json:"KeyName,omitempty"` +} + +func (m *RemoveNameRequest) Reset() { *m = RemoveNameRequest{} } +func (m *RemoveNameRequest) String() string { return proto.CompactTextString(m) } +func (*RemoveNameRequest) ProtoMessage() {} +func (*RemoveNameRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{4} } + +func (m *RemoveNameRequest) GetKeyName() string { + if m != nil { + return m.KeyName + } + return "" +} + +func (*RemoveNameRequest) XXX_MessageName() string { + return "keys.RemoveNameRequest" +} + +type GenRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"` + CurveType string `protobuf:"bytes,2,opt,name=CurveType,proto3" json:"CurveType,omitempty"` + KeyName string `protobuf:"bytes,3,opt,name=KeyName,proto3" json:"KeyName,omitempty"` +} + +func (m *GenRequest) Reset() { *m = GenRequest{} } +func (m *GenRequest) String() string { return proto.CompactTextString(m) } +func (*GenRequest) ProtoMessage() {} +func (*GenRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{5} } + +func (m *GenRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *GenRequest) GetCurveType() string { + if m != nil { + return m.CurveType + } + return "" +} + +func (m *GenRequest) GetKeyName() string { + if m != nil { + return m.KeyName + } + return "" +} + +func (*GenRequest) XXX_MessageName() string { + return "keys.GenRequest" +} + +type GenResponse struct { + Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"` +} + +func (m *GenResponse) Reset() { *m = GenResponse{} } +func (m *GenResponse) String() string { return proto.CompactTextString(m) } +func (*GenResponse) ProtoMessage() {} +func (*GenResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{6} } + +func (m *GenResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (*GenResponse) XXX_MessageName() string { + return "keys.GenResponse" +} + +type PubRequest struct { + Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"` + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` +} + +func (m *PubRequest) Reset() { *m = PubRequest{} } +func (m *PubRequest) String() string { return proto.CompactTextString(m) } +func (*PubRequest) ProtoMessage() {} +func (*PubRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{7} } + +func (m *PubRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *PubRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (*PubRequest) XXX_MessageName() string { + return "keys.PubRequest" +} + +type PubResponse struct { + PublicKey []byte `protobuf:"bytes,1,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"` + CurveType string `protobuf:"bytes,2,opt,name=CurveType,proto3" json:"CurveType,omitempty"` +} + +func (m *PubResponse) Reset() { *m = PubResponse{} } +func (m *PubResponse) String() string { return proto.CompactTextString(m) } +func (*PubResponse) ProtoMessage() {} +func (*PubResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{8} } + +func (m *PubResponse) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *PubResponse) GetCurveType() string { + if m != nil { + return m.CurveType + } + return "" +} + +func (*PubResponse) XXX_MessageName() string { + return "keys.PubResponse" +} + +type ImportJSONRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"` + JSON string `protobuf:"bytes,2,opt,name=JSON,proto3" json:"JSON,omitempty"` +} + +func (m *ImportJSONRequest) Reset() { *m = ImportJSONRequest{} } +func (m *ImportJSONRequest) String() string { return proto.CompactTextString(m) } +func (*ImportJSONRequest) ProtoMessage() {} +func (*ImportJSONRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{9} } + +func (m *ImportJSONRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *ImportJSONRequest) GetJSON() string { + if m != nil { + return m.JSON + } + return "" +} + +func (*ImportJSONRequest) XXX_MessageName() string { + return "keys.ImportJSONRequest" +} + +type ImportResponse struct { + Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"` +} + +func (m *ImportResponse) Reset() { *m = ImportResponse{} } +func (m *ImportResponse) String() string { return proto.CompactTextString(m) } +func (*ImportResponse) ProtoMessage() {} +func (*ImportResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{10} } + +func (m *ImportResponse) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (*ImportResponse) XXX_MessageName() string { + return "keys.ImportResponse" +} + +type ImportRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"` + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` + CurveType string `protobuf:"bytes,3,opt,name=CurveType,proto3" json:"CurveType,omitempty"` + KeyBytes []byte `protobuf:"bytes,4,opt,name=KeyBytes,proto3" json:"KeyBytes,omitempty"` +} + +func (m *ImportRequest) Reset() { *m = ImportRequest{} } +func (m *ImportRequest) String() string { return proto.CompactTextString(m) } +func (*ImportRequest) ProtoMessage() {} +func (*ImportRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{11} } + +func (m *ImportRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *ImportRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ImportRequest) GetCurveType() string { + if m != nil { + return m.CurveType + } + return "" +} + +func (m *ImportRequest) GetKeyBytes() []byte { + if m != nil { + return m.KeyBytes + } + return nil +} + +func (*ImportRequest) XXX_MessageName() string { + return "keys.ImportRequest" +} + +type ExportRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"` + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` + Address string `protobuf:"bytes,3,opt,name=Address,proto3" json:"Address,omitempty"` +} + +func (m *ExportRequest) Reset() { *m = ExportRequest{} } +func (m *ExportRequest) String() string { return proto.CompactTextString(m) } +func (*ExportRequest) ProtoMessage() {} +func (*ExportRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{12} } + +func (m *ExportRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *ExportRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *ExportRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (*ExportRequest) XXX_MessageName() string { + return "keys.ExportRequest" +} + +type ExportResponse struct { + Publickey []byte `protobuf:"bytes,1,opt,name=Publickey,proto3" json:"Publickey,omitempty"` + Privatekey []byte `protobuf:"bytes,2,opt,name=Privatekey,proto3" json:"Privatekey,omitempty"` + Address []byte `protobuf:"bytes,3,opt,name=Address,proto3" json:"Address,omitempty"` + CurveType string `protobuf:"bytes,4,opt,name=CurveType,proto3" json:"CurveType,omitempty"` +} + +func (m *ExportResponse) Reset() { *m = ExportResponse{} } +func (m *ExportResponse) String() string { return proto.CompactTextString(m) } +func (*ExportResponse) ProtoMessage() {} +func (*ExportResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{13} } + +func (m *ExportResponse) GetPublickey() []byte { + if m != nil { + return m.Publickey + } + return nil +} + +func (m *ExportResponse) GetPrivatekey() []byte { + if m != nil { + return m.Privatekey + } + return nil +} + +func (m *ExportResponse) GetAddress() []byte { + if m != nil { + return m.Address + } + return nil +} + +func (m *ExportResponse) GetCurveType() string { + if m != nil { + return m.CurveType + } + return "" +} + +func (*ExportResponse) XXX_MessageName() string { + return "keys.ExportResponse" +} + +type SignRequest struct { + Passphrase string `protobuf:"bytes,1,opt,name=Passphrase,proto3" json:"Passphrase,omitempty"` + Address string `protobuf:"bytes,2,opt,name=Address,proto3" json:"Address,omitempty"` + Name string `protobuf:"bytes,3,opt,name=Name,proto3" json:"Name,omitempty"` + Message []byte `protobuf:"bytes,4,opt,name=Message,proto3" json:"Message,omitempty"` +} + +func (m *SignRequest) Reset() { *m = SignRequest{} } +func (m *SignRequest) String() string { return proto.CompactTextString(m) } +func (*SignRequest) ProtoMessage() {} +func (*SignRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{14} } + +func (m *SignRequest) GetPassphrase() string { + if m != nil { + return m.Passphrase + } + return "" +} + +func (m *SignRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *SignRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *SignRequest) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +func (*SignRequest) XXX_MessageName() string { + return "keys.SignRequest" +} + +type SignResponse struct { + Signature []byte `protobuf:"bytes,1,opt,name=Signature,proto3" json:"Signature,omitempty"` + CurveType string `protobuf:"bytes,2,opt,name=CurveType,proto3" json:"CurveType,omitempty"` +} + +func (m *SignResponse) Reset() { *m = SignResponse{} } +func (m *SignResponse) String() string { return proto.CompactTextString(m) } +func (*SignResponse) ProtoMessage() {} +func (*SignResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{15} } + +func (m *SignResponse) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (m *SignResponse) GetCurveType() string { + if m != nil { + return m.CurveType + } + return "" +} + +func (*SignResponse) XXX_MessageName() string { + return "keys.SignResponse" +} + +type VerifyRequest struct { + CurveType string `protobuf:"bytes,1,opt,name=CurveType,proto3" json:"CurveType,omitempty"` + PublicKey []byte `protobuf:"bytes,2,opt,name=PublicKey,proto3" json:"PublicKey,omitempty"` + Message []byte `protobuf:"bytes,3,opt,name=Message,proto3" json:"Message,omitempty"` + Signature []byte `protobuf:"bytes,4,opt,name=Signature,proto3" json:"Signature,omitempty"` +} + +func (m *VerifyRequest) Reset() { *m = VerifyRequest{} } +func (m *VerifyRequest) String() string { return proto.CompactTextString(m) } +func (*VerifyRequest) ProtoMessage() {} +func (*VerifyRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{16} } + +func (m *VerifyRequest) GetCurveType() string { + if m != nil { + return m.CurveType + } + return "" +} + +func (m *VerifyRequest) GetPublicKey() []byte { + if m != nil { + return m.PublicKey + } + return nil +} + +func (m *VerifyRequest) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +func (m *VerifyRequest) GetSignature() []byte { + if m != nil { + return m.Signature + } + return nil +} + +func (*VerifyRequest) XXX_MessageName() string { + return "keys.VerifyRequest" +} + +type HashRequest struct { + Hashtype string `protobuf:"bytes,1,opt,name=Hashtype,proto3" json:"Hashtype,omitempty"` + Message []byte `protobuf:"bytes,2,opt,name=Message,proto3" json:"Message,omitempty"` +} + +func (m *HashRequest) Reset() { *m = HashRequest{} } +func (m *HashRequest) String() string { return proto.CompactTextString(m) } +func (*HashRequest) ProtoMessage() {} +func (*HashRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{17} } + +func (m *HashRequest) GetHashtype() string { + if m != nil { + return m.Hashtype + } + return "" +} + +func (m *HashRequest) GetMessage() []byte { + if m != nil { + return m.Message + } + return nil +} + +func (*HashRequest) XXX_MessageName() string { + return "keys.HashRequest" +} + +type HashResponse struct { + Hash string `protobuf:"bytes,1,opt,name=Hash,proto3" json:"Hash,omitempty"` +} + +func (m *HashResponse) Reset() { *m = HashResponse{} } +func (m *HashResponse) String() string { return proto.CompactTextString(m) } +func (*HashResponse) ProtoMessage() {} +func (*HashResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{18} } + +func (m *HashResponse) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +func (*HashResponse) XXX_MessageName() string { + return "keys.HashResponse" +} + +type KeyID struct { + Address string `protobuf:"bytes,1,opt,name=Address,proto3" json:"Address,omitempty"` + KeyName string `protobuf:"bytes,2,opt,name=KeyName,proto3" json:"KeyName,omitempty"` +} + +func (m *KeyID) Reset() { *m = KeyID{} } +func (m *KeyID) String() string { return proto.CompactTextString(m) } +func (*KeyID) ProtoMessage() {} +func (*KeyID) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{19} } + +func (m *KeyID) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *KeyID) GetKeyName() string { + if m != nil { + return m.KeyName + } + return "" +} + +func (*KeyID) XXX_MessageName() string { + return "keys.KeyID" +} + +type ListResponse struct { + Key []*KeyID `protobuf:"bytes,1,rep,name=key" json:"key,omitempty"` +} + +func (m *ListResponse) Reset() { *m = ListResponse{} } +func (m *ListResponse) String() string { return proto.CompactTextString(m) } +func (*ListResponse) ProtoMessage() {} +func (*ListResponse) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{20} } + +func (m *ListResponse) GetKey() []*KeyID { + if m != nil { + return m.Key + } + return nil +} + +func (*ListResponse) XXX_MessageName() string { + return "keys.ListResponse" +} + +type AddNameRequest struct { + Keyname string `protobuf:"bytes,1,opt,name=Keyname,proto3" json:"Keyname,omitempty"` + Address string `protobuf:"bytes,2,opt,name=Address,proto3" json:"Address,omitempty"` +} + +func (m *AddNameRequest) Reset() { *m = AddNameRequest{} } +func (m *AddNameRequest) String() string { return proto.CompactTextString(m) } +func (*AddNameRequest) ProtoMessage() {} +func (*AddNameRequest) Descriptor() ([]byte, []int) { return fileDescriptorKeys, []int{21} } + +func (m *AddNameRequest) GetKeyname() string { + if m != nil { + return m.Keyname + } + return "" +} + +func (m *AddNameRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (*AddNameRequest) XXX_MessageName() string { + return "keys.AddNameRequest" +} +func init() { + proto.RegisterType((*ListRequest)(nil), "keys.ListRequest") + golang_proto.RegisterType((*ListRequest)(nil), "keys.ListRequest") + proto.RegisterType((*VerifyResponse)(nil), "keys.VerifyResponse") + golang_proto.RegisterType((*VerifyResponse)(nil), "keys.VerifyResponse") + proto.RegisterType((*RemoveNameResponse)(nil), "keys.RemoveNameResponse") + golang_proto.RegisterType((*RemoveNameResponse)(nil), "keys.RemoveNameResponse") + proto.RegisterType((*AddNameResponse)(nil), "keys.AddNameResponse") + golang_proto.RegisterType((*AddNameResponse)(nil), "keys.AddNameResponse") + proto.RegisterType((*RemoveNameRequest)(nil), "keys.RemoveNameRequest") + golang_proto.RegisterType((*RemoveNameRequest)(nil), "keys.RemoveNameRequest") + proto.RegisterType((*GenRequest)(nil), "keys.GenRequest") + golang_proto.RegisterType((*GenRequest)(nil), "keys.GenRequest") + proto.RegisterType((*GenResponse)(nil), "keys.GenResponse") + golang_proto.RegisterType((*GenResponse)(nil), "keys.GenResponse") + proto.RegisterType((*PubRequest)(nil), "keys.PubRequest") + golang_proto.RegisterType((*PubRequest)(nil), "keys.PubRequest") + proto.RegisterType((*PubResponse)(nil), "keys.PubResponse") + golang_proto.RegisterType((*PubResponse)(nil), "keys.PubResponse") + proto.RegisterType((*ImportJSONRequest)(nil), "keys.ImportJSONRequest") + golang_proto.RegisterType((*ImportJSONRequest)(nil), "keys.ImportJSONRequest") + proto.RegisterType((*ImportResponse)(nil), "keys.ImportResponse") + golang_proto.RegisterType((*ImportResponse)(nil), "keys.ImportResponse") + proto.RegisterType((*ImportRequest)(nil), "keys.ImportRequest") + golang_proto.RegisterType((*ImportRequest)(nil), "keys.ImportRequest") + proto.RegisterType((*ExportRequest)(nil), "keys.ExportRequest") + golang_proto.RegisterType((*ExportRequest)(nil), "keys.ExportRequest") + proto.RegisterType((*ExportResponse)(nil), "keys.ExportResponse") + golang_proto.RegisterType((*ExportResponse)(nil), "keys.ExportResponse") + proto.RegisterType((*SignRequest)(nil), "keys.SignRequest") + golang_proto.RegisterType((*SignRequest)(nil), "keys.SignRequest") + proto.RegisterType((*SignResponse)(nil), "keys.SignResponse") + golang_proto.RegisterType((*SignResponse)(nil), "keys.SignResponse") + proto.RegisterType((*VerifyRequest)(nil), "keys.VerifyRequest") + golang_proto.RegisterType((*VerifyRequest)(nil), "keys.VerifyRequest") + proto.RegisterType((*HashRequest)(nil), "keys.HashRequest") + golang_proto.RegisterType((*HashRequest)(nil), "keys.HashRequest") + proto.RegisterType((*HashResponse)(nil), "keys.HashResponse") + golang_proto.RegisterType((*HashResponse)(nil), "keys.HashResponse") + proto.RegisterType((*KeyID)(nil), "keys.KeyID") + golang_proto.RegisterType((*KeyID)(nil), "keys.KeyID") + proto.RegisterType((*ListResponse)(nil), "keys.ListResponse") + golang_proto.RegisterType((*ListResponse)(nil), "keys.ListResponse") + proto.RegisterType((*AddNameRequest)(nil), "keys.AddNameRequest") + golang_proto.RegisterType((*AddNameRequest)(nil), "keys.AddNameRequest") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for Keys service + +type KeysClient interface { + GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) + PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) + Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) + Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error) + Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) + ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) + Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) + Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) + RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error) + List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) + AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error) +} + +type keysClient struct { + cc *grpc.ClientConn +} + +func NewKeysClient(cc *grpc.ClientConn) KeysClient { + return &keysClient{cc} +} + +func (c *keysClient) GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) { + out := new(GenResponse) + err := grpc.Invoke(ctx, "/keys.Keys/GenerateKey", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) { + out := new(PubResponse) + err := grpc.Invoke(ctx, "/keys.Keys/PublicKey", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) { + out := new(SignResponse) + err := grpc.Invoke(ctx, "/keys.Keys/Sign", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error) { + out := new(VerifyResponse) + err := grpc.Invoke(ctx, "/keys.Keys/Verify", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) { + out := new(ImportResponse) + err := grpc.Invoke(ctx, "/keys.Keys/Import", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) { + out := new(ImportResponse) + err := grpc.Invoke(ctx, "/keys.Keys/ImportJSON", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) { + out := new(ExportResponse) + err := grpc.Invoke(ctx, "/keys.Keys/Export", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) { + out := new(HashResponse) + err := grpc.Invoke(ctx, "/keys.Keys/Hash", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error) { + out := new(RemoveNameResponse) + err := grpc.Invoke(ctx, "/keys.Keys/RemoveName", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { + out := new(ListResponse) + err := grpc.Invoke(ctx, "/keys.Keys/List", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *keysClient) AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error) { + out := new(AddNameResponse) + err := grpc.Invoke(ctx, "/keys.Keys/AddName", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Keys service + +type KeysServer interface { + GenerateKey(context.Context, *GenRequest) (*GenResponse, error) + PublicKey(context.Context, *PubRequest) (*PubResponse, error) + Sign(context.Context, *SignRequest) (*SignResponse, error) + Verify(context.Context, *VerifyRequest) (*VerifyResponse, error) + Import(context.Context, *ImportRequest) (*ImportResponse, error) + ImportJSON(context.Context, *ImportJSONRequest) (*ImportResponse, error) + Export(context.Context, *ExportRequest) (*ExportResponse, error) + Hash(context.Context, *HashRequest) (*HashResponse, error) + RemoveName(context.Context, *RemoveNameRequest) (*RemoveNameResponse, error) + List(context.Context, *ListRequest) (*ListResponse, error) + AddName(context.Context, *AddNameRequest) (*AddNameResponse, error) +} + +func RegisterKeysServer(s *grpc.Server, srv KeysServer) { + s.RegisterService(&_Keys_serviceDesc, srv) +} + +func _Keys_GenerateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GenRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).GenerateKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/GenerateKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).GenerateKey(ctx, req.(*GenRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_PublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PubRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).PublicKey(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/PublicKey", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).PublicKey(ctx, req.(*PubRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SignRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Sign(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/Sign", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Sign(ctx, req.(*SignRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VerifyRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Verify(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/Verify", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Verify(ctx, req.(*VerifyRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Import_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImportRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Import(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/Import", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Import(ctx, req.(*ImportRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_ImportJSON_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ImportJSONRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).ImportJSON(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/ImportJSON", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).ImportJSON(ctx, req.(*ImportJSONRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ExportRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Export(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/Export", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Export(ctx, req.(*ExportRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HashRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).Hash(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/Hash", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).Hash(ctx, req.(*HashRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_RemoveName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RemoveNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).RemoveName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/RemoveName", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).RemoveName(ctx, req.(*RemoveNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).List(ctx, req.(*ListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Keys_AddName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(KeysServer).AddName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/keys.Keys/AddName", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(KeysServer).AddName(ctx, req.(*AddNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Keys_serviceDesc = grpc.ServiceDesc{ + ServiceName: "keys.Keys", + HandlerType: (*KeysServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GenerateKey", + Handler: _Keys_GenerateKey_Handler, + }, + { + MethodName: "PublicKey", + Handler: _Keys_PublicKey_Handler, + }, + { + MethodName: "Sign", + Handler: _Keys_Sign_Handler, + }, + { + MethodName: "Verify", + Handler: _Keys_Verify_Handler, + }, + { + MethodName: "Import", + Handler: _Keys_Import_Handler, + }, + { + MethodName: "ImportJSON", + Handler: _Keys_ImportJSON_Handler, + }, + { + MethodName: "Export", + Handler: _Keys_Export_Handler, + }, + { + MethodName: "Hash", + Handler: _Keys_Hash_Handler, + }, + { + MethodName: "RemoveName", + Handler: _Keys_RemoveName_Handler, + }, + { + MethodName: "List", + Handler: _Keys_List_Handler, + }, + { + MethodName: "AddName", + Handler: _Keys_AddName_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "keys.proto", +} + +func (m *ListRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ListRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *VerifyResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VerifyResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *RemoveNameResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RemoveNameResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *AddNameResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AddNameResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *RemoveNameRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RemoveNameRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.KeyName) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyName))) + i += copy(dAtA[i:], m.KeyName) + } + return i, nil +} + +func (m *GenRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Passphrase) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase))) + i += copy(dAtA[i:], m.Passphrase) + } + if len(m.CurveType) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType))) + i += copy(dAtA[i:], m.CurveType) + } + if len(m.KeyName) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyName))) + i += copy(dAtA[i:], m.KeyName) + } + return i, nil +} + +func (m *GenResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Address) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + return i, nil +} + +func (m *PubRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PubRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Address) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + if len(m.Name) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + return i, nil +} + +func (m *PubResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PubResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.PublicKey) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.PublicKey))) + i += copy(dAtA[i:], m.PublicKey) + } + if len(m.CurveType) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType))) + i += copy(dAtA[i:], m.CurveType) + } + return i, nil +} + +func (m *ImportJSONRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ImportJSONRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Passphrase) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase))) + i += copy(dAtA[i:], m.Passphrase) + } + if len(m.JSON) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.JSON))) + i += copy(dAtA[i:], m.JSON) + } + return i, nil +} + +func (m *ImportResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ImportResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Address) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + return i, nil +} + +func (m *ImportRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ImportRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Passphrase) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase))) + i += copy(dAtA[i:], m.Passphrase) + } + if len(m.Name) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.CurveType) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType))) + i += copy(dAtA[i:], m.CurveType) + } + if len(m.KeyBytes) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyBytes))) + i += copy(dAtA[i:], m.KeyBytes) + } + return i, nil +} + +func (m *ExportRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExportRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Passphrase) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase))) + i += copy(dAtA[i:], m.Passphrase) + } + if len(m.Name) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Address) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + return i, nil +} + +func (m *ExportResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ExportResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Publickey) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Publickey))) + i += copy(dAtA[i:], m.Publickey) + } + if len(m.Privatekey) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Privatekey))) + i += copy(dAtA[i:], m.Privatekey) + } + if len(m.Address) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + if len(m.CurveType) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType))) + i += copy(dAtA[i:], m.CurveType) + } + return i, nil +} + +func (m *SignRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SignRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Passphrase) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Passphrase))) + i += copy(dAtA[i:], m.Passphrase) + } + if len(m.Address) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + if len(m.Name) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Message) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Message))) + i += copy(dAtA[i:], m.Message) + } + return i, nil +} + +func (m *SignResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SignResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Signature) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Signature))) + i += copy(dAtA[i:], m.Signature) + } + if len(m.CurveType) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType))) + i += copy(dAtA[i:], m.CurveType) + } + return i, nil +} + +func (m *VerifyRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *VerifyRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.CurveType) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.CurveType))) + i += copy(dAtA[i:], m.CurveType) + } + if len(m.PublicKey) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.PublicKey))) + i += copy(dAtA[i:], m.PublicKey) + } + if len(m.Message) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Message))) + i += copy(dAtA[i:], m.Message) + } + if len(m.Signature) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Signature))) + i += copy(dAtA[i:], m.Signature) + } + return i, nil +} + +func (m *HashRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HashRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Hashtype) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Hashtype))) + i += copy(dAtA[i:], m.Hashtype) + } + if len(m.Message) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Message))) + i += copy(dAtA[i:], m.Message) + } + return i, nil +} + +func (m *HashResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HashResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Hash) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Hash))) + i += copy(dAtA[i:], m.Hash) + } + return i, nil +} + +func (m *KeyID) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *KeyID) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Address) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + if len(m.KeyName) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.KeyName))) + i += copy(dAtA[i:], m.KeyName) + } + return i, nil +} + +func (m *ListResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ListResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Key) > 0 { + for _, msg := range m.Key { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *AddNameRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AddNameRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Keyname) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Keyname))) + i += copy(dAtA[i:], m.Keyname) + } + if len(m.Address) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintKeys(dAtA, i, uint64(len(m.Address))) + i += copy(dAtA[i:], m.Address) + } + return i, nil +} + +func encodeVarintKeys(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *ListRequest) Size() (n int) { + var l int + _ = l + return n +} + +func (m *VerifyResponse) Size() (n int) { + var l int + _ = l + return n +} + +func (m *RemoveNameResponse) Size() (n int) { + var l int + _ = l + return n +} + +func (m *AddNameResponse) Size() (n int) { + var l int + _ = l + return n +} + +func (m *RemoveNameRequest) Size() (n int) { + var l int + _ = l + l = len(m.KeyName) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *GenRequest) Size() (n int) { + var l int + _ = l + l = len(m.Passphrase) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.CurveType) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.KeyName) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *GenResponse) Size() (n int) { + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *PubRequest) Size() (n int) { + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *PubResponse) Size() (n int) { + var l int + _ = l + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.CurveType) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *ImportJSONRequest) Size() (n int) { + var l int + _ = l + l = len(m.Passphrase) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.JSON) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *ImportResponse) Size() (n int) { + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *ImportRequest) Size() (n int) { + var l int + _ = l + l = len(m.Passphrase) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.CurveType) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.KeyBytes) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *ExportRequest) Size() (n int) { + var l int + _ = l + l = len(m.Passphrase) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *ExportResponse) Size() (n int) { + var l int + _ = l + l = len(m.Publickey) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Privatekey) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.CurveType) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *SignRequest) Size() (n int) { + var l int + _ = l + l = len(m.Passphrase) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *SignResponse) Size() (n int) { + var l int + _ = l + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.CurveType) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *VerifyRequest) Size() (n int) { + var l int + _ = l + l = len(m.CurveType) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.PublicKey) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Signature) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *HashRequest) Size() (n int) { + var l int + _ = l + l = len(m.Hashtype) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *HashResponse) Size() (n int) { + var l int + _ = l + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *KeyID) Size() (n int) { + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.KeyName) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func (m *ListResponse) Size() (n int) { + var l int + _ = l + if len(m.Key) > 0 { + for _, e := range m.Key { + l = e.Size() + n += 1 + l + sovKeys(uint64(l)) + } + } + return n +} + +func (m *AddNameRequest) Size() (n int) { + var l int + _ = l + l = len(m.Keyname) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + l = len(m.Address) + if l > 0 { + n += 1 + l + sovKeys(uint64(l)) + } + return n +} + +func sovKeys(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozKeys(x uint64) (n int) { + return sovKeys(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ListRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VerifyResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VerifyResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VerifyResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RemoveNameResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RemoveNameResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RemoveNameResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddNameResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddNameResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddNameResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RemoveNameRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RemoveNameRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RemoveNameRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Passphrase = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurveType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PubRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PubRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PubResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PubResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PubResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurveType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ImportJSONRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ImportJSONRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ImportJSONRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Passphrase = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field JSON", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.JSON = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ImportResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ImportResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ImportResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ImportRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ImportRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ImportRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Passphrase = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurveType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyBytes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyBytes = append(m.KeyBytes[:0], dAtA[iNdEx:postIndex]...) + if m.KeyBytes == nil { + m.KeyBytes = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExportRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExportRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExportRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Passphrase = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ExportResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ExportResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ExportResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Publickey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Publickey = append(m.Publickey[:0], dAtA[iNdEx:postIndex]...) + if m.Publickey == nil { + m.Publickey = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Privatekey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Privatekey = append(m.Privatekey[:0], dAtA[iNdEx:postIndex]...) + if m.Privatekey == nil { + m.Privatekey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = append(m.Address[:0], dAtA[iNdEx:postIndex]...) + if m.Address == nil { + m.Address = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurveType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SignRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SignRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Passphrase", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Passphrase = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = append(m.Message[:0], dAtA[iNdEx:postIndex]...) + if m.Message == nil { + m.Message = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SignResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SignResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SignResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurveType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *VerifyRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: VerifyRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: VerifyRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CurveType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.CurveType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PublicKey = append(m.PublicKey[:0], dAtA[iNdEx:postIndex]...) + if m.PublicKey == nil { + m.PublicKey = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = append(m.Message[:0], dAtA[iNdEx:postIndex]...) + if m.Message == nil { + m.Message = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signature = append(m.Signature[:0], dAtA[iNdEx:postIndex]...) + if m.Signature == nil { + m.Signature = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HashRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HashRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HashRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hashtype", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hashtype = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = append(m.Message[:0], dAtA[iNdEx:postIndex]...) + if m.Message == nil { + m.Message = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HashResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HashResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HashResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *KeyID) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: KeyID: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: KeyID: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ListResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = append(m.Key, &KeyID{}) + if err := m.Key[len(m.Key)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AddNameRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AddNameRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddNameRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyname", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyname = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowKeys + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthKeys + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipKeys(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthKeys + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipKeys(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKeys + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKeys + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKeys + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthKeys + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowKeys + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipKeys(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthKeys = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowKeys = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("keys.proto", fileDescriptorKeys) } +func init() { golang_proto.RegisterFile("keys.proto", fileDescriptorKeys) } + +var fileDescriptorKeys = []byte{ + // 759 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4d, 0x6f, 0xd3, 0x4c, + 0x10, 0x96, 0x63, 0xbf, 0x7d, 0xdb, 0x71, 0x92, 0xb7, 0xf1, 0x5b, 0x44, 0x64, 0x95, 0x08, 0xed, + 0x85, 0x0a, 0x29, 0x0d, 0x6a, 0x25, 0x84, 0xe8, 0x01, 0xf5, 0x03, 0x95, 0x36, 0x50, 0xaa, 0x14, + 0x71, 0x40, 0xe2, 0xe0, 0x34, 0xd3, 0x24, 0x6a, 0x13, 0x87, 0x5d, 0xbb, 0xe0, 0x03, 0x27, 0x24, + 0x7e, 0x17, 0xc7, 0x9e, 0x10, 0x3f, 0x01, 0xb5, 0x7f, 0x04, 0xed, 0xae, 0x37, 0xde, 0xdd, 0x96, + 0x12, 0x89, 0xdb, 0xce, 0xec, 0xcc, 0x3e, 0xf3, 0xf1, 0xe4, 0x71, 0x00, 0x4e, 0x31, 0x63, 0xab, + 0x13, 0x1a, 0x27, 0x71, 0xe0, 0xf1, 0x73, 0xd8, 0xec, 0x0f, 0x93, 0x41, 0xda, 0x5d, 0x3d, 0x8e, + 0x47, 0xad, 0x7e, 0xdc, 0x8f, 0x5b, 0xe2, 0xb2, 0x9b, 0x9e, 0x08, 0x4b, 0x18, 0xe2, 0x24, 0x93, + 0x48, 0x05, 0xfc, 0x97, 0x43, 0x96, 0x74, 0xf0, 0x43, 0x8a, 0x2c, 0x21, 0x8b, 0x50, 0x7d, 0x8b, + 0x74, 0x78, 0x92, 0x75, 0x90, 0x4d, 0xe2, 0x31, 0x43, 0xb2, 0x04, 0x41, 0x07, 0x47, 0xf1, 0x39, + 0x1e, 0x44, 0x23, 0x9c, 0x7a, 0x6b, 0xf0, 0xdf, 0x66, 0xaf, 0x67, 0xb8, 0x9a, 0x50, 0xd3, 0x03, + 0xc5, 0x7b, 0x41, 0x1d, 0xfe, 0x6d, 0x63, 0xc6, 0x3d, 0x75, 0xe7, 0xbe, 0xb3, 0xb2, 0xd0, 0x51, + 0x26, 0xe9, 0x01, 0xec, 0xe2, 0x58, 0xc5, 0x35, 0x00, 0x0e, 0x23, 0xc6, 0x26, 0x03, 0x1a, 0x31, + 0x15, 0xaa, 0x79, 0x82, 0x65, 0x58, 0xd8, 0x4e, 0xe9, 0x39, 0xbe, 0xc9, 0x26, 0x58, 0x2f, 0x89, + 0xeb, 0xc2, 0xa1, 0xa3, 0xb8, 0x26, 0xca, 0x03, 0xf0, 0x05, 0x8a, 0xac, 0x91, 0x07, 0x6e, 0xf6, + 0x7a, 0x14, 0x19, 0x53, 0xe5, 0xe4, 0x26, 0x79, 0x0a, 0x70, 0x98, 0x76, 0xb5, 0xb2, 0x6f, 0x8e, + 0x0b, 0x02, 0xf0, 0x04, 0x8e, 0xac, 0x41, 0x9c, 0xc9, 0x1e, 0xf8, 0x22, 0x37, 0x07, 0x59, 0x86, + 0x85, 0xc3, 0xb4, 0x7b, 0x36, 0x3c, 0x6e, 0x63, 0x26, 0xd2, 0xcb, 0x9d, 0xc2, 0x71, 0x7b, 0x27, + 0x64, 0x17, 0x6a, 0x7b, 0xa3, 0x49, 0x4c, 0x93, 0xfd, 0xa3, 0xd7, 0x07, 0xb3, 0x0e, 0x27, 0x00, + 0x8f, 0x87, 0xab, 0x9a, 0xf8, 0x99, 0x3c, 0x84, 0xaa, 0x7c, 0x68, 0x86, 0xde, 0x3f, 0x43, 0x45, + 0xc5, 0xce, 0x0c, 0x68, 0x0f, 0xc1, 0xec, 0xcb, 0xb5, 0x37, 0x14, 0xc2, 0x7c, 0x1b, 0xb3, 0xad, + 0x2c, 0x41, 0x56, 0xf7, 0xc4, 0x48, 0xa6, 0x36, 0x79, 0x0f, 0x95, 0xe7, 0x9f, 0xfe, 0x16, 0x5e, + 0xeb, 0xce, 0x35, 0xbb, 0xfb, 0xea, 0x40, 0x55, 0xbd, 0x6f, 0x6f, 0xe8, 0xd4, 0xde, 0xd0, 0x29, + 0x66, 0x02, 0x9e, 0x0e, 0xcf, 0xa3, 0x04, 0xf9, 0x75, 0x49, 0x5c, 0x6b, 0x1e, 0x1b, 0xaa, 0x5c, + 0x90, 0xc3, 0x98, 0x81, 0x67, 0xef, 0x36, 0x05, 0xff, 0x68, 0xd8, 0x9f, 0x99, 0xf2, 0x1a, 0x4c, + 0xe9, 0x66, 0x0e, 0xba, 0x66, 0xff, 0xaf, 0x90, 0xb1, 0xa8, 0x8f, 0xf9, 0x7c, 0x95, 0x49, 0xf6, + 0xa1, 0x2c, 0x61, 0x8b, 0xe6, 0xb9, 0x1d, 0x25, 0x29, 0x45, 0xd5, 0xfc, 0xd4, 0xf1, 0x07, 0x7a, + 0x7e, 0x71, 0xa0, 0xa2, 0xf4, 0x41, 0x76, 0x61, 0xc4, 0x3b, 0xf6, 0xda, 0x8d, 0x9f, 0x42, 0xc9, + 0xfe, 0x29, 0x68, 0x35, 0xbb, 0x46, 0xcd, 0x66, 0x8d, 0x9e, 0x55, 0x23, 0xd9, 0x06, 0xff, 0x45, + 0xc4, 0x06, 0xaa, 0x84, 0x10, 0xe6, 0xb9, 0x99, 0x14, 0x15, 0x4c, 0x6d, 0x1d, 0xa2, 0x64, 0x8e, + 0x85, 0x40, 0x59, 0x3e, 0x92, 0x8f, 0x25, 0x00, 0x8f, 0xdb, 0xf9, 0x0b, 0xe2, 0x4c, 0x36, 0xe0, + 0x9f, 0x36, 0x66, 0x7b, 0x3b, 0xb7, 0xe8, 0x81, 0x26, 0x3d, 0x25, 0x53, 0x7a, 0x9a, 0x50, 0x96, + 0xca, 0x9a, 0x03, 0xdc, 0x03, 0x57, 0xd2, 0xcd, 0x5d, 0xf1, 0xd7, 0xfc, 0x55, 0x21, 0xdc, 0xe2, + 0xf5, 0x0e, 0xf7, 0x93, 0x1d, 0xa8, 0x4e, 0x15, 0x55, 0xd7, 0xce, 0xb1, 0xa9, 0x9d, 0x63, 0x8b, + 0xec, 0x26, 0x35, 0xd6, 0xbe, 0x7b, 0xe0, 0xb5, 0x31, 0x63, 0xc1, 0x9a, 0x10, 0x3e, 0xa4, 0x51, + 0x82, 0x7c, 0xd4, 0x8b, 0x12, 0xaf, 0x50, 0xdc, 0xb0, 0xa6, 0x79, 0xf2, 0x0a, 0x1f, 0x69, 0xdb, + 0x52, 0x19, 0x85, 0x28, 0xaa, 0x0c, 0x5d, 0xea, 0x9a, 0xe0, 0xf1, 0xb5, 0x04, 0xf9, 0x95, 0x46, + 0xef, 0x30, 0xd0, 0x5d, 0x79, 0xf8, 0x3a, 0xcc, 0x49, 0xf6, 0x04, 0xff, 0xcb, 0x5b, 0x83, 0x4b, + 0xe1, 0x92, 0xe9, 0x2c, 0x92, 0xa4, 0x3a, 0xa9, 0x24, 0x43, 0xab, 0x54, 0x92, 0x25, 0x76, 0x1b, + 0x00, 0x85, 0x8e, 0x06, 0x77, 0xf5, 0x18, 0x4d, 0x59, 0x7f, 0x93, 0xbc, 0x0e, 0x73, 0x52, 0x30, + 0x14, 0xa2, 0x21, 0x4f, 0x2a, 0xc9, 0xd2, 0x94, 0xa6, 0xe4, 0x8f, 0x1a, 0x85, 0x46, 0x50, 0x35, + 0x0a, 0x83, 0x6e, 0xcf, 0x00, 0x8a, 0xaf, 0xa5, 0x2a, 0xf0, 0xda, 0xf7, 0x33, 0xac, 0x5f, 0xbf, + 0x28, 0xf0, 0x38, 0xbd, 0x14, 0x9e, 0xf6, 0x11, 0x57, 0x78, 0x06, 0xfb, 0x1e, 0x0b, 0xca, 0x08, + 0xb0, 0xbc, 0x7e, 0x93, 0x6d, 0xe1, 0x1d, 0xcb, 0x2b, 0xf3, 0xb6, 0x9e, 0x5c, 0x5c, 0x36, 0x9c, + 0x1f, 0x97, 0x0d, 0xe7, 0xe7, 0x65, 0xc3, 0xf9, 0x76, 0xd5, 0x70, 0x2e, 0xae, 0x1a, 0xce, 0x3b, + 0xa2, 0xfd, 0xc9, 0x18, 0x64, 0x13, 0xa4, 0x67, 0xd8, 0xeb, 0x23, 0x6d, 0x75, 0x53, 0x4a, 0xe3, + 0x8f, 0x2d, 0xfe, 0x52, 0x77, 0x4e, 0xfc, 0xc1, 0x58, 0xff, 0x15, 0x00, 0x00, 0xff, 0xff, 0xa9, + 0x48, 0xf7, 0x08, 0xa3, 0x08, 0x00, 0x00, +} diff --git a/keys/mock/key.go b/keys/mock/key.go index 83a7f0010aedd4c4646956b3bd5c6d1060425b73..c3e0ca683a2bcfbe219170596f8b244e638b5aff 100644 --- a/keys/mock/key.go +++ b/keys/mock/key.go @@ -5,7 +5,7 @@ import ( "encoding/json" "fmt" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/pkg/errors" @@ -55,7 +55,7 @@ func newKey(name string) (*Key, error) { return key, nil } -func mockKeyFromPrivateAccount(privateAccount acm.PrivateAccount) *Key { +func mockKeyFromPrivateAccount(privateAccount *acm.PrivateAccount) *Key { if privateAccount.PrivateKey().CurveType != crypto.CurveTypeEd25519 { panic(fmt.Errorf("mock key client only supports ed25519 private keys at present")) } diff --git a/keys/mock/key_client.go b/keys/mock/key_client.go index a9c646704cc466b027e0ec344a0962117ec7a410..de5527ef95c1fcde22d9b97008603a7ded65331e 100644 --- a/keys/mock/key_client.go +++ b/keys/mock/key_client.go @@ -17,7 +17,7 @@ package mock import ( "fmt" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys" ) @@ -32,7 +32,7 @@ type KeyClient struct { knownKeys map[crypto.Address]*Key } -func NewKeyClient(privateAccounts ...acm.PrivateAccount) *KeyClient { +func NewKeyClient(privateAccounts ...*acm.PrivateAccount) *KeyClient { client := &KeyClient{ knownKeys: make(map[crypto.Address]*Key), } diff --git a/keys/pbkeys/keys.pb.go b/keys/pbkeys/keys.pb.go deleted file mode 100644 index 320ab041965a12c94c3e0757f810c9602b2f228c..0000000000000000000000000000000000000000 --- a/keys/pbkeys/keys.pb.go +++ /dev/null @@ -1,1492 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: github.com/hyperledger/burrow/keys/pbkeys/keys.proto - -package pbkeys - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type ListRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ListRequest) Reset() { *m = ListRequest{} } -func (m *ListRequest) String() string { return proto.CompactTextString(m) } -func (*ListRequest) ProtoMessage() {} -func (*ListRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{0} -} -func (m *ListRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ListRequest.Unmarshal(m, b) -} -func (m *ListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ListRequest.Marshal(b, m, deterministic) -} -func (dst *ListRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ListRequest.Merge(dst, src) -} -func (m *ListRequest) XXX_Size() int { - return xxx_messageInfo_ListRequest.Size(m) -} -func (m *ListRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ListRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ListRequest proto.InternalMessageInfo - -type VerifyResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *VerifyResponse) Reset() { *m = VerifyResponse{} } -func (m *VerifyResponse) String() string { return proto.CompactTextString(m) } -func (*VerifyResponse) ProtoMessage() {} -func (*VerifyResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{1} -} -func (m *VerifyResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_VerifyResponse.Unmarshal(m, b) -} -func (m *VerifyResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_VerifyResponse.Marshal(b, m, deterministic) -} -func (dst *VerifyResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_VerifyResponse.Merge(dst, src) -} -func (m *VerifyResponse) XXX_Size() int { - return xxx_messageInfo_VerifyResponse.Size(m) -} -func (m *VerifyResponse) XXX_DiscardUnknown() { - xxx_messageInfo_VerifyResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_VerifyResponse proto.InternalMessageInfo - -type RemoveNameResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *RemoveNameResponse) Reset() { *m = RemoveNameResponse{} } -func (m *RemoveNameResponse) String() string { return proto.CompactTextString(m) } -func (*RemoveNameResponse) ProtoMessage() {} -func (*RemoveNameResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{2} -} -func (m *RemoveNameResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RemoveNameResponse.Unmarshal(m, b) -} -func (m *RemoveNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RemoveNameResponse.Marshal(b, m, deterministic) -} -func (dst *RemoveNameResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_RemoveNameResponse.Merge(dst, src) -} -func (m *RemoveNameResponse) XXX_Size() int { - return xxx_messageInfo_RemoveNameResponse.Size(m) -} -func (m *RemoveNameResponse) XXX_DiscardUnknown() { - xxx_messageInfo_RemoveNameResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_RemoveNameResponse proto.InternalMessageInfo - -type AddNameResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AddNameResponse) Reset() { *m = AddNameResponse{} } -func (m *AddNameResponse) String() string { return proto.CompactTextString(m) } -func (*AddNameResponse) ProtoMessage() {} -func (*AddNameResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{3} -} -func (m *AddNameResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AddNameResponse.Unmarshal(m, b) -} -func (m *AddNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AddNameResponse.Marshal(b, m, deterministic) -} -func (dst *AddNameResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_AddNameResponse.Merge(dst, src) -} -func (m *AddNameResponse) XXX_Size() int { - return xxx_messageInfo_AddNameResponse.Size(m) -} -func (m *AddNameResponse) XXX_DiscardUnknown() { - xxx_messageInfo_AddNameResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_AddNameResponse proto.InternalMessageInfo - -type RemoveNameRequest struct { - Keyname string `protobuf:"bytes,1,opt,name=keyname,proto3" json:"keyname,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *RemoveNameRequest) Reset() { *m = RemoveNameRequest{} } -func (m *RemoveNameRequest) String() string { return proto.CompactTextString(m) } -func (*RemoveNameRequest) ProtoMessage() {} -func (*RemoveNameRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{4} -} -func (m *RemoveNameRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_RemoveNameRequest.Unmarshal(m, b) -} -func (m *RemoveNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_RemoveNameRequest.Marshal(b, m, deterministic) -} -func (dst *RemoveNameRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_RemoveNameRequest.Merge(dst, src) -} -func (m *RemoveNameRequest) XXX_Size() int { - return xxx_messageInfo_RemoveNameRequest.Size(m) -} -func (m *RemoveNameRequest) XXX_DiscardUnknown() { - xxx_messageInfo_RemoveNameRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_RemoveNameRequest proto.InternalMessageInfo - -func (m *RemoveNameRequest) GetKeyname() string { - if m != nil { - return m.Keyname - } - return "" -} - -type GenRequest struct { - Passphrase string `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"` - Curvetype string `protobuf:"bytes,2,opt,name=curvetype,proto3" json:"curvetype,omitempty"` - Keyname string `protobuf:"bytes,3,opt,name=keyname,proto3" json:"keyname,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GenRequest) Reset() { *m = GenRequest{} } -func (m *GenRequest) String() string { return proto.CompactTextString(m) } -func (*GenRequest) ProtoMessage() {} -func (*GenRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{5} -} -func (m *GenRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GenRequest.Unmarshal(m, b) -} -func (m *GenRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GenRequest.Marshal(b, m, deterministic) -} -func (dst *GenRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenRequest.Merge(dst, src) -} -func (m *GenRequest) XXX_Size() int { - return xxx_messageInfo_GenRequest.Size(m) -} -func (m *GenRequest) XXX_DiscardUnknown() { - xxx_messageInfo_GenRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_GenRequest proto.InternalMessageInfo - -func (m *GenRequest) GetPassphrase() string { - if m != nil { - return m.Passphrase - } - return "" -} - -func (m *GenRequest) GetCurvetype() string { - if m != nil { - return m.Curvetype - } - return "" -} - -func (m *GenRequest) GetKeyname() string { - if m != nil { - return m.Keyname - } - return "" -} - -type GenResponse struct { - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *GenResponse) Reset() { *m = GenResponse{} } -func (m *GenResponse) String() string { return proto.CompactTextString(m) } -func (*GenResponse) ProtoMessage() {} -func (*GenResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{6} -} -func (m *GenResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_GenResponse.Unmarshal(m, b) -} -func (m *GenResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_GenResponse.Marshal(b, m, deterministic) -} -func (dst *GenResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_GenResponse.Merge(dst, src) -} -func (m *GenResponse) XXX_Size() int { - return xxx_messageInfo_GenResponse.Size(m) -} -func (m *GenResponse) XXX_DiscardUnknown() { - xxx_messageInfo_GenResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_GenResponse proto.InternalMessageInfo - -func (m *GenResponse) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -type PubRequest struct { - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PubRequest) Reset() { *m = PubRequest{} } -func (m *PubRequest) String() string { return proto.CompactTextString(m) } -func (*PubRequest) ProtoMessage() {} -func (*PubRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{7} -} -func (m *PubRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PubRequest.Unmarshal(m, b) -} -func (m *PubRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PubRequest.Marshal(b, m, deterministic) -} -func (dst *PubRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_PubRequest.Merge(dst, src) -} -func (m *PubRequest) XXX_Size() int { - return xxx_messageInfo_PubRequest.Size(m) -} -func (m *PubRequest) XXX_DiscardUnknown() { - xxx_messageInfo_PubRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_PubRequest proto.InternalMessageInfo - -func (m *PubRequest) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func (m *PubRequest) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -type PubResponse struct { - Pub []byte `protobuf:"bytes,1,opt,name=pub,proto3" json:"pub,omitempty"` - Curvetype string `protobuf:"bytes,2,opt,name=curvetype,proto3" json:"curvetype,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PubResponse) Reset() { *m = PubResponse{} } -func (m *PubResponse) String() string { return proto.CompactTextString(m) } -func (*PubResponse) ProtoMessage() {} -func (*PubResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{8} -} -func (m *PubResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PubResponse.Unmarshal(m, b) -} -func (m *PubResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PubResponse.Marshal(b, m, deterministic) -} -func (dst *PubResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_PubResponse.Merge(dst, src) -} -func (m *PubResponse) XXX_Size() int { - return xxx_messageInfo_PubResponse.Size(m) -} -func (m *PubResponse) XXX_DiscardUnknown() { - xxx_messageInfo_PubResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_PubResponse proto.InternalMessageInfo - -func (m *PubResponse) GetPub() []byte { - if m != nil { - return m.Pub - } - return nil -} - -func (m *PubResponse) GetCurvetype() string { - if m != nil { - return m.Curvetype - } - return "" -} - -type ImportJSONRequest struct { - Passphrase string `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"` - JSON string `protobuf:"bytes,2,opt,name=JSON,proto3" json:"JSON,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ImportJSONRequest) Reset() { *m = ImportJSONRequest{} } -func (m *ImportJSONRequest) String() string { return proto.CompactTextString(m) } -func (*ImportJSONRequest) ProtoMessage() {} -func (*ImportJSONRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{9} -} -func (m *ImportJSONRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ImportJSONRequest.Unmarshal(m, b) -} -func (m *ImportJSONRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ImportJSONRequest.Marshal(b, m, deterministic) -} -func (dst *ImportJSONRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ImportJSONRequest.Merge(dst, src) -} -func (m *ImportJSONRequest) XXX_Size() int { - return xxx_messageInfo_ImportJSONRequest.Size(m) -} -func (m *ImportJSONRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ImportJSONRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ImportJSONRequest proto.InternalMessageInfo - -func (m *ImportJSONRequest) GetPassphrase() string { - if m != nil { - return m.Passphrase - } - return "" -} - -func (m *ImportJSONRequest) GetJSON() string { - if m != nil { - return m.JSON - } - return "" -} - -type ImportResponse struct { - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ImportResponse) Reset() { *m = ImportResponse{} } -func (m *ImportResponse) String() string { return proto.CompactTextString(m) } -func (*ImportResponse) ProtoMessage() {} -func (*ImportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{10} -} -func (m *ImportResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ImportResponse.Unmarshal(m, b) -} -func (m *ImportResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ImportResponse.Marshal(b, m, deterministic) -} -func (dst *ImportResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ImportResponse.Merge(dst, src) -} -func (m *ImportResponse) XXX_Size() int { - return xxx_messageInfo_ImportResponse.Size(m) -} -func (m *ImportResponse) XXX_DiscardUnknown() { - xxx_messageInfo_ImportResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_ImportResponse proto.InternalMessageInfo - -func (m *ImportResponse) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -type ImportRequest struct { - Passphrase string `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Curvetype string `protobuf:"bytes,3,opt,name=curvetype,proto3" json:"curvetype,omitempty"` - Keybytes []byte `protobuf:"bytes,4,opt,name=keybytes,proto3" json:"keybytes,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ImportRequest) Reset() { *m = ImportRequest{} } -func (m *ImportRequest) String() string { return proto.CompactTextString(m) } -func (*ImportRequest) ProtoMessage() {} -func (*ImportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{11} -} -func (m *ImportRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ImportRequest.Unmarshal(m, b) -} -func (m *ImportRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ImportRequest.Marshal(b, m, deterministic) -} -func (dst *ImportRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ImportRequest.Merge(dst, src) -} -func (m *ImportRequest) XXX_Size() int { - return xxx_messageInfo_ImportRequest.Size(m) -} -func (m *ImportRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ImportRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ImportRequest proto.InternalMessageInfo - -func (m *ImportRequest) GetPassphrase() string { - if m != nil { - return m.Passphrase - } - return "" -} - -func (m *ImportRequest) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *ImportRequest) GetCurvetype() string { - if m != nil { - return m.Curvetype - } - return "" -} - -func (m *ImportRequest) GetKeybytes() []byte { - if m != nil { - return m.Keybytes - } - return nil -} - -type ExportRequest struct { - Passphrase string `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ExportRequest) Reset() { *m = ExportRequest{} } -func (m *ExportRequest) String() string { return proto.CompactTextString(m) } -func (*ExportRequest) ProtoMessage() {} -func (*ExportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{12} -} -func (m *ExportRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ExportRequest.Unmarshal(m, b) -} -func (m *ExportRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ExportRequest.Marshal(b, m, deterministic) -} -func (dst *ExportRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExportRequest.Merge(dst, src) -} -func (m *ExportRequest) XXX_Size() int { - return xxx_messageInfo_ExportRequest.Size(m) -} -func (m *ExportRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ExportRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ExportRequest proto.InternalMessageInfo - -func (m *ExportRequest) GetPassphrase() string { - if m != nil { - return m.Passphrase - } - return "" -} - -func (m *ExportRequest) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *ExportRequest) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -type ExportResponse struct { - Publickey []byte `protobuf:"bytes,1,opt,name=publickey,proto3" json:"publickey,omitempty"` - Privatekey []byte `protobuf:"bytes,2,opt,name=privatekey,proto3" json:"privatekey,omitempty"` - Address []byte `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` - Curvetype string `protobuf:"bytes,4,opt,name=curvetype,proto3" json:"curvetype,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ExportResponse) Reset() { *m = ExportResponse{} } -func (m *ExportResponse) String() string { return proto.CompactTextString(m) } -func (*ExportResponse) ProtoMessage() {} -func (*ExportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{13} -} -func (m *ExportResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ExportResponse.Unmarshal(m, b) -} -func (m *ExportResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ExportResponse.Marshal(b, m, deterministic) -} -func (dst *ExportResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ExportResponse.Merge(dst, src) -} -func (m *ExportResponse) XXX_Size() int { - return xxx_messageInfo_ExportResponse.Size(m) -} -func (m *ExportResponse) XXX_DiscardUnknown() { - xxx_messageInfo_ExportResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_ExportResponse proto.InternalMessageInfo - -func (m *ExportResponse) GetPublickey() []byte { - if m != nil { - return m.Publickey - } - return nil -} - -func (m *ExportResponse) GetPrivatekey() []byte { - if m != nil { - return m.Privatekey - } - return nil -} - -func (m *ExportResponse) GetAddress() []byte { - if m != nil { - return m.Address - } - return nil -} - -func (m *ExportResponse) GetCurvetype() string { - if m != nil { - return m.Curvetype - } - return "" -} - -type SignRequest struct { - Passphrase string `protobuf:"bytes,1,opt,name=passphrase,proto3" json:"passphrase,omitempty"` - Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` - Message []byte `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignRequest) Reset() { *m = SignRequest{} } -func (m *SignRequest) String() string { return proto.CompactTextString(m) } -func (*SignRequest) ProtoMessage() {} -func (*SignRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{14} -} -func (m *SignRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignRequest.Unmarshal(m, b) -} -func (m *SignRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignRequest.Marshal(b, m, deterministic) -} -func (dst *SignRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignRequest.Merge(dst, src) -} -func (m *SignRequest) XXX_Size() int { - return xxx_messageInfo_SignRequest.Size(m) -} -func (m *SignRequest) XXX_DiscardUnknown() { - xxx_messageInfo_SignRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_SignRequest proto.InternalMessageInfo - -func (m *SignRequest) GetPassphrase() string { - if m != nil { - return m.Passphrase - } - return "" -} - -func (m *SignRequest) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func (m *SignRequest) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *SignRequest) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -type SignResponse struct { - Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` - Curvetype string `protobuf:"bytes,2,opt,name=curvetype,proto3" json:"curvetype,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SignResponse) Reset() { *m = SignResponse{} } -func (m *SignResponse) String() string { return proto.CompactTextString(m) } -func (*SignResponse) ProtoMessage() {} -func (*SignResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{15} -} -func (m *SignResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignResponse.Unmarshal(m, b) -} -func (m *SignResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignResponse.Marshal(b, m, deterministic) -} -func (dst *SignResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignResponse.Merge(dst, src) -} -func (m *SignResponse) XXX_Size() int { - return xxx_messageInfo_SignResponse.Size(m) -} -func (m *SignResponse) XXX_DiscardUnknown() { - xxx_messageInfo_SignResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_SignResponse proto.InternalMessageInfo - -func (m *SignResponse) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -func (m *SignResponse) GetCurvetype() string { - if m != nil { - return m.Curvetype - } - return "" -} - -type VerifyRequest struct { - Curvetype string `protobuf:"bytes,1,opt,name=curvetype,proto3" json:"curvetype,omitempty"` - Pub []byte `protobuf:"bytes,2,opt,name=pub,proto3" json:"pub,omitempty"` - Message []byte `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` - Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *VerifyRequest) Reset() { *m = VerifyRequest{} } -func (m *VerifyRequest) String() string { return proto.CompactTextString(m) } -func (*VerifyRequest) ProtoMessage() {} -func (*VerifyRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{16} -} -func (m *VerifyRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_VerifyRequest.Unmarshal(m, b) -} -func (m *VerifyRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_VerifyRequest.Marshal(b, m, deterministic) -} -func (dst *VerifyRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_VerifyRequest.Merge(dst, src) -} -func (m *VerifyRequest) XXX_Size() int { - return xxx_messageInfo_VerifyRequest.Size(m) -} -func (m *VerifyRequest) XXX_DiscardUnknown() { - xxx_messageInfo_VerifyRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_VerifyRequest proto.InternalMessageInfo - -func (m *VerifyRequest) GetCurvetype() string { - if m != nil { - return m.Curvetype - } - return "" -} - -func (m *VerifyRequest) GetPub() []byte { - if m != nil { - return m.Pub - } - return nil -} - -func (m *VerifyRequest) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -func (m *VerifyRequest) GetSignature() []byte { - if m != nil { - return m.Signature - } - return nil -} - -type HashRequest struct { - Hashtype string `protobuf:"bytes,1,opt,name=hashtype,proto3" json:"hashtype,omitempty"` - Message []byte `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *HashRequest) Reset() { *m = HashRequest{} } -func (m *HashRequest) String() string { return proto.CompactTextString(m) } -func (*HashRequest) ProtoMessage() {} -func (*HashRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{17} -} -func (m *HashRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_HashRequest.Unmarshal(m, b) -} -func (m *HashRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_HashRequest.Marshal(b, m, deterministic) -} -func (dst *HashRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_HashRequest.Merge(dst, src) -} -func (m *HashRequest) XXX_Size() int { - return xxx_messageInfo_HashRequest.Size(m) -} -func (m *HashRequest) XXX_DiscardUnknown() { - xxx_messageInfo_HashRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_HashRequest proto.InternalMessageInfo - -func (m *HashRequest) GetHashtype() string { - if m != nil { - return m.Hashtype - } - return "" -} - -func (m *HashRequest) GetMessage() []byte { - if m != nil { - return m.Message - } - return nil -} - -type HashResponse struct { - Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *HashResponse) Reset() { *m = HashResponse{} } -func (m *HashResponse) String() string { return proto.CompactTextString(m) } -func (*HashResponse) ProtoMessage() {} -func (*HashResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{18} -} -func (m *HashResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_HashResponse.Unmarshal(m, b) -} -func (m *HashResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_HashResponse.Marshal(b, m, deterministic) -} -func (dst *HashResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_HashResponse.Merge(dst, src) -} -func (m *HashResponse) XXX_Size() int { - return xxx_messageInfo_HashResponse.Size(m) -} -func (m *HashResponse) XXX_DiscardUnknown() { - xxx_messageInfo_HashResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_HashResponse proto.InternalMessageInfo - -func (m *HashResponse) GetHash() string { - if m != nil { - return m.Hash - } - return "" -} - -type Key struct { - Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` - Keyname string `protobuf:"bytes,2,opt,name=keyname,proto3" json:"keyname,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Key) Reset() { *m = Key{} } -func (m *Key) String() string { return proto.CompactTextString(m) } -func (*Key) ProtoMessage() {} -func (*Key) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{19} -} -func (m *Key) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Key.Unmarshal(m, b) -} -func (m *Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Key.Marshal(b, m, deterministic) -} -func (dst *Key) XXX_Merge(src proto.Message) { - xxx_messageInfo_Key.Merge(dst, src) -} -func (m *Key) XXX_Size() int { - return xxx_messageInfo_Key.Size(m) -} -func (m *Key) XXX_DiscardUnknown() { - xxx_messageInfo_Key.DiscardUnknown(m) -} - -var xxx_messageInfo_Key proto.InternalMessageInfo - -func (m *Key) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func (m *Key) GetKeyname() string { - if m != nil { - return m.Keyname - } - return "" -} - -type ListResponse struct { - Key []*Key `protobuf:"bytes,1,rep,name=key,proto3" json:"key,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ListResponse) Reset() { *m = ListResponse{} } -func (m *ListResponse) String() string { return proto.CompactTextString(m) } -func (*ListResponse) ProtoMessage() {} -func (*ListResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{20} -} -func (m *ListResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ListResponse.Unmarshal(m, b) -} -func (m *ListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ListResponse.Marshal(b, m, deterministic) -} -func (dst *ListResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ListResponse.Merge(dst, src) -} -func (m *ListResponse) XXX_Size() int { - return xxx_messageInfo_ListResponse.Size(m) -} -func (m *ListResponse) XXX_DiscardUnknown() { - xxx_messageInfo_ListResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_ListResponse proto.InternalMessageInfo - -func (m *ListResponse) GetKey() []*Key { - if m != nil { - return m.Key - } - return nil -} - -type AddNameRequest struct { - Keyname string `protobuf:"bytes,1,opt,name=keyname,proto3" json:"keyname,omitempty"` - Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *AddNameRequest) Reset() { *m = AddNameRequest{} } -func (m *AddNameRequest) String() string { return proto.CompactTextString(m) } -func (*AddNameRequest) ProtoMessage() {} -func (*AddNameRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_keys_ff2cb7ec9ea3671c, []int{21} -} -func (m *AddNameRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_AddNameRequest.Unmarshal(m, b) -} -func (m *AddNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_AddNameRequest.Marshal(b, m, deterministic) -} -func (dst *AddNameRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_AddNameRequest.Merge(dst, src) -} -func (m *AddNameRequest) XXX_Size() int { - return xxx_messageInfo_AddNameRequest.Size(m) -} -func (m *AddNameRequest) XXX_DiscardUnknown() { - xxx_messageInfo_AddNameRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_AddNameRequest proto.InternalMessageInfo - -func (m *AddNameRequest) GetKeyname() string { - if m != nil { - return m.Keyname - } - return "" -} - -func (m *AddNameRequest) GetAddress() string { - if m != nil { - return m.Address - } - return "" -} - -func init() { - proto.RegisterType((*ListRequest)(nil), "pbkeys.ListRequest") - proto.RegisterType((*VerifyResponse)(nil), "pbkeys.VerifyResponse") - proto.RegisterType((*RemoveNameResponse)(nil), "pbkeys.RemoveNameResponse") - proto.RegisterType((*AddNameResponse)(nil), "pbkeys.AddNameResponse") - proto.RegisterType((*RemoveNameRequest)(nil), "pbkeys.RemoveNameRequest") - proto.RegisterType((*GenRequest)(nil), "pbkeys.GenRequest") - proto.RegisterType((*GenResponse)(nil), "pbkeys.GenResponse") - proto.RegisterType((*PubRequest)(nil), "pbkeys.PubRequest") - proto.RegisterType((*PubResponse)(nil), "pbkeys.PubResponse") - proto.RegisterType((*ImportJSONRequest)(nil), "pbkeys.ImportJSONRequest") - proto.RegisterType((*ImportResponse)(nil), "pbkeys.ImportResponse") - proto.RegisterType((*ImportRequest)(nil), "pbkeys.ImportRequest") - proto.RegisterType((*ExportRequest)(nil), "pbkeys.ExportRequest") - proto.RegisterType((*ExportResponse)(nil), "pbkeys.ExportResponse") - proto.RegisterType((*SignRequest)(nil), "pbkeys.SignRequest") - proto.RegisterType((*SignResponse)(nil), "pbkeys.SignResponse") - proto.RegisterType((*VerifyRequest)(nil), "pbkeys.VerifyRequest") - proto.RegisterType((*HashRequest)(nil), "pbkeys.HashRequest") - proto.RegisterType((*HashResponse)(nil), "pbkeys.HashResponse") - proto.RegisterType((*Key)(nil), "pbkeys.Key") - proto.RegisterType((*ListResponse)(nil), "pbkeys.ListResponse") - proto.RegisterType((*AddNameRequest)(nil), "pbkeys.AddNameRequest") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// KeysClient is the client API for Keys service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type KeysClient interface { - GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) - PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) - Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) - Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error) - Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) - ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) - Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) - Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) - RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error) - List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) - AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error) -} - -type keysClient struct { - cc *grpc.ClientConn -} - -func NewKeysClient(cc *grpc.ClientConn) KeysClient { - return &keysClient{cc} -} - -func (c *keysClient) GenerateKey(ctx context.Context, in *GenRequest, opts ...grpc.CallOption) (*GenResponse, error) { - out := new(GenResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/GenerateKey", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) PublicKey(ctx context.Context, in *PubRequest, opts ...grpc.CallOption) (*PubResponse, error) { - out := new(PubResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/PublicKey", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) Sign(ctx context.Context, in *SignRequest, opts ...grpc.CallOption) (*SignResponse, error) { - out := new(SignResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/Sign", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) Verify(ctx context.Context, in *VerifyRequest, opts ...grpc.CallOption) (*VerifyResponse, error) { - out := new(VerifyResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/Verify", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) Import(ctx context.Context, in *ImportRequest, opts ...grpc.CallOption) (*ImportResponse, error) { - out := new(ImportResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/Import", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) { - out := new(ImportResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/ImportJSON", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) { - out := new(ExportResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/Export", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) { - out := new(HashResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/Hash", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) RemoveName(ctx context.Context, in *RemoveNameRequest, opts ...grpc.CallOption) (*RemoveNameResponse, error) { - out := new(RemoveNameResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/RemoveName", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) { - out := new(ListResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/List", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *keysClient) AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*AddNameResponse, error) { - out := new(AddNameResponse) - err := c.cc.Invoke(ctx, "/pbkeys.Keys/AddName", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// KeysServer is the server API for Keys service. -type KeysServer interface { - GenerateKey(context.Context, *GenRequest) (*GenResponse, error) - PublicKey(context.Context, *PubRequest) (*PubResponse, error) - Sign(context.Context, *SignRequest) (*SignResponse, error) - Verify(context.Context, *VerifyRequest) (*VerifyResponse, error) - Import(context.Context, *ImportRequest) (*ImportResponse, error) - ImportJSON(context.Context, *ImportJSONRequest) (*ImportResponse, error) - Export(context.Context, *ExportRequest) (*ExportResponse, error) - Hash(context.Context, *HashRequest) (*HashResponse, error) - RemoveName(context.Context, *RemoveNameRequest) (*RemoveNameResponse, error) - List(context.Context, *ListRequest) (*ListResponse, error) - AddName(context.Context, *AddNameRequest) (*AddNameResponse, error) -} - -func RegisterKeysServer(s *grpc.Server, srv KeysServer) { - s.RegisterService(&_Keys_serviceDesc, srv) -} - -func _Keys_GenerateKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GenRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).GenerateKey(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/GenerateKey", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).GenerateKey(ctx, req.(*GenRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_PublicKey_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PubRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).PublicKey(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/PublicKey", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).PublicKey(ctx, req.(*PubRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_Sign_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SignRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).Sign(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/Sign", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).Sign(ctx, req.(*SignRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_Verify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(VerifyRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).Verify(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/Verify", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).Verify(ctx, req.(*VerifyRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_Import_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ImportRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).Import(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/Import", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).Import(ctx, req.(*ImportRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_ImportJSON_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ImportJSONRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).ImportJSON(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/ImportJSON", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).ImportJSON(ctx, req.(*ImportJSONRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_Export_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ExportRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).Export(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/Export", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).Export(ctx, req.(*ExportRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(HashRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).Hash(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/Hash", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).Hash(ctx, req.(*HashRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_RemoveName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RemoveNameRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).RemoveName(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/RemoveName", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).RemoveName(ctx, req.(*RemoveNameRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).List(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/List", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).List(ctx, req.(*ListRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Keys_AddName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddNameRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(KeysServer).AddName(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/pbkeys.Keys/AddName", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).AddName(ctx, req.(*AddNameRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Keys_serviceDesc = grpc.ServiceDesc{ - ServiceName: "pbkeys.Keys", - HandlerType: (*KeysServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GenerateKey", - Handler: _Keys_GenerateKey_Handler, - }, - { - MethodName: "PublicKey", - Handler: _Keys_PublicKey_Handler, - }, - { - MethodName: "Sign", - Handler: _Keys_Sign_Handler, - }, - { - MethodName: "Verify", - Handler: _Keys_Verify_Handler, - }, - { - MethodName: "Import", - Handler: _Keys_Import_Handler, - }, - { - MethodName: "ImportJSON", - Handler: _Keys_ImportJSON_Handler, - }, - { - MethodName: "Export", - Handler: _Keys_Export_Handler, - }, - { - MethodName: "Hash", - Handler: _Keys_Hash_Handler, - }, - { - MethodName: "RemoveName", - Handler: _Keys_RemoveName_Handler, - }, - { - MethodName: "List", - Handler: _Keys_List_Handler, - }, - { - MethodName: "AddName", - Handler: _Keys_AddName_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "github.com/hyperledger/burrow/keys/pbkeys/keys.proto", -} - -func init() { - proto.RegisterFile("github.com/hyperledger/burrow/keys/pbkeys/keys.proto", fileDescriptor_keys_ff2cb7ec9ea3671c) -} - -var fileDescriptor_keys_ff2cb7ec9ea3671c = []byte{ - // 716 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xd1, 0x6f, 0xd3, 0x3c, - 0x10, 0x57, 0x9b, 0xa8, 0x5b, 0x2f, 0x6d, 0xbf, 0xcd, 0xdf, 0xbe, 0x8f, 0x12, 0x0d, 0x84, 0xfc, - 0xc2, 0x84, 0xb4, 0x56, 0x1b, 0x13, 0x13, 0x93, 0x10, 0x42, 0x03, 0x0d, 0x36, 0x34, 0xa6, 0x4e, - 0xe2, 0x8d, 0x87, 0x64, 0x3d, 0xda, 0xa8, 0x6b, 0x13, 0xec, 0x64, 0x23, 0x0f, 0xbc, 0xf2, 0x47, - 0xf3, 0x84, 0x62, 0xc7, 0xb1, 0x9d, 0x6d, 0xac, 0x12, 0x2f, 0xad, 0x7d, 0xbe, 0xbb, 0xdf, 0xdd, - 0xf9, 0xd7, 0x9f, 0x0b, 0x7b, 0x93, 0x28, 0x9d, 0x66, 0xe1, 0xe0, 0x22, 0x9e, 0x0f, 0xa7, 0x79, - 0x82, 0xec, 0x12, 0xc7, 0x13, 0x64, 0xc3, 0x30, 0x63, 0x2c, 0xbe, 0x1e, 0xce, 0x30, 0xe7, 0xc3, - 0x24, 0x14, 0x5f, 0xc5, 0xc7, 0x20, 0x61, 0x71, 0x1a, 0x93, 0x96, 0x34, 0xd1, 0x2e, 0x78, 0x1f, - 0x23, 0x9e, 0x8e, 0xf0, 0x5b, 0x86, 0x3c, 0xa5, 0x6b, 0xd0, 0xfb, 0x8c, 0x2c, 0xfa, 0x9a, 0x8f, - 0x90, 0x27, 0xf1, 0x82, 0x23, 0xdd, 0x00, 0x32, 0xc2, 0x79, 0x7c, 0x85, 0xa7, 0xc1, 0x1c, 0x2b, - 0xeb, 0x3a, 0xfc, 0xf3, 0x66, 0x3c, 0xb6, 0x4c, 0xdb, 0xb0, 0x6e, 0x3a, 0x8a, 0x7c, 0xa4, 0x0f, - 0x2b, 0x33, 0xcc, 0x17, 0xc1, 0x1c, 0xfb, 0x8d, 0x27, 0x8d, 0xad, 0xf6, 0x48, 0x6d, 0xe9, 0x18, - 0xe0, 0x08, 0x17, 0xca, 0xef, 0x31, 0x40, 0x12, 0x70, 0x9e, 0x4c, 0x59, 0xc0, 0x95, 0xab, 0x61, - 0x21, 0x9b, 0xd0, 0xbe, 0xc8, 0xd8, 0x15, 0xa6, 0x79, 0x82, 0xfd, 0xa6, 0x38, 0xd6, 0x06, 0x13, - 0xc5, 0xb1, 0x51, 0x9e, 0x82, 0x27, 0x50, 0x64, 0x8d, 0x85, 0x63, 0x30, 0x1e, 0x33, 0xe4, 0x5c, - 0x95, 0x53, 0x6e, 0xe9, 0x01, 0xc0, 0x59, 0x16, 0x1a, 0x65, 0xdf, 0xee, 0x47, 0x08, 0xb8, 0x02, - 0x47, 0xd6, 0x20, 0xd6, 0xf4, 0x15, 0x78, 0x22, 0xb6, 0x04, 0x59, 0x03, 0x27, 0xc9, 0x42, 0x11, - 0xd8, 0x19, 0x15, 0xcb, 0x3f, 0x57, 0x4f, 0x8f, 0x60, 0xfd, 0xc3, 0x3c, 0x89, 0x59, 0x7a, 0x7c, - 0xfe, 0xe9, 0x74, 0xd9, 0x81, 0x10, 0x70, 0x0b, 0x77, 0x55, 0x47, 0xb1, 0xa6, 0xcf, 0xa0, 0x27, - 0x13, 0x2d, 0xd1, 0xef, 0x0f, 0xe8, 0x2a, 0xdf, 0xa5, 0x01, 0xeb, 0x8d, 0xdb, 0x7d, 0x39, 0xf5, - 0x5b, 0xf1, 0x61, 0x75, 0x86, 0x79, 0x98, 0xa7, 0xc8, 0xfb, 0xae, 0x18, 0x46, 0xb5, 0xa7, 0x5f, - 0xa0, 0xfb, 0xee, 0xfb, 0xdf, 0xc2, 0x1b, 0xdd, 0x39, 0x76, 0x77, 0x3f, 0x1b, 0xd0, 0x53, 0xf9, - 0xcb, 0x51, 0x6c, 0x42, 0x3b, 0xc9, 0xc2, 0xcb, 0xe8, 0x62, 0x86, 0x79, 0x79, 0x37, 0xda, 0x20, - 0xe0, 0x59, 0x74, 0x15, 0xa4, 0x58, 0x1c, 0x37, 0xc5, 0xb1, 0x61, 0xa9, 0x43, 0x75, 0x34, 0x21, - 0xac, 0x19, 0xb8, 0xf5, 0xbb, 0xcd, 0xc0, 0x3b, 0x8f, 0x26, 0x4b, 0xd3, 0xdc, 0x80, 0x69, 0xde, - 0xce, 0x3b, 0xc7, 0xee, 0x7f, 0x8e, 0x9c, 0x07, 0x13, 0x2c, 0xe7, 0xab, 0xb6, 0xf4, 0x18, 0x3a, - 0x12, 0x56, 0x37, 0xcf, 0xa3, 0xc9, 0x22, 0x48, 0x33, 0x86, 0xaa, 0xf9, 0xca, 0x70, 0x0f, 0x3d, - 0xaf, 0xa1, 0xab, 0x24, 0x41, 0x36, 0x61, 0xb9, 0x37, 0xea, 0xb7, 0x5e, 0xb2, 0xbf, 0xa9, 0xd9, - 0x6f, 0x94, 0xe9, 0x58, 0x65, 0xda, 0x65, 0xb9, 0xb5, 0xb2, 0xe8, 0x21, 0x78, 0xef, 0x03, 0x3e, - 0x55, 0xb0, 0x3e, 0xac, 0x4e, 0x03, 0x3e, 0x35, 0x50, 0xab, 0xbd, 0x09, 0xd1, 0xb4, 0x27, 0x41, - 0xa1, 0x23, 0x93, 0x94, 0x93, 0x20, 0xe0, 0x16, 0x51, 0x65, 0x06, 0xb1, 0xa6, 0x2f, 0xc1, 0x39, - 0xb1, 0xef, 0xb8, 0xf6, 0xa3, 0x37, 0xf4, 0xa5, 0x69, 0xeb, 0xcb, 0x36, 0x74, 0xa4, 0x7c, 0x96, - 0xe9, 0x1f, 0x81, 0x23, 0xf9, 0xe5, 0x6c, 0x79, 0xbb, 0xde, 0x40, 0x8a, 0xec, 0xe0, 0x04, 0xf3, - 0x51, 0x61, 0xa7, 0x6f, 0xa1, 0x57, 0xc9, 0xe6, 0x3d, 0x02, 0x79, 0x37, 0x17, 0x76, 0x7f, 0xb9, - 0xe0, 0x9e, 0x60, 0xce, 0xc9, 0x0b, 0xa1, 0x6e, 0xc8, 0x82, 0x14, 0x8b, 0x06, 0x88, 0xc2, 0xd3, - 0xc2, 0xea, 0xff, 0x6b, 0xd9, 0xca, 0x2a, 0xf7, 0xa0, 0x7d, 0x26, 0xa8, 0x6f, 0x45, 0x69, 0xfd, - 0xd3, 0x51, 0xa6, 0xae, 0xed, 0x80, 0x5b, 0x90, 0x8a, 0x54, 0x87, 0x06, 0xb3, 0xfd, 0x0d, 0xdb, - 0x58, 0x86, 0xec, 0x43, 0x4b, 0x72, 0x87, 0xfc, 0xa7, 0xce, 0x2d, 0x2e, 0xf9, 0xff, 0xd7, 0xcd, - 0x3a, 0x50, 0xca, 0x93, 0x0e, 0xb4, 0xe4, 0x4a, 0x07, 0xd6, 0x14, 0xef, 0x35, 0x80, 0x16, 0x53, - 0xf2, 0xd0, 0xf6, 0x32, 0x04, 0xf6, 0xce, 0x04, 0xfb, 0xd0, 0x92, 0xca, 0xa1, 0x91, 0x2d, 0xa5, - 0xd2, 0x81, 0x35, 0x81, 0xd9, 0x01, 0xb7, 0x60, 0x9a, 0x1e, 0x8f, 0x41, 0x5e, 0x3d, 0x1e, 0x8b, - 0x8c, 0x87, 0x00, 0xfa, 0xc9, 0xd4, 0xc5, 0xde, 0x78, 0x46, 0x7d, 0xff, 0xb6, 0x23, 0x8d, 0x5b, - 0x50, 0x50, 0xe3, 0x1a, 0xef, 0xb9, 0xc6, 0xb5, 0x58, 0x7a, 0x00, 0x2b, 0x25, 0x0d, 0x49, 0xd5, - 0x8d, 0xcd, 0x4b, 0xff, 0xc1, 0x0d, 0xbb, 0x8c, 0x0d, 0x5b, 0xe2, 0xff, 0xc3, 0xf3, 0xdf, 0x01, - 0x00, 0x00, 0xff, 0xff, 0x73, 0x20, 0x9f, 0xdf, 0x77, 0x08, 0x00, 0x00, -} diff --git a/keys/pbkeys/keys.proto b/keys/pbkeys/keys.proto deleted file mode 100644 index b1ceeb4cd3e4c2daf5bd0d7340d7a25043bdb54f..0000000000000000000000000000000000000000 --- a/keys/pbkeys/keys.proto +++ /dev/null @@ -1,131 +0,0 @@ -syntax = "proto3"; - -package pbkeys; - -service Keys { - rpc GenerateKey(GenRequest) returns (GenResponse); - rpc PublicKey(PubRequest) returns (PubResponse); - rpc Sign(SignRequest) returns (SignResponse); - rpc Verify(VerifyRequest) returns (VerifyResponse); - rpc Import(ImportRequest) returns (ImportResponse); - rpc ImportJSON(ImportJSONRequest) returns (ImportResponse); - rpc Export(ExportRequest) returns (ExportResponse); - rpc Hash(HashRequest) returns (HashResponse); - rpc RemoveName(RemoveNameRequest) returns (RemoveNameResponse); - rpc List(ListRequest) returns (ListResponse); - rpc AddName(AddNameRequest) returns (AddNameResponse); -} - -// Some empty types we may define later - -message ListRequest { - -} - -message VerifyResponse { - -} - -message RemoveNameResponse { - -} - -message AddNameResponse { - -} - -message RemoveNameRequest { - string keyname = 1; -} - - -message GenRequest { - string passphrase = 1; - string curvetype = 2; - string keyname = 3; -} - -message GenResponse { - string address = 1; -} - -message PubRequest { - string address = 1; - string name = 2; -} - -message PubResponse { - bytes pub = 1; - string curvetype = 2; -} - -message ImportJSONRequest { - string passphrase = 1; - string JSON = 2; -} - -message ImportResponse { - string address = 1; -} - -message ImportRequest { - string passphrase = 1; - string name = 2; - string curvetype = 3; - bytes keybytes = 4; -} - -message ExportRequest { - string passphrase = 1; - string name = 2; - string address = 3; -} - -message ExportResponse { - bytes publickey = 1; - bytes privatekey = 2; - bytes address = 3; - string curvetype = 4; -} - -message SignRequest { - string passphrase = 1; - string address = 2; - string name = 3; - bytes message = 4; -} - -message SignResponse { - bytes signature = 1; - string curvetype = 2; -} - -message VerifyRequest { - string curvetype = 1; - bytes pub = 2; - bytes message = 3; - bytes signature = 4; -} - -message HashRequest { - string hashtype = 1; - bytes message = 2; -} - -message HashResponse { - string hash = 1; -} - -message Key { - string address = 1; - string keyname = 2; -} - -message ListResponse { - repeated Key key = 1; -} - -message AddNameRequest { - string keyname = 1; - string address = 2; -} diff --git a/keys/server.go b/keys/server.go index 576c819c656fdda11e9286d7bc562f511c825f2a..5613a7b529a90cea442250101c69dd0952eb147d 100644 --- a/keys/server.go +++ b/keys/server.go @@ -9,7 +9,6 @@ import ( "strings" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging" "github.com/tmthrgd/go-hex" "golang.org/x/crypto/ripemd160" @@ -26,15 +25,15 @@ func StartStandAloneServer(keysDir, host, port string, AllowBadFilePermissions b return err } grpcServer := grpc.NewServer() - pbkeys.RegisterKeysServer(grpcServer, NewKeyStore(keysDir, AllowBadFilePermissions, logger)) + RegisterKeysServer(grpcServer, NewKeyStore(keysDir, AllowBadFilePermissions, logger)) return grpcServer.Serve(listen) } //------------------------------------------------------------------------ // handlers -func (k *KeyStore) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbkeys.GenResponse, error) { - curveT, err := crypto.CurveTypeFromString(in.Curvetype) +func (k *KeyStore) GenerateKey(ctx context.Context, in *GenRequest) (*GenResponse, error) { + curveT, err := crypto.CurveTypeFromString(in.CurveType) if err != nil { return nil, err } @@ -45,17 +44,17 @@ func (k *KeyStore) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbk } addrH := key.Address.String() - if in.Keyname != "" { - err = coreNameAdd(k.keysDirPath, in.Keyname, addrH) + if in.KeyName != "" { + err = coreNameAdd(k.keysDirPath, in.KeyName, addrH) if err != nil { return nil, err } } - return &pbkeys.GenResponse{Address: addrH}, nil + return &GenResponse{Address: addrH}, nil } -func (k *KeyStore) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkeys.ExportResponse, error) { +func (k *KeyStore) Export(ctx context.Context, in *ExportRequest) (*ExportResponse, error) { addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) if err != nil { @@ -73,15 +72,15 @@ func (k *KeyStore) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkey return nil, err } - return &pbkeys.ExportResponse{ + return &ExportResponse{ Address: addrB[:], - Curvetype: key.CurveType.String(), + CurveType: key.CurveType.String(), Publickey: key.PublicKey.PublicKey[:], Privatekey: key.PrivateKey.PrivateKey[:], }, nil } -func (k *KeyStore) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys.PubResponse, error) { +func (k *KeyStore) PublicKey(ctx context.Context, in *PubRequest) (*PubResponse, error) { addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) if err != nil { return nil, err @@ -98,10 +97,10 @@ func (k *KeyStore) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkey return nil, err } - return &pbkeys.PubResponse{Curvetype: key.CurveType.String(), Pub: key.Pubkey()}, nil + return &PubResponse{CurveType: key.CurveType.String(), PublicKey: key.Pubkey()}, nil } -func (k *KeyStore) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.SignResponse, error) { +func (k *KeyStore) Sign(ctx context.Context, in *SignRequest) (*SignResponse, error) { addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) if err != nil { return nil, err @@ -119,11 +118,11 @@ func (k *KeyStore) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.Si sig, err := key.Sign(in.GetMessage()) - return &pbkeys.SignResponse{Signature: sig, Curvetype: key.CurveType.String()}, nil + return &SignResponse{Signature: sig, CurveType: key.CurveType.String()}, nil } -func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys.VerifyResponse, error) { - if in.GetPub() == nil { +func (k *KeyStore) Verify(ctx context.Context, in *VerifyRequest) (*VerifyResponse, error) { + if in.GetPublicKey() == nil { return nil, fmt.Errorf("must provide a pubkey") } if in.GetMessage() == nil { @@ -133,7 +132,7 @@ func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkey return nil, fmt.Errorf("must provide a signature") } - curveT, err := crypto.CurveTypeFromString(in.GetCurvetype()) + curveT, err := crypto.CurveTypeFromString(in.GetCurveType()) if err != nil { return nil, err } @@ -141,7 +140,7 @@ func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkey if err != nil { return nil, err } - pubkey, err := crypto.PublicKeyFromBytes(in.GetPub(), curveT) + pubkey, err := crypto.PublicKeyFromBytes(in.GetPublicKey(), curveT) if err != nil { return nil, err } @@ -150,10 +149,10 @@ func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkey return nil, fmt.Errorf("Signature does not match") } - return &pbkeys.VerifyResponse{}, nil + return &VerifyResponse{}, nil } -func (k *KeyStore) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.HashResponse, error) { +func (k *KeyStore) Hash(ctx context.Context, in *HashRequest) (*HashResponse, error) { var hasher hash.Hash switch in.GetHashtype() { case "ripemd160": @@ -167,10 +166,10 @@ func (k *KeyStore) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.Ha hasher.Write(in.GetMessage()) - return &pbkeys.HashResponse{Hash: hex.EncodeUpperToString(hasher.Sum(nil))}, nil + return &HashResponse{Hash: hex.EncodeUpperToString(hasher.Sum(nil))}, nil } -func (k *KeyStore) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest) (*pbkeys.ImportResponse, error) { +func (k *KeyStore) ImportJSON(ctx context.Context, in *ImportJSONRequest) (*ImportResponse, error) { keyJSON := []byte(in.GetJSON()) var err error addr := IsValidKeyJson(keyJSON) @@ -182,15 +181,15 @@ func (k *KeyStore) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest) if err != nil { return nil, err } - return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(addr)}, nil + return &ImportResponse{Address: hex.EncodeUpperToString(addr)}, nil } -func (k *KeyStore) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkeys.ImportResponse, error) { - curveT, err := crypto.CurveTypeFromString(in.GetCurvetype()) +func (k *KeyStore) Import(ctx context.Context, in *ImportRequest) (*ImportResponse, error) { + curveT, err := crypto.CurveTypeFromString(in.GetCurveType()) if err != nil { return nil, err } - key, err := NewKeyFromPriv(curveT, in.GetKeybytes()) + key, err := NewKeyFromPriv(curveT, in.GetKeyBytes()) if err != nil { return nil, err } @@ -205,33 +204,33 @@ func (k *KeyStore) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkey return nil, err } } - return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(key.Address[:])}, nil + return &ImportResponse{Address: hex.EncodeUpperToString(key.Address[:])}, nil } -func (k *KeyStore) List(ctx context.Context, in *pbkeys.ListRequest) (*pbkeys.ListResponse, error) { +func (k *KeyStore) List(ctx context.Context, in *ListRequest) (*ListResponse, error) { names, err := coreNameList(k.keysDirPath) if err != nil { return nil, err } - var list []*pbkeys.Key + var list []*KeyID for name, addr := range names { - list = append(list, &pbkeys.Key{Keyname: name, Address: addr}) + list = append(list, &KeyID{KeyName: name, Address: addr}) } - return &pbkeys.ListResponse{Key: list}, nil + return &ListResponse{Key: list}, nil } -func (k *KeyStore) RemoveName(ctx context.Context, in *pbkeys.RemoveNameRequest) (*pbkeys.RemoveNameResponse, error) { - if in.GetKeyname() == "" { +func (k *KeyStore) RemoveName(ctx context.Context, in *RemoveNameRequest) (*RemoveNameResponse, error) { + if in.GetKeyName() == "" { return nil, fmt.Errorf("please specify a name") } - return &pbkeys.RemoveNameResponse{}, coreNameRm(k.keysDirPath, in.GetKeyname()) + return &RemoveNameResponse{}, coreNameRm(k.keysDirPath, in.GetKeyName()) } -func (k *KeyStore) AddName(ctx context.Context, in *pbkeys.AddNameRequest) (*pbkeys.AddNameResponse, error) { +func (k *KeyStore) AddName(ctx context.Context, in *AddNameRequest) (*AddNameResponse, error) { if in.GetKeyname() == "" { return nil, fmt.Errorf("please specify a name") } @@ -240,5 +239,5 @@ func (k *KeyStore) AddName(ctx context.Context, in *pbkeys.AddNameRequest) (*pbk return nil, fmt.Errorf("please specify an address") } - return &pbkeys.AddNameResponse{}, coreNameAdd(k.keysDirPath, in.GetKeyname(), strings.ToUpper(in.GetAddress())) + return &AddNameResponse{}, coreNameAdd(k.keysDirPath, in.GetKeyname(), strings.ToUpper(in.GetAddress())) } diff --git a/keys/server_test.go b/keys/server_test.go index 5ee1e204f571b3d61781b0ca73ef4b6aaf126761..68ed229b225c1d2a6c3ea5a2104e4b14950ff5fb 100644 --- a/keys/server_test.go +++ b/keys/server_test.go @@ -13,7 +13,6 @@ import ( "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/evm/sha3" - "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging" tm_crypto "github.com/tendermint/go-crypto" "google.golang.org/grpc" @@ -52,7 +51,7 @@ func init() { } } -func grpcKeysClient() pbkeys.KeysClient { +func grpcKeysClient() KeysClient { var opts []grpc.DialOption opts = append(opts, grpc.WithInsecure()) conn, err := grpc.Dial(DefaultHost+":"+TestPort, opts...) @@ -60,7 +59,7 @@ func grpcKeysClient() pbkeys.KeysClient { fmt.Printf("Failed to connect to grpc server: %v\n", err) os.Exit(1) } - return pbkeys.NewKeysClient(conn) + return NewKeysClient(conn) } func checkAddrFromPub(typ string, pub, addr []byte) error { @@ -90,12 +89,12 @@ func testServerKeygenAndPub(t *testing.T, typ string) { c := grpcKeysClient() ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ}) + genresp, err := c.GenerateKey(ctx, &GenRequest{CurveType: typ}) if err != nil { t.Fatal(err) } addr := genresp.Address - resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr}) + resp, err := c.PublicKey(ctx, &PubRequest{Address: addr}) if err != nil { t.Fatal(err) } @@ -103,7 +102,7 @@ func testServerKeygenAndPub(t *testing.T, typ string) { if err != nil { t.Fatal(err) } - if err = checkAddrFromPub(typ, resp.GetPub(), addrB[:]); err != nil { + if err = checkAddrFromPub(typ, resp.GetPublicKey(), addrB[:]); err != nil { t.Fatal(err) } } @@ -118,23 +117,27 @@ func testServerSignAndVerify(t *testing.T, typ string) { c := grpcKeysClient() ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - genresp, err := c.GenerateKey(ctx, &pbkeys.GenRequest{Curvetype: typ}) + genresp, err := c.GenerateKey(ctx, &GenRequest{CurveType: typ}) if err != nil { t.Fatal(err) } addr := genresp.Address - resp, err := c.PublicKey(ctx, &pbkeys.PubRequest{Address: addr}) + resp, err := c.PublicKey(ctx, &PubRequest{Address: addr}) if err != nil { t.Fatal(err) } hash := sha3.Sha3([]byte("the hash of something!")) - sig, err := c.Sign(ctx, &pbkeys.SignRequest{Address: addr, Message: hash}) + sig, err := c.Sign(ctx, &SignRequest{Address: addr, Message: hash}) if err != nil { t.Fatal(err) } - _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Signature: sig.GetSignature(), Pub: resp.GetPub(), Message: hash, Curvetype: typ}) + _, err = c.Verify(ctx, &VerifyRequest{ + Signature: sig.GetSignature(), + PublicKey: resp.GetPublicKey(), + Message: hash, + CurveType: typ}) if err != nil { t.Fatal(err) } @@ -153,7 +156,7 @@ func testServerHash(t *testing.T, typ string) { c := grpcKeysClient() ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.Hash(ctx, &pbkeys.HashRequest{Hashtype: typ, Message: []byte(data)}) + resp, err := c.Hash(ctx, &HashRequest{Hashtype: typ, Message: []byte(data)}) if err != nil { t.Fatal(err) } diff --git a/permission/types/account_permissions.go b/permission/account_permissions.go similarity index 93% rename from permission/types/account_permissions.go rename to permission/account_permissions.go index 91bee5f818dde74fd8f5a351ff84085da6ccbe17..6de0a44312c892bfbe1639caeba610ddb3ba0727 100644 --- a/permission/types/account_permissions.go +++ b/permission/account_permissions.go @@ -1,12 +1,7 @@ -package types +package permission import "github.com/hyperledger/burrow/binary" -type AccountPermissions struct { - Base BasePermissions - Roles []string -} - // Returns true if the role is found func (ap AccountPermissions) HasRole(role string) bool { role = string(binary.RightPadBytes([]byte(role), 32)) diff --git a/permission/types/base_permissions.go b/permission/base_permissions.go similarity index 83% rename from permission/types/base_permissions.go rename to permission/base_permissions.go index 401f46d1225a4589311cfa8472ce52310bbd576c..8aa80cd47607a3ef28a21e4b427aa93ef7d67c13 100644 --- a/permission/types/base_permissions.go +++ b/permission/base_permissions.go @@ -1,16 +1,7 @@ -package types +package permission import "fmt" -// Base chain permissions struct -type BasePermissions struct { - // bit array with "has"/"doesn't have" for each permission - Perms PermFlag - - // bit array with "set"/"not set" for each permission (not-set should fall back to global) - SetBit PermFlag -} - // Gets the permission value. // ErrValueNotSet is returned if the permission's set bits are not all on, // and should be caught by caller so the global permission can be fetched @@ -74,5 +65,3 @@ func (bp BasePermissions) Compose(bpFallthrough BasePermissions) BasePermissions func (bp BasePermissions) String() string { return fmt.Sprintf("Base: %b; Set: %b", bp.Perms, bp.SetBit) } - -//--------------------------------------------------------------------------------------------- diff --git a/permission/types/base_permissions_test.go b/permission/base_permissions_test.go similarity index 99% rename from permission/types/base_permissions_test.go rename to permission/base_permissions_test.go index 700006c45898858406c91bddcd4151b86146cf5f..9d0b8f288b8930e8ed62f42661129293c45d0305 100644 --- a/permission/types/base_permissions_test.go +++ b/permission/base_permissions_test.go @@ -1,4 +1,4 @@ -package types +package permission import ( "strconv" diff --git a/permission/types/errors.go b/permission/errors.go similarity index 98% rename from permission/types/errors.go rename to permission/errors.go index 0b022277e9352561b2fe83a655f750c6a146d21f..316ee913d8be0166990ef52d54bb7f26385582d5 100644 --- a/permission/types/errors.go +++ b/permission/errors.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package types +package permission import ( "fmt" diff --git a/permission/types/perm_flag.go b/permission/perm_flag.go similarity index 99% rename from permission/types/perm_flag.go rename to permission/perm_flag.go index c749aa308b6f3e1b292b0e30cefc4a4030958b24..617aa561fcc425fdff99ffc3e5d84bf0f3fb79c3 100644 --- a/permission/types/perm_flag.go +++ b/permission/perm_flag.go @@ -1,4 +1,4 @@ -package types +package permission import ( "fmt" diff --git a/permission/types/perm_flag_test.go b/permission/perm_flag_test.go similarity index 91% rename from permission/types/perm_flag_test.go rename to permission/perm_flag_test.go index 2ec7a6edb257f51ff897cc7d29151df051706e3a..5d930a7c703809a04adbf4cfe2512249b1490481 100644 --- a/permission/types/perm_flag_test.go +++ b/permission/perm_flag_test.go @@ -1,4 +1,4 @@ -package types +package permission import ( "testing" diff --git a/permission/permission.pb.go b/permission/permission.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..b72986011d0be70e3ed447ac9745961bd7388b3e --- /dev/null +++ b/permission/permission.pb.go @@ -0,0 +1,844 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: permission.proto + +/* + Package permission is a generated protocol buffer package. + + It is generated from these files: + permission.proto + + It has these top-level messages: + AccountPermissions + BasePermissions + PermArgs +*/ +package permission + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" + +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type AccountPermissions struct { + Base BasePermissions `protobuf:"bytes,1,opt,name=Base" json:"Base"` + Roles []string `protobuf:"bytes,2,rep,name=Roles" json:"Roles,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *AccountPermissions) Reset() { *m = AccountPermissions{} } +func (m *AccountPermissions) String() string { return proto.CompactTextString(m) } +func (*AccountPermissions) ProtoMessage() {} +func (*AccountPermissions) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{0} } + +func (m *AccountPermissions) GetBase() BasePermissions { + if m != nil { + return m.Base + } + return BasePermissions{} +} + +func (m *AccountPermissions) GetRoles() []string { + if m != nil { + return m.Roles + } + return nil +} + +func (*AccountPermissions) XXX_MessageName() string { + return "permission.AccountPermissions" +} + +type BasePermissions struct { + Perms PermFlag `protobuf:"varint,1,opt,name=Perms,casttype=PermFlag" json:"Perms"` + SetBit PermFlag `protobuf:"varint,2,opt,name=SetBit,casttype=PermFlag" json:"SetBit"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *BasePermissions) Reset() { *m = BasePermissions{} } +func (*BasePermissions) ProtoMessage() {} +func (*BasePermissions) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{1} } + +func (m *BasePermissions) GetPerms() PermFlag { + if m != nil { + return m.Perms + } + return 0 +} + +func (m *BasePermissions) GetSetBit() PermFlag { + if m != nil { + return m.SetBit + } + return 0 +} + +func (*BasePermissions) XXX_MessageName() string { + return "permission.BasePermissions" +} + +type PermArgs struct { + PermFlag PermFlag `protobuf:"varint,1,opt,name=PermFlag,casttype=PermFlag" json:"PermFlag"` + Address *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"` + Permission *PermFlag `protobuf:"varint,3,opt,name=Permission,casttype=PermFlag" json:"Permission,omitempty"` + Role *string `protobuf:"bytes,4,opt,name=Role" json:"Role,omitempty"` + Value *bool `protobuf:"varint,5,opt,name=Value" json:"Value,omitempty"` +} + +func (m *PermArgs) Reset() { *m = PermArgs{} } +func (*PermArgs) ProtoMessage() {} +func (*PermArgs) Descriptor() ([]byte, []int) { return fileDescriptorPermission, []int{2} } + +func (m *PermArgs) GetPermFlag() PermFlag { + if m != nil { + return m.PermFlag + } + return 0 +} + +func (m *PermArgs) GetPermission() PermFlag { + if m != nil && m.Permission != nil { + return *m.Permission + } + return 0 +} + +func (m *PermArgs) GetRole() string { + if m != nil && m.Role != nil { + return *m.Role + } + return "" +} + +func (m *PermArgs) GetValue() bool { + if m != nil && m.Value != nil { + return *m.Value + } + return false +} + +func (*PermArgs) XXX_MessageName() string { + return "permission.PermArgs" +} +func init() { + proto.RegisterType((*AccountPermissions)(nil), "permission.AccountPermissions") + golang_proto.RegisterType((*AccountPermissions)(nil), "permission.AccountPermissions") + proto.RegisterType((*BasePermissions)(nil), "permission.BasePermissions") + golang_proto.RegisterType((*BasePermissions)(nil), "permission.BasePermissions") + proto.RegisterType((*PermArgs)(nil), "permission.PermArgs") + golang_proto.RegisterType((*PermArgs)(nil), "permission.PermArgs") +} +func (m *AccountPermissions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AccountPermissions) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintPermission(dAtA, i, uint64(m.Base.Size())) + n1, err := m.Base.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + if len(m.Roles) > 0 { + for _, s := range m.Roles { + dAtA[i] = 0x12 + i++ + l = len(s) + for l >= 1<<7 { + dAtA[i] = uint8(uint64(l)&0x7f | 0x80) + l >>= 7 + i++ + } + dAtA[i] = uint8(l) + i++ + i += copy(dAtA[i:], s) + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *BasePermissions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BasePermissions) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0x8 + i++ + i = encodeVarintPermission(dAtA, i, uint64(m.Perms)) + dAtA[i] = 0x10 + i++ + i = encodeVarintPermission(dAtA, i, uint64(m.SetBit)) + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + +func (m *PermArgs) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PermArgs) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0x8 + i++ + i = encodeVarintPermission(dAtA, i, uint64(m.PermFlag)) + if m.Address != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintPermission(dAtA, i, uint64(m.Address.Size())) + n2, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.Permission != nil { + dAtA[i] = 0x18 + i++ + i = encodeVarintPermission(dAtA, i, uint64(*m.Permission)) + } + if m.Role != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintPermission(dAtA, i, uint64(len(*m.Role))) + i += copy(dAtA[i:], *m.Role) + } + if m.Value != nil { + dAtA[i] = 0x28 + i++ + if *m.Value { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + return i, nil +} + +func encodeVarintPermission(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *AccountPermissions) Size() (n int) { + var l int + _ = l + l = m.Base.Size() + n += 1 + l + sovPermission(uint64(l)) + if len(m.Roles) > 0 { + for _, s := range m.Roles { + l = len(s) + n += 1 + l + sovPermission(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *BasePermissions) Size() (n int) { + var l int + _ = l + n += 1 + sovPermission(uint64(m.Perms)) + n += 1 + sovPermission(uint64(m.SetBit)) + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PermArgs) Size() (n int) { + var l int + _ = l + n += 1 + sovPermission(uint64(m.PermFlag)) + if m.Address != nil { + l = m.Address.Size() + n += 1 + l + sovPermission(uint64(l)) + } + if m.Permission != nil { + n += 1 + sovPermission(uint64(*m.Permission)) + } + if m.Role != nil { + l = len(*m.Role) + n += 1 + l + sovPermission(uint64(l)) + } + if m.Value != nil { + n += 2 + } + return n +} + +func sovPermission(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozPermission(x uint64) (n int) { + return sovPermission(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *AccountPermissions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AccountPermissions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AccountPermissions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Base", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPermission + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Base.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Roles", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPermission + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Roles = append(m.Roles, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPermission(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPermission + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BasePermissions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BasePermissions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BasePermissions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Perms", wireType) + } + m.Perms = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Perms |= (PermFlag(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SetBit", wireType) + } + m.SetBit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SetBit |= (PermFlag(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPermission(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPermission + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PermArgs) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PermArgs: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PermArgs: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PermFlag", wireType) + } + m.PermFlag = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PermFlag |= (PermFlag(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPermission + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_hyperledger_burrow_crypto.Address + m.Address = &v + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permission", wireType) + } + var v PermFlag + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (PermFlag(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Permission = &v + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Role", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPermission + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.Role = &s + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPermission + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Value = &b + default: + iNdEx = preIndex + skippy, err := skipPermission(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPermission + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPermission(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPermission + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPermission + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPermission + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthPermission + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPermission + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipPermission(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthPermission = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPermission = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("permission.proto", fileDescriptorPermission) } +func init() { golang_proto.RegisterFile("permission.proto", fileDescriptorPermission) } + +var fileDescriptorPermission = []byte{ + // 351 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0x31, 0x4b, 0xc3, 0x40, + 0x14, 0xee, 0xb5, 0xa9, 0xb6, 0xcf, 0x82, 0xe5, 0x70, 0x08, 0x0a, 0x49, 0xe8, 0x20, 0x19, 0x6a, + 0x22, 0x82, 0x4b, 0x07, 0xa1, 0x19, 0x1c, 0x9c, 0xe4, 0x04, 0x07, 0xb7, 0x34, 0x3d, 0xd3, 0x40, + 0xda, 0x0b, 0x77, 0x17, 0xa4, 0xff, 0xc4, 0x51, 0xff, 0x89, 0x63, 0xc7, 0xce, 0x0e, 0x45, 0x5a, + 0xf0, 0x47, 0x38, 0xc9, 0x5d, 0x6a, 0x1b, 0x85, 0xba, 0xbd, 0xef, 0x7d, 0xdf, 0x7b, 0xdf, 0xbd, + 0xef, 0xa0, 0x9d, 0x51, 0x3e, 0x4e, 0x84, 0x48, 0xd8, 0xc4, 0xcb, 0x38, 0x93, 0x0c, 0xc3, 0xb6, + 0x73, 0x7c, 0x16, 0x27, 0x72, 0x94, 0x0f, 0xbc, 0x88, 0x8d, 0xfd, 0x98, 0xc5, 0xcc, 0xd7, 0x92, + 0x41, 0xfe, 0xa8, 0x91, 0x06, 0xba, 0x2a, 0x46, 0x3b, 0x21, 0xe0, 0x7e, 0x14, 0xb1, 0x7c, 0x22, + 0x6f, 0x37, 0x3b, 0x04, 0xbe, 0x04, 0x23, 0x08, 0x05, 0x35, 0x91, 0x83, 0xdc, 0x83, 0x8b, 0x13, + 0xaf, 0xe4, 0xa8, 0xfa, 0x25, 0x69, 0x60, 0xcc, 0x16, 0x76, 0x85, 0x68, 0x39, 0x3e, 0x82, 0x3a, + 0x61, 0x29, 0x15, 0x66, 0xd5, 0xa9, 0xb9, 0x4d, 0x52, 0x80, 0x4e, 0x02, 0x87, 0x7f, 0x86, 0xf0, + 0x29, 0xd4, 0x15, 0x14, 0xda, 0xc0, 0x08, 0xda, 0x6a, 0xc7, 0xd7, 0xc2, 0x6e, 0xa8, 0xe6, 0x75, + 0x1a, 0xc6, 0xa4, 0xa0, 0xb1, 0x0b, 0x7b, 0x77, 0x54, 0x06, 0x89, 0x34, 0xab, 0x3b, 0x84, 0x6b, + 0xbe, 0x67, 0x3c, 0xbf, 0xd8, 0x95, 0xce, 0x27, 0x02, 0x4d, 0xf5, 0x79, 0x2c, 0x70, 0x17, 0x36, + 0xb2, 0x9d, 0x3e, 0x9b, 0x0a, 0xdf, 0xc0, 0x7e, 0x7f, 0x38, 0xe4, 0x54, 0x08, 0xed, 0xd5, 0x0a, + 0xce, 0xdf, 0x17, 0x76, 0xb7, 0x14, 0xe6, 0x68, 0x9a, 0x51, 0x9e, 0xd2, 0x61, 0x4c, 0xb9, 0x3f, + 0xc8, 0x39, 0x67, 0x4f, 0x7e, 0xc4, 0xa7, 0x99, 0x64, 0xde, 0x7a, 0x8e, 0xfc, 0x2c, 0xc0, 0x5d, + 0x80, 0xed, 0xb5, 0x66, 0x4d, 0x7b, 0xb7, 0x7e, 0xf9, 0x96, 0x78, 0x8c, 0xc1, 0x50, 0x41, 0x99, + 0x86, 0x83, 0xdc, 0x26, 0xd1, 0xb5, 0x4a, 0xf2, 0x3e, 0x4c, 0x73, 0x6a, 0xd6, 0x1d, 0xe4, 0x36, + 0x48, 0x01, 0x7a, 0x0d, 0x75, 0xe4, 0xfc, 0xd5, 0xae, 0x04, 0x57, 0xb3, 0xa5, 0x85, 0xe6, 0x4b, + 0x0b, 0x7d, 0x2c, 0x2d, 0xf4, 0xb6, 0xb2, 0xd0, 0x6c, 0x65, 0xa1, 0x07, 0xf7, 0xff, 0xe7, 0x6e, + 0x7f, 0xf1, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x75, 0xf4, 0x5f, 0xe9, 0x44, 0x02, 0x00, 0x00, +} diff --git a/permission/permissions.go b/permission/permissions.go index 48b5bd9dd3bd2e11353993c8ce96964017a8a75a..3cac17d4e920e050f566011b6cb1c661ba91b446 100644 --- a/permission/permissions.go +++ b/permission/permissions.go @@ -14,26 +14,25 @@ package permission -import ( - "github.com/hyperledger/burrow/permission/types" -) - var ( - ZeroBasePermissions = types.BasePermissions{0, 0} - ZeroAccountPermissions = types.AccountPermissions{ + ZeroBasePermissions = BasePermissions{ + Perms: 0, + SetBit: 0, + } + ZeroAccountPermissions = AccountPermissions{ Base: ZeroBasePermissions, } - DefaultAccountPermissions = types.AccountPermissions{ - Base: types.BasePermissions{ - Perms: types.DefaultPermFlags, - SetBit: types.AllPermFlags, + DefaultAccountPermissions = AccountPermissions{ + Base: BasePermissions{ + Perms: DefaultPermFlags, + SetBit: AllPermFlags, }, Roles: []string{}, } - AllAccountPermissions = types.AccountPermissions{ - Base: types.BasePermissions{ - Perms: types.AllPermFlags, - SetBit: types.AllPermFlags, + AllAccountPermissions = AccountPermissions{ + Base: BasePermissions{ + Perms: AllPermFlags, + SetBit: AllPermFlags, }, Roles: []string{}, } diff --git a/permission/snatives/snatives.go b/permission/snatives.go similarity index 65% rename from permission/snatives/snatives.go rename to permission/snatives.go index 5b47b8af5e894c0b9f5cdf6e26947db2ad398c35..6f3df0a1ec184c07c3f0975a1e3c7693cdb3287a 100644 --- a/permission/snatives/snatives.go +++ b/permission/snatives.go @@ -12,37 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -package snatives +package permission import ( "fmt" "strings" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/permission" - "github.com/hyperledger/burrow/permission/types" - ptypes "github.com/hyperledger/burrow/permission/types" ) //--------------------------------------------------------------------------------------------------- // PermissionsTx.PermArgs interface and argument encoding -type PermArgs struct { - PermFlag types.PermFlag - Address *crypto.Address `json:",omitempty"` - Permission *types.PermFlag `json:",omitempty"` - Role *string `json:",omitempty"` - Value *bool `json:",omitempty"` -} - func (pa PermArgs) String() string { body := make([]string, 0, 5) - body = append(body, fmt.Sprintf("PermFlag: %v", permission.String(pa.PermFlag))) + body = append(body, fmt.Sprintf("PermFlag: %v", String(pa.PermFlag))) if pa.Address != nil { body = append(body, fmt.Sprintf("Address: %s", *pa.Address)) } if pa.Permission != nil { - body = append(body, fmt.Sprintf("Permission: %v", permission.String(*pa.Permission))) + body = append(body, fmt.Sprintf("Permission: %v", String(*pa.Permission))) } if pa.Role != nil { body = append(body, fmt.Sprintf("Role: %s", *pa.Role)) @@ -56,10 +45,10 @@ func (pa PermArgs) String() string { func (pa PermArgs) EnsureValid() error { pf := pa.PermFlag // Address - if pa.Address == nil && pf != ptypes.SetGlobal { + if pa.Address == nil && pf != SetGlobal { return fmt.Errorf("PermArgs for PermFlag %v requires Address to be provided but was nil", pf) } - if pf == ptypes.HasRole || pf == ptypes.AddRole || pf == ptypes.RemoveRole { + if pf == HasRole || pf == AddRole || pf == RemoveRole { // Role if pa.Role == nil { return fmt.Errorf("PermArgs for PermFlag %v requires Role to be provided but was nil", pf) @@ -68,40 +57,40 @@ func (pa PermArgs) EnsureValid() error { } else if pa.Permission == nil { return fmt.Errorf("PermArgs for PermFlag %v requires Permission to be provided but was nil", pf) // Value - } else if (pf == ptypes.SetBase || pf == ptypes.SetGlobal) && pa.Value == nil { + } else if (pf == SetBase || pf == SetGlobal) && pa.Value == nil { return fmt.Errorf("PermArgs for PermFlag %v requires Value to be provided but was nil", pf) } return nil } -func HasBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs { +func HasBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs { return PermArgs{ - PermFlag: ptypes.HasBase, + PermFlag: HasBase, Address: &address, Permission: &permFlag, } } -func SetBaseArgs(address crypto.Address, permFlag types.PermFlag, value bool) PermArgs { +func SetBaseArgs(address crypto.Address, permFlag PermFlag, value bool) PermArgs { return PermArgs{ - PermFlag: ptypes.SetBase, + PermFlag: SetBase, Address: &address, Permission: &permFlag, Value: &value, } } -func UnsetBaseArgs(address crypto.Address, permFlag types.PermFlag) PermArgs { +func UnsetBaseArgs(address crypto.Address, permFlag PermFlag) PermArgs { return PermArgs{ - PermFlag: ptypes.UnsetBase, + PermFlag: UnsetBase, Address: &address, Permission: &permFlag, } } -func SetGlobalArgs(permFlag types.PermFlag, value bool) PermArgs { +func SetGlobalArgs(permFlag PermFlag, value bool) PermArgs { return PermArgs{ - PermFlag: ptypes.SetGlobal, + PermFlag: SetGlobal, Permission: &permFlag, Value: &value, } @@ -109,7 +98,7 @@ func SetGlobalArgs(permFlag types.PermFlag, value bool) PermArgs { func HasRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ - PermFlag: ptypes.HasRole, + PermFlag: HasRole, Address: &address, Role: &role, } @@ -117,7 +106,7 @@ func HasRoleArgs(address crypto.Address, role string) PermArgs { func AddRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ - PermFlag: ptypes.AddRole, + PermFlag: AddRole, Address: &address, Role: &role, } @@ -125,7 +114,7 @@ func AddRoleArgs(address crypto.Address, role string) PermArgs { func RemoveRoleArgs(address crypto.Address, role string) PermArgs { return PermArgs{ - PermFlag: ptypes.RemoveRole, + PermFlag: RemoveRole, Address: &address, Role: &role, } diff --git a/permission/snatives/snatives_test.go b/permission/snatives/snatives_test.go deleted file mode 100644 index 9441ed15eaccc20c7391e3ce4452ec01933ecb4a..0000000000000000000000000000000000000000 --- a/permission/snatives/snatives_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package snatives - -import ( - "testing" - - permission "github.com/hyperledger/burrow/permission/types" - "github.com/stretchr/testify/assert" -) - -func TestPermArgs_String(t *testing.T) { - role := "foo" - value := true - permFlag := permission.AddRole | permission.RemoveRole - permArgs := PermArgs{ - PermFlag: permission.SetBase, - Permission: &permFlag, - Role: &role, - Value: &value, - } - assert.Equal(t, "PermArgs{PermFlag: setBase, Permission: addRole | removeRole, Role: foo, Value: true}", - permArgs.String()) -} diff --git a/permission/util.go b/permission/util.go index 7470b94d90b27ee48b04cf40b67b215c8370f4c2..6f4ba1ebe412695f6e8bb79b265999414f4bd037 100644 --- a/permission/util.go +++ b/permission/util.go @@ -17,8 +17,6 @@ package permission import ( "fmt" "strings" - - "github.com/hyperledger/burrow/permission/types" ) // ConvertMapStringIntToPermissions converts a map of string-bool pairs and a slice of @@ -27,9 +25,9 @@ import ( // will be set in the AccountsPermissions. For all unmentioned permissions the // ZeroBasePermissions is defaulted to. func ConvertPermissionsMapAndRolesToAccountPermissions(permissions map[string]bool, - roles []string) (*types.AccountPermissions, error) { + roles []string) (*AccountPermissions, error) { var err error - accountPermissions := &types.AccountPermissions{} + accountPermissions := &AccountPermissions{} accountPermissions.Base, err = convertPermissionsMapStringIntToBasePermissions(permissions) if err != nil { return nil, err @@ -40,12 +38,12 @@ func ConvertPermissionsMapAndRolesToAccountPermissions(permissions map[string]bo // convertPermissionsMapStringIntToBasePermissions converts a map of string-bool // pairs to BasePermissions. -func convertPermissionsMapStringIntToBasePermissions(permissions map[string]bool) (types.BasePermissions, error) { +func convertPermissionsMapStringIntToBasePermissions(permissions map[string]bool) (BasePermissions, error) { // initialise basePermissions as ZeroBasePermissions basePermissions := ZeroBasePermissions for permissionName, value := range permissions { - permissionsFlag, err := types.PermStringToFlag(permissionName) + permissionsFlag, err := PermStringToFlag(permissionName) if err != nil { return basePermissions, err } @@ -58,12 +56,12 @@ func convertPermissionsMapStringIntToBasePermissions(permissions map[string]bool // Builds a composite BasePermission by creating a PermFlag from permissions strings and // setting them all -func BasePermissionsFromStringList(permissions []string) (types.BasePermissions, error) { +func BasePermissionsFromStringList(permissions []string) (BasePermissions, error) { permFlag, err := PermFlagFromStringList(permissions) if err != nil { return ZeroBasePermissions, err } - return types.BasePermissions{ + return BasePermissions{ Perms: permFlag, SetBit: permFlag, }, nil @@ -71,10 +69,10 @@ func BasePermissionsFromStringList(permissions []string) (types.BasePermissions, // Builds a composite PermFlag by mapping each permission string in permissions to its // flag and composing them with binary or -func PermFlagFromStringList(permissions []string) (types.PermFlag, error) { - var permFlag types.PermFlag +func PermFlagFromStringList(permissions []string) (PermFlag, error) { + var permFlag PermFlag for _, perm := range permissions { - flag, err := types.PermStringToFlag(perm) + flag, err := PermStringToFlag(perm) if err != nil { return permFlag, err } @@ -85,19 +83,19 @@ func PermFlagFromStringList(permissions []string) (types.PermFlag, error) { // Builds a list of set permissions from a BasePermission by creating a list of permissions strings // from the resultant permissions of basePermissions -func BasePermissionsToStringList(basePermissions types.BasePermissions) ([]string, error) { +func BasePermissionsToStringList(basePermissions BasePermissions) ([]string, error) { return PermFlagToStringList(basePermissions.ResultantPerms()) } // Creates a list of individual permission flag strings from a possibly composite PermFlag // by projecting out each bit and adding its permission string if it is set -func PermFlagToStringList(permFlag types.PermFlag) ([]string, error) { - permStrings := make([]string, 0, types.NumPermissions) - if permFlag > types.AllPermFlags { +func PermFlagToStringList(permFlag PermFlag) ([]string, error) { + permStrings := make([]string, 0, NumPermissions) + if permFlag > AllPermFlags { return nil, fmt.Errorf("resultant permission 0b%b is invalid: has permission flag set above top flag 0b%b", - permFlag, types.TopPermFlag) + permFlag, TopPermFlag) } - for i := uint(0); i < types.NumPermissions; i++ { + for i := uint(0); i < NumPermissions; i++ { permFlag := permFlag & (1 << i) if permFlag > 0 { permStrings = append(permStrings, permFlag.String()) @@ -107,18 +105,18 @@ func PermFlagToStringList(permFlag types.PermFlag) ([]string, error) { } // Generates a human readable string from the resultant permissions of basePermission -func BasePermissionsString(basePermissions types.BasePermissions) string { +func BasePermissionsString(basePermissions BasePermissions) string { permStrings, err := BasePermissionsToStringList(basePermissions) if err != nil { - return types.UnknownString + return UnknownString } return strings.Join(permStrings, " | ") } -func String(permFlag types.PermFlag) string { +func String(permFlag PermFlag) string { permStrings, err := PermFlagToStringList(permFlag) if err != nil { - return types.UnknownString + return UnknownString } return strings.Join(permStrings, " | ") } diff --git a/permission/util_test.go b/permission/util_test.go index 780c1651cb91900798536133288d0a8cdfeed134..1055361206e1a36745c7611439cf87f9a049571e 100644 --- a/permission/util_test.go +++ b/permission/util_test.go @@ -3,21 +3,20 @@ package permission import ( "testing" - "github.com/hyperledger/burrow/permission/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestBasePermissionsFromStringList(t *testing.T) { - basePerms, err := BasePermissionsFromStringList([]string{types.HasRoleString, types.CreateContractString, types.SendString}) + basePerms, err := BasePermissionsFromStringList([]string{HasRoleString, CreateContractString, SendString}) require.NoError(t, err) - permFlag := types.HasRole | types.CreateContract | types.Send + permFlag := HasRole | CreateContract | Send assert.Equal(t, permFlag, basePerms.Perms) assert.Equal(t, permFlag, basePerms.SetBit) - basePerms, err = BasePermissionsFromStringList([]string{types.AllString}) + basePerms, err = BasePermissionsFromStringList([]string{AllString}) require.NoError(t, err) - permFlag = types.AllPermFlags + permFlag = AllPermFlags assert.Equal(t, permFlag, basePerms.Perms) assert.Equal(t, permFlag, basePerms.SetBit) @@ -26,27 +25,27 @@ func TestBasePermissionsFromStringList(t *testing.T) { } func TestBasePermissionsToStringList(t *testing.T) { - permStrings, err := BasePermissionsToStringList(allSetBasePermission(types.Root | types.HasRole | types.SetBase | types.Call)) + permStrings, err := BasePermissionsToStringList(allSetBasePermission(Root | HasRole | SetBase | Call)) require.NoError(t, err) assert.Equal(t, []string{"root", "call", "setBase", "hasRole"}, permStrings) - permStrings, err = BasePermissionsToStringList(allSetBasePermission(types.AllPermFlags)) + permStrings, err = BasePermissionsToStringList(allSetBasePermission(AllPermFlags)) require.NoError(t, err) assert.Equal(t, []string{"root", "send", "call", "createContract", "createAccount", "bond", "name", "hasBase", "setBase", "unsetBase", "setGlobal", "hasRole", "addRole", "removeRole"}, permStrings) - permStrings, err = BasePermissionsToStringList(allSetBasePermission(types.AllPermFlags + 1)) + permStrings, err = BasePermissionsToStringList(allSetBasePermission(AllPermFlags + 1)) assert.Error(t, err) } func TestBasePermissionsString(t *testing.T) { - permissionString := BasePermissionsString(allSetBasePermission(types.AllPermFlags &^ types.Root)) + permissionString := BasePermissionsString(allSetBasePermission(AllPermFlags &^ Root)) assert.Equal(t, "send | call | createContract | createAccount | bond | name | hasBase | "+ "setBase | unsetBase | setGlobal | hasRole | addRole | removeRole", permissionString) } -func allSetBasePermission(perms types.PermFlag) types.BasePermissions { - return types.BasePermissions{ +func allSetBasePermission(perms PermFlag) BasePermissions { + return BasePermissions{ Perms: perms, SetBit: perms, } diff --git a/rpc/config.go b/rpc/config.go index 549961f344ea3a77bb77f239fa7090b0afbea01a..ef5095817727fd0b9e2ff7005416516f7b9e35c5 100644 --- a/rpc/config.go +++ b/rpc/config.go @@ -1,9 +1,6 @@ package rpc -import "github.com/hyperledger/burrow/rpc/v0/server" - type RPCConfig struct { - V0 *V0Config `json:",omitempty" toml:",omitempty"` TM *ServerConfig `json:",omitempty" toml:",omitempty"` Profiler *ServerConfig `json:",omitempty" toml:",omitempty"` GRPC *ServerConfig `json:",omitempty" toml:",omitempty"` @@ -15,11 +12,6 @@ type ServerConfig struct { ListenAddress string } -type V0Config struct { - Enabled bool - Server *server.ServerConfig -} - type ProfilerConfig struct { Enabled bool ListenAddress string @@ -40,20 +32,12 @@ type MetricsConfig struct { func DefaultRPCConfig() *RPCConfig { return &RPCConfig{ TM: DefaultTMConfig(), - V0: DefaultV0Config(), Profiler: DefaultProfilerConfig(), GRPC: DefaultGRPCConfig(), Metrics: DefaultMetricsConfig(), } } -func DefaultV0Config() *V0Config { - return &V0Config{ - Enabled: true, - Server: server.DefaultServerConfig(), - } -} - func DefaultTMConfig() *ServerConfig { return &ServerConfig{ Enabled: true, diff --git a/rpc/filters/accounts.go b/rpc/filters/accounts.go deleted file mode 100644 index d1cad4a301e8fb8fa21bb00ab2d1dcbef27cccc0..0000000000000000000000000000000000000000 --- a/rpc/filters/accounts.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package filters - -// Accounts is part of the pipe for BurrowMint and provides the implementation -// for the pipe to call into the BurrowMint application - -import ( - "bytes" - "encoding/hex" - "fmt" - "sync" - - acm "github.com/hyperledger/burrow/account" -) - -// TODO: [Silas] there are various notes about using mempool (which I guess translates to CheckTx cache). We need -// to understand if this is the right thing to do, since we cannot guarantee stability of the check cache it doesn't -// seem like the right thing to do.... -func NewAccountFilterFactory() *FilterFactory { - filterFactory := NewFilterFactory() - - filterFactory.RegisterFilterPool("code", &sync.Pool{ - New: func() interface{} { - return &AccountCodeFilter{} - }, - }) - - filterFactory.RegisterFilterPool("balance", &sync.Pool{ - New: func() interface{} { - return &AccountBalanceFilter{} - }, - }) - - return filterFactory -} - -// Filter for account code. -// Ops: == or != -// Could be used to match against nil, to see if an account is a contract account. -type AccountCodeFilter struct { - op string - value []byte - match func([]byte, []byte) bool -} - -func (acf *AccountCodeFilter) Configure(fd *FilterData) error { - op := fd.Op - val, err := hex.DecodeString(fd.Value) - - if err != nil { - return fmt.Errorf("Wrong value type.") - } - if op == "==" { - acf.match = func(a, b []byte) bool { - return bytes.Equal(a, b) - } - } else if op == "!=" { - acf.match = func(a, b []byte) bool { - return !bytes.Equal(a, b) - } - } else { - return fmt.Errorf("Op: " + acf.op + " is not supported for 'code' filtering") - } - acf.op = op - acf.value = val - return nil -} - -func (acf *AccountCodeFilter) Match(v interface{}) bool { - acc, ok := v.(acm.Account) - if !ok { - return false - } - return acf.match(acc.Code(), acf.value) -} - -// Filter for account balance. -// Ops: All -type AccountBalanceFilter struct { - op string - value uint64 - match func(uint64, uint64) bool -} - -func (abf *AccountBalanceFilter) Configure(fd *FilterData) error { - val, err := ParseNumberValue(fd.Value) - if err != nil { - return err - } - match, err2 := GetRangeFilter(fd.Op, "balance") - if err2 != nil { - return err2 - } - abf.match = match - abf.op = fd.Op - abf.value = uint64(val) - return nil -} - -func (abf *AccountBalanceFilter) Match(v interface{}) bool { - acc, ok := v.(acm.Account) - if !ok { - return false - } - return abf.match(acc.Balance(), abf.value) -} diff --git a/rpc/filters/filter.go b/rpc/filters/filter.go deleted file mode 100644 index ae9c2d785def9b45ccfb9baf179eb980b4336f58..0000000000000000000000000000000000000000 --- a/rpc/filters/filter.go +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package filters - -import ( - "fmt" - "math" - "strconv" - "strings" -) - -// TODO add generic filters for various different kinds of matching. - -// Filters based on fields. -type Filter interface { - Match(v interface{}) bool -} - -// A filter that can be configured with in-data. -type ConfigurableFilter interface { - Filter - Configure(*FilterData) error -} - -// Used to filter. -// Op can be any of the following: -// The usual relative operators: <, >, <=, >=, ==, != (where applicable) -// A range parameter (see: https://help.github.com/articles/search-syntax/) -type FilterData struct { - Field string `json:"field"` - Op string `json:"op"` - Value string `json:"value"` -} - -// Filter made up of many filters. -type CompositeFilter struct { - filters []Filter -} - -func (cf *CompositeFilter) SetData(filters []Filter) { - cf.filters = filters -} - -func (cf *CompositeFilter) Match(v interface{}) bool { - for _, f := range cf.filters { - if !f.Match(v) { - return false - } - } - return true -} - -// Rubberstamps everything. -type MatchAllFilter struct{} - -func (maf *MatchAllFilter) Match(v interface{}) bool { return true } - -// Some standard value parsing functions. - -func ParseNumberValue(value string) (uint64, error) { - var val uint64 - // Check for wildcards. - if value == "min" { - val = 0 - } else if value == "max" { - val = math.MaxUint64 - } else { - tv, err := strconv.ParseUint(value, 10, 64) - - if err != nil { - return 0, fmt.Errorf("Wrong value type.") - } - val = tv - } - return val, nil -} - -// Some standard filtering functions. - -func GetRangeFilter(op, fName string) (func(a, b uint64) bool, error) { - if op == "==" { - return func(a, b uint64) bool { - return a == b - }, nil - } else if op == "!=" { - return func(a, b uint64) bool { - return a != b - }, nil - } else if op == "<=" { - return func(a, b uint64) bool { - return a <= b - }, nil - } else if op == ">=" { - return func(a, b uint64) bool { - return a >= b - }, nil - } else if op == "<" { - return func(a, b uint64) bool { - return a < b - }, nil - } else if op == ">" { - return func(a, b uint64) bool { - return a > b - }, nil - } else { - return nil, fmt.Errorf("Op: " + op + " is not supported for '" + fName + "' filtering") - } -} - -func GetStringFilter(op, fName string) (func(s0, s1 string) bool, error) { - if op == "==" { - return func(s0, s1 string) bool { - return strings.EqualFold(s0, s1) - }, nil - } else if op == "!=" { - return func(s0, s1 string) bool { - return !strings.EqualFold(s0, s1) - }, nil - } else { - return nil, fmt.Errorf("Op: " + op + " is not supported for '" + fName + "' filtering.") - } -} diff --git a/rpc/filters/filter_factory.go b/rpc/filters/filter_factory.go deleted file mode 100644 index 02a4016a939e3b2735bb3f2544fdb56ad54ace86..0000000000000000000000000000000000000000 --- a/rpc/filters/filter_factory.go +++ /dev/null @@ -1,78 +0,0 @@ -package filters - -import ( - "fmt" - "strings" - "sync" -) - -// Used to generate filters based on filter data. -// Keeping separate pools for "edge cases" (Composite and MatchAll) -type FilterFactory struct { - filterPools map[string]*sync.Pool - compositeFilterPool *sync.Pool - matchAllFilterPool *sync.Pool -} - -func NewFilterFactory() *FilterFactory { - aff := &FilterFactory{} - // Match all. - aff.matchAllFilterPool = &sync.Pool{ - New: func() interface{} { - return &MatchAllFilter{} - }, - } - // Composite. - aff.compositeFilterPool = &sync.Pool{ - New: func() interface{} { - return &CompositeFilter{} - }, - } - // Regular. - aff.filterPools = make(map[string]*sync.Pool) - - return aff -} - -func (ff *FilterFactory) RegisterFilterPool(fieldName string, pool *sync.Pool) { - ff.filterPools[strings.ToLower(fieldName)] = pool -} - -// Creates a new filter given the input data array. If the array is zero length or nil, an empty -// filter will be returned that returns true on all matches. If the array is of size 1, a regular -// filter is returned, otherwise a CompositeFieldFilter is returned, which is a special filter that -// contains a number of other filters. It implements AccountFieldFilter, and will match an account -// only if all the sub-filters matches. -func (ff *FilterFactory) NewFilter(fdArr []*FilterData) (Filter, error) { - - if len(fdArr) == 0 { - return &MatchAllFilter{}, nil - } - if len(fdArr) == 1 { - return ff.newSingleFilter(fdArr[0]) - } - filters := []Filter{} - for _, fd := range fdArr { - f, err := ff.newSingleFilter(fd) - if err != nil { - return nil, err - } - filters = append(filters, f) - } - cf := ff.compositeFilterPool.Get().(*CompositeFilter) - cf.filters = filters - return cf, nil -} - -func (ff *FilterFactory) newSingleFilter(fd *FilterData) (ConfigurableFilter, error) { - fp, ok := ff.filterPools[strings.ToLower(fd.Field)] - if !ok { - return nil, fmt.Errorf("Field is not supported: " + fd.Field) - } - f := fp.Get().(ConfigurableFilter) - err := f.Configure(fd) - if err != nil { - return nil, err - } - return f, nil -} diff --git a/rpc/filters/filter_test.go b/rpc/filters/filter_test.go deleted file mode 100644 index b635c0296e7a1b5c1bf1075c61befe526dcbe532..0000000000000000000000000000000000000000 --- a/rpc/filters/filter_test.go +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package filters - -import ( - "fmt" - "sync" - "testing" - - "github.com/stretchr/testify/suite" -) - -const OBJECTS = 100 - -type FilterableObject struct { - Integer int - String string -} - -// Filter for integer value. -// Ops: All -type IntegerFilter struct { - op string - value uint64 - match func(uint64, uint64) bool -} - -func (this *IntegerFilter) Configure(fd *FilterData) error { - val, err := ParseNumberValue(fd.Value) - if err != nil { - return err - } - match, err2 := GetRangeFilter(fd.Op, "integer") - if err2 != nil { - return err2 - } - this.match = match - this.op = fd.Op - this.value = val - return nil -} - -func (this *IntegerFilter) Match(v interface{}) bool { - fo, ok := v.(FilterableObject) - if !ok { - return false - } - return this.match(uint64(fo.Integer), this.value) -} - -// Filter for integer value. -// Ops: All -type StringFilter struct { - op string - value string - match func(string, string) bool -} - -func (this *StringFilter) Configure(fd *FilterData) error { - match, err := GetStringFilter(fd.Op, "string") - if err != nil { - return err - } - this.match = match - this.op = fd.Op - this.value = fd.Value - return nil -} - -func (this *StringFilter) Match(v interface{}) bool { - fo, ok := v.(FilterableObject) - if !ok { - return false - } - return this.match(fo.String, this.value) -} - -// Test suite -type FilterSuite struct { - suite.Suite - objects []FilterableObject - filterFactory *FilterFactory -} - -func (fs *FilterSuite) SetupSuite() { - objects := make([]FilterableObject, OBJECTS) - - for i := 0; i < 100; i++ { - objects[i] = FilterableObject{i, fmt.Sprintf("string%d", i)} - } - - ff := NewFilterFactory() - - ff.RegisterFilterPool("integer", &sync.Pool{ - New: func() interface{} { - return &IntegerFilter{} - }, - }) - - ff.RegisterFilterPool("string", &sync.Pool{ - New: func() interface{} { - return &StringFilter{} - }, - }) - - fs.objects = objects - fs.filterFactory = ff -} - -func (fs *FilterSuite) TearDownSuite() { - -} - -// ********************************************* Tests ********************************************* - -func (fs *FilterSuite) Test_FilterIntegersEquals() { - fd := &FilterData{"integer", "==", "5"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - break - } - } - fs.Equal(arr, fs.objects[5:6]) -} - -func (fs *FilterSuite) Test_FilterIntegersLT() { - fd := &FilterData{"integer", "<", "5"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - fs.Equal(arr, fs.objects[:5]) -} - -func (fs *FilterSuite) Test_FilterIntegersLTEQ() { - fd := &FilterData{"integer", "<=", "10"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - fs.Equal(arr, fs.objects[:11]) -} - -func (fs *FilterSuite) Test_FilterIntegersGT() { - fd := &FilterData{"integer", ">", "50"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - fs.Equal(arr, fs.objects[51:]) -} - -func (fs *FilterSuite) Test_FilterIntegersRange() { - fd0 := &FilterData{"integer", ">", "5"} - fd1 := &FilterData{"integer", "<", "38"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd0, fd1}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - fs.Equal(arr, fs.objects[6:38]) -} - -func (fs *FilterSuite) Test_FilterIntegersGTEQ() { - fd := &FilterData{"integer", ">=", "77"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - fs.Equal(arr, fs.objects[77:]) -} - -func (fs *FilterSuite) Test_FilterIntegersNEQ() { - fd := &FilterData{"integer", "!=", "50"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - res := make([]FilterableObject, OBJECTS) - copy(res, fs.objects) - res = append(res[:50], res[51:]...) - fs.Equal(arr, res) -} - -func (fs *FilterSuite) Test_FilterStringEquals() { - fd := &FilterData{"string", "==", "string7"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - fs.Equal(arr, fs.objects[7:8]) -} - -func (fs *FilterSuite) Test_FilterStringNEQ() { - fd := &FilterData{"string", "!=", "string50"} - filter, err := fs.filterFactory.NewFilter([]*FilterData{fd}) - fs.NoError(err) - arr := []FilterableObject{} - - for _, o := range fs.objects { - if filter.Match(o) { - arr = append(arr, o) - } - } - res := make([]FilterableObject, OBJECTS) - copy(res, fs.objects) - res = append(res[:50], res[51:]...) - fs.Equal(arr, res) -} - -// ********************************************* Entrypoint ********************************************* - -func TestFilterSuite(t *testing.T) { - suite.Run(t, &FilterSuite{}) -} diff --git a/rpc/filters/namereg.go b/rpc/filters/namereg.go deleted file mode 100644 index 6d822fb177c21221a627d8cb4f8c90211de744a9..0000000000000000000000000000000000000000 --- a/rpc/filters/namereg.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package filters - -import ( - "bytes" - "encoding/hex" - "fmt" - "sync" - - "github.com/hyperledger/burrow/execution/names" -) - -func NewNameRegFilterFactory() *FilterFactory { - filterFactory := NewFilterFactory() - - filterFactory.RegisterFilterPool("name", &sync.Pool{ - New: func() interface{} { - return &NameRegNameFilter{} - }, - }) - - filterFactory.RegisterFilterPool("owner", &sync.Pool{ - New: func() interface{} { - return &NameRegOwnerFilter{} - }, - }) - - filterFactory.RegisterFilterPool("data", &sync.Pool{ - New: func() interface{} { - return &NameRegDataFilter{} - }, - }) - - filterFactory.RegisterFilterPool("expires", &sync.Pool{ - New: func() interface{} { - return &NameRegExpiresFilter{} - }, - }) - - return filterFactory -} - -// Filter for namereg name. This should not be used to get individual entries by name. -// Ops: == or != -type NameRegNameFilter struct { - op string - value string - match func(string, string) bool -} - -func (nrnf *NameRegNameFilter) Configure(fd *FilterData) error { - op := fd.Op - val := fd.Value - - if op == "==" { - nrnf.match = func(a, b string) bool { - return a == b - } - } else if op == "!=" { - nrnf.match = func(a, b string) bool { - return a != b - } - } else { - return fmt.Errorf("Op: " + nrnf.op + " is not supported for 'name' filtering") - } - nrnf.op = op - nrnf.value = val - return nil -} - -func (nrnf *NameRegNameFilter) Match(v interface{}) bool { - nre, ok := v.(*names.Entry) - if !ok { - return false - } - return nrnf.match(nre.Name, nrnf.value) -} - -// Filter for owner. -// Ops: == or != -type NameRegOwnerFilter struct { - op string - value []byte - match func([]byte, []byte) bool -} - -func (nrof *NameRegOwnerFilter) Configure(fd *FilterData) error { - op := fd.Op - val, err := hex.DecodeString(fd.Value) - - if err != nil { - return fmt.Errorf("wrong value type.") - } - if op == "==" { - nrof.match = func(a, b []byte) bool { - return bytes.Equal(a, b) - } - } else if op == "!=" { - nrof.match = func(a, b []byte) bool { - return !bytes.Equal(a, b) - } - } else { - return fmt.Errorf("Op: " + nrof.op + " is not supported for 'owner' filtering") - } - nrof.op = op - nrof.value = val - return nil -} - -func (nrof *NameRegOwnerFilter) Match(v interface{}) bool { - nre, ok := v.(*names.Entry) - if !ok { - return false - } - return nrof.match(nre.Owner.Bytes(), nrof.value) -} - -// Filter for namereg data. Useful for example if you store an ipfs hash and know the hash but need the key. -// Ops: == or != -type NameRegDataFilter struct { - op string - value string - match func(string, string) bool -} - -func (nrdf *NameRegDataFilter) Configure(fd *FilterData) error { - op := fd.Op - val := fd.Value - - if op == "==" { - nrdf.match = func(a, b string) bool { - return a == b - } - } else if op == "!=" { - nrdf.match = func(a, b string) bool { - return a != b - } - } else { - return fmt.Errorf("Op: " + nrdf.op + " is not supported for 'data' filtering") - } - nrdf.op = op - nrdf.value = val - return nil -} - -func (nrdf *NameRegDataFilter) Match(v interface{}) bool { - nre, ok := v.(*names.Entry) - if !ok { - return false - } - return nrdf.match(nre.Data, nrdf.value) -} - -// Filter for expires. -// Ops: All -type NameRegExpiresFilter struct { - op string - value uint64 - match func(uint64, uint64) bool -} - -func (nref *NameRegExpiresFilter) Configure(fd *FilterData) error { - val, err := ParseNumberValue(fd.Value) - if err != nil { - return err - } - match, err2 := GetRangeFilter(fd.Op, "expires") - if err2 != nil { - return err2 - } - nref.match = match - nref.op = fd.Op - nref.value = val - return nil -} - -func (nref *NameRegExpiresFilter) Match(v interface{}) bool { - nre, ok := v.(*names.Entry) - if !ok { - return false - } - return nref.match(nre.Expires, nref.value) -} diff --git a/rpc/grpc.go b/rpc/grpc.go index a30bdad14dd20607bdaaf04f31cee111e349f778..c1a17233c4658e702b2d6beb8060da02b251fd52 100644 --- a/rpc/grpc.go +++ b/rpc/grpc.go @@ -2,7 +2,6 @@ package rpc import ( "fmt" - "runtime/debug" "github.com/hyperledger/burrow/logging" @@ -25,7 +24,7 @@ func unaryInterceptor(logger *logging.Logger) grpc.UnaryServerInterceptor { defer func() { if r := recover(); r != nil { logger.InfoMsg("panic in GRPC unary call", structure.ErrorKey, fmt.Sprintf("%v", r)) - err = fmt.Errorf("panic in GRPC unary call %s: %v", info.FullMethod, r) + err = fmt.Errorf("panic in GRPC unary call %s: %v: %s", info.FullMethod, r, debug.Stack()) } }() logger.TraceMsg("GRPC unary call") diff --git a/rpc/lib/client/ws_client.go b/rpc/lib/client/ws_client.go index e18a6cfb69108d1b7094d7178c0aaa6bdd008f6e..e93f069087b988383c8aeaade16faf076479f4bb 100644 --- a/rpc/lib/client/ws_client.go +++ b/rpc/lib/client/ws_client.go @@ -12,7 +12,7 @@ import ( "github.com/gorilla/websocket" "github.com/hyperledger/burrow/rpc/lib/types" "github.com/pkg/errors" - "github.com/rcrowley/go-metrics" + metrics "github.com/rcrowley/go-metrics" cmn "github.com/tendermint/tmlibs/common" ) diff --git a/rpc/lib/server/http_params.go b/rpc/lib/server/http_params.go index 248e451b2d9fc5d8f61286cb39966a012a3b3122..cd18cd1023b97c2e4ce8b3b05fd92530b9093cc1 100644 --- a/rpc/lib/server/http_params.go +++ b/rpc/lib/server/http_params.go @@ -1,12 +1,12 @@ package server import ( + "encoding/hex" "net/http" "regexp" "strconv" "github.com/pkg/errors" - "github.com/tmthrgd/go-hex" ) var ( diff --git a/rpc/result.go b/rpc/result.go index 44a61c1d7186c87c06b77555f731352c9b66fc8c..af777d9406642929bb03fbe31f34ea858ea07ade 100644 --- a/rpc/result.go +++ b/rpc/result.go @@ -15,17 +15,11 @@ package rpc import ( - "encoding/json" - "fmt" - "time" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/execution/events/pbevents" "github.com/hyperledger/burrow/execution/names" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/txs" @@ -50,25 +44,12 @@ type ResultGetStorage struct { Value binary.HexBytes } -type ResultCall struct { - execution.Call -} - -func (rc ResultCall) MarshalJSON() ([]byte, error) { - return json.Marshal(rc.Call) -} - -func (rc *ResultCall) UnmarshalJSON(data []byte) (err error) { - return json.Unmarshal(data, &rc.Call) -} - type ResultListAccounts struct { BlockHeight uint64 Accounts []*acm.ConcreteAccount } type ResultDumpStorage struct { - StorageRoot binary.HexBytes StorageItems []StorageItem } @@ -188,7 +169,6 @@ type AccountHumanReadable struct { Sequence uint64 Balance uint64 Code []string - StorageRoot string Permissions []string Roles []string } @@ -197,18 +177,6 @@ type ResultGetAccountHumanReadable struct { Account *AccountHumanReadable } -type ResultBroadcastTx struct { - txs.Receipt -} - -func (rbt ResultBroadcastTx) MarshalJSON() ([]byte, error) { - return json.Marshal(rbt.Receipt) -} - -func (rbt ResultBroadcastTx) UnmarshalJSON(data []byte) (err error) { - return json.Unmarshal(data, &rbt.Receipt) -} - type ResultListUnconfirmedTxs struct { NumTxs int Txs []*txs.Envelope @@ -225,67 +193,3 @@ type ResultGenesis struct { type ResultSignTx struct { Tx *txs.Envelope } - -type TendermintEvent struct { - tmTypes.TMEventData -} - -func (te TendermintEvent) MarshalJSON() ([]byte, error) { - return aminoCodec.MarshalJSON(te.TMEventData) -} - -func (te *TendermintEvent) UnmarshalJSON(data []byte) (err error) { - return aminoCodec.UnmarshalJSON(data, &te.TMEventData) -} - -func (te *TendermintEvent) EventDataNewBlock() *tmTypes.EventDataNewBlock { - if te != nil { - eventData, _ := te.TMEventData.(tmTypes.EventDataNewBlock) - return &eventData - } - return nil -} - -type ResultEvent struct { - Event string - Tendermint *TendermintEvent `json:",omitempty"` - Execution *events.Event `json:",omitempty"` -} - -// Map any supported event data element to our ResultEvent sum type -func NewResultEvent(event string, eventData interface{}) (*ResultEvent, error) { - res := &ResultEvent{ - Event: event, - } - switch ed := eventData.(type) { - case tmTypes.TMEventData: - res.Tendermint = &TendermintEvent{ed} - case *events.Event: - res.Execution = ed - default: - return nil, fmt.Errorf("could not map event data of type %T to ResultEvent", eventData) - } - return res, nil -} - -func (re *ResultEvent) GetEvent() (*pbevents.Event, error) { - ev := &pbevents.Event{ - Name: re.Event, - } - if re.Tendermint != nil { - bs, err := json.Marshal(re.Tendermint) - if err != nil { - return nil, err - } - ev.Event = &pbevents.Event_TendermintEventJSON{ - TendermintEventJSON: string(bs), - } - } else if re.Execution != nil { - ev.Event = &pbevents.Event_ExecutionEvent{ - ExecutionEvent: pbevents.GetExecutionEvent(re.Execution), - } - } else { - return nil, fmt.Errorf("ResultEvent is empty") - } - return ev, nil -} diff --git a/rpc/result_test.go b/rpc/result_test.go index ade8a61574da9b417e4b8ac8e3c4b3587f030a8e..ca972de49f7f1357ca6646a7bc7bddc72aba3ca7 100644 --- a/rpc/result_test.go +++ b/rpc/result_test.go @@ -22,12 +22,8 @@ import ( "fmt" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" goCrypto "github.com/tendermint/go-crypto" @@ -36,36 +32,6 @@ import ( "github.com/tendermint/tmlibs/common" ) -func TestResultBroadcastTx(t *testing.T) { - // Make sure these are unpacked as expected - res := ResultBroadcastTx{ - Receipt: txs.Receipt{ - ContractAddress: crypto.Address{0, 2, 3}, - CreatesContract: true, - TxHash: []byte("foo"), - }, - } - - bs, err := json.Marshal(res) - require.NoError(t, err) - assert.Equal(t, `{"TxHash":"666F6F","CreatesContract":true,"ContractAddress":"0002030000000000000000000000000000000000"}`, string(bs)) -} - -func TestListUnconfirmedTxs(t *testing.T) { - res := &ResultListUnconfirmedTxs{ - NumTxs: 3, - Txs: []*txs.Envelope{ - txs.Enclose("testChain", &payload.CallTx{ - Address: &crypto.Address{1}, - }), - }, - } - bs, err := json.Marshal(res) - require.NoError(t, err) - assert.Equal(t, "{\"NumTxs\":3,\"Txs\":[{\"Signatories\":null,\"Tx\":{\"ChainID\":\"testChain\",\"Type\":\"CallTx\",\"Payload\":{\"Input\":null,\"Address\":\"0100000000000000000000000000000000000000\",\"GasLimit\":0,\"Fee\":0}}}]}", - string(bs)) -} - func TestResultListAccounts(t *testing.T) { concreteAcc := acm.AsConcreteAccount(acm.FromAddressable( acm.GeneratePrivateAccountFromSecret("Super Semi Secret"))) @@ -83,56 +49,6 @@ func TestResultListAccounts(t *testing.T) { assert.Equal(t, string(bs), string(bsOut)) } -func TestResultCall_MarshalJSON(t *testing.T) { - res := ResultCall{ - Call: execution.Call{ - Return: []byte("hi"), - GasUsed: 1, - }, - } - bs, err := json.Marshal(res) - require.NoError(t, err) - - resOut := new(ResultCall) - json.Unmarshal(bs, resOut) - bsOut, err := json.Marshal(resOut) - require.NoError(t, err) - assert.Equal(t, string(bs), string(bsOut)) -} - -func TestResultEvent(t *testing.T) { - eventDataNewBlock := tmTypes.EventDataNewBlock{ - Block: &tmTypes.Block{ - Header: &tmTypes.Header{ - ChainID: "chainy", - NumTxs: 30, - }, - LastCommit: &tmTypes.Commit{ - Precommits: []*tmTypes.Vote{ - { - Signature: goCrypto.SignatureEd25519{1, 2, 3}, - }, - }, - }, - }, - } - res := ResultEvent{ - Tendermint: &TendermintEvent{ - TMEventData: &eventDataNewBlock, - }, - } - bs, err := json.Marshal(res) - require.NoError(t, err) - - resOut := new(ResultEvent) - require.NoError(t, json.Unmarshal(bs, resOut)) - bsOut, err := json.Marshal(resOut) - require.NoError(t, err) - assert.Equal(t, string(bs), string(bsOut)) - //fmt.Println(string(bs)) - //fmt.Println(string(bsOut)) -} - func TestResultGetBlock(t *testing.T) { res := &ResultGetBlock{ Block: &Block{&tmTypes.Block{ diff --git a/execution/events/pbevents/blocks.go b/rpc/rpcevents/blocks.go similarity index 72% rename from execution/events/pbevents/blocks.go rename to rpc/rpcevents/blocks.go index b2df626d2783d1b50472d693864bf5d811170b1b..b016207fe8d8ff5d3c295d631b3c53aa40e43e67 100644 --- a/execution/events/pbevents/blocks.go +++ b/rpc/rpcevents/blocks.go @@ -1,18 +1,12 @@ -package pbevents - -import "github.com/hyperledger/burrow/execution/events" +package rpcevents // Get bounds suitable for events.Provider -func (br *BlockRange) Bounds(latestBlockHeight uint64) (startKey, endKey events.Key, streaming bool) { +func (br *BlockRange) Bounds(latestBlockHeight uint64) (startHeight, endHeight uint64, streaming bool) { // End bound is exclusive in state.GetEvents so we increment the height - return br.GetStart().Key(latestBlockHeight), br.GetEnd().Key(latestBlockHeight).IncHeight(), + return br.GetStart().Bound(latestBlockHeight), br.GetEnd().Bound(latestBlockHeight) + 1, br.GetEnd().GetType() == Bound_STREAM } -func (b *Bound) Key(latestBlockHeight uint64) events.Key { - return events.NewKey(b.Bound(latestBlockHeight), 0) -} - func (b *Bound) Bound(latestBlockHeight uint64) uint64 { if b == nil { return latestBlockHeight diff --git a/execution/events/pbevents/blocks_test.go b/rpc/rpcevents/blocks_test.go similarity index 56% rename from execution/events/pbevents/blocks_test.go rename to rpc/rpcevents/blocks_test.go index a7a05b47e1e44e7ecb9b0b2418c17962b90d01f3..e773a84e7ad6f8b3657db25af4eff5bbb937772f 100644 --- a/execution/events/pbevents/blocks_test.go +++ b/rpc/rpcevents/blocks_test.go @@ -1,9 +1,8 @@ -package pbevents +package rpcevents import ( "testing" - "github.com/hyperledger/burrow/execution/events" "github.com/stretchr/testify/assert" ) @@ -11,7 +10,7 @@ func TestBlockRange_Bounds(t *testing.T) { latestHeight := uint64(2344) br := &BlockRange{} start, end, streaming := br.Bounds(latestHeight) - assert.Equal(t, events.NewKey(latestHeight, 0), start) - assert.Equal(t, events.NewKey(latestHeight+1, 0), end) + assert.Equal(t, latestHeight, start) + assert.Equal(t, latestHeight+1, end) assert.False(t, streaming) } diff --git a/rpc/rpcevents/events_server.go b/rpc/rpcevents/events_server.go deleted file mode 100644 index 699edcbff002a9ab6901b735d9c03344ac5f9b78..0000000000000000000000000000000000000000 --- a/rpc/rpcevents/events_server.go +++ /dev/null @@ -1,57 +0,0 @@ -package rpcevents - -import ( - "github.com/hyperledger/burrow/execution/events/pbevents" - "github.com/hyperledger/burrow/rpc" - "golang.org/x/net/context" -) - -type eventServer struct { - subscriptions *rpc.Subscriptions -} - -func NewEventsServer(subscriptions *rpc.Subscriptions) pbevents.EventsServer { - return &eventServer{ - subscriptions: subscriptions, - } -} - -func (es *eventServer) EventPoll(ctx context.Context, param *pbevents.SubIdParam) (*pbevents.PollResponse, error) { - msgs, err := es.subscriptions.Poll(param.GetSubId()) - if err != nil { - return nil, err - } - resp := &pbevents.PollResponse{ - Events: make([]*pbevents.Event, 0, len(msgs)), - } - for _, msg := range msgs { - if resultEvent, ok := msg.(*rpc.ResultEvent); ok { - ev, err := resultEvent.GetEvent() - if err != nil { - return nil, err - } - resp.Events = append(resp.Events, ev) - } - } - return resp, nil -} - -func (es *eventServer) EventSubscribe(ctx context.Context, param *pbevents.EventIdParam) (*pbevents.SubIdParam, error) { - subID, err := es.subscriptions.Add(param.GetEventId()) - if err != nil { - return nil, err - } - return &pbevents.SubIdParam{ - SubId: subID, - }, nil -} - -func (es *eventServer) EventUnsubscribe(ctx context.Context, param *pbevents.SubIdParam) (*pbevents.EventUnSub, error) { - err := es.subscriptions.Remove(param.GetSubId()) - if err != nil { - return nil, err - } - return &pbevents.EventUnSub{ - Result: true, - }, nil -} diff --git a/rpc/rpcevents/execution_events_server.go b/rpc/rpcevents/execution_events_server.go index 57645b8bb4cd6daeba49107ac3ee4b8ccddcfa72..2b042c77f19851db816fe367e0b12775355b5bd4 100644 --- a/rpc/rpcevents/execution_events_server.go +++ b/rpc/rpcevents/execution_events_server.go @@ -1,113 +1,270 @@ package rpcevents import ( + "context" "fmt" - "context" + "io" + "github.com/gogo/protobuf/proto" bcm "github.com/hyperledger/burrow/blockchain" - "github.com/hyperledger/burrow/consensus/tendermint" "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/execution/events/pbevents" - "github.com/tendermint/tendermint/libs/pubsub" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/logging" + "google.golang.org/grpc" ) +const SubscribeBufferSize = 100 + +type Provider interface { + // Get a particular BlockExecution + GetBlock(height uint64) (*exec.BlockExecution, error) + // Get a partiualr TxExecution by hash + GetTx(txHash []byte) (*exec.TxExecution, error) + // Get events between startKey (inclusive) and endKey (exclusive) - i.e. the half open interval [start, end) + GetBlocks(startHeight, endHeight uint64, consumer func(*exec.BlockExecution) (stop bool)) (stopped bool, err error) +} + type executionEventsServer struct { - eventsProvider events.Provider - emitter event.Emitter + eventsProvider Provider + subscribable event.Subscribable tip bcm.TipInfo + logger *logging.Logger } -func NewExecutionEventsServer(eventsProvider events.Provider, emitter event.Emitter, - tip bcm.TipInfo) pbevents.ExecutionEventsServer { +func NewExecutionEventsServer(eventsProvider Provider, subscribable event.Subscribable, + tip bcm.TipInfo, logger *logging.Logger) ExecutionEventsServer { return &executionEventsServer{ eventsProvider: eventsProvider, - emitter: emitter, + subscribable: subscribable, tip: tip, + logger: logger.WithScope("NewExecutionEventsServer"), } } -func (ees *executionEventsServer) GetEvents(request *pbevents.GetEventsRequest, - stream pbevents.ExecutionEvents_GetEventsServer) error { +func (ees *executionEventsServer) GetBlock(ctx context.Context, request *GetBlockRequest) (*exec.BlockExecution, error) { + be, err := ees.eventsProvider.GetBlock(request.GetHeight()) + if err != nil { + return nil, err + } + if be != nil { + return be, nil + } + if !request.Wait { + if ees.tip.LastBlockHeight() < request.Height { + return nil, fmt.Errorf("block at height %v not yet produced (last block height: %v)", + request.Height, ees.tip.LastBlockHeight()) + } + return nil, fmt.Errorf("block at height %v not found in state but should have been! (last block height: %v)", + request.Height, ees.tip.LastBlockHeight()) + } + err = ees.streamBlocks(ctx, &BlockRange{End: StreamBound()}, func(block *exec.BlockExecution) error { + if block.Height == request.Height { + be = block + return io.EOF + } + return nil + }) + if err != io.EOF { + return nil, err + } + return be, nil +} - blockRange := request.GetBlockRange() - start, end, streaming := blockRange.Bounds(ees.tip.LastBlockHeight()) +func (ees *executionEventsServer) GetBlocks(request *BlocksRequest, stream ExecutionEvents_GetBlocksServer) error { qry, err := query.NewBuilder(request.Query).Query() if err != nil { - return fmt.Errorf("could not parse event query: %v", err) + return fmt.Errorf("could not parse BlockExecution query: %v", err) + } + return ees.streamBlocks(stream.Context(), request.BlockRange, func(block *exec.BlockExecution) error { + if qry.Matches(block.Tagged()) { + return flush(stream, block) + } + return nil + }) +} + +func (ees *executionEventsServer) GetTx(ctx context.Context, request *GetTxRequest) (*exec.TxExecution, error) { + txe, err := ees.eventsProvider.GetTx(request.TxHash) + if err != nil { + return nil, err + } + if txe != nil { + return txe, nil + } + if !request.Wait { + return nil, fmt.Errorf("transaction with hash %v not found in state", request.TxHash) + } + subID := event.GenSubID() + out, err := ees.subscribable.Subscribe(ctx, subID, exec.QueryForTxExecution(request.TxHash), SubscribeBufferSize) + if err != nil { + return nil, err + } + defer ees.subscribable.UnsubscribeAll(ctx, subID) + for msg := range out { + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + return msg.(*exec.TxExecution), nil + } } + return nil, fmt.Errorf("subscription waiting for tx %v ended prematurely", request.TxHash) +} - if !streaming { - return ees.steamEvents(stream, start, end, 1, qry) +func (ees *executionEventsServer) GetTxs(request *BlocksRequest, stream ExecutionEvents_GetTxsServer) error { + qry, err := query.NewBuilder(request.Query).Query() + if err != nil { + return fmt.Errorf("could not parse TxExecution query: %v", err) } + return ees.streamBlocks(stream.Context(), request.BlockRange, func(block *exec.BlockExecution) error { + txs := filterTxs(block, qry) + if len(txs) > 0 { + response := &GetTxsResponse{ + Height: block.Height, + TxExecutions: txs, + } + return flush(stream, response) + } + return nil + }) +} - // Streaming +func (ees *executionEventsServer) GetEvents(request *BlocksRequest, stream ExecutionEvents_GetEventsServer) error { + qry, err := query.NewBuilder(request.Query).Query() if err != nil { + return fmt.Errorf("could not parse Event query: %v", err) + } + return ees.streamBlocks(stream.Context(), request.BlockRange, func(block *exec.BlockExecution) error { + evs := filterEvents(block, qry) + if len(evs) == 0 { + return nil + } + response := &GetEventsResponse{ + Height: block.Height, + Events: evs, + } + return flush(stream, response) + }) +} + +func (ees *executionEventsServer) streamBlocks(ctx context.Context, blockRange *BlockRange, + consumer func(*exec.BlockExecution) error) error { + + // Converts the bounds to half-open interval needed + start, end, streaming := blockRange.Bounds(ees.tip.LastBlockHeight()) + ees.logger.TraceMsg("Streaming blocks", "start", start, "end", end, "streaming", streaming) + + // Pull blocks from state and receive the upper bound (exclusive) on the what we were able to send + // Set this to start since it will be the start of next streaming batch (if needed) + start, err := ees.iterateBlocks(start, end, consumer) + + // If we are not streaming and all blocks requested were retrieved from state then we are done + if !streaming && start == end { return err } - out, err := tendermint.SubscribeNewBlock(context.Background(), ees.emitter) + // Otherwise we need to begin streaming blocks as they are produced + subID := event.GenSubID() + // Subscribe to BlockExecution events + out, err := ees.subscribable.Subscribe(ctx, subID, exec.QueryForBlockExecutionFromHeight(end), + SubscribeBufferSize) if err != nil { return err } + defer ees.subscribable.UnsubscribeAll(context.Background(), subID) - for newBlock := range out { - if newBlock == nil { - return fmt.Errorf("received non-new-block event when subscribed with query") - } - if newBlock.Block == nil { - return fmt.Errorf("new block contains no block info: %v", newBlock) - } - height := uint64(newBlock.Block.Height) - start = end - end = events.NewKey(height, 0) - err := ees.steamEvents(stream, start, end, 1, qry) - if err != nil { - return err + for msg := range out { + select { + case <-ctx.Done(): + return ctx.Err() + default: + block := msg.(*exec.BlockExecution) + streamEnd := block.Height + + finished := !streaming && streamEnd >= end + if finished { + // Truncate streamEnd to final end to get exactly the blocks we want from state + streamEnd = end + } + if start < streamEnd { + // This implies there are some blocks between the previous batchEnd (now start) and the current BlockExecution that + // we have not emitted so we will pull them from state. This can occur if a block is emitted during/after + // the initial streaming but before we have subscribed to block events or if we spill BlockExecutions + // when streaming them and need to catch up + _, err := ees.iterateBlocks(start, streamEnd, consumer) + if err != nil { + return err + } + } + if finished { + return nil + } + err = consumer(block) + if err != nil { + return err + } + // We've just streamed block so our next start marker is the next block + start = block.Height + 1 } } return nil } -func (ees *executionEventsServer) steamEvents(stream pbevents.ExecutionEvents_GetEventsServer, start, end events.Key, - batchSize uint64, qry pubsub.Query) error { - +// Converts blocks into responses and streams them returning the height one greater than the last seen block +// that can be used as next start point (half-open interval) +func (ees *executionEventsServer) iterateBlocks(start, end uint64, consumer func(*exec.BlockExecution) error) (uint64, error) { var streamErr error - buf := new(pbevents.GetEventsResponse) - - batchStart := start.Height() - _, err := ees.eventsProvider.GetEvents(start, end, func(ev *events.Event) (stop bool) { - if qry.Matches(ev) { - // Start a new batch, flush the last lot - if ev.Header.Index == 0 && (ev.Header.Height-batchStart)%batchSize == 0 { - streamErr = flush(stream, buf) - if streamErr != nil { - return true - } - batchStart = ev.Header.Height - buf = new(pbevents.GetEventsResponse) + var lastHeightSeen uint64 + + _, err := ees.eventsProvider.GetBlocks(start, end, + func(be *exec.BlockExecution) (stop bool) { + lastHeightSeen = be.Height + streamErr = consumer(be) + if streamErr != nil { + return true } - buf.Events = append(buf.Events, pbevents.GetExecutionEvent(ev)) - } - return false - }) + return false + }) + if err != nil { - return err + return 0, err } if streamErr != nil { - return streamErr + return 0, streamErr + } + // Returns the appropriate starting block for the next stream + return lastHeightSeen + 1, nil +} + +func filterTxs(be *exec.BlockExecution, qry query.Query) []*exec.TxExecution { + var txs []*exec.TxExecution + for _, txe := range be.TxExecutions { + if qry.Matches(txe.Tagged()) { + txs = append(txs, txe) + } + } + return txs +} + +func filterEvents(be *exec.BlockExecution, qry query.Query) []*exec.Event { + var evs []*exec.Event + for _, txe := range be.TxExecutions { + for _, ev := range txe.Events { + if qry.Matches(ev.Tagged()) { + evs = append(evs, ev) + } + } } - // Flush any remaining events not filling batchSize many blocks - return flush(stream, buf) + return evs } -func flush(stream pbevents.ExecutionEvents_GetEventsServer, buf *pbevents.GetEventsResponse) error { - if len(buf.Events) > 0 { - err := stream.Send(buf) +func flush(stream grpc.Stream, buf proto.Message) error { + if buf != nil { + err := stream.SendMsg(buf) if err != nil { return err } diff --git a/rpc/rpcevents/integration/events_server_test.go b/rpc/rpcevents/integration/events_server_test.go deleted file mode 100644 index 0e8aebb14b8259ebdd426e9b51ca2eed9a1e1107..0000000000000000000000000000000000000000 --- a/rpc/rpcevents/integration/events_server_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "context" - "testing" - "time" - - "encoding/json" - - "strings" - - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/execution/events/pbevents" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/rpc/test" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - tmTypes "github.com/tendermint/tendermint/types" -) - -const eventWait = 2 * time.Second - -func TestEventSubscribeNewBlock(t *testing.T) { - testEventSubscribe(t, tmTypes.EventNewBlock, nil, func(evs []*pbevents.Event) { - require.True(t, len(evs) > 0, "event poll should return at least 1 event") - tendermintEvent := new(rpc.TendermintEvent) - tendermintEventJSON := evs[0].GetTendermintEventJSON() - require.NoError(t, json.Unmarshal([]byte(tendermintEventJSON), tendermintEvent)) - newBlock, ok := tendermintEvent.TMEventData.(tmTypes.EventDataNewBlock) - require.True(t, ok, "new block event expected") - assert.Equal(t, genesisDoc.ChainID(), newBlock.Block.ChainID) - }) -} - -func TestEventSubscribeCall(t *testing.T) { - cli := test.NewTransactorClient(t) - create := test.CreateContract(t, cli, inputAccount) - address, err := crypto.AddressFromBytes(create.CallData.Callee) - require.NoError(t, err) - testEventSubscribe(t, events.EventStringAccountCall(address), - func() { - t.Logf("Calling contract at: %v", address) - test.CallContract(t, cli, inputAccount, address.Bytes()) - }, - func(evs []*pbevents.Event) { - require.Len(t, evs, test.UpsieDownsieCallCount, "should see 30 recursive call events") - for i, ev := range evs { - assert.Equal(t, uint64(test.UpsieDownsieCallCount-i-1), ev.GetExecutionEvent().GetEventDataCall().GetStackDepth()) - } - }) -} - -func TestEventSubscribeLog(t *testing.T) { - cli := test.NewTransactorClient(t) - create := test.CreateContract(t, cli, inputAccount) - address, err := crypto.AddressFromBytes(create.CallData.Callee) - require.NoError(t, err) - testEventSubscribe(t, events.EventStringLogEvent(address), - func() { - t.Logf("Calling contract at: %v", address) - test.CallContract(t, cli, inputAccount, address.Bytes()) - }, - func(evs []*pbevents.Event) { - require.Len(t, evs, test.UpsieDownsieCallCount-2) - log := evs[0].GetExecutionEvent().GetEventDataLog() - depth := binary.Int64FromWord256(binary.LeftPadWord256(log.Topics[2])) - direction := strings.TrimRight(string(log.Topics[1]), "\x00") - assert.Equal(t, int64(18), depth) - assert.Equal(t, "Upsie!", direction) - }) -} - -func testEventSubscribe(t *testing.T, eventID string, runner func(), eventsCallback func(evs []*pbevents.Event)) { - cli := test.NewEventsClient(t) - t.Logf("Subscribing to event: %s", eventID) - sub, err := cli.EventSubscribe(context.Background(), &pbevents.EventIdParam{ - EventId: eventID, - }) - require.NoError(t, err) - defer cli.EventUnsubscribe(context.Background(), sub) - - if runner != nil { - go runner() - } - - pollCh := make(chan *pbevents.PollResponse) - errCh := make(chan error) - // Catch a single block of events - go func() { - for { - time.Sleep(eventWait) - poll, err := cli.EventPoll(context.Background(), sub) - if err != nil { - errCh <- err - return - } - if len(poll.Events) > 0 { - pollCh <- poll - } - } - }() - //var evs []*pbevents.Event - select { - case err := <-errCh: - require.NoError(t, err, "should be no error from EventPoll") - case poll := <-pollCh: - eventsCallback(poll.Events) - case <-time.After(2 * eventWait): - t.Fatal("timed out waiting for poll event") - } -} diff --git a/rpc/rpcevents/integration/execution_events_server_test.go b/rpc/rpcevents/integration/execution_events_server_test.go deleted file mode 100644 index cdd80b1df22a6c3e48de046f84dc0fd0a21762c0..0000000000000000000000000000000000000000 --- a/rpc/rpcevents/integration/execution_events_server_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "context" - "testing" - - "io" - - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/event/query" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/execution/events/pbevents" - "github.com/hyperledger/burrow/execution/pbtransactor" - "github.com/hyperledger/burrow/rpc/test" - "github.com/hyperledger/burrow/txs/payload" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestExecutionEventsSendStream(t *testing.T) { - request := &pbevents.GetEventsRequest{ - BlockRange: pbevents.NewBlockRange(pbevents.LatestBound(), pbevents.StreamBound()), - } - tcli := test.NewTransactorClient(t) - ecli := test.NewExecutionEventsClient(t) - stream, err := ecli.GetEvents(context.Background(), request) - require.NoError(t, err) - numSends := 1 - for i := 0; i < numSends; i++ { - doSends(t, 2, tcli) - response, err := stream.Recv() - require.NoError(t, err) - require.Len(t, response.Events, 4, "expect multiple events") - assert.Equal(t, payload.TypeSend.String(), response.Events[0].GetHeader().GetTxType()) - assert.Equal(t, payload.TypeSend.String(), response.Events[1].GetHeader().GetTxType()) - } - require.NoError(t, stream.CloseSend()) -} - -func TestExecutionEventsSend(t *testing.T) { - request := &pbevents.GetEventsRequest{ - BlockRange: pbevents.NewBlockRange(pbevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()), - pbevents.AbsoluteBound(300)), - } - numSends := 1100 - responses := testExecutionEventsSend(t, numSends, request) - assert.Equal(t, numSends*2, totalEvents(responses), "should receive and input and output event per send") -} - -func TestExecutionEventsSendFiltered(t *testing.T) { - request := &pbevents.GetEventsRequest{ - BlockRange: pbevents.NewBlockRange(pbevents.AbsoluteBound(kern.Blockchain.LastBlockHeight()), - pbevents.AbsoluteBound(300)), - Query: query.NewBuilder().AndEquals(event.EventTypeKey, events.TypeAccountInput.String()).String(), - } - numSends := 500 - responses := testExecutionEventsSend(t, numSends, request) - assert.Equal(t, numSends, totalEvents(responses), "should receive a single input event per send") -} - -func testExecutionEventsSend(t *testing.T, numSends int, request *pbevents.GetEventsRequest) []*pbevents.GetEventsResponse { - doSends(t, numSends, test.NewTransactorClient(t)) - ecli := test.NewExecutionEventsClient(t) - - evs, err := ecli.GetEvents(context.Background(), request) - require.NoError(t, err) - var responses []*pbevents.GetEventsResponse - for { - resp, err := evs.Recv() - if err != nil { - if err == io.EOF { - break - } - require.NoError(t, err) - } - responses = append(responses, resp) - } - return responses -} - -func doSends(t *testing.T, numSends int, cli pbtransactor.TransactorClient) { - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numSends; i++ { - send, err := cli.Send(context.Background(), &pbtransactor.SendParam{ - InputAccount: inputAccount, - Amount: 2003, - ToAddress: privateAccounts[3].Address().Bytes(), - }) - require.NoError(t, err) - assert.Equal(t, false, send.CreatesContract) - } - require.Equal(t, numSends, <-countCh) -} - -func totalEvents(respones []*pbevents.GetEventsResponse) int { - i := 0 - for _, resp := range respones { - i += len(resp.Events) - } - return i -} diff --git a/rpc/rpcevents/rpcevents.pb.go b/rpc/rpcevents/rpcevents.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..d7b9f93685ed61d709ef8114070953cef1447191 --- /dev/null +++ b/rpc/rpcevents/rpcevents.pb.go @@ -0,0 +1,1838 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rpcevents.proto + +/* + Package rpcevents is a generated protocol buffer package. + + It is generated from these files: + rpcevents.proto + + It has these top-level messages: + GetBlockRequest + GetTxRequest + BlocksRequest + GetEventsResponse + GetTxsResponse + Bound + BlockRange +*/ +package rpcevents + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import exec "github.com/hyperledger/burrow/execution/exec" + +import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" + +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type Bound_BoundType int32 + +const ( + // Index is absolute index of an item + Bound_ABSOLUTE Bound_BoundType = 0 + // Index is an offset relative to last item + Bound_RELATIVE Bound_BoundType = 1 + // The first block + Bound_FIRST Bound_BoundType = 2 + // Ignore provided index and evaluate to latest index + Bound_LATEST Bound_BoundType = 3 + // Ignore provided index and stream new objects as they are generated + Bound_STREAM Bound_BoundType = 4 +) + +var Bound_BoundType_name = map[int32]string{ + 0: "ABSOLUTE", + 1: "RELATIVE", + 2: "FIRST", + 3: "LATEST", + 4: "STREAM", +} +var Bound_BoundType_value = map[string]int32{ + "ABSOLUTE": 0, + "RELATIVE": 1, + "FIRST": 2, + "LATEST": 3, + "STREAM": 4, +} + +func (x Bound_BoundType) String() string { + return proto.EnumName(Bound_BoundType_name, int32(x)) +} +func (Bound_BoundType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{5, 0} } + +type GetBlockRequest struct { + // Height of block required + Height uint64 `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"` + // Whether to wait for the block to become available + Wait bool `protobuf:"varint,2,opt,name=Wait,proto3" json:"Wait,omitempty"` +} + +func (m *GetBlockRequest) Reset() { *m = GetBlockRequest{} } +func (m *GetBlockRequest) String() string { return proto.CompactTextString(m) } +func (*GetBlockRequest) ProtoMessage() {} +func (*GetBlockRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{0} } + +func (m *GetBlockRequest) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *GetBlockRequest) GetWait() bool { + if m != nil { + return m.Wait + } + return false +} + +func (*GetBlockRequest) XXX_MessageName() string { + return "rpcevents.GetBlockRequest" +} + +type GetTxRequest struct { + // Height of block required + TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,1,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"` + // Whether to wait for the block to become available + Wait bool `protobuf:"varint,2,opt,name=Wait,proto3" json:"Wait,omitempty"` +} + +func (m *GetTxRequest) Reset() { *m = GetTxRequest{} } +func (m *GetTxRequest) String() string { return proto.CompactTextString(m) } +func (*GetTxRequest) ProtoMessage() {} +func (*GetTxRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{1} } + +func (m *GetTxRequest) GetWait() bool { + if m != nil { + return m.Wait + } + return false +} + +func (*GetTxRequest) XXX_MessageName() string { + return "rpcevents.GetTxRequest" +} + +type BlocksRequest struct { + BlockRange *BlockRange `protobuf:"bytes,1,opt,name=BlockRange" json:"BlockRange,omitempty"` + // Specify a query on which to match the tags of events. + // Tag | Match type | Values + // ----------------------------------------- + // All events + // ----------------------------------------- + // TxType | String | "UnknownTx", "SendTx", "CallTx", "NameTx", "BondTx", "UnbondTx", "PermissionsTx", "GovernanceTx" + // TxHash | String | bytes + // EventType | String | "CallEvent", "LogEvent", "AccountInputEvent", "AccountOutputEvent" + // EventID | String | string + // Height | Integer | uint64 + // Index | Integer | uint64 + // MessageType | String | Go type name + // ----------------------------------------- + // Log event + // ----------------------------------------- + // Address | String | Address (hex) + // Log<0-4> | String | Word256 (hex) + // Log<0-4>Text | String | string (trimmed) + // ----------------------------------------- + // Call event + // ----------------------------------------- + // Origin | String | Address (hex) + // Callee | String | Address (hex) + // Caller | String | Address (hex) + // Value | Integer | uint64 + // Gas | Integer | uint64 + // StackDepth | Integer | uint64 + // Exception | String | string + // ----------------------------------------- + // Tx event (input/output) + // ----------------------------------------- + // Exception | String | string + // + // For example: + // EventType = 'LogEvent' AND EventID CONTAINS 'bar' AND TxHash = '020304' AND Height >= 34 AND Index < 3 AND Address = 'DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF' + Query string `protobuf:"bytes,2,opt,name=Query,proto3" json:"Query,omitempty"` +} + +func (m *BlocksRequest) Reset() { *m = BlocksRequest{} } +func (m *BlocksRequest) String() string { return proto.CompactTextString(m) } +func (*BlocksRequest) ProtoMessage() {} +func (*BlocksRequest) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{2} } + +func (m *BlocksRequest) GetBlockRange() *BlockRange { + if m != nil { + return m.BlockRange + } + return nil +} + +func (m *BlocksRequest) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +func (*BlocksRequest) XXX_MessageName() string { + return "rpcevents.BlocksRequest" +} + +type GetEventsResponse struct { + Height uint64 `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"` + Events []*exec.Event `protobuf:"bytes,2,rep,name=Events" json:"Events,omitempty"` +} + +func (m *GetEventsResponse) Reset() { *m = GetEventsResponse{} } +func (m *GetEventsResponse) String() string { return proto.CompactTextString(m) } +func (*GetEventsResponse) ProtoMessage() {} +func (*GetEventsResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{3} } + +func (m *GetEventsResponse) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *GetEventsResponse) GetEvents() []*exec.Event { + if m != nil { + return m.Events + } + return nil +} + +func (*GetEventsResponse) XXX_MessageName() string { + return "rpcevents.GetEventsResponse" +} + +type GetTxsResponse struct { + Height uint64 `protobuf:"varint,1,opt,name=Height,proto3" json:"Height,omitempty"` + TxExecutions []*exec.TxExecution `protobuf:"bytes,2,rep,name=TxExecutions" json:"TxExecutions,omitempty"` +} + +func (m *GetTxsResponse) Reset() { *m = GetTxsResponse{} } +func (m *GetTxsResponse) String() string { return proto.CompactTextString(m) } +func (*GetTxsResponse) ProtoMessage() {} +func (*GetTxsResponse) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{4} } + +func (m *GetTxsResponse) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *GetTxsResponse) GetTxExecutions() []*exec.TxExecution { + if m != nil { + return m.TxExecutions + } + return nil +} + +func (*GetTxsResponse) XXX_MessageName() string { + return "rpcevents.GetTxsResponse" +} + +type Bound struct { + Type Bound_BoundType `protobuf:"varint,1,opt,name=Type,proto3,enum=rpcevents.Bound_BoundType" json:"Type,omitempty"` + Index uint64 `protobuf:"varint,2,opt,name=Index,proto3" json:"Index,omitempty"` +} + +func (m *Bound) Reset() { *m = Bound{} } +func (m *Bound) String() string { return proto.CompactTextString(m) } +func (*Bound) ProtoMessage() {} +func (*Bound) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{5} } + +func (m *Bound) GetType() Bound_BoundType { + if m != nil { + return m.Type + } + return Bound_ABSOLUTE +} + +func (m *Bound) GetIndex() uint64 { + if m != nil { + return m.Index + } + return 0 +} + +func (*Bound) XXX_MessageName() string { + return "rpcevents.Bound" +} + +// An inclusive range of blocks to include in output +type BlockRange struct { + // Bounds can be set to: + // absolute: block height + // relative: block height counting back from latest + // latest: latest block when call is processed + // stream: for End keep sending new blocks, for start same as latest + Start *Bound `protobuf:"bytes,1,opt,name=Start" json:"Start,omitempty"` + End *Bound `protobuf:"bytes,2,opt,name=End" json:"End,omitempty"` +} + +func (m *BlockRange) Reset() { *m = BlockRange{} } +func (m *BlockRange) String() string { return proto.CompactTextString(m) } +func (*BlockRange) ProtoMessage() {} +func (*BlockRange) Descriptor() ([]byte, []int) { return fileDescriptorRpcevents, []int{6} } + +func (m *BlockRange) GetStart() *Bound { + if m != nil { + return m.Start + } + return nil +} + +func (m *BlockRange) GetEnd() *Bound { + if m != nil { + return m.End + } + return nil +} + +func (*BlockRange) XXX_MessageName() string { + return "rpcevents.BlockRange" +} +func init() { + proto.RegisterType((*GetBlockRequest)(nil), "rpcevents.GetBlockRequest") + golang_proto.RegisterType((*GetBlockRequest)(nil), "rpcevents.GetBlockRequest") + proto.RegisterType((*GetTxRequest)(nil), "rpcevents.GetTxRequest") + golang_proto.RegisterType((*GetTxRequest)(nil), "rpcevents.GetTxRequest") + proto.RegisterType((*BlocksRequest)(nil), "rpcevents.BlocksRequest") + golang_proto.RegisterType((*BlocksRequest)(nil), "rpcevents.BlocksRequest") + proto.RegisterType((*GetEventsResponse)(nil), "rpcevents.GetEventsResponse") + golang_proto.RegisterType((*GetEventsResponse)(nil), "rpcevents.GetEventsResponse") + proto.RegisterType((*GetTxsResponse)(nil), "rpcevents.GetTxsResponse") + golang_proto.RegisterType((*GetTxsResponse)(nil), "rpcevents.GetTxsResponse") + proto.RegisterType((*Bound)(nil), "rpcevents.Bound") + golang_proto.RegisterType((*Bound)(nil), "rpcevents.Bound") + proto.RegisterType((*BlockRange)(nil), "rpcevents.BlockRange") + golang_proto.RegisterType((*BlockRange)(nil), "rpcevents.BlockRange") + proto.RegisterEnum("rpcevents.Bound_BoundType", Bound_BoundType_name, Bound_BoundType_value) + golang_proto.RegisterEnum("rpcevents.Bound_BoundType", Bound_BoundType_name, Bound_BoundType_value) +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for ExecutionEvents service + +type ExecutionEventsClient interface { + // Get Blockexecution at particular height + GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*exec.BlockExecution, error) + // Get BlockExecutions for a range of blocks + GetBlocks(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetBlocksClient, error) + // Get a particular TxExecution + GetTx(ctx context.Context, in *GetTxRequest, opts ...grpc.CallOption) (*exec.TxExecution, error) + // Get TxExecutions for a range of block + GetTxs(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetTxsClient, error) + // GetEvents provides events streaming one block at a time - that is all events emitted in a particular block + // are guaranteed to be delivered in each GetEventsResponse + GetEvents(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error) +} + +type executionEventsClient struct { + cc *grpc.ClientConn +} + +func NewExecutionEventsClient(cc *grpc.ClientConn) ExecutionEventsClient { + return &executionEventsClient{cc} +} + +func (c *executionEventsClient) GetBlock(ctx context.Context, in *GetBlockRequest, opts ...grpc.CallOption) (*exec.BlockExecution, error) { + out := new(exec.BlockExecution) + err := grpc.Invoke(ctx, "/rpcevents.ExecutionEvents/GetBlock", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionEventsClient) GetBlocks(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetBlocksClient, error) { + stream, err := grpc.NewClientStream(ctx, &_ExecutionEvents_serviceDesc.Streams[0], c.cc, "/rpcevents.ExecutionEvents/GetBlocks", opts...) + if err != nil { + return nil, err + } + x := &executionEventsGetBlocksClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type ExecutionEvents_GetBlocksClient interface { + Recv() (*exec.BlockExecution, error) + grpc.ClientStream +} + +type executionEventsGetBlocksClient struct { + grpc.ClientStream +} + +func (x *executionEventsGetBlocksClient) Recv() (*exec.BlockExecution, error) { + m := new(exec.BlockExecution) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *executionEventsClient) GetTx(ctx context.Context, in *GetTxRequest, opts ...grpc.CallOption) (*exec.TxExecution, error) { + out := new(exec.TxExecution) + err := grpc.Invoke(ctx, "/rpcevents.ExecutionEvents/GetTx", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *executionEventsClient) GetTxs(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetTxsClient, error) { + stream, err := grpc.NewClientStream(ctx, &_ExecutionEvents_serviceDesc.Streams[1], c.cc, "/rpcevents.ExecutionEvents/GetTxs", opts...) + if err != nil { + return nil, err + } + x := &executionEventsGetTxsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type ExecutionEvents_GetTxsClient interface { + Recv() (*GetTxsResponse, error) + grpc.ClientStream +} + +type executionEventsGetTxsClient struct { + grpc.ClientStream +} + +func (x *executionEventsGetTxsClient) Recv() (*GetTxsResponse, error) { + m := new(GetTxsResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *executionEventsClient) GetEvents(ctx context.Context, in *BlocksRequest, opts ...grpc.CallOption) (ExecutionEvents_GetEventsClient, error) { + stream, err := grpc.NewClientStream(ctx, &_ExecutionEvents_serviceDesc.Streams[2], c.cc, "/rpcevents.ExecutionEvents/GetEvents", opts...) + if err != nil { + return nil, err + } + x := &executionEventsGetEventsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type ExecutionEvents_GetEventsClient interface { + Recv() (*GetEventsResponse, error) + grpc.ClientStream +} + +type executionEventsGetEventsClient struct { + grpc.ClientStream +} + +func (x *executionEventsGetEventsClient) Recv() (*GetEventsResponse, error) { + m := new(GetEventsResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// Server API for ExecutionEvents service + +type ExecutionEventsServer interface { + // Get Blockexecution at particular height + GetBlock(context.Context, *GetBlockRequest) (*exec.BlockExecution, error) + // Get BlockExecutions for a range of blocks + GetBlocks(*BlocksRequest, ExecutionEvents_GetBlocksServer) error + // Get a particular TxExecution + GetTx(context.Context, *GetTxRequest) (*exec.TxExecution, error) + // Get TxExecutions for a range of block + GetTxs(*BlocksRequest, ExecutionEvents_GetTxsServer) error + // GetEvents provides events streaming one block at a time - that is all events emitted in a particular block + // are guaranteed to be delivered in each GetEventsResponse + GetEvents(*BlocksRequest, ExecutionEvents_GetEventsServer) error +} + +func RegisterExecutionEventsServer(s *grpc.Server, srv ExecutionEventsServer) { + s.RegisterService(&_ExecutionEvents_serviceDesc, srv) +} + +func _ExecutionEvents_GetBlock_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetBlockRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionEventsServer).GetBlock(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpcevents.ExecutionEvents/GetBlock", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionEventsServer).GetBlock(ctx, req.(*GetBlockRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionEvents_GetBlocks_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(BlocksRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ExecutionEventsServer).GetBlocks(m, &executionEventsGetBlocksServer{stream}) +} + +type ExecutionEvents_GetBlocksServer interface { + Send(*exec.BlockExecution) error + grpc.ServerStream +} + +type executionEventsGetBlocksServer struct { + grpc.ServerStream +} + +func (x *executionEventsGetBlocksServer) Send(m *exec.BlockExecution) error { + return x.ServerStream.SendMsg(m) +} + +func _ExecutionEvents_GetTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTxRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ExecutionEventsServer).GetTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpcevents.ExecutionEvents/GetTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ExecutionEventsServer).GetTx(ctx, req.(*GetTxRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ExecutionEvents_GetTxs_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(BlocksRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ExecutionEventsServer).GetTxs(m, &executionEventsGetTxsServer{stream}) +} + +type ExecutionEvents_GetTxsServer interface { + Send(*GetTxsResponse) error + grpc.ServerStream +} + +type executionEventsGetTxsServer struct { + grpc.ServerStream +} + +func (x *executionEventsGetTxsServer) Send(m *GetTxsResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _ExecutionEvents_GetEvents_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(BlocksRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ExecutionEventsServer).GetEvents(m, &executionEventsGetEventsServer{stream}) +} + +type ExecutionEvents_GetEventsServer interface { + Send(*GetEventsResponse) error + grpc.ServerStream +} + +type executionEventsGetEventsServer struct { + grpc.ServerStream +} + +func (x *executionEventsGetEventsServer) Send(m *GetEventsResponse) error { + return x.ServerStream.SendMsg(m) +} + +var _ExecutionEvents_serviceDesc = grpc.ServiceDesc{ + ServiceName: "rpcevents.ExecutionEvents", + HandlerType: (*ExecutionEventsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetBlock", + Handler: _ExecutionEvents_GetBlock_Handler, + }, + { + MethodName: "GetTx", + Handler: _ExecutionEvents_GetTx_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "GetBlocks", + Handler: _ExecutionEvents_GetBlocks_Handler, + ServerStreams: true, + }, + { + StreamName: "GetTxs", + Handler: _ExecutionEvents_GetTxs_Handler, + ServerStreams: true, + }, + { + StreamName: "GetEvents", + Handler: _ExecutionEvents_GetEvents_Handler, + ServerStreams: true, + }, + }, + Metadata: "rpcevents.proto", +} + +func (m *GetBlockRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetBlockRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Height != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.Height)) + } + if m.Wait { + dAtA[i] = 0x10 + i++ + if m.Wait { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + return i, nil +} + +func (m *GetTxRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetTxRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.TxHash.Size())) + n1, err := m.TxHash.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + if m.Wait { + dAtA[i] = 0x10 + i++ + if m.Wait { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + return i, nil +} + +func (m *BlocksRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlocksRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.BlockRange != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.BlockRange.Size())) + n2, err := m.BlockRange.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if len(m.Query) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(len(m.Query))) + i += copy(dAtA[i:], m.Query) + } + return i, nil +} + +func (m *GetEventsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetEventsResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Height != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.Height)) + } + if len(m.Events) > 0 { + for _, msg := range m.Events { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *GetTxsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetTxsResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Height != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.Height)) + } + if len(m.TxExecutions) > 0 { + for _, msg := range m.TxExecutions { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *Bound) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Bound) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Type != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.Type)) + } + if m.Index != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.Index)) + } + return i, nil +} + +func (m *BlockRange) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlockRange) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Start != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.Start.Size())) + n3, err := m.Start.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.End != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpcevents(dAtA, i, uint64(m.End.Size())) + n4, err := m.End.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + return i, nil +} + +func encodeVarintRpcevents(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *GetBlockRequest) Size() (n int) { + var l int + _ = l + if m.Height != 0 { + n += 1 + sovRpcevents(uint64(m.Height)) + } + if m.Wait { + n += 2 + } + return n +} + +func (m *GetTxRequest) Size() (n int) { + var l int + _ = l + l = m.TxHash.Size() + n += 1 + l + sovRpcevents(uint64(l)) + if m.Wait { + n += 2 + } + return n +} + +func (m *BlocksRequest) Size() (n int) { + var l int + _ = l + if m.BlockRange != nil { + l = m.BlockRange.Size() + n += 1 + l + sovRpcevents(uint64(l)) + } + l = len(m.Query) + if l > 0 { + n += 1 + l + sovRpcevents(uint64(l)) + } + return n +} + +func (m *GetEventsResponse) Size() (n int) { + var l int + _ = l + if m.Height != 0 { + n += 1 + sovRpcevents(uint64(m.Height)) + } + if len(m.Events) > 0 { + for _, e := range m.Events { + l = e.Size() + n += 1 + l + sovRpcevents(uint64(l)) + } + } + return n +} + +func (m *GetTxsResponse) Size() (n int) { + var l int + _ = l + if m.Height != 0 { + n += 1 + sovRpcevents(uint64(m.Height)) + } + if len(m.TxExecutions) > 0 { + for _, e := range m.TxExecutions { + l = e.Size() + n += 1 + l + sovRpcevents(uint64(l)) + } + } + return n +} + +func (m *Bound) Size() (n int) { + var l int + _ = l + if m.Type != 0 { + n += 1 + sovRpcevents(uint64(m.Type)) + } + if m.Index != 0 { + n += 1 + sovRpcevents(uint64(m.Index)) + } + return n +} + +func (m *BlockRange) Size() (n int) { + var l int + _ = l + if m.Start != nil { + l = m.Start.Size() + n += 1 + l + sovRpcevents(uint64(l)) + } + if m.End != nil { + l = m.End.Size() + n += 1 + l + sovRpcevents(uint64(l)) + } + return n +} + +func sovRpcevents(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozRpcevents(x uint64) (n int) { + return sovRpcevents(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GetBlockRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetBlockRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetBlockRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Wait", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Wait = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipRpcevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetTxRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetTxRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetTxRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpcevents + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Wait", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Wait = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipRpcevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BlocksRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BlocksRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlocksRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BlockRange", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpcevents + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.BlockRange == nil { + m.BlockRange = &BlockRange{} + } + if err := m.BlockRange.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpcevents + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetEventsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetEventsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetEventsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Events", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpcevents + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Events = append(m.Events, &exec.Event{}) + if err := m.Events[len(m.Events)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetTxsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetTxsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetTxsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxExecutions", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpcevents + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TxExecutions = append(m.TxExecutions, &exec.TxExecution{}) + if err := m.TxExecutions[len(m.TxExecutions)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Bound) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Bound: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Bound: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Type |= (Bound_BoundType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRpcevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BlockRange) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BlockRange: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlockRange: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Start", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpcevents + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Start == nil { + m.Start = &Bound{} + } + if err := m.Start.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field End", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcevents + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpcevents + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.End == nil { + m.End = &Bound{} + } + if err := m.End.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcevents(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcevents + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRpcevents(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcevents + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcevents + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcevents + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthRpcevents + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcevents + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipRpcevents(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthRpcevents = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRpcevents = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("rpcevents.proto", fileDescriptorRpcevents) } +func init() { golang_proto.RegisterFile("rpcevents.proto", fileDescriptorRpcevents) } + +var fileDescriptorRpcevents = []byte{ + // 584 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x54, 0x5f, 0x8f, 0xd2, 0x40, + 0x10, 0xbf, 0xe5, 0x4f, 0x03, 0x03, 0x1e, 0xbd, 0xcd, 0xa9, 0x48, 0x0c, 0x47, 0x6a, 0x62, 0x48, + 0x8c, 0x85, 0x70, 0xe1, 0xcd, 0x8b, 0xa1, 0x49, 0x05, 0x0c, 0x17, 0x75, 0xa9, 0x7f, 0x62, 0x4c, + 0x0c, 0x94, 0xb5, 0x10, 0xcf, 0xb6, 0xd7, 0x6e, 0xb5, 0x7c, 0x14, 0xbf, 0x8d, 0x8f, 0x24, 0xbe, + 0xf8, 0xec, 0xc3, 0xc5, 0x70, 0x5f, 0xc4, 0x74, 0x17, 0x7a, 0x05, 0xef, 0xf0, 0xa5, 0x99, 0xd9, + 0xf9, 0xcd, 0x6f, 0x66, 0x7f, 0x33, 0x5b, 0x28, 0x79, 0xae, 0x49, 0xbf, 0x52, 0x9b, 0xf9, 0xaa, + 0xeb, 0x39, 0xcc, 0xc1, 0xf9, 0xf8, 0xa0, 0xf2, 0xd8, 0x9a, 0xb1, 0x69, 0x30, 0x56, 0x4d, 0xe7, + 0x4b, 0xc3, 0x72, 0x2c, 0xa7, 0xc1, 0x11, 0xe3, 0xe0, 0x13, 0xf7, 0xb8, 0xc3, 0x2d, 0x91, 0x59, + 0x01, 0x1a, 0x52, 0x53, 0xd8, 0xca, 0x09, 0x94, 0xba, 0x94, 0x69, 0x67, 0x8e, 0xf9, 0x99, 0xd0, + 0xf3, 0x80, 0xfa, 0x0c, 0xdf, 0x01, 0xa9, 0x47, 0x67, 0xd6, 0x94, 0x95, 0x51, 0x0d, 0xd5, 0x33, + 0x64, 0xe5, 0x61, 0x0c, 0x99, 0xb7, 0xa3, 0x19, 0x2b, 0xa7, 0x6a, 0xa8, 0x9e, 0x23, 0xdc, 0x56, + 0xce, 0xa1, 0xd8, 0xa5, 0xcc, 0x08, 0xd7, 0xb9, 0xa7, 0x20, 0x19, 0x61, 0x6f, 0xe4, 0x4f, 0x79, + 0x6e, 0x51, 0x6b, 0x2f, 0x2e, 0x8e, 0xf6, 0x7e, 0x5f, 0x1c, 0x25, 0x3b, 0x9c, 0xce, 0x5d, 0xea, + 0x9d, 0xd1, 0x89, 0x45, 0xbd, 0xc6, 0x38, 0xf0, 0x3c, 0xe7, 0x5b, 0x63, 0x3c, 0xb3, 0x47, 0xde, + 0x5c, 0xed, 0xd1, 0x50, 0x9b, 0x33, 0xea, 0x93, 0x15, 0xc9, 0xb5, 0x25, 0x3f, 0xc0, 0x2d, 0xde, + 0xae, 0xbf, 0xae, 0xd9, 0x06, 0x10, 0xfd, 0x8f, 0x6c, 0x8b, 0xf2, 0xba, 0x85, 0xd6, 0x6d, 0xf5, + 0x4a, 0xae, 0xab, 0x20, 0x49, 0x00, 0xf1, 0x21, 0x64, 0x5f, 0x05, 0xd4, 0x9b, 0x73, 0xf2, 0x3c, + 0x11, 0x8e, 0xf2, 0x12, 0x0e, 0xba, 0x94, 0xe9, 0x3c, 0x93, 0x50, 0xdf, 0x75, 0x6c, 0x9f, 0xde, + 0xa8, 0xc8, 0x03, 0x90, 0x04, 0xb2, 0x9c, 0xaa, 0xa5, 0xeb, 0x85, 0x56, 0x41, 0xe5, 0xca, 0xf2, + 0x33, 0xb2, 0x0a, 0x29, 0x1f, 0x61, 0x9f, 0x4b, 0xf4, 0x7f, 0xba, 0x36, 0x14, 0x8d, 0x50, 0x0f, + 0xa9, 0x19, 0xb0, 0x99, 0x63, 0xaf, 0x49, 0x0f, 0x04, 0x69, 0x22, 0x42, 0x36, 0x60, 0xca, 0x77, + 0x04, 0x59, 0xcd, 0x09, 0xec, 0x09, 0x56, 0x21, 0x63, 0xcc, 0x5d, 0xa1, 0xc1, 0x7e, 0xab, 0x92, + 0xd4, 0x20, 0x8a, 0x8b, 0x6f, 0x84, 0x20, 0x1c, 0x17, 0x49, 0xd0, 0xb7, 0x27, 0x34, 0xe4, 0x12, + 0x64, 0x88, 0x70, 0x94, 0xe7, 0x90, 0x8f, 0x81, 0xb8, 0x08, 0xb9, 0x8e, 0x36, 0x7c, 0x31, 0x78, + 0x6d, 0xe8, 0xf2, 0x5e, 0xe4, 0x11, 0x7d, 0xd0, 0x31, 0xfa, 0x6f, 0x74, 0x19, 0xe1, 0x3c, 0x64, + 0x9f, 0xf5, 0xc9, 0xd0, 0x90, 0x53, 0x18, 0x40, 0x1a, 0x74, 0x0c, 0x7d, 0x68, 0xc8, 0xe9, 0xc8, + 0x1e, 0x1a, 0x44, 0xef, 0x9c, 0xca, 0x19, 0xe5, 0x5d, 0x72, 0x36, 0xf8, 0x21, 0x64, 0x87, 0x6c, + 0xe4, 0xb1, 0xd5, 0x90, 0xe4, 0xed, 0x06, 0x89, 0x08, 0x63, 0x05, 0xd2, 0xba, 0x3d, 0xe1, 0x5d, + 0x5d, 0x87, 0x8a, 0x82, 0xad, 0x9f, 0x29, 0x28, 0xc5, 0x22, 0x08, 0xa9, 0xf1, 0x13, 0xc8, 0xad, + 0x97, 0x19, 0x27, 0x6f, 0xbf, 0xb5, 0xe1, 0x95, 0x43, 0x21, 0x29, 0x3f, 0x8b, 0x39, 0xf0, 0x09, + 0xe4, 0xd7, 0x40, 0x1f, 0x97, 0xb7, 0x17, 0xc8, 0xdf, 0x99, 0xdc, 0x44, 0xf8, 0x18, 0xb2, 0x7c, + 0xce, 0xf8, 0xee, 0x66, 0xe5, 0xf8, 0x71, 0x54, 0xfe, 0x9d, 0x24, 0x7e, 0x0a, 0x92, 0x58, 0x8e, + 0x1d, 0x05, 0xef, 0x6d, 0xf3, 0xc5, 0x9b, 0xd4, 0x44, 0x58, 0xe7, 0x4d, 0xaf, 0xee, 0x7f, 0x33, + 0xc7, 0xfd, 0x4d, 0x8e, 0xcd, 0xfd, 0x6e, 0x22, 0xad, 0xb3, 0x58, 0x56, 0xd1, 0xaf, 0x65, 0x15, + 0xfd, 0x59, 0x56, 0xd1, 0x8f, 0xcb, 0x2a, 0x5a, 0x5c, 0x56, 0xd1, 0xfb, 0x47, 0xbb, 0x5f, 0xad, + 0xe7, 0x9a, 0x8d, 0x98, 0x76, 0x2c, 0xf1, 0x1f, 0xca, 0xf1, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x5d, 0x9d, 0x65, 0x82, 0xa9, 0x04, 0x00, 0x00, +} diff --git a/rpc/rpcquery/query_server.go b/rpc/rpcquery/query_server.go new file mode 100644 index 0000000000000000000000000000000000000000..edcb968b6b1810329395acfb90bb5d1d8b11c97e --- /dev/null +++ b/rpc/rpcquery/query_server.go @@ -0,0 +1,76 @@ +package rpcquery + +import ( + "context" + + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" + "github.com/hyperledger/burrow/event/query" + "github.com/hyperledger/burrow/execution/names" +) + +type queryServer struct { + accounts state.IterableReader + nameReg names.IterableReader +} + +var _ QueryServer = &queryServer{} + +func NewQueryServer(state state.IterableReader, nameReg names.IterableReader) *queryServer { + return &queryServer{ + accounts: state, + nameReg: nameReg, + } +} + +func (qs *queryServer) GetAccount(ctx context.Context, param *GetAccountParam) (*acm.ConcreteAccount, error) { + acc, err := qs.accounts.GetAccount(param.Address) + if err != nil { + return nil, err + } + return acm.AsConcreteAccount(acc), nil +} + +func (qs *queryServer) ListAccounts(param *ListAccountsParam, stream Query_ListAccountsServer) error { + qry, err := query.NewBuilder(param.Query).Query() + var streamErr error + _, err = qs.accounts.IterateAccounts(func(acc acm.Account) (stop bool) { + if qry.Matches(acc.Tagged()) { + streamErr = stream.Send(acm.AsConcreteAccount(acc)) + if streamErr != nil { + return true + } + } + return + }) + if err != nil { + return err + } + return streamErr +} + +// Name registry +func (qs *queryServer) GetName(ctx context.Context, param *GetNameParam) (*names.Entry, error) { + return qs.nameReg.GetName(param.Name) +} + +func (qs *queryServer) ListNames(param *ListNamesParam, stream Query_ListNamesServer) error { + qry, err := query.NewBuilder(param.Query).Query() + if err != nil { + return err + } + var streamErr error + _, err = qs.nameReg.IterateNames(func(entry *names.Entry) (stop bool) { + if qry.Matches(entry.Tagged()) { + streamErr = stream.Send(entry) + if streamErr != nil { + return true + } + } + return + }) + if err != nil { + return err + } + return streamErr +} diff --git a/rpc/rpcquery/rpcquery.pb.go b/rpc/rpcquery/rpcquery.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..ce9b9f17d5a7fc89e4b3eb2efbe19c953b6dc72a --- /dev/null +++ b/rpc/rpcquery/rpcquery.pb.go @@ -0,0 +1,961 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rpcquery.proto + +/* + Package rpcquery is a generated protocol buffer package. + + It is generated from these files: + rpcquery.proto + + It has these top-level messages: + GetAccountParam + ListAccountsParam + GetNameParam + ListNamesParam +*/ +package rpcquery + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import names "github.com/hyperledger/burrow/execution/names" +import acm "github.com/hyperledger/burrow/acm" + +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" + +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type GetAccountParam struct { + Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"` +} + +func (m *GetAccountParam) Reset() { *m = GetAccountParam{} } +func (m *GetAccountParam) String() string { return proto.CompactTextString(m) } +func (*GetAccountParam) ProtoMessage() {} +func (*GetAccountParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{0} } + +func (*GetAccountParam) XXX_MessageName() string { + return "rpcquery.GetAccountParam" +} + +type ListAccountsParam struct { + Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"` +} + +func (m *ListAccountsParam) Reset() { *m = ListAccountsParam{} } +func (m *ListAccountsParam) String() string { return proto.CompactTextString(m) } +func (*ListAccountsParam) ProtoMessage() {} +func (*ListAccountsParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{1} } + +func (m *ListAccountsParam) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +func (*ListAccountsParam) XXX_MessageName() string { + return "rpcquery.ListAccountsParam" +} + +type GetNameParam struct { + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` +} + +func (m *GetNameParam) Reset() { *m = GetNameParam{} } +func (m *GetNameParam) String() string { return proto.CompactTextString(m) } +func (*GetNameParam) ProtoMessage() {} +func (*GetNameParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{2} } + +func (m *GetNameParam) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (*GetNameParam) XXX_MessageName() string { + return "rpcquery.GetNameParam" +} + +type ListNamesParam struct { + Query string `protobuf:"bytes,1,opt,name=Query,proto3" json:"Query,omitempty"` +} + +func (m *ListNamesParam) Reset() { *m = ListNamesParam{} } +func (m *ListNamesParam) String() string { return proto.CompactTextString(m) } +func (*ListNamesParam) ProtoMessage() {} +func (*ListNamesParam) Descriptor() ([]byte, []int) { return fileDescriptorRpcquery, []int{3} } + +func (m *ListNamesParam) GetQuery() string { + if m != nil { + return m.Query + } + return "" +} + +func (*ListNamesParam) XXX_MessageName() string { + return "rpcquery.ListNamesParam" +} +func init() { + proto.RegisterType((*GetAccountParam)(nil), "rpcquery.GetAccountParam") + golang_proto.RegisterType((*GetAccountParam)(nil), "rpcquery.GetAccountParam") + proto.RegisterType((*ListAccountsParam)(nil), "rpcquery.ListAccountsParam") + golang_proto.RegisterType((*ListAccountsParam)(nil), "rpcquery.ListAccountsParam") + proto.RegisterType((*GetNameParam)(nil), "rpcquery.GetNameParam") + golang_proto.RegisterType((*GetNameParam)(nil), "rpcquery.GetNameParam") + proto.RegisterType((*ListNamesParam)(nil), "rpcquery.ListNamesParam") + golang_proto.RegisterType((*ListNamesParam)(nil), "rpcquery.ListNamesParam") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for Query service + +type QueryClient interface { + GetAccount(ctx context.Context, in *GetAccountParam, opts ...grpc.CallOption) (*acm.ConcreteAccount, error) + ListAccounts(ctx context.Context, in *ListAccountsParam, opts ...grpc.CallOption) (Query_ListAccountsClient, error) + GetName(ctx context.Context, in *GetNameParam, opts ...grpc.CallOption) (*names.Entry, error) + ListNames(ctx context.Context, in *ListNamesParam, opts ...grpc.CallOption) (Query_ListNamesClient, error) +} + +type queryClient struct { + cc *grpc.ClientConn +} + +func NewQueryClient(cc *grpc.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) GetAccount(ctx context.Context, in *GetAccountParam, opts ...grpc.CallOption) (*acm.ConcreteAccount, error) { + out := new(acm.ConcreteAccount) + err := grpc.Invoke(ctx, "/rpcquery.Query/GetAccount", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ListAccounts(ctx context.Context, in *ListAccountsParam, opts ...grpc.CallOption) (Query_ListAccountsClient, error) { + stream, err := grpc.NewClientStream(ctx, &_Query_serviceDesc.Streams[0], c.cc, "/rpcquery.Query/ListAccounts", opts...) + if err != nil { + return nil, err + } + x := &queryListAccountsClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Query_ListAccountsClient interface { + Recv() (*acm.ConcreteAccount, error) + grpc.ClientStream +} + +type queryListAccountsClient struct { + grpc.ClientStream +} + +func (x *queryListAccountsClient) Recv() (*acm.ConcreteAccount, error) { + m := new(acm.ConcreteAccount) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *queryClient) GetName(ctx context.Context, in *GetNameParam, opts ...grpc.CallOption) (*names.Entry, error) { + out := new(names.Entry) + err := grpc.Invoke(ctx, "/rpcquery.Query/GetName", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ListNames(ctx context.Context, in *ListNamesParam, opts ...grpc.CallOption) (Query_ListNamesClient, error) { + stream, err := grpc.NewClientStream(ctx, &_Query_serviceDesc.Streams[1], c.cc, "/rpcquery.Query/ListNames", opts...) + if err != nil { + return nil, err + } + x := &queryListNamesClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Query_ListNamesClient interface { + Recv() (*names.Entry, error) + grpc.ClientStream +} + +type queryListNamesClient struct { + grpc.ClientStream +} + +func (x *queryListNamesClient) Recv() (*names.Entry, error) { + m := new(names.Entry) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// Server API for Query service + +type QueryServer interface { + GetAccount(context.Context, *GetAccountParam) (*acm.ConcreteAccount, error) + ListAccounts(*ListAccountsParam, Query_ListAccountsServer) error + GetName(context.Context, *GetNameParam) (*names.Entry, error) + ListNames(*ListNamesParam, Query_ListNamesServer) error +} + +func RegisterQueryServer(s *grpc.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_GetAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetAccountParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetAccount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpcquery.Query/GetAccount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetAccount(ctx, req.(*GetAccountParam)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ListAccounts_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(ListAccountsParam) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QueryServer).ListAccounts(m, &queryListAccountsServer{stream}) +} + +type Query_ListAccountsServer interface { + Send(*acm.ConcreteAccount) error + grpc.ServerStream +} + +type queryListAccountsServer struct { + grpc.ServerStream +} + +func (x *queryListAccountsServer) Send(m *acm.ConcreteAccount) error { + return x.ServerStream.SendMsg(m) +} + +func _Query_GetName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetNameParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpcquery.Query/GetName", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetName(ctx, req.(*GetNameParam)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ListNames_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(ListNamesParam) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(QueryServer).ListNames(m, &queryListNamesServer{stream}) +} + +type Query_ListNamesServer interface { + Send(*names.Entry) error + grpc.ServerStream +} + +type queryListNamesServer struct { + grpc.ServerStream +} + +func (x *queryListNamesServer) Send(m *names.Entry) error { + return x.ServerStream.SendMsg(m) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "rpcquery.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetAccount", + Handler: _Query_GetAccount_Handler, + }, + { + MethodName: "GetName", + Handler: _Query_GetName_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "ListAccounts", + Handler: _Query_ListAccounts_Handler, + ServerStreams: true, + }, + { + StreamName: "ListNames", + Handler: _Query_ListNames_Handler, + ServerStreams: true, + }, + }, + Metadata: "rpcquery.proto", +} + +func (m *GetAccountParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetAccountParam) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintRpcquery(dAtA, i, uint64(m.Address.Size())) + n1, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + return i, nil +} + +func (m *ListAccountsParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ListAccountsParam) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Query) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpcquery(dAtA, i, uint64(len(m.Query))) + i += copy(dAtA[i:], m.Query) + } + return i, nil +} + +func (m *GetNameParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GetNameParam) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpcquery(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + return i, nil +} + +func (m *ListNamesParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ListNamesParam) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Query) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintRpcquery(dAtA, i, uint64(len(m.Query))) + i += copy(dAtA[i:], m.Query) + } + return i, nil +} + +func encodeVarintRpcquery(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *GetAccountParam) Size() (n int) { + var l int + _ = l + l = m.Address.Size() + n += 1 + l + sovRpcquery(uint64(l)) + return n +} + +func (m *ListAccountsParam) Size() (n int) { + var l int + _ = l + l = len(m.Query) + if l > 0 { + n += 1 + l + sovRpcquery(uint64(l)) + } + return n +} + +func (m *GetNameParam) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpcquery(uint64(l)) + } + return n +} + +func (m *ListNamesParam) Size() (n int) { + var l int + _ = l + l = len(m.Query) + if l > 0 { + n += 1 + l + sovRpcquery(uint64(l)) + } + return n +} + +func sovRpcquery(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozRpcquery(x uint64) (n int) { + return sovRpcquery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GetAccountParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetAccountParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetAccountParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpcquery + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcquery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcquery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ListAccountsParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListAccountsParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListAccountsParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpcquery + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcquery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcquery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GetNameParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GetNameParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GetNameParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpcquery + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcquery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcquery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ListNamesParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListNamesParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListNamesParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Query", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpcquery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpcquery + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Query = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpcquery(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpcquery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRpcquery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcquery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcquery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcquery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthRpcquery + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpcquery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipRpcquery(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthRpcquery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRpcquery = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("rpcquery.proto", fileDescriptorRpcquery) } +func init() { golang_proto.RegisterFile("rpcquery.proto", fileDescriptorRpcquery) } + +var fileDescriptorRpcquery = []byte{ + // 349 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xcd, 0x4a, 0xc3, 0x40, + 0x14, 0x85, 0x1d, 0x50, 0x6b, 0xaf, 0xa1, 0xe2, 0x50, 0xa4, 0x46, 0x48, 0x25, 0x0b, 0x51, 0xd1, + 0xa4, 0xf8, 0xb3, 0x14, 0x6c, 0x8b, 0x74, 0x23, 0x45, 0xbb, 0x74, 0x97, 0x4c, 0xc7, 0xb4, 0x60, + 0x32, 0xf1, 0x66, 0x82, 0xe4, 0xed, 0x5c, 0x76, 0xe9, 0xda, 0x45, 0x91, 0xf6, 0x11, 0x7c, 0x01, + 0xc9, 0x24, 0xe9, 0x8f, 0x4a, 0x77, 0xf7, 0x84, 0x7b, 0xce, 0x99, 0x6f, 0x26, 0x50, 0xc1, 0x90, + 0xbd, 0xc6, 0x1c, 0x13, 0x2b, 0x44, 0x21, 0x05, 0xdd, 0x2a, 0xb4, 0x7e, 0xee, 0x0d, 0xe5, 0x20, + 0x76, 0x2d, 0x26, 0x7c, 0xdb, 0x13, 0x9e, 0xb0, 0xd5, 0x82, 0x1b, 0x3f, 0x2b, 0xa5, 0x84, 0x9a, + 0x32, 0xa3, 0xbe, 0x1d, 0x38, 0x3e, 0x8f, 0x72, 0x51, 0x76, 0x98, 0x9f, 0x8d, 0xa6, 0x03, 0x3b, + 0x1d, 0x2e, 0x9b, 0x8c, 0x89, 0x38, 0x90, 0x0f, 0x0e, 0x3a, 0x3e, 0xed, 0x42, 0xa9, 0xd9, 0xef, + 0x23, 0x8f, 0xa2, 0x1a, 0x39, 0x24, 0xc7, 0x5a, 0xeb, 0x6a, 0x34, 0xae, 0xaf, 0x7d, 0x8e, 0xeb, + 0x67, 0x0b, 0x95, 0x83, 0x24, 0xe4, 0xf8, 0xc2, 0xfb, 0x1e, 0x47, 0xdb, 0x8d, 0x11, 0xc5, 0x9b, + 0xcd, 0x30, 0x09, 0xa5, 0xb0, 0x72, 0x6f, 0xaf, 0x08, 0x31, 0x4f, 0x60, 0xf7, 0x7e, 0x18, 0x15, + 0x1d, 0x51, 0x56, 0x52, 0x85, 0x8d, 0xc7, 0x94, 0x43, 0x55, 0x94, 0x7b, 0x99, 0x30, 0x4d, 0xd0, + 0x3a, 0x5c, 0x76, 0x1d, 0x9f, 0x67, 0x5b, 0x14, 0xd6, 0x53, 0x91, 0x2f, 0xa9, 0xd9, 0x3c, 0x82, + 0x4a, 0x1a, 0x97, 0xce, 0xab, 0xb2, 0x2e, 0xbe, 0x49, 0xfe, 0x99, 0xde, 0x00, 0xcc, 0x19, 0xe9, + 0xbe, 0x35, 0xbb, 0xd3, 0x5f, 0xe4, 0x7a, 0xd5, 0x4a, 0x2f, 0xa6, 0x2d, 0x02, 0x86, 0x5c, 0xf2, + 0xc2, 0xd0, 0x06, 0x6d, 0xf1, 0xfc, 0xf4, 0x60, 0x1e, 0xf0, 0x87, 0xeb, 0xff, 0x88, 0x06, 0xa1, + 0x36, 0x94, 0x72, 0x32, 0xba, 0xb7, 0x74, 0x80, 0x19, 0xac, 0xae, 0x59, 0xd9, 0x1b, 0xdd, 0x05, + 0x12, 0x13, 0x7a, 0x0d, 0xe5, 0x19, 0x26, 0xad, 0x2d, 0x57, 0xce, 0xd9, 0x97, 0x4d, 0x0d, 0xd2, + 0xba, 0x1d, 0x4d, 0x0c, 0xf2, 0x31, 0x31, 0xc8, 0xd7, 0xc4, 0x20, 0xef, 0x53, 0x83, 0x8c, 0xa6, + 0x06, 0x79, 0x3a, 0x5d, 0xfd, 0x72, 0x18, 0x32, 0xbb, 0x28, 0x70, 0x37, 0xd5, 0x8f, 0x71, 0xf9, + 0x13, 0x00, 0x00, 0xff, 0xff, 0xfa, 0xef, 0x21, 0x21, 0x7b, 0x02, 0x00, 0x00, +} diff --git a/rpc/rpctransact/rpctransact.pb.go b/rpc/rpctransact/rpctransact.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..903e977b455a69b1ca70085ad713b1995aac5134 --- /dev/null +++ b/rpc/rpctransact/rpctransact.pb.go @@ -0,0 +1,1488 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rpctransact.proto + +/* + Package rpctransact is a generated protocol buffer package. + + It is generated from these files: + rpctransact.proto + + It has these top-level messages: + CallCodeParam + PayloadParam + TxEnvelope + TxEnvelopeParam +*/ +package rpctransact + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import exec "github.com/hyperledger/burrow/execution/exec" +import payload "github.com/hyperledger/burrow/txs/payload" +import txs "github.com/hyperledger/burrow/txs" + +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" +import github_com_hyperledger_burrow_txs "github.com/hyperledger/burrow/txs" + +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type CallCodeParam struct { + FromAddress github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=FromAddress,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"FromAddress"` + Code []byte `protobuf:"bytes,2,opt,name=Code,proto3" json:"Code,omitempty"` + Data []byte `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"` +} + +func (m *CallCodeParam) Reset() { *m = CallCodeParam{} } +func (m *CallCodeParam) String() string { return proto.CompactTextString(m) } +func (*CallCodeParam) ProtoMessage() {} +func (*CallCodeParam) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{0} } + +func (m *CallCodeParam) GetCode() []byte { + if m != nil { + return m.Code + } + return nil +} + +func (m *CallCodeParam) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (*CallCodeParam) XXX_MessageName() string { + return "rpctransact.CallCodeParam" +} + +type PayloadParam struct { + CallTx *payload.CallTx `protobuf:"bytes,1,opt,name=CallTx" json:"CallTx,omitempty"` + SendTx *payload.SendTx `protobuf:"bytes,2,opt,name=SendTx" json:"SendTx,omitempty"` + NameTx *payload.NameTx `protobuf:"bytes,3,opt,name=NameTx" json:"NameTx,omitempty"` +} + +func (m *PayloadParam) Reset() { *m = PayloadParam{} } +func (m *PayloadParam) String() string { return proto.CompactTextString(m) } +func (*PayloadParam) ProtoMessage() {} +func (*PayloadParam) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{1} } + +func (m *PayloadParam) GetCallTx() *payload.CallTx { + if m != nil { + return m.CallTx + } + return nil +} + +func (m *PayloadParam) GetSendTx() *payload.SendTx { + if m != nil { + return m.SendTx + } + return nil +} + +func (m *PayloadParam) GetNameTx() *payload.NameTx { + if m != nil { + return m.NameTx + } + return nil +} + +func (*PayloadParam) XXX_MessageName() string { + return "rpctransact.PayloadParam" +} + +type TxEnvelope struct { + Envelope *github_com_hyperledger_burrow_txs.Envelope `protobuf:"bytes,1,opt,name=Envelope,customtype=github.com/hyperledger/burrow/txs.Envelope" json:"Envelope,omitempty"` +} + +func (m *TxEnvelope) Reset() { *m = TxEnvelope{} } +func (m *TxEnvelope) String() string { return proto.CompactTextString(m) } +func (*TxEnvelope) ProtoMessage() {} +func (*TxEnvelope) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{2} } + +func (*TxEnvelope) XXX_MessageName() string { + return "rpctransact.TxEnvelope" +} + +type TxEnvelopeParam struct { + // An existing Envelope - either signed or unsigned - if the latter will be signed server-side + Envelope *github_com_hyperledger_burrow_txs.Envelope `protobuf:"bytes,1,opt,name=Envelope,customtype=github.com/hyperledger/burrow/txs.Envelope" json:"Envelope,omitempty"` + // If no Envelope provided then one will be generated from the provided payload and signed server-side + Payload *PayloadParam `protobuf:"bytes,2,opt,name=Payload" json:"Payload,omitempty"` +} + +func (m *TxEnvelopeParam) Reset() { *m = TxEnvelopeParam{} } +func (m *TxEnvelopeParam) String() string { return proto.CompactTextString(m) } +func (*TxEnvelopeParam) ProtoMessage() {} +func (*TxEnvelopeParam) Descriptor() ([]byte, []int) { return fileDescriptorRpctransact, []int{3} } + +func (m *TxEnvelopeParam) GetPayload() *PayloadParam { + if m != nil { + return m.Payload + } + return nil +} + +func (*TxEnvelopeParam) XXX_MessageName() string { + return "rpctransact.TxEnvelopeParam" +} +func init() { + proto.RegisterType((*CallCodeParam)(nil), "rpctransact.CallCodeParam") + golang_proto.RegisterType((*CallCodeParam)(nil), "rpctransact.CallCodeParam") + proto.RegisterType((*PayloadParam)(nil), "rpctransact.PayloadParam") + golang_proto.RegisterType((*PayloadParam)(nil), "rpctransact.PayloadParam") + proto.RegisterType((*TxEnvelope)(nil), "rpctransact.TxEnvelope") + golang_proto.RegisterType((*TxEnvelope)(nil), "rpctransact.TxEnvelope") + proto.RegisterType((*TxEnvelopeParam)(nil), "rpctransact.TxEnvelopeParam") + golang_proto.RegisterType((*TxEnvelopeParam)(nil), "rpctransact.TxEnvelopeParam") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for Transact service + +type TransactClient interface { + // Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side + // and wait for it to be included in block + BroadcastTxSync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*exec.TxExecution, error) + // Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side + BroadcastTxAsync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*txs.Receipt, error) + // Sign transaction server-side + SignTx(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*TxEnvelope, error) + // Formulate a transaction from a Payload and retrun the envelop with the Tx bytes ready to sign + FormulateTx(ctx context.Context, in *PayloadParam, opts ...grpc.CallOption) (*TxEnvelope, error) + // Formulate and sign a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response + CallTxSync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error) + // Formulate and sign a CallTx transaction signed server-side + CallTxAsync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*txs.Receipt, error) + // Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved + // and wait for the transaction to be included in a block + CallTxSim(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error) + // Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved + CallCodeSim(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*exec.TxExecution, error) + // Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response + SendTxSync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*exec.TxExecution, error) + // Formulate and SendTx transaction signed server-side + SendTxAsync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*txs.Receipt, error) + // Formualte a NameTx signed server-side and wait for it to be included in a block returning the registered name + NameTxSync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*exec.TxExecution, error) + // Formulate a NameTx signed server-side + NameTxAsync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*txs.Receipt, error) +} + +type transactClient struct { + cc *grpc.ClientConn +} + +func NewTransactClient(cc *grpc.ClientConn) TransactClient { + return &transactClient{cc} +} + +func (c *transactClient) BroadcastTxSync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*exec.TxExecution, error) { + out := new(exec.TxExecution) + err := grpc.Invoke(ctx, "/rpctransact.Transact/BroadcastTxSync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) BroadcastTxAsync(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*txs.Receipt, error) { + out := new(txs.Receipt) + err := grpc.Invoke(ctx, "/rpctransact.Transact/BroadcastTxAsync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) SignTx(ctx context.Context, in *TxEnvelopeParam, opts ...grpc.CallOption) (*TxEnvelope, error) { + out := new(TxEnvelope) + err := grpc.Invoke(ctx, "/rpctransact.Transact/SignTx", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) FormulateTx(ctx context.Context, in *PayloadParam, opts ...grpc.CallOption) (*TxEnvelope, error) { + out := new(TxEnvelope) + err := grpc.Invoke(ctx, "/rpctransact.Transact/FormulateTx", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) CallTxSync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error) { + out := new(exec.TxExecution) + err := grpc.Invoke(ctx, "/rpctransact.Transact/CallTxSync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) CallTxAsync(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*txs.Receipt, error) { + out := new(txs.Receipt) + err := grpc.Invoke(ctx, "/rpctransact.Transact/CallTxAsync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) CallTxSim(ctx context.Context, in *payload.CallTx, opts ...grpc.CallOption) (*exec.TxExecution, error) { + out := new(exec.TxExecution) + err := grpc.Invoke(ctx, "/rpctransact.Transact/CallTxSim", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) CallCodeSim(ctx context.Context, in *CallCodeParam, opts ...grpc.CallOption) (*exec.TxExecution, error) { + out := new(exec.TxExecution) + err := grpc.Invoke(ctx, "/rpctransact.Transact/CallCodeSim", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) SendTxSync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*exec.TxExecution, error) { + out := new(exec.TxExecution) + err := grpc.Invoke(ctx, "/rpctransact.Transact/SendTxSync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) SendTxAsync(ctx context.Context, in *payload.SendTx, opts ...grpc.CallOption) (*txs.Receipt, error) { + out := new(txs.Receipt) + err := grpc.Invoke(ctx, "/rpctransact.Transact/SendTxAsync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) NameTxSync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*exec.TxExecution, error) { + out := new(exec.TxExecution) + err := grpc.Invoke(ctx, "/rpctransact.Transact/NameTxSync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *transactClient) NameTxAsync(ctx context.Context, in *payload.NameTx, opts ...grpc.CallOption) (*txs.Receipt, error) { + out := new(txs.Receipt) + err := grpc.Invoke(ctx, "/rpctransact.Transact/NameTxAsync", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Transact service + +type TransactServer interface { + // Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side + // and wait for it to be included in block + BroadcastTxSync(context.Context, *TxEnvelopeParam) (*exec.TxExecution, error) + // Broadcast a transaction to the mempool - if the transaction is not signed signing will be attempted server-side + BroadcastTxAsync(context.Context, *TxEnvelopeParam) (*txs.Receipt, error) + // Sign transaction server-side + SignTx(context.Context, *TxEnvelopeParam) (*TxEnvelope, error) + // Formulate a transaction from a Payload and retrun the envelop with the Tx bytes ready to sign + FormulateTx(context.Context, *PayloadParam) (*TxEnvelope, error) + // Formulate and sign a CallTx transaction signed server-side and wait for it to be included in a block, retrieving response + CallTxSync(context.Context, *payload.CallTx) (*exec.TxExecution, error) + // Formulate and sign a CallTx transaction signed server-side + CallTxAsync(context.Context, *payload.CallTx) (*txs.Receipt, error) + // Perform a 'simulated' call of a contract against the current committed EVM state without any changes been saved + // and wait for the transaction to be included in a block + CallTxSim(context.Context, *payload.CallTx) (*exec.TxExecution, error) + // Perform a 'simulated' execution of provided code against the current committed EVM state without any changes been saved + CallCodeSim(context.Context, *CallCodeParam) (*exec.TxExecution, error) + // Formulate a SendTx transaction signed server-side and wait for it to be included in a block, retrieving response + SendTxSync(context.Context, *payload.SendTx) (*exec.TxExecution, error) + // Formulate and SendTx transaction signed server-side + SendTxAsync(context.Context, *payload.SendTx) (*txs.Receipt, error) + // Formualte a NameTx signed server-side and wait for it to be included in a block returning the registered name + NameTxSync(context.Context, *payload.NameTx) (*exec.TxExecution, error) + // Formulate a NameTx signed server-side + NameTxAsync(context.Context, *payload.NameTx) (*txs.Receipt, error) +} + +func RegisterTransactServer(s *grpc.Server, srv TransactServer) { + s.RegisterService(&_Transact_serviceDesc, srv) +} + +func _Transact_BroadcastTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TxEnvelopeParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).BroadcastTxSync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/BroadcastTxSync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).BroadcastTxSync(ctx, req.(*TxEnvelopeParam)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_BroadcastTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TxEnvelopeParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).BroadcastTxAsync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/BroadcastTxAsync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).BroadcastTxAsync(ctx, req.(*TxEnvelopeParam)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_SignTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(TxEnvelopeParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).SignTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/SignTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).SignTx(ctx, req.(*TxEnvelopeParam)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_FormulateTx_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PayloadParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).FormulateTx(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/FormulateTx", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).FormulateTx(ctx, req.(*PayloadParam)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_CallTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(payload.CallTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).CallTxSync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/CallTxSync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).CallTxSync(ctx, req.(*payload.CallTx)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_CallTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(payload.CallTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).CallTxAsync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/CallTxAsync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).CallTxAsync(ctx, req.(*payload.CallTx)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_CallTxSim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(payload.CallTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).CallTxSim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/CallTxSim", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).CallTxSim(ctx, req.(*payload.CallTx)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_CallCodeSim_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CallCodeParam) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).CallCodeSim(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/CallCodeSim", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).CallCodeSim(ctx, req.(*CallCodeParam)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_SendTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(payload.SendTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).SendTxSync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/SendTxSync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).SendTxSync(ctx, req.(*payload.SendTx)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_SendTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(payload.SendTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).SendTxAsync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/SendTxAsync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).SendTxAsync(ctx, req.(*payload.SendTx)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_NameTxSync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(payload.NameTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).NameTxSync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/NameTxSync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).NameTxSync(ctx, req.(*payload.NameTx)) + } + return interceptor(ctx, in, info, handler) +} + +func _Transact_NameTxAsync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(payload.NameTx) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TransactServer).NameTxAsync(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rpctransact.Transact/NameTxAsync", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TransactServer).NameTxAsync(ctx, req.(*payload.NameTx)) + } + return interceptor(ctx, in, info, handler) +} + +var _Transact_serviceDesc = grpc.ServiceDesc{ + ServiceName: "rpctransact.Transact", + HandlerType: (*TransactServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "BroadcastTxSync", + Handler: _Transact_BroadcastTxSync_Handler, + }, + { + MethodName: "BroadcastTxAsync", + Handler: _Transact_BroadcastTxAsync_Handler, + }, + { + MethodName: "SignTx", + Handler: _Transact_SignTx_Handler, + }, + { + MethodName: "FormulateTx", + Handler: _Transact_FormulateTx_Handler, + }, + { + MethodName: "CallTxSync", + Handler: _Transact_CallTxSync_Handler, + }, + { + MethodName: "CallTxAsync", + Handler: _Transact_CallTxAsync_Handler, + }, + { + MethodName: "CallTxSim", + Handler: _Transact_CallTxSim_Handler, + }, + { + MethodName: "CallCodeSim", + Handler: _Transact_CallCodeSim_Handler, + }, + { + MethodName: "SendTxSync", + Handler: _Transact_SendTxSync_Handler, + }, + { + MethodName: "SendTxAsync", + Handler: _Transact_SendTxAsync_Handler, + }, + { + MethodName: "NameTxSync", + Handler: _Transact_NameTxSync_Handler, + }, + { + MethodName: "NameTxAsync", + Handler: _Transact_NameTxAsync_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "rpctransact.proto", +} + +func (m *CallCodeParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CallCodeParam) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(m.FromAddress.Size())) + n1, err := m.FromAddress.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + if len(m.Code) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(len(m.Code))) + i += copy(dAtA[i:], m.Code) + } + if len(m.Data) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + return i, nil +} + +func (m *PayloadParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PayloadParam) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.CallTx != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(m.CallTx.Size())) + n2, err := m.CallTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.SendTx != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(m.SendTx.Size())) + n3, err := m.SendTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.NameTx != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(m.NameTx.Size())) + n4, err := m.NameTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + return i, nil +} + +func (m *TxEnvelope) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TxEnvelope) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Envelope != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(m.Envelope.Size())) + n5, err := m.Envelope.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + return i, nil +} + +func (m *TxEnvelopeParam) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TxEnvelopeParam) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Envelope != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(m.Envelope.Size())) + n6, err := m.Envelope.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n6 + } + if m.Payload != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintRpctransact(dAtA, i, uint64(m.Payload.Size())) + n7, err := m.Payload.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n7 + } + return i, nil +} + +func encodeVarintRpctransact(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *CallCodeParam) Size() (n int) { + var l int + _ = l + l = m.FromAddress.Size() + n += 1 + l + sovRpctransact(uint64(l)) + l = len(m.Code) + if l > 0 { + n += 1 + l + sovRpctransact(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovRpctransact(uint64(l)) + } + return n +} + +func (m *PayloadParam) Size() (n int) { + var l int + _ = l + if m.CallTx != nil { + l = m.CallTx.Size() + n += 1 + l + sovRpctransact(uint64(l)) + } + if m.SendTx != nil { + l = m.SendTx.Size() + n += 1 + l + sovRpctransact(uint64(l)) + } + if m.NameTx != nil { + l = m.NameTx.Size() + n += 1 + l + sovRpctransact(uint64(l)) + } + return n +} + +func (m *TxEnvelope) Size() (n int) { + var l int + _ = l + if m.Envelope != nil { + l = m.Envelope.Size() + n += 1 + l + sovRpctransact(uint64(l)) + } + return n +} + +func (m *TxEnvelopeParam) Size() (n int) { + var l int + _ = l + if m.Envelope != nil { + l = m.Envelope.Size() + n += 1 + l + sovRpctransact(uint64(l)) + } + if m.Payload != nil { + l = m.Payload.Size() + n += 1 + l + sovRpctransact(uint64(l)) + } + return n +} + +func sovRpctransact(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozRpctransact(x uint64) (n int) { + return sovRpctransact(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *CallCodeParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CallCodeParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CallCodeParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromAddress", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.FromAddress.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Code = append(m.Code[:0], dAtA[iNdEx:postIndex]...) + if m.Code == nil { + m.Code = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpctransact(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpctransact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PayloadParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PayloadParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PayloadParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CallTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CallTx == nil { + m.CallTx = &payload.CallTx{} + } + if err := m.CallTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SendTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SendTx == nil { + m.SendTx = &payload.SendTx{} + } + if err := m.SendTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NameTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NameTx == nil { + m.NameTx = &payload.NameTx{} + } + if err := m.NameTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpctransact(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpctransact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TxEnvelope) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxEnvelope: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxEnvelope: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Envelope", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Envelope == nil { + m.Envelope = &github_com_hyperledger_burrow_txs.Envelope{} + } + if err := m.Envelope.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpctransact(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpctransact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TxEnvelopeParam) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxEnvelopeParam: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxEnvelopeParam: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Envelope", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Envelope == nil { + m.Envelope = &github_com_hyperledger_burrow_txs.Envelope{} + } + if err := m.Envelope.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Payload", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpctransact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpctransact + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Payload == nil { + m.Payload = &PayloadParam{} + } + if err := m.Payload.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpctransact(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpctransact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipRpctransact(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpctransact + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpctransact + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpctransact + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthRpctransact + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowRpctransact + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipRpctransact(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthRpctransact = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowRpctransact = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("rpctransact.proto", fileDescriptorRpctransact) } +func init() { golang_proto.RegisterFile("rpctransact.proto", fileDescriptorRpctransact) } + +var fileDescriptorRpctransact = []byte{ + // 552 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xc6, 0xfc, 0x84, 0x76, 0x92, 0x28, 0x74, 0x2f, 0x84, 0x08, 0x25, 0x28, 0x17, 0x10, 0x6a, + 0xed, 0xa8, 0xe5, 0x88, 0x40, 0x49, 0x68, 0x8f, 0xa8, 0x72, 0x2c, 0x24, 0xb8, 0x6d, 0xec, 0xc5, + 0x8d, 0x64, 0x7b, 0xad, 0xf5, 0x06, 0x36, 0x8f, 0xc0, 0x89, 0x67, 0xe8, 0x9b, 0x70, 0xcc, 0x91, + 0x73, 0x0f, 0x11, 0x4a, 0x5f, 0x04, 0xed, 0x4f, 0x60, 0x6d, 0x9a, 0x96, 0x4b, 0x6f, 0xe3, 0x6f, + 0x66, 0xbe, 0x99, 0xef, 0xd3, 0x8e, 0x61, 0x8f, 0xe5, 0x21, 0x67, 0x38, 0x2b, 0x70, 0xc8, 0xdd, + 0x9c, 0x51, 0x4e, 0x51, 0xdd, 0x82, 0x3a, 0x07, 0xf1, 0x8c, 0x9f, 0xcd, 0xa7, 0x6e, 0x48, 0x53, + 0x2f, 0xa6, 0x31, 0xf5, 0x54, 0xcd, 0x74, 0xfe, 0x59, 0x7d, 0xa9, 0x0f, 0x15, 0xe9, 0xde, 0x0e, + 0x10, 0x41, 0x42, 0x13, 0x37, 0x73, 0xbc, 0x48, 0x28, 0x8e, 0xcc, 0xe7, 0x2e, 0x17, 0x85, 0x0e, + 0xfb, 0xdf, 0x1d, 0x68, 0x8e, 0x71, 0x92, 0x8c, 0x69, 0x44, 0x4e, 0x31, 0xc3, 0x29, 0xfa, 0x00, + 0xf5, 0x13, 0x46, 0xd3, 0x61, 0x14, 0x31, 0x52, 0x14, 0x6d, 0xe7, 0x99, 0xf3, 0xa2, 0x31, 0x7a, + 0xb5, 0x5c, 0xf5, 0xee, 0x5c, 0xac, 0x7a, 0xfb, 0xd6, 0x0e, 0x67, 0x8b, 0x9c, 0xb0, 0x84, 0x44, + 0x31, 0x61, 0xde, 0x74, 0xce, 0x18, 0xfd, 0xea, 0x85, 0x6c, 0x91, 0x73, 0xea, 0x9a, 0x5e, 0xdf, + 0x26, 0x42, 0x08, 0xee, 0xcb, 0x21, 0xed, 0xbb, 0x92, 0xd0, 0x57, 0xb1, 0xc4, 0xde, 0x61, 0x8e, + 0xdb, 0xf7, 0x34, 0x26, 0xe3, 0xfe, 0x37, 0x07, 0x1a, 0xa7, 0x7a, 0x5d, 0xbd, 0xd0, 0x73, 0xa8, + 0xc9, 0x0d, 0x03, 0xa1, 0x76, 0xa9, 0x1f, 0xb6, 0xdc, 0x8d, 0x1a, 0x0d, 0xfb, 0x26, 0x2d, 0x0b, + 0x27, 0x24, 0x8b, 0x02, 0xa1, 0x66, 0xd8, 0x85, 0x1a, 0xf6, 0x4d, 0x5a, 0x16, 0xbe, 0xc7, 0x29, + 0x09, 0x84, 0x1a, 0x6c, 0x17, 0x6a, 0xd8, 0x37, 0xe9, 0x7e, 0x0c, 0x10, 0x88, 0xe3, 0xec, 0x0b, + 0x49, 0x68, 0x4e, 0xd0, 0x47, 0xd8, 0xd9, 0xc4, 0x66, 0x95, 0xa6, 0x2b, 0x9d, 0xdc, 0x80, 0x23, + 0xf7, 0x62, 0xd5, 0x7b, 0x79, 0xbd, 0x43, 0x76, 0xbd, 0xff, 0x87, 0xae, 0x7f, 0xee, 0x40, 0xeb, + 0xef, 0x24, 0xad, 0xfb, 0xf6, 0xc6, 0xa1, 0x23, 0x78, 0x68, 0x2c, 0x36, 0x56, 0x3d, 0x71, 0xed, + 0xc7, 0x67, 0xdb, 0xef, 0x6f, 0x2a, 0x0f, 0xcf, 0x1f, 0xc0, 0x4e, 0x60, 0x4a, 0xd0, 0x08, 0x5a, + 0x23, 0x46, 0x71, 0x14, 0xe2, 0x82, 0x07, 0x62, 0xb2, 0xc8, 0x42, 0xf4, 0xb4, 0xc4, 0x51, 0x51, + 0xd3, 0xd9, 0x73, 0xd5, 0x7b, 0x0c, 0xc4, 0xb1, 0x20, 0xe1, 0x9c, 0xcf, 0x68, 0x86, 0xde, 0xc0, + 0x23, 0x8b, 0x63, 0x58, 0xdc, 0x4c, 0xd2, 0x50, 0x06, 0xf8, 0x24, 0x24, 0xb3, 0x9c, 0xa3, 0xb7, + 0x50, 0x9b, 0xcc, 0xe2, 0x2c, 0x10, 0x37, 0x74, 0x3d, 0xde, 0x92, 0x45, 0x43, 0xa8, 0x9f, 0x50, + 0x96, 0xce, 0x13, 0xcc, 0x49, 0x20, 0xd0, 0x76, 0x13, 0xb6, 0x53, 0x0c, 0x00, 0xf4, 0xeb, 0x53, + 0x16, 0x54, 0x9f, 0xe6, 0x55, 0xaa, 0xf7, 0xa1, 0xae, 0x93, 0x5a, 0xf0, 0x3f, 0x2d, 0x65, 0x8d, + 0x1e, 0xec, 0x1a, 0xfe, 0x59, 0xfa, 0x5f, 0xf4, 0xaf, 0x35, 0xbd, 0x3c, 0x2f, 0xd9, 0xd2, 0x29, + 0x2d, 0x5e, 0xba, 0xf4, 0xab, 0xba, 0x07, 0x00, 0xfa, 0x46, 0x2a, 0x72, 0x34, 0xb8, 0x45, 0x8e, + 0x4e, 0x56, 0xe5, 0x98, 0x96, 0xb2, 0x9c, 0x01, 0x80, 0x3e, 0xad, 0x0a, 0xbf, 0x06, 0xb7, 0xf0, + 0xeb, 0x64, 0x95, 0xdf, 0xb4, 0x94, 0xf8, 0x47, 0xe3, 0xe5, 0xba, 0xeb, 0xfc, 0x5c, 0x77, 0x9d, + 0x5f, 0xeb, 0xae, 0xf3, 0xe3, 0xb2, 0xeb, 0x2c, 0x2f, 0xbb, 0xce, 0xa7, 0x83, 0xeb, 0x8f, 0x84, + 0xe5, 0xa1, 0x67, 0xb9, 0x34, 0xad, 0xa9, 0x5f, 0xe3, 0xd1, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x0f, 0x15, 0x24, 0xfe, 0x91, 0x05, 0x00, 0x00, +} diff --git a/rpc/rpctransact/transact_server.go b/rpc/rpctransact/transact_server.go new file mode 100644 index 0000000000000000000000000000000000000000..ab3a8c6ea712dfebd4d81f08345b3b5070ef98d2 --- /dev/null +++ b/rpc/rpctransact/transact_server.go @@ -0,0 +1,148 @@ +package rpctransact + +import ( + "fmt" + + "github.com/hyperledger/burrow/execution" + "github.com/hyperledger/burrow/execution/exec" + "github.com/hyperledger/burrow/txs" + "github.com/hyperledger/burrow/txs/payload" + "golang.org/x/net/context" +) + +type transactServer struct { + transactor *execution.Transactor + txCodec txs.Codec +} + +func NewTransactServer(transactor *execution.Transactor, txCodec txs.Codec) TransactServer { + return &transactServer{ + transactor: transactor, + txCodec: txCodec, + } +} + +func (ts *transactServer) BroadcastTxSync(ctx context.Context, param *TxEnvelopeParam) (*exec.TxExecution, error) { + txEnv := param.GetEnvelope(ts.transactor.Tip.ChainID()) + if txEnv == nil { + return nil, fmt.Errorf("no transaction envelope or payload provided") + } + return ts.transactor.BroadcastTxSync(ctx, txEnv) +} + +func (ts *transactServer) BroadcastTxAsync(ctx context.Context, param *TxEnvelopeParam) (*txs.Receipt, error) { + txEnv := param.GetEnvelope(ts.transactor.Tip.ChainID()) + if txEnv == nil { + return nil, fmt.Errorf("no transaction envelope or payload provided") + } + return ts.transactor.BroadcastTxAsync(txEnv) +} + +func (ts *transactServer) SignTx(ctx context.Context, param *TxEnvelopeParam) (*TxEnvelope, error) { + txEnv := param.GetEnvelope(ts.transactor.Tip.ChainID()) + if txEnv == nil { + return nil, fmt.Errorf("no transaction envelope or payload provided") + } + txEnv, err := ts.transactor.SignTx(txEnv) + if err != nil { + return nil, err + } + return &TxEnvelope{ + Envelope: txEnv, + }, nil +} + +func (ts *transactServer) FormulateTx(ctx context.Context, param *PayloadParam) (*TxEnvelope, error) { + txEnv := param.Envelope(ts.transactor.Tip.ChainID()) + if txEnv == nil { + return nil, fmt.Errorf("no payload provided to FormulateTx") + } + return &TxEnvelope{ + Envelope: txEnv, + }, nil +} + +func (ts *transactServer) CallTxSync(ctx context.Context, param *payload.CallTx) (*exec.TxExecution, error) { + return ts.BroadcastTxSync(ctx, txEnvelopeParam(param)) +} + +func (ts *transactServer) CallTxAsync(ctx context.Context, param *payload.CallTx) (*txs.Receipt, error) { + return ts.BroadcastTxAsync(ctx, txEnvelopeParam(param)) +} + +func (ts *transactServer) CallTxSim(ctx context.Context, param *payload.CallTx) (*exec.TxExecution, error) { + if param.Address == nil { + return nil, fmt.Errorf("CallSim requires a non-nil address from which to retrieve code") + } + return ts.transactor.CallSim(param.Input.Address, *param.Address, param.Data) +} + +func (ts *transactServer) CallCodeSim(ctx context.Context, param *CallCodeParam) (*exec.TxExecution, error) { + return ts.transactor.CallCodeSim(param.FromAddress, param.Code, param.Data) +} + +func (ts *transactServer) SendTxSync(ctx context.Context, param *payload.SendTx) (*exec.TxExecution, error) { + return ts.BroadcastTxSync(ctx, txEnvelopeParam(param)) +} + +func (ts *transactServer) SendTxAsync(ctx context.Context, param *payload.SendTx) (*txs.Receipt, error) { + return ts.BroadcastTxAsync(ctx, txEnvelopeParam(param)) +} + +func (ts *transactServer) NameTxSync(ctx context.Context, param *payload.NameTx) (*exec.TxExecution, error) { + return ts.BroadcastTxSync(ctx, txEnvelopeParam(param)) +} + +func (ts *transactServer) NameTxAsync(ctx context.Context, param *payload.NameTx) (*txs.Receipt, error) { + return ts.BroadcastTxAsync(ctx, txEnvelopeParam(param)) +} + +func (te *TxEnvelopeParam) GetEnvelope(chainID string) *txs.Envelope { + if te == nil { + return nil + } + if te.Envelope != nil { + return te.Envelope + } + if te.Payload != nil { + return te.Payload.Envelope(chainID) + } + return nil +} + +func (pp *PayloadParam) Envelope(chainID string) *txs.Envelope { + if pp.CallTx != nil { + return txs.Enclose(chainID, pp.CallTx) + } + if pp.SendTx != nil { + return txs.Enclose(chainID, pp.SendTx) + } + if pp.NameTx != nil { + return txs.Enclose(chainID, pp.NameTx) + } + return nil +} + +func txEnvelopeParam(pl payload.Payload) *TxEnvelopeParam { + switch tx := pl.(type) { + case *payload.CallTx: + return &TxEnvelopeParam{ + Payload: &PayloadParam{ + CallTx: tx, + }, + } + case *payload.SendTx: + return &TxEnvelopeParam{ + Payload: &PayloadParam{ + SendTx: tx, + }, + } + case *payload.NameTx: + return &TxEnvelopeParam{ + Payload: &PayloadParam{ + NameTx: tx, + }, + } + } + return nil +} diff --git a/rpc/rpctransactor/integration/transactor_server_test.go b/rpc/rpctransactor/integration/transactor_server_test.go deleted file mode 100644 index cbb1a1c7556ee52f14070d099145334ae8a631ab..0000000000000000000000000000000000000000 --- a/rpc/rpctransactor/integration/transactor_server_test.go +++ /dev/null @@ -1,168 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "context" - "sync" - "testing" - - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/execution/pbtransactor" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/rpc/test" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/grpc" -) - -func TestTransactCallNoCode(t *testing.T) { - cli := newClient(t) - - // Flip flops between sending private key and input address to test private key and address based signing - toAddress := privateAccounts[2].Address() - - numCreates := 1000 - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numCreates; i++ { - receipt, err := cli.Transact(context.Background(), &pbtransactor.TransactParam{ - InputAccount: inputAccount(i), - Address: toAddress.Bytes(), - Data: []byte{}, - Value: 0, - Fee: 2, - GasLimit: 10000 + uint64(i), - }) - require.NoError(t, err) - assert.False(t, receipt.CreatesContract) - assert.Equal(t, toAddress.Bytes(), receipt.ContractAddress) - } - require.Equal(t, numCreates, <-countCh) -} - -func TestTransactCreate(t *testing.T) { - cli := newClient(t) - numGoroutines := 100 - numCreates := 50 - wg := new(sync.WaitGroup) - wg.Add(numGoroutines) - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numGoroutines; i++ { - go func() { - for j := 0; j < numCreates; j++ { - create, err := cli.Transact(context.Background(), &pbtransactor.TransactParam{ - InputAccount: inputAccount(i), - Address: nil, - Data: test.Bytecode_strange_loop, - Value: 0, - Fee: 2, - GasLimit: 10000, - }) - if assert.NoError(t, err) { - assert.True(t, create.CreatesContract) - } - } - wg.Done() - }() - } - wg.Wait() - - require.Equal(t, numGoroutines*numCreates, <-countCh) -} - -func BenchmarkTransactCreateContract(b *testing.B) { - cli := newClient(b) - for i := 0; i < b.N; i++ { - create, err := cli.Transact(context.Background(), &pbtransactor.TransactParam{ - InputAccount: inputAccount(i), - Address: nil, - Data: test.Bytecode_strange_loop, - Value: 0, - Fee: 2, - GasLimit: 10000, - }) - require.NoError(b, err) - assert.True(b, create.CreatesContract) - } -} - -func TestTransactAndHold(t *testing.T) { - cli := newClient(t) - numGoroutines := 5 - numRuns := 2 - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numGoroutines; i++ { - for j := 0; j < numRuns; j++ { - create := test.CreateContract(t, cli, inputAccount(i)) - call := test.CallContract(t, cli, inputAccount(i), create.CallData.Callee) - depth := binary.Uint64FromWord256(binary.LeftPadWord256(call.Return)) - // Would give 23 if taken from wrong frame - assert.Equal(t, 18, int(depth)) - } - } - require.Equal(t, numGoroutines*numRuns*2, <-countCh) -} - -func TestSend(t *testing.T) { - cli := newClient(t) - numSends := 1000 - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numSends; i++ { - send, err := cli.Send(context.Background(), &pbtransactor.SendParam{ - InputAccount: inputAccount(i), - Amount: 2003, - ToAddress: privateAccounts[3].Address().Bytes(), - }) - require.NoError(t, err) - assert.Equal(t, false, send.CreatesContract) - } - require.Equal(t, numSends, <-countCh) -} - -func TestSendAndHold(t *testing.T) { - cli := newClient(t) - for i := 0; i < 2; i++ { - send, err := cli.SendAndHold(context.Background(), &pbtransactor.SendParam{ - InputAccount: inputAccount(i), - Amount: 2003, - ToAddress: privateAccounts[3].Address().Bytes(), - }) - require.NoError(t, err) - assert.Equal(t, false, send.CreatesContract) - } -} - -// Helpers -func newClient(t testing.TB) pbtransactor.TransactorClient { - conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure()) - require.NoError(t, err) - return pbtransactor.NewTransactorClient(conn) -} - -var inputPrivateKey = privateAccounts[0].PrivateKey().RawBytes() -var inputAddress = privateAccounts[0].Address().Bytes() - -func inputAccount(i int) *pbtransactor.InputAccount { - ia := new(pbtransactor.InputAccount) - if i%2 == 0 { - ia.PrivateKey = inputPrivateKey - } else { - ia.Address = inputAddress - } - return ia -} diff --git a/rpc/rpctransactor/transactor_server.go b/rpc/rpctransactor/transactor_server.go deleted file mode 100644 index aeed1c4b011a96604d073c34609370e41543f513..0000000000000000000000000000000000000000 --- a/rpc/rpctransactor/transactor_server.go +++ /dev/null @@ -1,190 +0,0 @@ -package rpctransactor - -import ( - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution" - "github.com/hyperledger/burrow/execution/events/pbevents" - "github.com/hyperledger/burrow/execution/pbtransactor" - "github.com/hyperledger/burrow/txs" - "golang.org/x/net/context" -) - -type transactorServer struct { - transactor *execution.Transactor - accounts *execution.Accounts - txCodec txs.Codec - reader state.Reader -} - -func NewTransactorServer(transactor *execution.Transactor, accounts *execution.Accounts, reader state.Reader, - txCodec txs.Codec) pbtransactor.TransactorServer { - return &transactorServer{ - transactor: transactor, - accounts: accounts, - reader: reader, - txCodec: txCodec, - } -} - -func (ts *transactorServer) BroadcastTx(ctx context.Context, param *pbtransactor.TxParam) (*pbtransactor.TxReceipt, error) { - receipt, err := ts.transactor.BroadcastTxRaw(param.GetTx()) - if err != nil { - return nil, err - } - return txReceipt(receipt), nil -} - -func (ts *transactorServer) Call(ctx context.Context, param *pbtransactor.CallParam) (*pbtransactor.CallResult, error) { - fromAddress, err := crypto.AddressFromBytes(param.GetFrom()) - if err != nil { - return nil, err - } - address, err := crypto.AddressFromBytes(param.GetAddress()) - if err != nil { - return nil, err - } - call, err := ts.transactor.Call(ts.reader, fromAddress, address, param.GetData()) - return &pbtransactor.CallResult{ - Return: call.Return, - GasUsed: call.GasUsed, - }, nil -} - -func (ts *transactorServer) CallCode(ctx context.Context, param *pbtransactor.CallCodeParam) (*pbtransactor.CallResult, error) { - fromAddress, err := crypto.AddressFromBytes(param.GetFrom()) - if err != nil { - return nil, err - } - call, err := ts.transactor.CallCode(ts.reader, fromAddress, param.GetCode(), param.GetData()) - return &pbtransactor.CallResult{ - Return: call.Return, - GasUsed: call.GasUsed, - }, nil -} - -func (ts *transactorServer) Transact(ctx context.Context, param *pbtransactor.TransactParam) (*pbtransactor.TxReceipt, error) { - inputAccount, err := ts.inputAccount(param.GetInputAccount()) - if err != nil { - return nil, err - } - address, err := crypto.MaybeAddressFromBytes(param.GetAddress()) - if err != nil { - return nil, err - } - receipt, err := ts.transactor.Transact(inputAccount, address, param.GetData(), param.GetGasLimit(), param.GetValue(), - param.GetFee()) - if err != nil { - return nil, err - } - return txReceipt(receipt), nil -} - -func (ts *transactorServer) TransactAndHold(ctx context.Context, param *pbtransactor.TransactParam) (*pbevents.EventDataCall, error) { - inputAccount, err := ts.inputAccount(param.GetInputAccount()) - if err != nil { - return nil, err - } - address, err := crypto.MaybeAddressFromBytes(param.GetAddress()) - if err != nil { - return nil, err - } - edt, err := ts.transactor.TransactAndHold(ctx, inputAccount, address, param.GetData(), param.GetGasLimit(), - param.GetValue(), param.GetFee()) - if err != nil { - return nil, err - } - return pbevents.GetEventDataCall(edt), nil -} - -func (ts *transactorServer) Send(ctx context.Context, param *pbtransactor.SendParam) (*pbtransactor.TxReceipt, error) { - inputAccount, err := ts.inputAccount(param.GetInputAccount()) - if err != nil { - return nil, err - } - toAddress, err := crypto.AddressFromBytes(param.GetToAddress()) - if err != nil { - return nil, err - } - receipt, err := ts.transactor.Send(inputAccount, toAddress, param.GetAmount()) - if err != nil { - return nil, err - } - return txReceipt(receipt), nil -} - -func (ts *transactorServer) SendAndHold(ctx context.Context, param *pbtransactor.SendParam) (*pbtransactor.TxReceipt, error) { - inputAccount, err := ts.inputAccount(param.GetInputAccount()) - if err != nil { - return nil, err - } - toAddress, err := crypto.AddressFromBytes(param.GetToAddress()) - if err != nil { - return nil, err - } - receipt, err := ts.transactor.SendAndHold(ctx, inputAccount, toAddress, param.GetAmount()) - if err != nil { - return nil, err - } - return txReceipt(receipt), nil -} - -func (ts *transactorServer) SignTx(ctx context.Context, param *pbtransactor.SignTxParam) (*pbtransactor.SignedTx, error) { - txEnv, err := ts.txCodec.DecodeTx(param.GetTx()) - if err != nil { - return nil, err - } - signers, err := signersFromPrivateAccounts(param.GetPrivateAccounts()) - if err != nil { - return nil, err - } - txEnvSigned, err := ts.transactor.SignTx(txEnv, signers) - if err != nil { - return nil, err - } - bs, err := ts.txCodec.EncodeTx(txEnvSigned) - if err != nil { - return nil, err - } - return &pbtransactor.SignedTx{ - Tx: bs, - }, nil -} - -func (ts *transactorServer) inputAccount(inAcc *pbtransactor.InputAccount) (*execution.SequentialSigningAccount, error) { - return ts.accounts.GetSequentialSigningAccount(inAcc.GetAddress(), inAcc.GetPrivateKey()) -} - -func txReceipt(receipt *txs.Receipt) *pbtransactor.TxReceipt { - return &pbtransactor.TxReceipt{ - ContractAddress: receipt.ContractAddress.Bytes(), - CreatesContract: receipt.CreatesContract, - TxHash: receipt.TxHash, - } -} - -func signersFromPrivateAccounts(privateAccounts []*pbtransactor.PrivateAccount) ([]acm.AddressableSigner, error) { - signers := make([]acm.AddressableSigner, len(privateAccounts)) - var err error - for i, pa := range privateAccounts { - signers[i], err = privateAccount(pa) - if err != nil { - return nil, err - } - } - return signers, nil -} - -func privateAccount(privateAccount *pbtransactor.PrivateAccount) (acm.PrivateAccount, error) { - privateKey, err := crypto.PrivateKeyFromRawBytes(privateAccount.PrivateKey, crypto.CurveTypeEd25519) - if err != nil { - return nil, err - } - publicKey := privateKey.GetPublicKey() - return acm.ConcretePrivateAccount{ - Address: publicKey.Address(), - PrivateKey: privateKey, - PublicKey: publicKey, - }.PrivateAccount(), nil -} diff --git a/rpc/service.go b/rpc/service.go index 0863a65a4e4678ecd2d9aff64a25ad37d2a10422..098dd150386500ea623adbdb9cf31aff8a2d27a8 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -15,73 +15,51 @@ package rpc import ( - "context" + "encoding/json" "fmt" - "time" - "encoding/json" - - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/binary" bcm "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/consensus/tendermint/query" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/execution/names" - "github.com/hyperledger/burrow/keys" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/permission" "github.com/hyperledger/burrow/project" "github.com/hyperledger/burrow/txs" - tm_types "github.com/tendermint/tendermint/types" - "github.com/tmthrgd/go-hex" + tmTypes "github.com/tendermint/tendermint/types" ) // Magic! Should probably be configurable, but not shouldn't be so huge we // end up DoSing ourselves. const MaxBlockLookback = 1000 -const AccountsRingMutexCount = 100 // Base service that provides implementation for all underlying RPC methods type Service struct { - ctx context.Context - state state.IterableReader - nameReg names.IterableReader - mempoolAccounts *execution.Accounts - subscribable event.Subscribable - blockchain bcm.BlockchainInfo - transactor *execution.Transactor - nodeView *query.NodeView - logger *logging.Logger + state state.IterableReader + nameReg names.IterableReader + blockchain bcm.BlockchainInfo + transactor *execution.Transactor + nodeView *query.NodeView + logger *logging.Logger } -func NewService(ctx context.Context, state state.IterableReader, nameReg names.IterableReader, - checker state.Reader, subscribable event.Subscribable, blockchain bcm.BlockchainInfo, keyClient keys.KeyClient, - transactor *execution.Transactor, nodeView *query.NodeView, logger *logging.Logger) *Service { - - return &Service{ - ctx: ctx, - state: state, - mempoolAccounts: execution.NewAccounts(checker, keyClient, AccountsRingMutexCount), - nameReg: nameReg, - subscribable: subscribable, - blockchain: blockchain, - transactor: transactor, - nodeView: nodeView, - logger: logger.With(structure.ComponentKey, "Service"), - } -} +func NewService(state state.IterableReader, nameReg names.IterableReader, + blockchain bcm.BlockchainInfo, transactor *execution.Transactor, nodeView *query.NodeView, + logger *logging.Logger) *Service { -// Provides a sub-service with only the subscriptions methods -func NewSubscribableService(subscribable event.Subscribable, logger *logging.Logger) *Service { return &Service{ - ctx: context.Background(), - subscribable: subscribable, - logger: logger.With(structure.ComponentKey, "Service"), + state: state, + nameReg: nameReg, + blockchain: blockchain, + transactor: transactor, + nodeView: nodeView, + logger: logger.With(structure.ComponentKey, "Service"), } } @@ -91,18 +69,6 @@ func (s *Service) Transactor() *execution.Transactor { return s.transactor } -// By providing certain methods on the Transactor (such as Transact, Send, etc) with the (non-final) MempoolAccounts -// rather than the committed (final) Accounts state the transactor can assign a sequence number based on all of the txs -// it has seen since the last block - provided these transactions are successfully committed (via DeliverTx) then -// subsequent transactions will have valid sequence numbers. This allows Burrow to coordinate sequencing and signing -// for a key it holds or is provided - it is down to the key-holder to manage the mutual information between transactions -// concurrent within a new block window. - -// Get pending account state residing in the mempool -func (s *Service) MempoolAccounts() *execution.Accounts { - return s.mempoolAccounts -} - func (s *Service) State() state.Reader { return s.state } @@ -111,6 +77,10 @@ func (s *Service) BlockchainInfo() bcm.BlockchainInfo { return s.blockchain } +func (s *Service) ChainID() string { + return s.blockchain.ChainID() +} + func (s *Service) ListUnconfirmedTxs(maxTxs int) (*ResultListUnconfirmedTxs, error) { // Get all transactions for now transactions, err := s.nodeView.MempoolTransactions(maxTxs) @@ -127,42 +97,10 @@ func (s *Service) ListUnconfirmedTxs(maxTxs int) (*ResultListUnconfirmedTxs, err }, nil } -func (s *Service) Subscribe(ctx context.Context, subscriptionID string, eventID string, - callback func(resultEvent *ResultEvent) (stop bool)) error { - - queryBuilder := event.QueryForEventID(eventID) - s.logger.InfoMsg("Subscribing to events", - "query", queryBuilder.String(), - "subscription_id", subscriptionID, - "event_id", eventID) - return event.SubscribeCallback(ctx, s.subscribable, subscriptionID, queryBuilder, - func(message interface{}) (stop bool) { - resultEvent, err := NewResultEvent(eventID, message) - if err != nil { - s.logger.InfoMsg("Received event that could not be mapped to ResultEvent", - structure.ErrorKey, err, - "subscription_id", subscriptionID, - "event_id", eventID) - return false - } - return callback(resultEvent) - }) -} - -func (s *Service) Unsubscribe(ctx context.Context, subscriptionID string) error { - s.logger.InfoMsg("Unsubscribing from events", - "subscription_id", subscriptionID) - err := s.subscribable.UnsubscribeAll(ctx, subscriptionID) - if err != nil { - return fmt.Errorf("error unsubscribing from event with subscriptionID '%s': %v", subscriptionID, err) - } - return nil -} - func (s *Service) Status() (*ResultStatus, error) { latestHeight := s.blockchain.LastBlockHeight() var ( - latestBlockMeta *tm_types.BlockMeta + latestBlockMeta *tmTypes.BlockMeta latestBlockHash []byte latestBlockTime int64 ) @@ -287,7 +225,6 @@ func (s *Service) DumpStorage(address crypto.Address) (*ResultDumpStorage, error return }) return &ResultDumpStorage{ - StorageRoot: account.StorageRoot(), StorageItems: storageItems, }, nil } @@ -315,7 +252,6 @@ func (s *Service) GetAccountHumanReadable(address crypto.Address) (*ResultGetAcc Sequence: acc.Sequence(), Balance: acc.Balance(), Code: tokens, - StorageRoot: hex.EncodeUpperToString(acc.StorageRoot()), Permissions: perms, Roles: acc.Permissions().Roles, }, @@ -324,7 +260,7 @@ func (s *Service) GetAccountHumanReadable(address crypto.Address) (*ResultGetAcc // Name registry func (s *Service) GetName(name string) (*ResultGetName, error) { - entry, err := s.nameReg.GetNameEntry(name) + entry, err := s.nameReg.GetName(name) if err != nil { return nil, err } @@ -336,7 +272,7 @@ func (s *Service) GetName(name string) (*ResultGetName, error) { func (s *Service) ListNames(predicate func(*names.Entry) bool) (*ResultListNames, error) { var nms []*names.Entry - s.nameReg.IterateNameEntries(func(entry *names.Entry) (stop bool) { + s.nameReg.IterateNames(func(entry *names.Entry) (stop bool) { if predicate(entry) { nms = append(nms, entry) } @@ -373,7 +309,7 @@ func (s *Service) ListBlocks(minHeight, maxHeight uint64) (*ResultListBlocks, er minHeight = maxHeight - MaxBlockLookback } - var blockMetas []*tm_types.BlockMeta + var blockMetas []*tmTypes.BlockMeta for height := maxHeight; height >= minHeight; height-- { blockMeta := s.nodeView.BlockStore().LoadBlockMeta(int64(height)) blockMetas = append(blockMetas, blockMeta) @@ -419,7 +355,7 @@ func (s *Service) GeneratePrivateAccount() (*ResultGeneratePrivateAccount, error return nil, err } return &ResultGeneratePrivateAccount{ - PrivateAccount: acm.AsConcretePrivateAccount(privateAccount), + PrivateAccount: privateAccount.ConcretePrivateAccount(), }, nil } diff --git a/rpc/subscriptions.go b/rpc/subscriptions.go deleted file mode 100644 index 35808890bcf78067304934bd41c0d7015bd82fda..0000000000000000000000000000000000000000 --- a/rpc/subscriptions.go +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package rpc - -import ( - "context" - "fmt" - "sync" - "time" - - "github.com/hyperledger/burrow/event" -) - -var ( - reaperPeriod = 5 * time.Second - reaperThreshold = 20 * time.Second -) - -// Catches events that callers subscribe to and adds them to an array ready to be polled. -type Subscriptions struct { - mtx *sync.RWMutex - service *Service - subs map[string]*SubscriptionsCache - reap bool -} - -type SubscriptionsCache struct { - mtx *sync.Mutex - events []interface{} - ts time.Time - subID string -} - -func NewSubscriptions(service *Service) *Subscriptions { - es := &Subscriptions{ - mtx: &sync.RWMutex{}, - service: service, - subs: make(map[string]*SubscriptionsCache), - reap: true, - } - if es.reap { - go reap(es) - } - return es -} - -func newSubscriptionsCache(subID string) *SubscriptionsCache { - return &SubscriptionsCache{ - subID: subID, - mtx: &sync.Mutex{}, - events: make([]interface{}, 0), - ts: time.Now(), - } -} - -func (subsCache *SubscriptionsCache) poll() []interface{} { - subsCache.mtx.Lock() - defer subsCache.mtx.Unlock() - var evts []interface{} - if len(subsCache.events) > 0 { - evts = subsCache.events - subsCache.events = []interface{}{} - } else { - evts = []interface{}{} - } - subsCache.ts = time.Now() - return evts -} - -// Remove old subscriptions not recently polled -func reap(es *Subscriptions) { - for { - time.Sleep(reaperPeriod) - for id, sub := range es.subs { - if time.Since(sub.ts) > reaperThreshold { - es.mtx.Lock() - delete(es.subs, id) - es.service.Unsubscribe(context.Background(), id) - es.mtx.Unlock() - } - } - } -} - -// Add a subscription and return the generated id. Note event dispatcher -// has to call func which involves acquiring a mutex lock, so might be -// a delay - though a conflict is practically impossible, and if it does -// happen it's for an insignificant amount of time (the time it takes to -// carry out SubscriptionsCache.poll() ). -func (subs *Subscriptions) Add(eventId string) (string, error) { - subID, err := event.GenerateSubscriptionID() - if err != nil { - return "", err - } - subs.mtx.Lock() - defer subs.mtx.Unlock() - cache := newSubscriptionsCache(subID) - subs.subs[subID] = cache - - err = subs.service.Subscribe(context.Background(), subID, eventId, func(resultEvent *ResultEvent) (stop bool) { - cache.mtx.Lock() - defer cache.mtx.Unlock() - cache.events = append(cache.events, resultEvent) - return - }) - if err != nil { - return "", err - } - - return subID, nil -} - -func (subs *Subscriptions) Poll(subId string) ([]interface{}, error) { - subs.mtx.RLock() - defer subs.mtx.RUnlock() - sub, ok := subs.subs[subId] - if !ok { - return nil, fmt.Errorf("Subscription not active. ID: " + subId) - } - return sub.poll(), nil -} - -func (subs *Subscriptions) Remove(subId string) error { - subs.mtx.Lock() - defer subs.mtx.Unlock() - _, ok := subs.subs[subId] - if !ok { - return fmt.Errorf("Subscription not active. ID: " + subId) - } - delete(subs.subs, subId) - return nil -} diff --git a/rpc/subscriptions_test.go b/rpc/subscriptions_test.go deleted file mode 100644 index fa67f6cf706636ccfd40b0abfb9f6b468a00c02a..0000000000000000000000000000000000000000 --- a/rpc/subscriptions_test.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package rpc - -import ( - "encoding/hex" - "fmt" - "testing" - "time" - - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/logging" - "github.com/stretchr/testify/assert" -) - -var mockInterval = 20 * time.Millisecond - -// Test that event subscriptions can be added manually and then automatically reaped. -func TestSubReaping(t *testing.T) { - NUM_SUBS := 100 - reaperThreshold = 200 * time.Millisecond - reaperPeriod = 100 * time.Millisecond - - mee := event.NewEmitter(logging.NewNoopLogger()) - eSubs := NewSubscriptions(NewSubscribableService(mee, logging.NewNoopLogger())) - doneChan := make(chan error) - go func() { - for i := 0; i < NUM_SUBS; i++ { - time.Sleep(2 * time.Millisecond) - go func() { - id, err := eSubs.Add("WeirdEvent") - if err != nil { - doneChan <- err - return - } - if len(id) != 64 { - doneChan <- fmt.Errorf("Id not of length 64") - return - } - _, err2 := hex.DecodeString(id) - if err2 != nil { - doneChan <- err2 - } - - doneChan <- nil - }() - } - }() - k := 0 - for k < NUM_SUBS { - err := <-doneChan - assert.NoError(t, err) - k++ - } - time.Sleep(1100 * time.Millisecond) - - assert.Len(t, eSubs.subs, 0) - t.Logf("Added %d subs that were all automatically reaped.", NUM_SUBS) -} - -// Test that event subscriptions can be added and removed manually. -func TestSubManualClose(t *testing.T) { - NUM_SUBS := 100 - // Keep the reaper out of this. - reaperThreshold = 10000 * time.Millisecond - reaperPeriod = 10000 * time.Millisecond - - mee := event.NewEmitter(logging.NewNoopLogger()) - eSubs := NewSubscriptions(NewSubscribableService(mee, logging.NewNoopLogger())) - doneChan := make(chan error) - go func() { - for i := 0; i < NUM_SUBS; i++ { - time.Sleep(2 * time.Millisecond) - go func() { - id, err := eSubs.Add("WeirdEvent") - if err != nil { - doneChan <- err - return - } - if len(id) != 64 { - doneChan <- fmt.Errorf("Id not of length 64") - return - } - _, err2 := hex.DecodeString(id) - if err2 != nil { - doneChan <- err2 - } - time.Sleep(100 * time.Millisecond) - err3 := eSubs.Remove(id) - if err3 != nil { - doneChan <- err3 - } - doneChan <- nil - }() - } - }() - k := 0 - for k < NUM_SUBS { - err := <-doneChan - assert.NoError(t, err) - k++ - } - - assert.Len(t, eSubs.subs, 0) - t.Logf("Added %d subs that were all closed down by unsubscribing.", NUM_SUBS) -} - -// Test that the system doesn't fail under high pressure. -func TestSubFlooding(t *testing.T) { - NUM_SUBS := 100 - // Keep the reaper out of this. - reaperThreshold = 10000 * time.Millisecond - reaperPeriod = 10000 * time.Millisecond - // Crank it up. Now pressure is 10 times higher on each sub. - mockInterval = 1 * time.Millisecond - mee := event.NewEmitter(logging.NewNoopLogger()) - eSubs := NewSubscriptions(NewSubscribableService(mee, logging.NewNoopLogger())) - doneChan := make(chan error) - go func() { - for i := 0; i < NUM_SUBS; i++ { - time.Sleep(1 * time.Millisecond) - go func() { - id, err := eSubs.Add("WeirdEvent") - if err != nil { - doneChan <- err - return - } - if len(id) != 64 { - doneChan <- fmt.Errorf("Id not of length 64") - return - } - _, err2 := hex.DecodeString(id) - if err2 != nil { - doneChan <- err2 - } - time.Sleep(1000 * time.Millisecond) - err3 := eSubs.Remove(id) - if err3 != nil { - doneChan <- err3 - } - doneChan <- nil - }() - } - }() - k := 0 - for k < NUM_SUBS { - err := <-doneChan - assert.NoError(t, err) - k++ - } - - assert.Len(t, eSubs.subs, 0) - t.Logf("Added %d subs that all received 1000 events each. They were all closed down by unsubscribing.", NUM_SUBS) -} diff --git a/rpc/test/helpers.go b/rpc/test/helpers.go deleted file mode 100644 index 0e7d934f526806819c3aa14e648c3aa963ea1046..0000000000000000000000000000000000000000 --- a/rpc/test/helpers.go +++ /dev/null @@ -1,99 +0,0 @@ -package test - -import ( - "context" - "testing" - - "github.com/hyperledger/burrow/consensus/tendermint" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/events/pbevents" - "github.com/hyperledger/burrow/execution/evm/abi" - "github.com/hyperledger/burrow/execution/pbtransactor" - "github.com/hyperledger/burrow/rpc" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "google.golang.org/grpc" -) - -// Recursive call count for UpsieDownsie() function call from strange_loop.sol -// Equals initial call, then depth from 17 -> 34, one for the bounce, then depth from 34 -> 23, -// so... (I didn't say it had to make sense): -const UpsieDownsieCallCount = 1 + (34 - 17) + 1 + (34 - 23) - -// Helpers -func NewTransactorClient(t testing.TB) pbtransactor.TransactorClient { - conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure()) - require.NoError(t, err) - return pbtransactor.NewTransactorClient(conn) -} - -func NewExecutionEventsClient(t testing.TB) pbevents.ExecutionEventsClient { - conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure()) - require.NoError(t, err) - return pbevents.NewExecutionEventsClient(conn) -} - -func NewEventsClient(t testing.TB) pbevents.EventsClient { - conn, err := grpc.Dial(rpc.DefaultGRPCConfig().ListenAddress, grpc.WithInsecure()) - require.NoError(t, err) - return pbevents.NewEventsClient(conn) -} - -func CommittedTxCount(t *testing.T, em event.Emitter) chan int { - var numTxs int64 - emptyBlocks := 0 - maxEmptyBlocks := 2 - outCh := make(chan int) - ctx := context.Background() - ch, err := tendermint.SubscribeNewBlock(ctx, em) - require.NoError(t, err) - - go func() { - for ed := range ch { - if ed.Block.NumTxs == 0 { - emptyBlocks++ - } else { - emptyBlocks = 0 - } - if emptyBlocks > maxEmptyBlocks { - break - } - numTxs += ed.Block.NumTxs - t.Logf("Total TXs committed at block %v: %v (+%v)\n", ed.Block.Height, numTxs, ed.Block.NumTxs) - } - outCh <- int(numTxs) - }() - return outCh -} - -func CreateContract(t testing.TB, cli pbtransactor.TransactorClient, - inputAccount *pbtransactor.InputAccount) *pbevents.EventDataCall { - - create, err := cli.TransactAndHold(context.Background(), &pbtransactor.TransactParam{ - InputAccount: inputAccount, - Address: nil, - Data: Bytecode_strange_loop, - Value: 0, - Fee: 2, - GasLimit: 10000, - }) - require.NoError(t, err) - assert.Equal(t, uint64(0), create.StackDepth) - return create -} - -func CallContract(t testing.TB, cli pbtransactor.TransactorClient, - inputAccount *pbtransactor.InputAccount, contractAddress []byte) (call *pbevents.EventDataCall) { - - functionID := abi.FunctionID("UpsieDownsie()") - call, err := cli.TransactAndHold(context.Background(), &pbtransactor.TransactParam{ - InputAccount: inputAccount, - Address: contractAddress, - Data: functionID[:], - Value: 0, - Fee: 2, - GasLimit: 10000, - }) - require.NoError(t, err) - return call -} diff --git a/rpc/tm/client/websocket_client.go b/rpc/tm/client/websocket_client.go deleted file mode 100644 index d07f05f1d2dbfd586f628769313c10d220fffb2d..0000000000000000000000000000000000000000 --- a/rpc/tm/client/websocket_client.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package client - -import ( - "context" - - "github.com/hyperledger/burrow/rpc/lib/types" - "github.com/hyperledger/burrow/rpc/tm" -) - -type WebsocketClient interface { - Send(ctx context.Context, request types.RPCRequest) error -} - -const SubscribeRequestID = "Subscribe" -const UnsubscribeRequestID = "Unsubscribe" - -func EventResponseID(eventID string) string { - return tm.EventResponseID(SubscribeRequestID, eventID) -} - -func Subscribe(wsc WebsocketClient, eventID string) error { - req, err := types.MapToRequest(SubscribeRequestID, - "subscribe", map[string]interface{}{"eventID": eventID}) - if err != nil { - return err - } - return wsc.Send(context.Background(), req) -} - -func Unsubscribe(websocketClient WebsocketClient, subscriptionID string) error { - req, err := types.MapToRequest(UnsubscribeRequestID, - "unsubscribe", map[string]interface{}{"subscriptionID": subscriptionID}) - if err != nil { - return err - } - return websocketClient.Send(context.Background(), req) -} diff --git a/rpc/tm/integration/server_test.go b/rpc/tm/integration/server_test.go deleted file mode 100644 index b30a66ec13da1107732b75f8d97337f858827e90..0000000000000000000000000000000000000000 --- a/rpc/tm/integration/server_test.go +++ /dev/null @@ -1,398 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "bytes" - "testing" - "time" - - "fmt" - "strings" - - "github.com/hyperledger/burrow/binary" - exe_events "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/execution/names" - "github.com/hyperledger/burrow/rpc" - tm_client "github.com/hyperledger/burrow/rpc/tm/client" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/tendermint/tendermint/consensus/types" - "golang.org/x/crypto/ripemd160" -) - -func testWithAllClients(t *testing.T, testFunction func(*testing.T, string, tm_client.RPCClient)) { - for clientName, client := range clients { - testFunction(t, clientName, client) - } -} - -//-------------------------------------------------------------------------------- -func TestStatus(t *testing.T) { - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - resp, err := tm_client.Status(client) - assert.NoError(t, err) - assert.Equal(t, genesisDoc.ChainID(), resp.NodeInfo.Network, "ChainID should match NodeInfo.Network") - }) -} - -func TestBroadcastTx(t *testing.T) { - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - // Avoid duplicate Tx in mempool - amt := hashString(clientName) % 1000 - toAddr := privateAccounts[1].Address() - txEnv := makeDefaultSendTxSigned(t, client, toAddr, amt) - receipt, err := broadcastTxAndWait(t, client, txEnv) - require.NoError(t, err) - assert.False(t, receipt.CreatesContract, "This tx should not create a contract") - assert.NotEmpty(t, receipt.TxHash, "Failed to compute tx hash") - - hasher := ripemd160.New() - txSignBytes, err := txEnv.Tx.SignBytes() - require.NoError(t, err) - hasher.Write(txSignBytes) - txHashExpected := hasher.Sum(nil) - - if bytes.Compare(receipt.TxHash, txHashExpected) != 0 { - t.Fatalf("The receipt hash '%x' does not equal the ripemd160 hash of the "+ - "transaction signed bytes calculated in the test: '%x'", - receipt.TxHash, txHashExpected) - } - }) -} - -func TestGetAccount(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - acc := getAccount(t, client, privateAccounts[0].Address()) - if acc == nil { - t.Fatal("Account was nil") - } - if acc.Address() != privateAccounts[0].Address() { - t.Fatalf("Failed to get correct account. Got %s, expected %s", acc.Address(), - privateAccounts[0].Address()) - } - }) -} - -func TestGetStorage(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000) - code := []byte{0x60, 0x5, 0x60, 0x1, 0x55} - // Call with nil address will create a contract - tx := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee) - receipt, err := broadcastTxAndWait(t, client, tx) - assert.NoError(t, err) - assert.Equal(t, true, receipt.CreatesContract, "This transaction should"+ - " create a contract") - assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+ - " transaction hash") - contractAddr := receipt.ContractAddress - assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+ - " created a contract but the contract address is empty") - - v := getStorage(t, client, contractAddr, []byte{0x1}) - got := binary.LeftPadWord256(v) - expected := binary.LeftPadWord256([]byte{0x5}) - if got.Compare(expected) != 0 { - t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(), - expected.Bytes()) - } - }) -} - -func TestCallCode(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - // add two integers and return the result - code := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, 0x60, - 0x0, 0xf3} - data := []byte{} - expected := []byte{0xb} - callCode(t, client, privateAccounts[0].Address(), code, data, expected) - - // pass two ints as calldata, add, and return the result - code = []byte{0x60, 0x0, 0x35, 0x60, 0x20, 0x35, 0x1, 0x60, 0x0, 0x52, 0x60, - 0x20, 0x60, 0x0, 0xf3} - data = append(binary.LeftPadWord256([]byte{0x5}).Bytes(), - binary.LeftPadWord256([]byte{0x6}).Bytes()...) - expected = []byte{0xb} - callCode(t, client, privateAccounts[0].Address(), code, data, expected) - }) -} - -func TestCallContract(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - // create the contract - amt, gasLim, fee := uint64(6969), uint64(1000), uint64(1000) - code, _, _ := simpleContract() - tx := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee) - receipt, err := broadcastTxAndWait(t, client, tx) - assert.NoError(t, err) - if err != nil { - t.Fatalf("Problem broadcasting transaction: %v", err) - } - assert.Equal(t, true, receipt.CreatesContract, "This transaction should"+ - " create a contract") - assert.NotEqual(t, 0, len(receipt.TxHash), "Receipt should contain a"+ - " transaction hash") - contractAddr := receipt.ContractAddress - assert.NotEqual(t, 0, len(contractAddr), "Transactions claims to have"+ - " created a contract but the contract address is empty") - - // run a call through the contract - data := []byte{} - expected := []byte{0xb} - callContract(t, client, privateAccounts[0].Address(), contractAddr, data, expected) - }) -} - -func TestNameReg(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := newWSClient() - defer stopWSClient(wsc) - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - names.MinNameRegistrationPeriod = 1 - - // register a new name, check if its there - // since entries ought to be unique and these run against different clients, we append the client - name := "ye_old_domain_name_" + clientName - const data = "if not now, when" - fee := uint64(1000) - numDesiredBlocks := uint64(2) - amt := fee + numDesiredBlocks*names.NameByteCostMultiplier*names.NameBlockCostMultiplier*names.NameBaseCost(name, data) - - txEnv := makeDefaultNameTx(t, client, name, data, amt, fee) - // verify the name by both using the event and by checking get_name - subscribeAndWaitForNext(t, wsc, exe_events.EventStringNameReg(name), - func() { - broadcastTx(t, client, txEnv) - }, - func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - - eventDataTx := resultEvent.Execution.GetTx() - assert.NotNil(t, eventDataTx, "could not convert %s to EventDataTx", resultEvent) - tx, ok := eventDataTx.Tx.Payload.(*payload.NameTx) - if !ok { - t.Fatalf("Could not convert %v to *NameTx", eventDataTx) - } - assert.Equal(t, name, tx.Name) - assert.Equal(t, data, tx.Data) - return true, nil - }) - - entry := getNameRegEntry(t, client, name) - assert.Equal(t, data, entry.Data) - assert.Equal(t, privateAccounts[0].Address(), entry.Owner) - - // update the data as the owner, make sure still there - numDesiredBlocks = uint64(5) - const updatedData = "these are amongst the things I wish to bestow upon " + - "the youth of generations come: a safe supply of honey, and a better " + - "money. For what else shall they need" - amt = fee + numDesiredBlocks*names.NameByteCostMultiplier* - names.NameBlockCostMultiplier*names.NameBaseCost(name, updatedData) - txEnv = makeDefaultNameTx(t, client, name, updatedData, amt, fee) - broadcastTxAndWait(t, client, txEnv) - entry = getNameRegEntry(t, client, name) - - assert.Equal(t, updatedData, entry.Data) - - // try to update as non owner, should fail - tx := payload.NewNameTxWithSequence(privateAccounts[1].PublicKey(), name, "never mind", amt, fee, - getSequence(t, client, privateAccounts[1].Address())+1) - txEnv = txs.Enclose(genesisDoc.ChainID(), tx) - require.NoError(t, txEnv.Sign(privateAccounts[1])) - - _, err := tm_client.BroadcastTx(client, txEnv) - assert.Error(t, err, "Expected error when updating someone else's unexpired"+ - " name registry entry") - if err != nil { - assert.Contains(t, err.Error(), "permission denied", "Error should be "+ - "permission denied") - } - - // Wait a couple of blocks to make sure name registration expires - waitNBlocks(t, wsc, 5) - - //now the entry should be expired, so we can update as non owner - const data2 = "this is not my beautiful house" - tx = payload.NewNameTxWithSequence(privateAccounts[1].PublicKey(), name, data2, amt, fee, - getSequence(t, client, privateAccounts[1].Address())+1) - txEnv = txs.Enclose(genesisDoc.ChainID(), tx) - require.NoError(t, txEnv.Sign(privateAccounts[1])) - - //_, err = tm_client.BroadcastTx(client, tx) - require.NoError(t, subscribeAndWaitForNext(t, wsc, exe_events.EventStringNameReg(name), - func() { - _, err = tm_client.BroadcastTx(client, txEnv) - assert.NoError(t, err, "Should be able to update a previously expired name"+ - " registry entry as a different address") - }, - func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - return true, nil - })) - entry = getNameRegEntry(t, client, name) - assert.Equal(t, data2, entry.Data) - assert.Equal(t, privateAccounts[1].Address(), entry.Owner) - }) -} - -func TestWaitBlocks(t *testing.T) { - wsc := newWSClient() - defer stopWSClient(wsc) - waitNBlocks(t, wsc, 5) -} - -func TestBlockchainInfo(t *testing.T) { - wsc := newWSClient() - defer stopWSClient(wsc) - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - // wait a mimimal number of blocks to ensure that the later query for block - // headers has a non-trivial length - nBlocks := 4 - waitNBlocks(t, wsc, nBlocks) - - resp, err := tm_client.ListBlocks(client, 0, 0) - if err != nil { - t.Fatalf("Failed to get blockchain info: %v", err) - } - lastBlockHeight := resp.LastHeight - nMetaBlocks := len(resp.BlockMetas) - assert.True(t, uint64(nMetaBlocks) <= lastBlockHeight, - "Logically number of block metas should be equal or less than block height.") - assert.True(t, nBlocks <= len(resp.BlockMetas), - "Should see at least %v BlockMetas after waiting for %v blocks but saw %v", - nBlocks, nBlocks, len(resp.BlockMetas)) - // For the maximum number (default to 20) of retrieved block headers, - // check that they correctly chain to each other. - lastBlockHash := resp.BlockMetas[nMetaBlocks-1].Header.Hash() - for i := nMetaBlocks - 2; i >= 0; i-- { - // the blockhash in header of height h should be identical to the hash - // in the LastBlockID of the header of block height h+1. - assert.Equal(t, lastBlockHash, resp.BlockMetas[i].Header.LastBlockID.Hash, - "Blockchain should be a hash tree!") - lastBlockHash = resp.BlockMetas[i].Header.Hash() - } - - // Now retrieve only two blockheaders (h=1, and h=2) and check that we got - // two results. - resp, err = tm_client.ListBlocks(client, 1, 2) - assert.NoError(t, err) - assert.Equal(t, 2, len(resp.BlockMetas), - "Should see 2 BlockMetas after extracting 2 blocks") - }) -} - -func TestListUnconfirmedTxs(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := newWSClient() - defer stopWSClient(wsc) - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - amt, gasLim, fee := uint64(1100), uint64(1000), uint64(1000) - code := []byte{0x60, 0x5, 0x60, 0x1, 0x55} - // Call with nil address will create a contract - txEnv := makeDefaultCallTx(t, client, nil, code, amt, gasLim, fee) - txChan := make(chan []*txs.Envelope) - - // We want to catch the Tx in mempool before it gets reaped by tendermint - // consensus. We should be able to do this almost always if we broadcast our - // transaction immediately after a block has been committed. There is about - // 1 second between blocks, and we will have the lock on Reap - // So we wait for a block here - waitNBlocks(t, wsc, 1) - - go func() { - for { - resp, err := tm_client.ListUnconfirmedTxs(client, -1) - if resp != nil { - - } - require.NoError(t, err) - if resp.NumTxs > 0 { - txChan <- resp.Txs - } - } - }() - - require.NoError(t, runThenWaitForBlock(t, wsc, nextBlockPredicateFn(), func() { - broadcastTx(t, client, txEnv) - select { - case <-time.After(time.Second * timeoutSeconds * 10): - t.Fatal("Timeout out waiting for unconfirmed transactions to appear") - case transactions := <-txChan: - assert.Len(t, transactions, 1, "There should only be a single transaction in the "+ - "mempool during this test (previous txs should have made it into a block)") - assert.Contains(t, transactions, txEnv, "Transaction should be returned by ListUnconfirmedTxs") - } - })) - }) -} - -func TestGetBlock(t *testing.T) { - wsc := newWSClient() - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - waitNBlocks(t, wsc, 3) - resp, err := tm_client.GetBlock(client, 2) - assert.NoError(t, err) - assert.Equal(t, int64(2), resp.Block.Height) - assert.Equal(t, int64(2), resp.BlockMeta.Header.Height) - }) -} - -func TestListValidators(t *testing.T) { - wsc := newWSClient() - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - waitNBlocks(t, wsc, 3) - resp, err := tm_client.ListValidators(client) - assert.NoError(t, err) - assert.Len(t, resp.BondedValidators, 1) - validator := resp.BondedValidators[0] - assert.Equal(t, genesisDoc.Validators[0].PublicKey, validator.PublicKey) - }) -} - -func TestDumpConsensusState(t *testing.T) { - wsc := newWSClient() - startTime := time.Now() - testWithAllClients(t, func(t *testing.T, clientName string, client tm_client.RPCClient) { - waitNBlocks(t, wsc, 3) - resp, err := tm_client.DumpConsensusState(client) - assert.NoError(t, err) - assert.NotZero(t, startTime) - assert.Equal(t, fmt.Sprintf("/0/%d", types.RoundStepNewHeight), - strings.TrimLeft(resp.RoundState.HeightRoundStep, "0123456789")) - }) -} diff --git a/rpc/tm/integration/shared.go b/rpc/tm/integration/shared.go deleted file mode 100644 index 8b33acc3be0f3a0add0f38de9c0ffcdc1a8a898c..0000000000000000000000000000000000000000 --- a/rpc/tm/integration/shared.go +++ /dev/null @@ -1,240 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "bytes" - "hash/fnv" - "testing" - - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/core/integration" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/names" - "github.com/hyperledger/burrow/rpc" - rpcClient "github.com/hyperledger/burrow/rpc/lib/client" - tmClient "github.com/hyperledger/burrow/rpc/tm/client" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" - "github.com/stretchr/testify/require" -) - -const ( - rpcAddr = "0.0.0.0:46657" - websocketAddr = rpcAddr - websocketEndpoint = "/websocket" -) - -// global variables for use across all tests -var ( - privateAccounts = integration.MakePrivateAccounts(5) // make keys - jsonRpcClient = rpcClient.NewJSONRPCClient(rpcAddr) - httpClient = rpcClient.NewURIClient(rpcAddr) - clients = map[string]tmClient.RPCClient{ - "JSONRPC": jsonRpcClient, - "HTTP": httpClient, - } - genesisDoc = integration.TestGenesisDoc(privateAccounts) -) - -//------------------------------------------------------------------------------- -// some default transaction functions - -func makeDefaultSendTx(t *testing.T, client tmClient.RPCClient, addr crypto.Address, amt uint64) *payload.SendTx { - sequence := getSequence(t, client, privateAccounts[0].Address()) - tx := payload.NewSendTx() - tx.AddInputWithSequence(privateAccounts[0].PublicKey(), amt, sequence+1) - tx.AddOutput(addr, amt) - return tx -} - -func makeDefaultSendTxSigned(t *testing.T, client tmClient.RPCClient, addr crypto.Address, amt uint64) *txs.Envelope { - txEnv := txs.Enclose(genesisDoc.ChainID(), makeDefaultSendTx(t, client, addr, amt)) - require.NoError(t, txEnv.Sign(privateAccounts[0])) - return txEnv -} - -func makeDefaultCallTx(t *testing.T, client tmClient.RPCClient, addr *crypto.Address, code []byte, amt, gasLim, - fee uint64) *txs.Envelope { - sequence := getSequence(t, client, privateAccounts[0].Address()) - tx := payload.NewCallTxWithSequence(privateAccounts[0].PublicKey(), addr, code, amt, gasLim, fee, sequence+1) - txEnv := txs.Enclose(genesisDoc.ChainID(), tx) - require.NoError(t, txEnv.Sign(privateAccounts[0])) - return txEnv -} - -func makeDefaultNameTx(t *testing.T, client tmClient.RPCClient, name, value string, amt, fee uint64) *txs.Envelope { - sequence := getSequence(t, client, privateAccounts[0].Address()) - tx := payload.NewNameTxWithSequence(privateAccounts[0].PublicKey(), name, value, amt, fee, sequence+1) - txEnv := txs.Enclose(genesisDoc.ChainID(), tx) - require.NoError(t, txEnv.Sign(privateAccounts[0])) - return txEnv -} - -//------------------------------------------------------------------------------- -// rpc call wrappers (fail on err) - -// get an account's sequence number -func getSequence(t *testing.T, client tmClient.RPCClient, addr crypto.Address) uint64 { - acc, err := tmClient.GetAccount(client, addr) - if err != nil { - t.Fatal(err) - } - if acc == nil { - return 0 - } - return acc.Sequence() -} - -// get the account -func getAccount(t *testing.T, client tmClient.RPCClient, addr crypto.Address) acm.Account { - ac, err := tmClient.GetAccount(client, addr) - if err != nil { - t.Fatal(err) - } - return ac -} - -// sign transaction -func signTx(t *testing.T, client tmClient.RPCClient, tx txs.Tx, - privAcc *acm.ConcretePrivateAccount) *txs.Envelope { - signedTx, err := tmClient.SignTx(client, tx, []*acm.ConcretePrivateAccount{privAcc}) - if err != nil { - t.Fatal(err) - } - return signedTx -} - -// broadcast transaction -func broadcastTx(t *testing.T, client tmClient.RPCClient, txEnv *txs.Envelope) *txs.Receipt { - rec, err := tmClient.BroadcastTx(client, txEnv) - require.NoError(t, err) - return rec -} - -// dump all storage for an account. currently unused -func dumpStorage(t *testing.T, addr crypto.Address) *rpc.ResultDumpStorage { - client := clients["HTTP"] - resp, err := tmClient.DumpStorage(client, addr) - if err != nil { - t.Fatal(err) - } - return resp -} - -func getStorage(t *testing.T, client tmClient.RPCClient, addr crypto.Address, key []byte) []byte { - resp, err := tmClient.GetStorage(client, addr, key) - if err != nil { - t.Fatal(err) - } - return resp -} - -func callCode(t *testing.T, client tmClient.RPCClient, fromAddress crypto.Address, code, data, - expected []byte) { - resp, err := tmClient.CallCode(client, fromAddress, code, data) - if err != nil { - t.Fatal(err) - } - ret := resp.Return - // NOTE: we don't flip memory when it comes out of RETURN (?!) - if bytes.Compare(ret, binary.LeftPadWord256(expected).Bytes()) != 0 { - t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected) - } -} - -func callContract(t *testing.T, client tmClient.RPCClient, fromAddress, toAddress crypto.Address, - data, expected []byte) { - resp, err := tmClient.Call(client, fromAddress, toAddress, data) - if err != nil { - t.Fatal(err) - } - ret := resp.Return - // NOTE: we don't flip memory when it comes out of RETURN (?!) - if bytes.Compare(ret, binary.LeftPadWord256(expected).Bytes()) != 0 { - t.Fatalf("Conflicting return value. Got %x, expected %x", ret, expected) - } -} - -// get the namereg entry -func getNameRegEntry(t *testing.T, client tmClient.RPCClient, name string) *names.Entry { - entry, err := tmClient.GetName(client, name) - if err != nil { - t.Fatal(err) - } - return entry -} - -// Returns a positive int64 hash of text (consumers want int64 instead of uint64) -func hashString(text string) uint64 { - hasher := fnv.New64() - hasher.Write([]byte(text)) - return uint64(hasher.Sum64()) -} - -//-------------------------------------------------------------------------------- -// utility verification function - -// simple contract returns 5 + 6 = 0xb -func simpleContract() ([]byte, []byte, []byte) { - // this is the code we want to run when the contract is called - contractCode := []byte{0x60, 0x5, 0x60, 0x6, 0x1, 0x60, 0x0, 0x52, 0x60, 0x20, - 0x60, 0x0, 0xf3} - // the is the code we need to return the contractCode when the contract is initialized - lenCode := len(contractCode) - // push code to the stack - //code := append([]byte{byte(0x60 + lenCode - 1)}, RightPadWord256(contractCode).Bytes()...) - code := append([]byte{0x7f}, - binary.RightPadWord256(contractCode).Bytes()...) - // store it in memory - code = append(code, []byte{0x60, 0x0, 0x52}...) - // return whats in memory - //code = append(code, []byte{0x60, byte(32 - lenCode), 0x60, byte(lenCode), 0xf3}...) - code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) - // return init code, contract code, expected return - return code, contractCode, binary.LeftPadBytes([]byte{0xb}, 32) -} - -// simple call contract calls another contract -func simpleCallContract(addr crypto.Address) ([]byte, []byte, []byte) { - gas1, gas2 := byte(0x1), byte(0x1) - value := byte(0x1) - inOff, inSize := byte(0x0), byte(0x0) // no call data - retOff, retSize := byte(0x0), byte(0x20) - // this is the code we want to run (call a contract and return) - contractCode := []byte{0x60, retSize, 0x60, retOff, 0x60, inSize, 0x60, inOff, - 0x60, value, 0x73} - contractCode = append(contractCode, addr.Bytes()...) - contractCode = append(contractCode, []byte{0x61, gas1, gas2, 0xf1, 0x60, 0x20, - 0x60, 0x0, 0xf3}...) - - // the is the code we need to return; the contractCode when the contract is initialized - // it should copy the code from the input into memory - lenCode := len(contractCode) - memOff := byte(0x0) - inOff = byte(0xc) // length of code before codeContract - length := byte(lenCode) - - code := []byte{0x60, length, 0x60, inOff, 0x60, memOff, 0x37} - // return whats in memory - code = append(code, []byte{0x60, byte(lenCode), 0x60, 0x0, 0xf3}...) - code = append(code, contractCode...) - // return init code, contract code, expected return - return code, contractCode, binary.LeftPadBytes([]byte{0xb}, 32) -} diff --git a/rpc/tm/integration/websocket_client_test.go b/rpc/tm/integration/websocket_client_test.go deleted file mode 100644 index 2c996ac1ec956a4745d80e535117a2b572334a89..0000000000000000000000000000000000000000 --- a/rpc/tm/integration/websocket_client_test.go +++ /dev/null @@ -1,337 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "encoding/json" - "fmt" - "testing" - "time" - - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/rpc" - tmClient "github.com/hyperledger/burrow/rpc/tm/client" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - tmTypes "github.com/tendermint/tendermint/types" -) - -//-------------------------------------------------------------------------------- -// Test the websocket service - -// make a simple connection to the server -func TestWSConnect(t *testing.T) { - wsc := newWSClient() - stopWSClient(wsc) -} - -// receive a new block message -func TestWSNewBlock(t *testing.T) { - wsc := newWSClient() - eid := tmTypes.EventNewBlock - subId := subscribeAndGetSubscriptionId(t, wsc, eid) - defer func() { - unsubscribe(t, wsc, subId) - stopWSClient(wsc) - }() - waitForEvent(t, wsc, eid, func() {}, - func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - fmt.Println("Check: ", resultEvent.Tendermint.EventDataNewBlock().Block) - return true, nil - }) -} - -// receive a few new block messages in a row, with increasing height -func TestWSBlockchainGrowth(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := newWSClient() - eid := tmTypes.EventNewBlock - subId := subscribeAndGetSubscriptionId(t, wsc, eid) - defer func() { - unsubscribe(t, wsc, subId) - stopWSClient(wsc) - }() - // listen for NewBlock, ensure height increases by 1 - var initBlockN int64 - for i := int64(0); i < 2; i++ { - waitForEvent(t, wsc, eid, func() {}, - func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - eventDataNewBlock := resultEvent.Tendermint.EventDataNewBlock() - if eventDataNewBlock == nil { - t.Fatalf("Was expecting EventDataNewBlock but got %v", resultEvent) - } - block := eventDataNewBlock.Block - if i == 0 { - initBlockN = block.Height - } else { - if block.Header.Height != initBlockN+i { - return true, fmt.Errorf("Expected block %d, got block %d", i, - block.Header.Height) - } - } - return true, nil - }) - } -} - -// send a transaction and validate the events from listening for both sender and receiver -func TestWSSend(t *testing.T) { - wsc := newWSClient() - toAddr := privateAccounts[1].Address() - amt := uint64(100) - eidInput := events.EventStringAccountInput(privateAccounts[0].Address()) - eidOutput := events.EventStringAccountOutput(toAddr) - subIdInput := subscribeAndGetSubscriptionId(t, wsc, eidInput) - subIdOutput := subscribeAndGetSubscriptionId(t, wsc, eidOutput) - defer func() { - unsubscribe(t, wsc, subIdInput) - unsubscribe(t, wsc, subIdOutput) - stopWSClient(wsc) - }() - - tx := makeDefaultSendTxSigned(t, jsonRpcClient, toAddr, amt) - broadcastTx(t, jsonRpcClient, tx) - - // Set of response IDs we expect - rids := map[string]struct{}{tmClient.EventResponseID(eidInput): {}, tmClient.EventResponseID(eidOutput): {}} - - r := <-wsc.ResponsesCh - result, err := readResponse(r) - assert.NoError(t, err) - assert.NoError(t, unmarshalValidateSend(amt, toAddr, result)) - delete(rids, r.ID) - - r = <-wsc.ResponsesCh - result, err = readResponse(r) - assert.NoError(t, err) - assert.NoError(t, unmarshalValidateSend(amt, toAddr, result)) - delete(rids, r.ID) - - // Note currently we cannot guarantee order with pubsub event system - assert.Empty(t, rids, "Should receive input and output event") -} - -// ensure events are only fired once for a given transaction -func TestWSDoubleFire(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := newWSClient() - eid := events.EventStringAccountInput(privateAccounts[0].Address()) - subId := subscribeAndGetSubscriptionId(t, wsc, eid) - defer func() { - unsubscribe(t, wsc, subId) - stopWSClient(wsc) - }() - amt := uint64(100) - toAddr := privateAccounts[1].Address() - // broadcast the transaction, wait to hear about it - waitForEvent(t, wsc, eid, func() { - tx := makeDefaultSendTxSigned(t, jsonRpcClient, toAddr, amt) - broadcastTx(t, jsonRpcClient, tx) - }, func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - return true, nil - }) - select { - case <-wsc.ResponsesCh: - t.Fatal("Should time out waiting for second event") - case <-time.After(timeoutSeconds * time.Second): - - } -} - -// create a contract, wait for the event, and send it a msg, validate the return -func TestWSCallWait(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := newWSClient() - defer stopWSClient(wsc) - // Mini soak test - for i := 0; i < 20; i++ { - amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000) - code, returnCode, returnVal := simpleContract() - var contractAddr crypto.Address - eid1 := events.EventStringAccountInput(privateAccounts[0].Address()) - subId1 := subscribeAndGetSubscriptionId(t, wsc, eid1) - // wait for the contract to be created - waitForEvent(t, wsc, eid1, func() { - tx := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee) - receipt := broadcastTx(t, jsonRpcClient, tx) - contractAddr = receipt.ContractAddress - }, unmarshalValidateTx(amt, returnCode)) - - unsubscribe(t, wsc, subId1) - - // susbscribe to the new contract - amt = uint64(10001) - eid2 := events.EventStringAccountOutput(contractAddr) - subId2 := subscribeAndGetSubscriptionId(t, wsc, eid2) - // get the return value from a call - data := []byte{0x1} - waitForEvent(t, wsc, eid2, func() { - tx := makeDefaultCallTx(t, jsonRpcClient, &contractAddr, data, amt, gasLim, fee) - receipt := broadcastTx(t, jsonRpcClient, tx) - contractAddr = receipt.ContractAddress - }, unmarshalValidateTx(amt, returnVal)) - unsubscribe(t, wsc, subId2) - } -} - -// create a contract and send it a msg without waiting. wait for contract event -// and validate return -func TestWSCallNoWait(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := newWSClient() - defer stopWSClient(wsc) - amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000) - code, _, returnVal := simpleContract() - - sequence := getSequence(t, jsonRpcClient, privateAccounts[0].Address()) - txEnv := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee) - receipt := broadcastTx(t, jsonRpcClient, txEnv) - contractAddr := receipt.ContractAddress - - // susbscribe to the new contract - amt = uint64(10001) - eid := events.EventStringAccountOutput(contractAddr) - subId := subscribeAndGetSubscriptionId(t, wsc, eid) - defer unsubscribe(t, wsc, subId) - - data := []byte{0x1} - waitForEvent(t, wsc, eid, func() { - tx := payload.NewCallTxWithSequence(privateAccounts[0].PublicKey(), &contractAddr, data, amt, gasLim, fee, - sequence+3) - txEnv = txs.Enclose(genesisDoc.ChainID(), tx) - require.NoError(t, txEnv.Sign(privateAccounts[0])) - broadcastTx(t, jsonRpcClient, txEnv) - }, unmarshalValidateTx(amt, returnVal)) -} - -// create two contracts, one of which calls the other -func TestWSCallCall(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode.") - } - wsc := newWSClient() - defer stopWSClient(wsc) - amt, gasLim, fee := uint64(10000), uint64(1000), uint64(1000) - code, _, returnVal := simpleContract() - TxHash := new([]byte) - - // deploy the two contracts - txEnv := makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee) - receipt := txEnv.Tx.GenerateReceipt() - contractAddr1 := receipt.ContractAddress - // subscribe to the new contracts - eid := events.EventStringAccountCall(contractAddr1) - subId := subscribeAndGetSubscriptionId(t, wsc, eid) - defer unsubscribe(t, wsc, subId) - - _, err := broadcastTxAndWait(t, jsonRpcClient, txEnv) - require.NoError(t, err) - - // call contract2, which should call contract1, and wait for ev1 - code, _, _ = simpleCallContract(contractAddr1) - txEnv = makeDefaultCallTx(t, jsonRpcClient, nil, code, amt, gasLim, fee) - receipt2, err := broadcastTxAndWait(t, jsonRpcClient, txEnv) - require.NoError(t, err) - contractAddr2 := receipt2.ContractAddress - - // let the contract get created first - waitForEvent(t, wsc, eid, - // Runner - func() { - }, - // Event Checker - func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - return true, nil - }) - // call it - waitForEvent(t, wsc, eid, - // Runner - func() { - txEnv := makeDefaultCallTx(t, jsonRpcClient, &contractAddr2, nil, amt, gasLim, fee) - broadcastTx(t, jsonRpcClient, txEnv) - *TxHash = txEnv.Tx.Hash() - }, - // Event checker - unmarshalValidateCall(privateAccounts[0].Address(), returnVal, TxHash)) -} - -func TestSubscribe(t *testing.T) { - wsc := newWSClient() - var subId string - subscribe(t, wsc, tmTypes.EventNewBlock) - -Subscribe: - for { - select { - case <-time.After(timeoutSeconds * time.Second): - t.Fatal("Timed out waiting for subscription result") - - case response := <-wsc.ResponsesCh: - require.Nil(t, response.Error) - res := new(rpc.ResultSubscribe) - require.NoError(t, json.Unmarshal(response.Result, res)) - assert.Equal(t, tmTypes.EventNewBlock, res.EventID) - subId = res.SubscriptionID - break Subscribe - } - } - - blocksSeen := 0 - for { - select { - // wait long enough to check we don't see another new block event even though - // a block will have come - case <-time.After(expectBlockInSeconds * time.Second): - if blocksSeen == 0 { - t.Fatal("Timed out without seeing a NewBlock event") - } - return - - case response := <-wsc.ResponsesCh: - require.Nil(t, response.Error) - - if response.ID == tmClient.EventResponseID(tmTypes.EventNewBlock) { - res := new(rpc.ResultEvent) - json.Unmarshal(response.Result, res) - enb := res.Tendermint.EventDataNewBlock() - if enb != nil { - assert.Equal(t, genesisDoc.ChainID(), enb.Block.ChainID) - if blocksSeen > 1 { - t.Fatal("Continued to see NewBlock event after unsubscribing") - } else { - if blocksSeen == 0 { - unsubscribe(t, wsc, subId) - } - blocksSeen++ - } - } - } - } - } -} diff --git a/rpc/tm/integration/websocket_helpers.go b/rpc/tm/integration/websocket_helpers.go deleted file mode 100644 index 6e19d8fee2f0c83328fe2c3b4cc361bc388ec010..0000000000000000000000000000000000000000 --- a/rpc/tm/integration/websocket_helpers.go +++ /dev/null @@ -1,323 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "bytes" - "encoding/json" - "fmt" - "runtime/debug" - "testing" - "time" - - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/rpc" - rpcClient "github.com/hyperledger/burrow/rpc/lib/client" - rpcTypes "github.com/hyperledger/burrow/rpc/lib/types" - tmClient "github.com/hyperledger/burrow/rpc/tm/client" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" - "github.com/stretchr/testify/require" - tmTypes "github.com/tendermint/tendermint/types" -) - -const ( - timeoutSeconds = 8 - expectBlockInSeconds = 2 -) - -//-------------------------------------------------------------------------------- -// Utilities for testing the websocket service -type blockPredicate func(block *tmTypes.Block) bool -type resultEventChecker func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) - -// create a new connection -func newWSClient() *rpcClient.WSClient { - wsc := rpcClient.NewWSClient(websocketAddr, websocketEndpoint) - if err := wsc.Start(); err != nil { - panic(err) - } - return wsc -} - -func stopWSClient(wsc *rpcClient.WSClient) { - wsc.Stop() -} - -// subscribe to an event -func subscribe(t *testing.T, wsc *rpcClient.WSClient, eventId string) { - if err := tmClient.Subscribe(wsc, eventId); err != nil { - t.Fatal(err) - } -} - -func subscribeAndGetSubscriptionId(t *testing.T, wsc *rpcClient.WSClient, eventId string) string { - if err := tmClient.Subscribe(wsc, eventId); err != nil { - t.Fatal(err) - } - - timeout := time.NewTimer(timeoutSeconds * time.Second) - for { - select { - case <-timeout.C: - t.Fatal("Timeout waiting for subscription result") - case response := <-wsc.ResponsesCh: - require.Nil(t, response.Error, "Got error response from websocket channel: %v", response.Error) - if response.ID == tmClient.SubscribeRequestID { - res := new(rpc.ResultSubscribe) - err := json.Unmarshal(response.Result, res) - if err == nil { - return res.SubscriptionID - } - } - } - } -} - -// unsubscribe from an event -func unsubscribe(t *testing.T, wsc *rpcClient.WSClient, subscriptionId string) { - if err := tmClient.Unsubscribe(wsc, subscriptionId); err != nil { - t.Fatal(err) - } -} - -// broadcast transaction and wait for new block -func broadcastTxAndWait(t *testing.T, client tmClient.RPCClient, txEnv *txs.Envelope) (*txs.Receipt, error) { - wsc := newWSClient() - defer stopWSClient(wsc) - inputs := txEnv.Tx.GetInputs() - if len(inputs) == 0 { - t.Fatalf("cannot broadcastAndWait fot Tx with no inputs") - } - address := inputs[0].Address - - var rec *txs.Receipt - var err error - - err = subscribeAndWaitForNext(t, wsc, events.EventStringAccountInput(address), - func() { - rec, err = tmClient.BroadcastTx(client, txEnv) - }, func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - return true, nil - }) - if err != nil { - return nil, err - } - return rec, err -} - -func nextBlockPredicateFn() blockPredicate { - initialHeight := int64(-1) - return func(block *tmTypes.Block) bool { - if initialHeight <= 0 { - initialHeight = block.Height - return false - } else { - // TODO: [Silas] remove the + 1 here. It is a workaround for the fact - // that tendermint fires the NewBlock event before it has finalised its - // state updates, so we have to wait for the block after the block we - // want in order for the Tx to be genuinely final. - // This should be addressed by: https://github.com/tendermint/tendermint/pull/265 - return block.Height > initialHeight+1 - } - } -} - -func waitNBlocks(t *testing.T, wsc *rpcClient.WSClient, n int) { - i := 0 - require.NoError(t, runThenWaitForBlock(t, wsc, - func(block *tmTypes.Block) bool { - i++ - return i >= n - }, - func() {})) -} - -func runThenWaitForBlock(t *testing.T, wsc *rpcClient.WSClient, predicate blockPredicate, runner func()) error { - eventDataChecker := func(event string, eventData *rpc.ResultEvent) (bool, error) { - eventDataNewBlock := eventData.Tendermint.EventDataNewBlock() - if eventDataNewBlock == nil { - return false, fmt.Errorf("could not convert %#v to EventDataNewBlock", eventData) - } - return predicate(eventDataNewBlock.Block), nil - } - return subscribeAndWaitForNext(t, wsc, tmTypes.EventNewBlock, runner, eventDataChecker) -} - -func subscribeAndWaitForNext(t *testing.T, wsc *rpcClient.WSClient, event string, runner func(), - checker resultEventChecker) error { - - subId := subscribeAndGetSubscriptionId(t, wsc, event) - defer unsubscribe(t, wsc, subId) - return waitForEvent(t, wsc, event, runner, checker) -} - -// waitForEvent executes runner that is expected to trigger events. It then -// waits for any events on the supplies WSClient and checks the eventData with -// the eventDataChecker which is a function that is passed the event name -// and the Data and returns the pair of stopWaiting, err. Where if -// stopWaiting is true waitForEvent will return or if stopWaiting is false -// waitForEvent will keep listening for new events. If an error is returned -// waitForEvent will fail the test. -func waitForEvent(t *testing.T, wsc *rpcClient.WSClient, eventID string, runner func(), - checker resultEventChecker) error { - - // go routine to wait for websocket msg - eventsCh := make(chan *rpc.ResultEvent) - shutdownEventsCh := make(chan bool, 1) - errCh := make(chan error) - - // do stuff (transactions) - runner() - - // Read message - go func() { - for { - select { - case <-shutdownEventsCh: - return - case r := <-wsc.ResponsesCh: - if r.Error != nil { - errCh <- r.Error - return - } - if r.ID == tmClient.EventResponseID(eventID) { - resultEvent, err := readResponse(r) - if err != nil { - errCh <- err - } else { - eventsCh <- resultEvent - } - } - case <-wsc.Quit(): - return - } - } - }() - - // Don't block up WSClient - defer func() { shutdownEventsCh <- true }() - - for { - select { - // wait for an event or timeout - case <-time.After(timeoutSeconds * time.Second): - t.Fatalf("waitForEvent timed out: %s", debug.Stack()) - case eventData := <-eventsCh: - // run the check - stopWaiting, err := checker(eventID, eventData) - if err != nil { - return err - } - if stopWaiting { - return nil - } - case err := <-errCh: - return err - } - } - return nil -} - -func readResponse(r rpcTypes.RPCResponse) (*rpc.ResultEvent, error) { - if r.Error != nil { - return nil, r.Error - } - resultEvent := new(rpc.ResultEvent) - err := json.Unmarshal(r.Result, resultEvent) - if err != nil { - return nil, err - } - return resultEvent, nil -} - -//-------------------------------------------------------------------------------- - -func unmarshalValidateSend(amt uint64, toAddr crypto.Address, resultEvent *rpc.ResultEvent) error { - data := resultEvent.Execution.GetTx() - if data == nil { - return fmt.Errorf("event data %v is not EventDataTx", resultEvent) - } - if data.Exception == nil { - return data.Exception.AsError() - } - tx := data.Tx.Payload.(*payload.SendTx) - if tx.Inputs[0].Address != privateAccounts[0].Address() { - return fmt.Errorf("senders do not match up! Got %s, expected %s", tx.Inputs[0].Address, - privateAccounts[0].Address()) - } - if tx.Inputs[0].Amount != amt { - return fmt.Errorf("amt does not match up! Got %d, expected %d", tx.Inputs[0].Amount, amt) - } - if tx.Outputs[0].Address != toAddr { - return fmt.Errorf("receivers do not match up! Got %s, expected %s", tx.Outputs[0].Address, - privateAccounts[0].Address()) - } - return nil -} - -func unmarshalValidateTx(amt uint64, returnCode []byte) resultEventChecker { - return func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - data := resultEvent.Execution.GetTx() - if data == nil { - return true, fmt.Errorf("event data %v is not EventDataTx", *resultEvent) - } - if data.Exception != nil { - return true, data.Exception.AsError() - } - tx := data.Tx.Payload.(*payload.CallTx) - if tx.Input.Address != privateAccounts[0].Address() { - return true, fmt.Errorf("senders do not match up! Got %s, expected %s", - tx.Input.Address, privateAccounts[0].Address()) - } - if tx.Input.Amount != amt { - return true, fmt.Errorf("amount does not match up! Got %d, expected %d", - tx.Input.Amount, amt) - } - ret := data.Return - if !bytes.Equal(ret, returnCode) { - return true, fmt.Errorf("tx did not return correctly. Got %x, expected %x", ret, returnCode) - } - return true, nil - } -} - -func unmarshalValidateCall(origin crypto.Address, returnCode []byte, txid *[]byte) resultEventChecker { - return func(eventID string, resultEvent *rpc.ResultEvent) (bool, error) { - data := resultEvent.Execution.Call - if data == nil { - return true, fmt.Errorf("event data %v is not EventDataTx", *resultEvent) - } - if data.Exception != nil { - return true, data.Exception.AsError() - } - if data.Origin != origin { - return true, fmt.Errorf("origin does not match up! Got %s, expected %s", data.Origin, origin) - } - ret := data.Return - if !bytes.Equal(ret, returnCode) { - return true, fmt.Errorf("call did not return correctly. Got %x, expected %x", ret, returnCode) - } - if !bytes.Equal(resultEvent.Execution.Header.TxHash, *txid) { - return true, fmt.Errorf("TxIDs do not match up! Got %x, expected %x", - resultEvent.Execution.Header.TxHash, *txid) - } - return true, nil - } -} diff --git a/rpc/tm/methods.go b/rpc/tm/methods.go index 017cf29c9bf88c4114f472d2825bc611532cdd14..e28e7d8626ad45c307e8fdd57fa3823eb857e2ad 100644 --- a/rpc/tm/methods.go +++ b/rpc/tm/methods.go @@ -1,27 +1,16 @@ package tm import ( - "context" "fmt" - "time" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/execution/names" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/rpc" "github.com/hyperledger/burrow/rpc/lib/server" - "github.com/hyperledger/burrow/rpc/lib/types" - "github.com/hyperledger/burrow/txs" ) // Method names const ( - BroadcastTx = "broadcast_tx" - Subscribe = "subscribe" - Unsubscribe = "unsubscribe" - // Status Status = "status" NetInfo = "net_info" @@ -60,87 +49,9 @@ const ( LastBlockInfo = "last_block_info" ) -const SubscriptionTimeout = 5 * time.Second - func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*server.RPCFunc { logger = logger.WithScope("GetRoutes") return map[string]*server.RPCFunc{ - // Transact - BroadcastTx: server.NewRPCFunc(func(txEnv *txs.Envelope) (*rpc.ResultBroadcastTx, error) { - receipt, err := service.Transactor().BroadcastTx(txEnv) - if err != nil { - return nil, err - } - return &rpc.ResultBroadcastTx{ - Receipt: *receipt, - }, nil - }, "tx"), - - SignTx: server.NewRPCFunc(func(txEnv *txs.Envelope, concretePrivateAccounts []*acm.ConcretePrivateAccount) (*rpc.ResultSignTx, error) { - txEnv, err := service.Transactor().SignTx(txEnv, acm.SigningAccounts(concretePrivateAccounts)) - return &rpc.ResultSignTx{Tx: txEnv}, err - - }, "tx,privAccounts"), - - // Simulated call - Call: server.NewRPCFunc(func(fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) { - call, err := service.Transactor().Call(service.State(), fromAddress, toAddress, data) - if err != nil { - return nil, err - } - return &rpc.ResultCall{Call: *call}, nil - }, "fromAddress,toAddress,data"), - - CallCode: server.NewRPCFunc(func(fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) { - call, err := service.Transactor().CallCode(service.State(), fromAddress, code, data) - if err != nil { - return nil, err - } - return &rpc.ResultCall{Call: *call}, nil - }, "fromAddress,code,data"), - - // Events - Subscribe: server.NewWSRPCFunc(func(wsCtx types.WSRPCContext, eventID string) (*rpc.ResultSubscribe, error) { - subscriptionID, err := event.GenerateSubscriptionID() - if err != nil { - return nil, err - } - - ctx, cancel := context.WithTimeout(context.Background(), SubscriptionTimeout) - defer cancel() - - err = service.Subscribe(ctx, subscriptionID, eventID, func(resultEvent *rpc.ResultEvent) (stop bool) { - keepAlive := wsCtx.TryWriteRPCResponse(types.NewRPCSuccessResponse( - EventResponseID(wsCtx.Request.ID, eventID), resultEvent)) - if !keepAlive { - logger.InfoMsg("dropping subscription because could not write to websocket", - "subscription_id", subscriptionID, - "event_id", eventID) - } - return !keepAlive - }) - if err != nil { - return nil, err - } - return &rpc.ResultSubscribe{ - EventID: eventID, - SubscriptionID: subscriptionID, - }, nil - }, "eventID"), - - Unsubscribe: server.NewWSRPCFunc(func(wsCtx types.WSRPCContext, subscriptionID string) (*rpc.ResultUnsubscribe, error) { - ctx, cancel := context.WithTimeout(context.Background(), SubscriptionTimeout) - defer cancel() - // Since our model uses a random subscription ID per request we just drop all matching requests - err := service.Unsubscribe(ctx, subscriptionID) - if err != nil { - return nil, err - } - return &rpc.ResultUnsubscribe{ - SubscriptionID: subscriptionID, - }, nil - }, "subscriptionID"), - // Status Status: server.NewRPCFunc(service.Status, ""), NetInfo: server.NewRPCFunc(service.NetInfo, ""), @@ -169,12 +80,8 @@ func GetRoutes(service *rpc.Service, logger *logging.Logger) map[string]*server. DumpConsensusState: server.NewRPCFunc(service.DumpConsensusState, ""), // Names - GetName: server.NewRPCFunc(service.GetName, "name"), - ListNames: server.NewRPCFunc(func() (*rpc.ResultListNames, error) { - return service.ListNames(func(*names.Entry) bool { - return true - }) - }, ""), + GetName: server.NewRPCFunc(service.GetName, "name"), + ListNames: server.NewRPCFunc(service.ListNames, ""), // Private account GeneratePrivateAccount: server.NewRPCFunc(service.GeneratePrivateAccount, ""), diff --git a/rpc/tm/server.go b/rpc/tm/tm_server.go similarity index 75% rename from rpc/tm/server.go rename to rpc/tm/tm_server.go index 2baf381b65d86a367baa7ff50a5a21c2215a5c12..2944606ec8ba78f4b1e7b34270ff16289f991bcd 100644 --- a/rpc/tm/server.go +++ b/rpc/tm/tm_server.go @@ -17,26 +17,22 @@ package tm import ( "net/http" - "github.com/hyperledger/burrow/consensus/tendermint" - "github.com/hyperledger/burrow/event" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/rpc" "github.com/hyperledger/burrow/rpc/lib/server" ) -func StartServer(service *rpc.Service, pattern, listenAddress string, emitter event.Emitter, - logger *logging.Logger) (*http.Server, error) { - +func StartServer(service *rpc.Service, pattern, listenAddress string, logger *logging.Logger) (*http.Server, error) { logger = logger.With(structure.ComponentKey, "RPC_TM") routes := GetRoutes(service, logger) mux := http.NewServeMux() - wm := server.NewWebsocketManager(routes, logger, server.EventSubscriber(tendermint.SubscribableAsEventBus(emitter))) + wm := server.NewWebsocketManager(routes, logger) mux.HandleFunc(pattern, wm.WebsocketHandler) server.RegisterRPCFuncs(mux, routes, logger) - server, err := server.StartHTTPServer(listenAddress, mux, logger) + srv, err := server.StartHTTPServer(listenAddress, mux, logger) if err != nil { return nil, err } - return server, nil + return srv, nil } diff --git a/rpc/tm/client/client.go b/rpc/tm/tmclient/client.go similarity index 84% rename from rpc/tm/client/client.go rename to rpc/tm/tmclient/client.go index 1b03a76e348cd6ae9042376aab316b7dfc41d488..f0fa4d43dcdebfaff06b7a99900348ab6fee55aa 100644 --- a/rpc/tm/client/client.go +++ b/rpc/tm/tmclient/client.go @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package client +package tmclient import ( "errors" "fmt" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/execution/names" "github.com/hyperledger/burrow/rpc" @@ -30,15 +30,6 @@ type RPCClient interface { Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) } -func BroadcastTx(client RPCClient, txEnv *txs.Envelope) (*txs.Receipt, error) { - res := new(txs.Receipt) - _, err := client.Call(tm.BroadcastTx, pmap("tx", txEnv), res) - if err != nil { - return nil, err - } - return res, nil -} - func Status(client RPCClient) (*rpc.ResultStatus, error) { res := new(rpc.ResultStatus) _, err := client.Call(tm.Status, pmap(), res) @@ -106,25 +97,6 @@ func GetStorage(client RPCClient, address crypto.Address, key []byte) ([]byte, e return res.Value, nil } -func CallCode(client RPCClient, fromAddress crypto.Address, code, data []byte) (*rpc.ResultCall, error) { - res := new(rpc.ResultCall) - _, err := client.Call(tm.CallCode, pmap("fromAddress", fromAddress, "code", code, "data", data), res) - if err != nil { - return nil, err - } - return res, nil -} - -func Call(client RPCClient, fromAddress, toAddress crypto.Address, data []byte) (*rpc.ResultCall, error) { - res := new(rpc.ResultCall) - _, err := client.Call(tm.Call, pmap("fromAddress", fromAddress, "toAddress", toAddress, - "data", data), res) - if err != nil { - return nil, err - } - return res, nil -} - func GetName(client RPCClient, name string) (*names.Entry, error) { res := new(rpc.ResultGetName) _, err := client.Call(tm.GetName, pmap("name", name), res) diff --git a/rpc/tm/client/client_test.go b/rpc/tm/tmclient/client_test.go similarity index 97% rename from rpc/tm/client/client_test.go rename to rpc/tm/tmclient/client_test.go index b8c322d597b15695fda54a815f40c257170c6ec3..3adeec8d345c1c2e9f34a0a6928c1da8952f30f7 100644 --- a/rpc/tm/client/client_test.go +++ b/rpc/tm/tmclient/client_test.go @@ -1,4 +1,4 @@ -package client +package tmclient import ( "testing" diff --git a/rpc/v0/client.go b/rpc/v0/client.go deleted file mode 100644 index f663a7993509daf900b8f1d4a4c7e25a4662783d..0000000000000000000000000000000000000000 --- a/rpc/v0/client.go +++ /dev/null @@ -1,127 +0,0 @@ -package v0 - -import ( - "bytes" - "encoding/json" - "io/ioutil" - "net/http" - "time" - - "github.com/hyperledger/burrow/execution" - "github.com/hyperledger/burrow/execution/events" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/txs" -) - -type V0Client struct { - url string - codec rpc.Codec - client *http.Client -} - -type RPCResponse struct { - Result json.RawMessage `json:"result"` - Error *rpc.RPCError `json:"error"` - Id string `json:"id"` - JSONRPC string `json:"jsonrpc"` -} - -func NewV0Client(url string) *V0Client { - return &V0Client{ - url: url, - codec: NewTCodec(), - client: &http.Client{ - Timeout: 1000 * time.Second, - }, - } -} - -func (vc *V0Client) Transact(param TransactParam) (*txs.Receipt, error) { - receipt := new(txs.Receipt) - err := vc.CallMethod(TRANSACT, param, receipt) - if err != nil { - return nil, err - } - return receipt, nil -} - -func (vc *V0Client) TransactAndHold(param TransactParam) (*events.EventDataCall, error) { - eventDataCall := new(events.EventDataCall) - err := vc.CallMethod(TRANSACT_AND_HOLD, param, eventDataCall) - if err != nil { - return nil, err - } - return eventDataCall, nil -} - -func (vc *V0Client) Send(param SendParam) (*txs.Receipt, error) { - receipt := new(txs.Receipt) - err := vc.CallMethod(SEND, param, receipt) - if err != nil { - return nil, err - } - return receipt, nil -} - -func (vc *V0Client) SendAndHold(param SendParam) (*txs.Receipt, error) { - receipt := new(txs.Receipt) - err := vc.CallMethod(SEND_AND_HOLD, param, receipt) - if err != nil { - return nil, err - } - return receipt, nil -} - -func (vc *V0Client) Call(param CallParam) (*execution.Call, error) { - call := new(execution.Call) - err := vc.CallMethod(CALL, param, call) - if err != nil { - return nil, err - } - return call, nil -} - -func (vc *V0Client) CallCode(param CallCodeParam) (*execution.Call, error) { - call := new(execution.Call) - err := vc.CallMethod(CALL_CODE, param, call) - if err != nil { - return nil, err - } - return call, nil -} - -func (vc *V0Client) CallMethod(method string, param interface{}, result interface{}) error { - // Marhsal into JSONRPC request object - bs, err := vc.codec.EncodeBytes(param) - if err != nil { - return err - } - request := rpc.NewRPCRequest("test", method, bs) - bs, err = json.Marshal(request) - if err != nil { - return err - } - // Post to JSONService - resp, err := vc.client.Post(vc.url, "application/json", bytes.NewBuffer(bs)) - if err != nil { - return err - } - // Marshal into JSONRPC response object - bs, err = ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - rpcResponse := new(RPCResponse) - err = json.Unmarshal(bs, rpcResponse) - if err != nil { - return err - } - if rpcResponse.Error != nil { - return rpcResponse.Error - } - vc.codec.DecodeBytes(result, rpcResponse.Result) - if err != nil { - return err - } - return nil -} diff --git a/rpc/v0/codec.go b/rpc/v0/codec.go deleted file mode 100644 index dc29f3e2fcb89af88b81fe574e4fc1de719da03b..0000000000000000000000000000000000000000 --- a/rpc/v0/codec.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - "io" - "io/ioutil" - - "encoding/json" - - "github.com/hyperledger/burrow/rpc" -) - -// Codec that uses tendermints 'binary' package for JSON. -type TCodec struct { -} - -// Get a new codec. -func NewTCodec() rpc.Codec { - return &TCodec{} -} - -// Encode to an io.Writer. -func (codec *TCodec) Encode(v interface{}, w io.Writer) error { - bs, err := codec.EncodeBytes(v) - if err != nil { - return err - } - _, err = w.Write(bs) - return err -} - -// Encode to a byte array. -func (codec *TCodec) EncodeBytes(v interface{}) ([]byte, error) { - return json.Marshal(v) -} - -// Decode from an io.Reader. -func (codec *TCodec) Decode(v interface{}, r io.Reader) error { - bs, err := ioutil.ReadAll(r) - if err != nil { - return err - } - return codec.DecodeBytes(v, bs) -} - -// Decode from a byte array. -func (codec *TCodec) DecodeBytes(v interface{}, bs []byte) error { - return json.Unmarshal(bs, v) -} diff --git a/rpc/v0/codec_test.go b/rpc/v0/codec_test.go deleted file mode 100644 index 500afb1e5c8f8f8ab4adfb42da5c4ceb49bed822..0000000000000000000000000000000000000000 --- a/rpc/v0/codec_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - "testing" - - "github.com/hyperledger/burrow/crypto" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestKeysEncoding(t *testing.T) { - codec := NewTCodec() - privateKey := crypto.PrivateKeyFromSecret("foo", crypto.CurveTypeEd25519) - type keyPair struct { - PrivateKey crypto.PrivateKey - PublicKey crypto.PublicKey - } - - kp := keyPair{ - PrivateKey: privateKey, - PublicKey: privateKey.GetPublicKey(), - } - - bs, err := codec.EncodeBytes(kp) - require.NoError(t, err) - - kpOut := keyPair{} - codec.DecodeBytes(&kpOut, bs) - - assert.Equal(t, kp, kpOut) -} diff --git a/rpc/v0/integration/v0_test.go b/rpc/v0/integration/v0_test.go deleted file mode 100644 index 563512eb7e8fdff10962b76a0bb7cd8929288119..0000000000000000000000000000000000000000 --- a/rpc/v0/integration/v0_test.go +++ /dev/null @@ -1,178 +0,0 @@ -// +build integration - -// Space above here matters -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package integration - -import ( - "sync" - "testing" - - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/execution/evm/abi" - "github.com/hyperledger/burrow/rpc/test" - "github.com/hyperledger/burrow/rpc/v0" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestTransactCallNoCode(t *testing.T) { - cli := v0.NewV0Client("http://localhost:1337/rpc") - - // Flip flops between sending private key and input address to test private key and address based signing - toAddress := privateAccounts[2].Address() - - numCreates := 1000 - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numCreates; i++ { - receipt, err := cli.Transact(v0.TransactParam{ - InputAccount: inputAccount(i), - Address: toAddress.Bytes(), - Data: []byte{}, - Fee: 2, - GasLimit: 10000 + uint64(i), - }) - require.NoError(t, err) - assert.False(t, receipt.CreatesContract) - assert.Equal(t, toAddress, receipt.ContractAddress) - } - require.Equal(t, numCreates, <-countCh) -} - -func TestTransactCreate(t *testing.T) { - numGoroutines := 100 - numCreates := 50 - wg := new(sync.WaitGroup) - wg.Add(numGoroutines) - cli := v0.NewV0Client("http://localhost:1337/rpc") - // Flip flops between sending private key and input address to test private key and address based signing - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numGoroutines; i++ { - go func() { - for j := 0; j < numCreates; j++ { - create, err := cli.Transact(v0.TransactParam{ - InputAccount: inputAccount(i), - Address: nil, - Data: test.Bytecode_strange_loop, - Fee: 2, - GasLimit: 10000, - }) - if assert.NoError(t, err) { - assert.True(t, create.CreatesContract) - } - } - wg.Done() - }() - } - wg.Wait() - - require.Equal(t, numGoroutines*numCreates, <-countCh) -} - -func BenchmarkTransactCreateContract(b *testing.B) { - cli := v0.NewV0Client("http://localhost:1337/rpc") - - for i := 0; i < b.N; i++ { - create, err := cli.Transact(v0.TransactParam{ - InputAccount: inputAccount(i), - Address: nil, - Data: test.Bytecode_strange_loop, - Fee: 2, - GasLimit: 10000, - }) - require.NoError(b, err) - assert.True(b, create.CreatesContract) - } -} - -func TestTransactAndHold(t *testing.T) { - cli := v0.NewV0Client("http://localhost:1337/rpc") - - numGoroutines := 5 - numRuns := 2 - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numGoroutines; i++ { - for j := 0; j < numRuns; j++ { - create, err := cli.TransactAndHold(v0.TransactParam{ - InputAccount: inputAccount(i), - Address: nil, - Data: test.Bytecode_strange_loop, - Fee: 2, - GasLimit: 10000, - }) - require.NoError(t, err) - assert.Equal(t, uint64(0), create.StackDepth) - functionID := abi.FunctionID("UpsieDownsie()") - call, err := cli.TransactAndHold(v0.TransactParam{ - InputAccount: inputAccount(i), - Address: create.CallData.Callee.Bytes(), - Data: functionID[:], - Fee: 2, - GasLimit: 10000, - }) - require.NoError(t, err) - depth := binary.Uint64FromWord256(binary.LeftPadWord256(call.Return)) - // Would give 23 if taken from wrong frame - assert.Equal(t, 18, int(depth)) - } - } - require.Equal(t, numGoroutines*numRuns*2, <-countCh) -} - -func TestSend(t *testing.T) { - cli := v0.NewV0Client("http://localhost:1337/rpc") - numSends := 1000 - countCh := test.CommittedTxCount(t, kern.Emitter) - for i := 0; i < numSends; i++ { - send, err := cli.Send(v0.SendParam{ - InputAccount: inputAccount(i), - Amount: 2003, - ToAddress: privateAccounts[3].Address().Bytes(), - }) - require.NoError(t, err) - assert.Equal(t, false, send.CreatesContract) - } - require.Equal(t, numSends, <-countCh) -} - -func TestSendAndHold(t *testing.T) { - cli := v0.NewV0Client("http://localhost:1337/rpc") - - for i := 0; i < 2; i++ { - send, err := cli.SendAndHold(v0.SendParam{ - InputAccount: inputAccount(i), - Amount: 2003, - ToAddress: privateAccounts[3].Address().Bytes(), - }) - require.NoError(t, err) - assert.Equal(t, false, send.CreatesContract) - } -} - -// Helpers - -var inputPrivateKey = privateAccounts[0].PrivateKey().RawBytes() -var inputAddress = privateAccounts[0].Address().Bytes() - -func inputAccount(i int) v0.InputAccount { - ia := v0.InputAccount{} - if i%2 == 0 { - ia.PrivateKey = inputPrivateKey - } else { - ia.Address = inputAddress - } - return ia -} diff --git a/rpc/v0/json_service.go b/rpc/v0/json_service.go deleted file mode 100644 index 41595de660ede4e892f287403ca9a76098c4c4f3..0000000000000000000000000000000000000000 --- a/rpc/v0/json_service.go +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - "context" - "encoding/json" - "net/http" - - "github.com/gin-gonic/gin" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/rpc/v0/server" -) - -// EventSubscribe -type EventSub struct { - SubId string `json:"subId"` -} - -// EventUnsubscribe -type EventUnsub struct { - Result bool `json:"result"` -} - -// EventPoll -type PollResponse struct { - Events []interface{} `json:"events"` -} - -// Server used to handle JSON-RPC 2.0 requests. Implements server.Server -type JsonRpcServer struct { - service server.HttpService - running bool -} - -// Create a new JsonRpcServer -func NewJSONServer(service server.HttpService) *JsonRpcServer { - return &JsonRpcServer{service: service} -} - -// Start adds the rpc path to the router. -func (jrs *JsonRpcServer) Start(config *server.ServerConfig, router *gin.Engine) { - router.POST(config.HTTP.JsonRpcEndpoint, jrs.handleFunc) - jrs.running = true -} - -// Is the server currently running? -func (jrs *JsonRpcServer) Running() bool { - return jrs.running -} - -// Shut the server down. Does nothing. -func (jrs *JsonRpcServer) Shutdown(ctx context.Context) error { - jrs.running = false - return nil -} - -// Handler passes message on directly to the service which expects -// a normal http request and response writer. -func (jrs *JsonRpcServer) handleFunc(c *gin.Context) { - r := c.Request - w := c.Writer - - jrs.service.Process(r, w) -} - -// Used for Burrow. Implements server.HttpService -type JSONService struct { - codec rpc.Codec - service *rpc.Service - eventSubs *rpc.Subscriptions - defaultHandlers map[string]RequestHandlerFunc - logger *logging.Logger -} - -// Create a new JSON-RPC 2.0 service for burrow (tendermint). -func NewJSONService(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) server.HttpService { - - tmhttps := &JSONService{ - codec: codec, - service: service, - eventSubs: rpc.NewSubscriptions(service), - logger: logger.WithScope("NewJSONService"), - } - - dhMap := GetMethods(codec, service, tmhttps.logger) - // Events - dhMap[EVENT_SUBSCRIBE] = tmhttps.EventSubscribe - dhMap[EVENT_UNSUBSCRIBE] = tmhttps.EventUnsubscribe - dhMap[EVENT_POLL] = tmhttps.EventPoll - tmhttps.defaultHandlers = dhMap - return tmhttps -} - -// Process a request. -func (js *JSONService) Process(r *http.Request, w http.ResponseWriter) { - - // Create new request object and unmarshal. - req := &rpc.RPCRequest{} - decoder := json.NewDecoder(r.Body) - errU := decoder.Decode(req) - - // Error when decoding. - if errU != nil { - js.writeError("Failed to parse request: "+errU.Error(), "", - rpc.PARSE_ERROR, w) - return - } - - // Wrong protocol version. - if req.JSONRPC != "2.0" { - js.writeError("Wrong protocol version: "+req.JSONRPC, req.Id, - rpc.INVALID_REQUEST, w) - return - } - - mName := req.Method - - if handler, ok := js.defaultHandlers[mName]; ok { - js.logger.TraceMsg("Request received", - "id", req.Id, - "method", req.Method) - resp, errCode, err := handler(req, w) - if err != nil { - js.writeError(err.Error(), req.Id, errCode, w) - } else { - js.writeResponse(req.Id, resp, w) - } - } else { - js.writeError("Method not found: "+mName, req.Id, rpc.METHOD_NOT_FOUND, w) - } -} - -// Helper for writing error responses. -func (js *JSONService) writeError(msg, id string, code int, w http.ResponseWriter) { - response := rpc.NewRPCErrorResponse(id, code, msg) - err := js.codec.Encode(response, w) - // If there's an error here all bets are off. - if err != nil { - http.Error(w, "Failed to marshal standard error response: "+err.Error(), 500) - return - } - w.WriteHeader(200) -} - -// Helper for writing responses. -func (js *JSONService) writeResponse(id string, result interface{}, w http.ResponseWriter) { - response := rpc.NewRPCResponse(id, result) - err := js.codec.Encode(response, w) - if err != nil { - js.writeError("Internal error: "+err.Error(), id, rpc.INTERNAL_ERROR, w) - return - } - w.WriteHeader(200) -} - -// *************************************** Events ************************************ - -// Subscribe to an -func (js *JSONService) EventSubscribe(request *rpc.RPCRequest, - requester interface{}) (interface{}, int, error) { - param := &EventIdParam{} - err := json.Unmarshal(request.Params, param) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - eventId := param.EventId - subId, errC := js.eventSubs.Add(eventId) - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } - return &EventSub{subId}, 0, nil -} - -// Un-subscribe from an -func (js *JSONService) EventUnsubscribe(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &SubIdParam{} - err := json.Unmarshal(request.Params, param) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - subId := param.SubId - - err = js.service.Unsubscribe(context.Background(), subId) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return &EventUnsub{true}, 0, nil -} - -// Check subscription event cache for new data. -func (js *JSONService) EventPoll(request *rpc.RPCRequest, - requester interface{}) (interface{}, int, error) { - param := &SubIdParam{} - err := json.Unmarshal(request.Params, param) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - subId := param.SubId - - result, errC := js.eventSubs.Poll(subId) - if errC != nil { - return nil, rpc.INTERNAL_ERROR, errC - } - return &PollResponse{result}, 0, nil -} diff --git a/rpc/v0/json_service_data_test.go b/rpc/v0/json_service_data_test.go deleted file mode 100644 index c258c4c2ca3f2b1275d1d4743779586a5b0f740a..0000000000000000000000000000000000000000 --- a/rpc/v0/json_service_data_test.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - "encoding/json" - "fmt" - "testing" - - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/txs" - "github.com/hyperledger/burrow/txs/payload" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -var txEnvelopeString = `{"Signatories":[{"Address":"83207817DC3814B96F57EFF925F467E07CAA9138","PublicKey":{"CurveType":"ed25519",` + - `"PublicKey":"34D26579DBB456693E540672CF922F52DDE0D6532E35BF06BE013A7C532F20E0"},` + - `"Signature":"5042F208824AA5AF8E03B2F11FB8CFCDDAE4F889B2F720714627395406E00D7740B2DB5B5F93BD6C13DED9B7C1FD5FB0DB4ECA31E6DA0B81033A72922076E90C"}],` + - `"Tx":{"ChainID":"testChain","Type":"CallTx","Payload":{"Input":{"Address":"83207817DC3814B96F57EFF925F467E07CAA9138","Amount":343,"Sequence":3},` + - `"Address":"AC280D53FD359D9FF11F19D0796D9B89907F3B53","GasLimit":2323,"Fee":12,"Data":"03040505"}}}` - -var testBroadcastCallTxJsonRequest = []byte(` -{ - "id": "57EC1D39-7B3D-4F96-B286-8FC128177AFC4", - "jsonrpc": "2.0", - "method": "burrow.broadcastTx", - "params": ` + txEnvelopeString + ` -}`) - -// strictly test the codec for go-wire encoding of the Json format, -// This should restore compatibility with the format on v0.11.4 -// (which was broken on v0.12) -func fixTestCallTxJsonFormatCodec(t *testing.T) { - codec := NewTCodec() - txEnv := new(txs.Envelope) - // Create new request object and unmarshal. - request := &rpc.RPCRequest{} - assert.NoError(t, json.Unmarshal(testBroadcastCallTxJsonRequest, request), - "Provided JSON test data does not unmarshal to rpc.RPCRequest object.") - assert.NoError(t, codec.DecodeBytes(txEnv, request.Params), - "RPC codec failed to decode params as transaction type.") - _, ok := txEnv.Tx.Payload.(*payload.CallTx) - assert.True(t, ok, "Type byte 0x02 should unmarshal into CallTx.") -} - -func TestGenTxEnvelope(t *testing.T) { - codec := NewTCodec() - privAccFrom := acm.GeneratePrivateAccountFromSecret("foo") - privAccTo := acm.GeneratePrivateAccountFromSecret("bar") - toAddress := privAccTo.Address() - txEnv := txs.Enclose("testChain", payload.NewCallTxWithSequence(privAccFrom.PublicKey(), &toAddress, - []byte{3, 4, 5, 5}, 343, 2323, 12, 3)) - err := txEnv.Sign(privAccFrom) - require.NoError(t, err) - bs, err := codec.EncodeBytes(txEnv) - require.NoError(t, err) - if !assert.Equal(t, txEnvelopeString, string(bs)) { - fmt.Println(string(bs)) - } -} diff --git a/rpc/v0/json_service_test.go b/rpc/v0/json_service_test.go deleted file mode 100644 index 23ec7620908b691326cff65c5c13095ea8cedb7d..0000000000000000000000000000000000000000 --- a/rpc/v0/json_service_test.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestPollResponse(t *testing.T) { - pr := PollResponse{} - bs, err := json.Marshal(pr) - require.NoError(t, err) - fmt.Println(string(bs)) -} diff --git a/rpc/v0/methods.go b/rpc/v0/methods.go deleted file mode 100644 index 7b510f23c169c54abb1215027409fee7885cf212..0000000000000000000000000000000000000000 --- a/rpc/v0/methods.go +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - "context" - - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/names" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/rpc/filters" - "github.com/hyperledger/burrow/txs" -) - -// TODO use the method name definition file. -const ( - SERVICE_NAME = "burrow" - - GET_ACCOUNTS = SERVICE_NAME + ".getAccounts" // Accounts - GET_ACCOUNT = SERVICE_NAME + ".getAccount" - GET_STORAGE = SERVICE_NAME + ".getStorage" - GET_STORAGE_AT = SERVICE_NAME + ".getStorageAt" - GEN_PRIV_ACCOUNT = SERVICE_NAME + ".genPrivAccount" - GEN_PRIV_ACCOUNT_FROM_KEY = SERVICE_NAME + ".genPrivAccountFromKey" - GET_BLOCKCHAIN_INFO = SERVICE_NAME + ".getBlockchainInfo" // Blockchain - GET_LATEST_BLOCK = SERVICE_NAME + ".getLatestBlock" - GET_BLOCKS = SERVICE_NAME + ".getBlocks" - GET_BLOCK = SERVICE_NAME + ".getBlock" - GET_CONSENSUS_STATE = SERVICE_NAME + ".getConsensusState" // Consensus - GET_VALIDATORS = SERVICE_NAME + ".getValidators" - GET_NETWORK_INFO = SERVICE_NAME + ".getNetworkInfo" // Net - GET_CHAIN_ID = SERVICE_NAME + ".getChainId" - GET_PEERS = SERVICE_NAME + ".getPeers" - CALL = SERVICE_NAME + ".call" // Tx - CALL_CODE = SERVICE_NAME + ".callCode" - BROADCAST_TX = SERVICE_NAME + ".broadcastTx" - GET_UNCONFIRMED_TXS = SERVICE_NAME + ".getUnconfirmedTxs" - SIGN_TX = SERVICE_NAME + ".signTx" - TRANSACT = SERVICE_NAME + ".transact" - TRANSACT_AND_HOLD = SERVICE_NAME + ".transactAndHold" - SEND = SERVICE_NAME + ".send" - SEND_AND_HOLD = SERVICE_NAME + ".sendAndHold" - TRANSACT_NAMEREG = SERVICE_NAME + ".transactNameReg" - EVENT_SUBSCRIBE = SERVICE_NAME + ".eventSubscribe" // Events - EVENT_UNSUBSCRIBE = SERVICE_NAME + ".eventUnsubscribe" - EVENT_POLL = SERVICE_NAME + ".eventPoll" - GET_NAMEREG_ENTRY = SERVICE_NAME + ".getNameRegEntry" // Namereg - GET_NAMEREG_ENTRIES = SERVICE_NAME + ".getNameRegEntries" -) - -// Used to handle requests. interface{} param is a wildcard used for example with socket events. -type RequestHandlerFunc func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) - -// Private. Create a method name -> method handler map. -func GetMethods(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) map[string]RequestHandlerFunc { - accountFilterFactory := filters.NewAccountFilterFactory() - nameRegFilterFactory := filters.NewNameRegFilterFactory() - return map[string]RequestHandlerFunc{ - // Accounts - GET_ACCOUNTS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &FilterListParam{} - if len(request.Params) > 0 { - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - } - filter, err := accountFilterFactory.NewFilter(param.Filters) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - list, err := service.ListAccounts(func(account acm.Account) bool { - return filter.Match(account) - - }) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return list, 0, nil - }, - GET_ACCOUNT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &AddressParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - address, err := crypto.AddressFromBytes(param.Address) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - account, err := service.GetAccount(address) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return account, 0, nil - }, - GET_STORAGE: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &AddressParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - address, err := crypto.AddressFromBytes(param.Address) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - storage, err := service.DumpStorage(address) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return storage, 0, nil - }, - GET_STORAGE_AT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &StorageAtParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - address, err := crypto.AddressFromBytes(param.Address) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - storageItem, err := service.GetStorage(address, param.Key) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return storageItem, 0, nil - }, - GEN_PRIV_ACCOUNT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - pa, err := acm.GeneratePrivateAccount() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return acm.AsConcretePrivateAccount(pa), 0, nil - }, - GEN_PRIV_ACCOUNT_FROM_KEY: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &PrivateKeyParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - pa, err := acm.GeneratePrivateAccountFromPrivateKeyBytes(param.PrivateKey) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return acm.AsConcretePrivateAccount(pa), 0, nil - }, - // Txs - CALL: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &CallParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - from, err := crypto.AddressFromBytes(param.From) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - address, err := crypto.AddressFromBytes(param.Address) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - call, err := service.Transactor().Call(service.MempoolAccounts(), from, address, param.Data) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return call, 0, nil - }, - CALL_CODE: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &CallCodeParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - from, err := crypto.AddressFromBytes(param.From) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - call, err := service.Transactor().CallCode(service.MempoolAccounts(), from, param.Code, param.Data) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return call, 0, nil - }, - BROADCAST_TX: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - // Accept all transaction types as parameter for broadcast. - txEnv := new(txs.Envelope) - err := codec.DecodeBytes(txEnv, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - receipt, err := service.Transactor().BroadcastTx(txEnv) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return receipt, 0, nil - }, - SIGN_TX: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &SignTxParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - txRet, err := service.Transactor().SignTx(txs.Enclose(service.BlockchainInfo().ChainID(), param.Tx), - acm.SigningAccounts(param.PrivateAccounts)) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return txRet, 0, nil - }, - TRANSACT: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &TransactParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - address, err := crypto.MaybeAddressFromBytes(param.Address) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - // Use mempool state so that transact can generate a run of sequence numbers when formulating transactions - inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address, - param.InputAccount.PrivateKey) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - // We ensure zero value transfer for legacy compatibility reason (i.e. we always have) - receipt, err := service.Transactor().Transact(inputAccount, address, param.Data, param.GasLimit, 0, - param.Fee) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return receipt, 0, nil - }, - TRANSACT_AND_HOLD: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &TransactParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - address, err := crypto.MaybeAddressFromBytes(param.Address) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address, - param.InputAccount.PrivateKey) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - // We ensure zero value transfer for legacy compatibility reason (i.e. we always have) - eventDataCall, err := service.Transactor().TransactAndHold(context.Background(), inputAccount, address, - param.Data, param.GasLimit, 0, param.Fee) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return eventDataCall, 0, nil - }, - SEND: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &SendParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - toAddress, err := crypto.AddressFromBytes(param.ToAddress) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - // Run Send against mempool state - inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address, - param.InputAccount.PrivateKey) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - receipt, err := service.Transactor().Send(inputAccount, toAddress, param.Amount) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return receipt, 0, nil - }, - SEND_AND_HOLD: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &SendParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - toAddress, err := crypto.AddressFromBytes(param.ToAddress) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - // Run Send against mempool state - inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address, - param.InputAccount.PrivateKey) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - rec, err := service.Transactor().SendAndHold(context.Background(), inputAccount, toAddress, param.Amount) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return rec, 0, nil - }, - TRANSACT_NAMEREG: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &TransactNameRegParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - inputAccount, err := service.MempoolAccounts().GetSequentialSigningAccount(param.InputAccount.Address, - param.InputAccount.PrivateKey) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - receipt, err := service.Transactor().TransactNameReg(inputAccount, param.Name, param.Data, param.Amount, param.Fee) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return receipt, 0, nil - }, - - // Namereg - GET_NAMEREG_ENTRY: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &NameRegEntryParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - name := param.Name - // TODO is address check? - resultGetName, err := service.GetName(name) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultGetName.Entry, 0, nil - }, - GET_NAMEREG_ENTRIES: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &FilterListParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - filter, err := nameRegFilterFactory.NewFilter(param.Filters) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - list, err := service.ListNames(func(entry *names.Entry) bool { - return filter.Match(entry) - }) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return list, 0, nil - }, - // Blockchain - GET_BLOCKCHAIN_INFO: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - resultStatus, err := service.Status() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultStatus, 0, nil - }, - GET_LATEST_BLOCK: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - stat, err := service.Status() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - resultGetBlock, err := service.GetBlock(stat.LatestBlockHeight) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultGetBlock, 0, nil - }, - GET_BLOCKS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &BlocksParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - blocks, err := service.ListBlocks(param.MinHeight, param.MaxHeight) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return blocks, 0, nil - }, - GET_BLOCK: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &HeightParam{} - err := codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - block, err := service.GetBlock(param.Height) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return block, 0, nil - }, - GET_UNCONFIRMED_TXS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - trans, err := service.ListUnconfirmedTxs(-1) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return trans, 0, nil - }, - // Consensus - GET_CONSENSUS_STATE: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - resultDumpConsensusState, err := service.DumpConsensusState() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultDumpConsensusState, 0, nil - }, - GET_VALIDATORS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - resultListValidators, err := service.ListValidators() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultListValidators, 0, nil - }, - // Network - GET_NETWORK_INFO: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - resultNetInfo, err := service.NetInfo() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultNetInfo, 0, nil - }, - GET_CHAIN_ID: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - resultChainID, err := service.ChainIdentifiers() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultChainID, 0, nil - }, - GET_PEERS: func(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - resultPeers, err := service.Peers() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return resultPeers, 0, nil - }, - } -} diff --git a/rpc/v0/params.go b/rpc/v0/params.go deleted file mode 100644 index b84c131e18d89d24d55acf0537b851dc90067be7..0000000000000000000000000000000000000000 --- a/rpc/v0/params.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/binary" - "github.com/hyperledger/burrow/rpc/filters" - "github.com/hyperledger/burrow/txs/payload" -) - -type ( - // Used to send an address. The address should be hex and properly formatted. - AddressParam struct { - Address binary.HexBytes `json:"address"` - } - - // Used to send an address - FilterListParam struct { - Filters []*filters.FilterData `json:"filters"` - } - - PrivateKeyParam struct { - PrivateKey binary.HexBytes `json:"privateKey"` - } - - InputAccount struct { - PrivateKey binary.HexBytes `json:"privateKey"` - Address binary.HexBytes `json:"address"` - } - - // StorageAt - StorageAtParam struct { - Address binary.HexBytes `json:"address"` - Key binary.HexBytes `json:"key"` - } - - // Get a block - HeightParam struct { - Height uint64 `json:"height"` - } - - BlocksParam struct { - MinHeight uint64 `json:"minHeight"` - MaxHeight uint64 `json:"maxHeight"` - } - - // Event Id - EventIdParam struct { - EventId string `json:"eventId"` - } - - // Event Id - SubIdParam struct { - SubId string `json:"subId"` - } - - PeerParam struct { - Address string `json:"address"` - } - - // Used when doing calls - CallParam struct { - Address binary.HexBytes `json:"address"` - From binary.HexBytes `json:"from"` - Data binary.HexBytes `json:"data"` - } - - // Used when doing code calls - CallCodeParam struct { - From binary.HexBytes `json:"from"` - Code binary.HexBytes `json:"code"` - Data binary.HexBytes `json:"data"` - } - - // Used when signing a tx. Uses placeholders just like TxParam - SignTxParam struct { - Tx *payload.CallTx `json:"tx"` - PrivateAccounts []*acm.ConcretePrivateAccount `json:"privateAccounts"` - } - - // Used when sending a transaction to be created and signed on the server - // (using the private key). This only uses the standard key type for now. - TransactParam struct { - InputAccount InputAccount `json:"inputAccount"` - Data binary.HexBytes `json:"data"` - Address binary.HexBytes `json:"address"` - Fee uint64 `json:"fee"` - GasLimit uint64 `json:"gasLimit"` - } - - // Used when sending a 'Send' transaction. - SendParam struct { - InputAccount InputAccount `json:"inputAccount"` - ToAddress binary.HexBytes `json:"toAddress"` - Amount uint64 `json:"amount"` - } - - NameRegEntryParam struct { - Name string `json:"name"` - } - - // Used when sending a namereg transaction to be created and signed on the server - // (using the private key). This only uses the standard key type for now. - TransactNameRegParam struct { - InputAccount InputAccount `json:"inputAccount"` - Name string `json:"name"` - Data string `json:"data"` - Fee uint64 `json:"fee"` - Amount uint64 `json:"amount"` - } -) diff --git a/rpc/v0/server/README.md b/rpc/v0/server/README.md deleted file mode 100644 index 14526e2b6ff47541494c06907be7463923e54187..0000000000000000000000000000000000000000 --- a/rpc/v0/server/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Server - -This package contains classes for starting and running HTTP and websocket servers. - -## Server interface - -Servers implements the `Server` interface. A 'ServerConfig' and 'gin.Engine' object is supplied in the 'Start' method, so that they may set themselves up and set up the routes etc. - -``` -type Server interface { - Start(*ServerConfig, *gin.Engine) - Running() bool - ShutDown() -} -``` - -The `Server` interface can be found in `server.go`. - -## ServeProcess - -The `ServeProcess` does the port binding and listening. You may attach any number of servers to the serve-process, and it will automatically call their 'Start' and 'ShutDown' methods when starting up and shutting down. You may also attach start and shutdown listeners to the `ServeProcess`. - -The `ServeProcess` class can be found in `server.go`. - -## WebSocketServer - -The `WebSocketServer` is a template for servers that use websocket connections rather then HTTP. It will - -## Config - -The config assumes that there is a default HTTP and Websocket server for RPC, and some other fields. See the main README.md for details. - -While the system is generic (i.e. it does not care what a `Server` is or does), the configuration file is not. The reason is that the server is written specifically for burrow, and I do not want to manage generic config files (or perhaps even one per server). \ No newline at end of file diff --git a/rpc/v0/server/config.go b/rpc/v0/server/config.go deleted file mode 100644 index 6db3bdbe875221c317c3d8348166ba48b90aa560..0000000000000000000000000000000000000000 --- a/rpc/v0/server/config.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package server - -type ( - ServerConfig struct { - Bind Bind `toml:"bind"` - TLS TLS `toml:"TLS"` - CORS CORS `toml:"CORS"` - HTTP HTTP `toml:"HTTP"` - WebSocket WebSocket `toml:"web_socket"` - } - - Bind struct { - Address string `toml:"address"` - Port uint16 `toml:"port"` - } - - TLS struct { - TLS bool `toml:"tls"` - CertPath string `toml:"cert_path"` - KeyPath string `toml:"key_path"` - } - - // Options stores configurations - CORS struct { - Enable bool `toml:"enable"` - AllowOrigins []string `toml:"allow_origins"` - AllowCredentials bool `toml:"allow_credentials"` - AllowMethods []string `toml:"allow_methods"` - AllowHeaders []string `toml:"allow_headers"` - ExposeHeaders []string `toml:"expose_headers"` - MaxAge uint64 `toml:"max_age"` - } - - HTTP struct { - JsonRpcEndpoint string `toml:"json_rpc_endpoint"` - } - - WebSocket struct { - WebSocketEndpoint string `toml:"websocket_endpoint"` - MaxWebSocketSessions uint16 `toml:"max_websocket_sessions"` - ReadBufferSize uint64 `toml:"read_buffer_size"` - WriteBufferSize uint64 `toml:"write_buffer_size"` - } -) - -func DefaultServerConfig() *ServerConfig { - cp := "" - kp := "" - return &ServerConfig{ - Bind: Bind{ - Address: "localhost", - Port: 1337, - }, - TLS: TLS{TLS: false, - CertPath: cp, - KeyPath: kp, - }, - CORS: CORS{}, - HTTP: HTTP{ - JsonRpcEndpoint: "/rpc", - }, - WebSocket: WebSocket{ - WebSocketEndpoint: "/socketrpc", - MaxWebSocketSessions: 50, - ReadBufferSize: 4096, - WriteBufferSize: 4096, - }, - } -} diff --git a/rpc/v0/server/idpool.go b/rpc/v0/server/idpool.go deleted file mode 100644 index 44a72cba4d1b3266430b4ff95841a90db4316de8..0000000000000000000000000000000000000000 --- a/rpc/v0/server/idpool.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package server - -import ( - "container/list" - "fmt" -) - -// Simple id pool. Lets you get and release uints. Will panic -// if trying to get an id and it's empty. -type IdPool struct { - ids *list.List -} - -func NewIdPool(totNum uint) *IdPool { - idPool := &IdPool{} - idPool.init(totNum) - return idPool -} - -// We start from 1, so that 0 is not used as an id. -func (idp *IdPool) init(totNum uint) { - idp.ids = list.New() - for i := uint(1); i <= totNum; i++ { - idp.ids.PushBack(i) - } -} - -// Get an id from the pool. -func (idp *IdPool) GetId() (uint, error) { - if idp.ids.Len() == 0 { - return 0, fmt.Errorf("Out of IDs") - } - val := idp.ids.Front() - idp.ids.Remove(val) - num, _ := val.Value.(uint) - return num, nil -} - -// Release an id back into the pool. -func (idp *IdPool) ReleaseId(id uint) { - idp.ids.PushBack(id) -} diff --git a/rpc/v0/server/server.go b/rpc/v0/server/server.go deleted file mode 100644 index ec4c89c2e8d7733ef4c5d0c16460780f22a7f4dc..0000000000000000000000000000000000000000 --- a/rpc/v0/server/server.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package server - -import ( - "context" - "crypto/tls" - "fmt" - "net" - "net/http" - "time" - - "github.com/gin-gonic/gin" - "github.com/hyperledger/burrow/logging" - "github.com/tommy351/gin-cors" - "gopkg.in/tylerb/graceful.v1" -) - -var ( - killTime = 100 * time.Millisecond -) - -type HttpService interface { - Process(*http.Request, http.ResponseWriter) -} - -// A server serves a number of different http calls. -type Server interface { - Start(*ServerConfig, *gin.Engine) - Running() bool - Shutdown(ctx context.Context) error -} - -// The ServeProcess wraps all the Servers. Starting it will -// add all the server handlers to the router and start listening -// for incoming requests. There is also startup and shutdown events -// that can be listened to, on top of any events that the servers -// may have (the default websocket server has events for monitoring -// sessions. Startup event listeners should be added before calling -// 'Start()'. Stop event listeners can be added up to the point where -// the server is stopped and the event is fired. -type ServeProcess struct { - config *ServerConfig - servers []Server - stopChan chan struct{} - startListenChans []chan struct{} - stopListenChans []chan struct{} - srv *graceful.Server - logger *logging.Logger -} - -// Initializes all the servers and starts listening for connections. -func (serveProcess *ServeProcess) Start() error { - gin.SetMode(gin.ReleaseMode) - router := gin.New() - config := serveProcess.config - - ch := NewCORSMiddleware(config.CORS) - router.Use(gin.Recovery(), logHandler(serveProcess.logger), contentTypeMW, ch) - - address := config.Bind.Address - port := config.Bind.Port - - if port == 0 { - return fmt.Errorf("0 is not a valid port.") - } - - listenAddress := address + ":" + fmt.Sprintf("%d", port) - srv := &graceful.Server{ - Server: &http.Server{ - Handler: router, - }, - } - - // Start the servers/handlers. - for _, s := range serveProcess.servers { - s.Start(config, router) - } - - var lst net.Listener - l, lErr := net.Listen("tcp", listenAddress) - if lErr != nil { - return lErr - } - - // For secure connections. - if config.TLS.TLS { - addr := srv.Addr - if addr == "" { - addr = ":https" - } - - tConfig := &tls.Config{} - if tConfig.NextProtos == nil { - tConfig.NextProtos = []string{"http/1.1"} - } - - var tErr error - tConfig.Certificates = make([]tls.Certificate, 1) - tConfig.Certificates[0], tErr = tls.LoadX509KeyPair(config.TLS.CertPath, config.TLS.KeyPath) - if tErr != nil { - return tErr - } - - lst = tls.NewListener(l, tConfig) - } else { - lst = l - } - serveProcess.srv = srv - serveProcess.logger.InfoMsg("Server started.", - "address", serveProcess.config.Bind.Address, - "port", serveProcess.config.Bind.Port) - for _, c := range serveProcess.startListenChans { - c <- struct{}{} - } - // Start the serve routine. - go func() { - serveProcess.srv.Serve(lst) - for _, s := range serveProcess.servers { - s.Shutdown(context.Background()) - } - }() - // Listen to the process stop event, it will call 'Stop' - // on the graceful Server. This happens when someone - // calls 'Stop' on the process. - go func() { - <-serveProcess.stopChan - serveProcess.logger.InfoMsg("Close signal sent to server.") - serveProcess.srv.Stop(killTime) - }() - // Listen to the servers stop event. It is triggered when - // the server has been fully shut down. - go func() { - <-serveProcess.srv.StopChan() - serveProcess.logger.InfoMsg("Server stop event fired. Good bye.") - for _, c := range serveProcess.stopListenChans { - c <- struct{}{} - } - }() - return nil -} - -// Stop will release the port, process any remaining requests -// up until the timeout duration is passed, at which point it -// will abort them and shut down. -func (serveProcess *ServeProcess) Shutdown(ctx context.Context) error { - var err error - for _, s := range serveProcess.servers { - serr := s.Shutdown(ctx) - if serr != nil && err == nil { - err = serr - } - } - - lChan := serveProcess.StopEventChannel() - serveProcess.stopChan <- struct{}{} - select { - case <-lChan: - return err - case <-ctx.Done(): - return ctx.Err() - } -} - -// Get a start-event channel from the server. The start event -// is fired after the Start() function is called, and after -// the server has started listening for incoming connections. -// An error here . -func (serveProcess *ServeProcess) StartEventChannel() <-chan struct{} { - lChan := make(chan struct{}, 1) - serveProcess.startListenChans = append(serveProcess.startListenChans, lChan) - return lChan -} - -// Get a stop-event channel from the server. The event happens -// after the Stop() function has been called, and after the -// timeout has passed. When the timeout has passed it will wait -// for confirmation from the http.Server, which normally takes -// a very short time (milliseconds). -func (serveProcess *ServeProcess) StopEventChannel() <-chan struct{} { - lChan := make(chan struct{}, 1) - serveProcess.stopListenChans = append(serveProcess.stopListenChans, lChan) - return lChan -} - -// Creates a new serve process. -func NewServeProcess(config *ServerConfig, logger *logging.Logger, - servers ...Server) (*ServeProcess, error) { - var scfg ServerConfig - if config == nil { - return nil, fmt.Errorf("Nil passed as server configuration") - } else { - scfg = *config - } - stopChan := make(chan struct{}, 1) - startListeners := make([]chan struct{}, 0) - stopListeners := make([]chan struct{}, 0) - sp := &ServeProcess{ - config: &scfg, - servers: servers, - stopChan: stopChan, - startListenChans: startListeners, - stopListenChans: stopListeners, - srv: nil, - logger: logger.WithScope("ServeProcess"), - } - return sp, nil -} - -// Used to enable log15 logging instead of the default Gin logging. -func logHandler(logger *logging.Logger) gin.HandlerFunc { - logger = logger.WithScope("ginLogHandler") - return func(c *gin.Context) { - - path := c.Request.URL.Path - - // Process request - c.Next() - - clientIP := c.ClientIP() - method := c.Request.Method - statusCode := c.Writer.Status() - comment := c.Errors.String() - - logger.Info.Log("client_ip", clientIP, - "status_code", statusCode, - "method", method, - "path", path, - "error", comment) - } -} - -func NewCORSMiddleware(options CORS) gin.HandlerFunc { - o := cors.Options{ - AllowCredentials: options.AllowCredentials, - AllowHeaders: options.AllowHeaders, - AllowMethods: options.AllowMethods, - AllowOrigins: options.AllowOrigins, - ExposeHeaders: options.ExposeHeaders, - MaxAge: time.Duration(options.MaxAge), - } - return cors.Middleware(o) -} - -// Just a catch-all for POST requests right now. Only allow default charset (utf8). -func contentTypeMW(c *gin.Context) { - if c.Request.Method == "POST" && c.ContentType() != "application/json" { - c.AbortWithError(415, fmt.Errorf("Media type not supported: "+c.ContentType())) - } else { - c.Next() - } -} diff --git a/rpc/v0/server/server_test.go b/rpc/v0/server/server_test.go deleted file mode 100644 index 5efdad26819e4d2f12ed568c71954eb27ce1405c..0000000000000000000000000000000000000000 --- a/rpc/v0/server/server_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package server - -import ( - //"fmt" - "testing" - - "github.com/stretchr/testify/assert" -) - -// Unit tests for server components goes here. Full-on client-server tests -// can be found in the test folder. - -func TestIdGet(t *testing.T) { - idPool := NewIdPool(100) - idparr := make([]uint, 100) - arr := make([]uint, 100) - for i := 0; i < 100; i++ { - idparr[i] = uint(i + 1) - arr[i], _ = idPool.GetId() - } - assert.Equal(t, idparr, arr, "Array of gotten id's is not [1, 2, ..., 101] as expected") -} - -func TestIdPut(t *testing.T) { - idPool := NewIdPool(10) - for i := 0; i < 10; i++ { - idPool.GetId() - } - idPool.ReleaseId(5) - id, _ := idPool.GetId() - assert.Equal(t, id, uint(5), "Id gotten is not 5.") -} - -func TestIdFull(t *testing.T) { - idPool := NewIdPool(10) - for i := 0; i < 10; i++ { - idPool.GetId() - } - _, err := idPool.GetId() - assert.Error(t, err) -} diff --git a/rpc/v0/server/websocket.go b/rpc/v0/server/websocket.go deleted file mode 100644 index cda4f7def80b26957378e6d789db9a1e4e735f9c..0000000000000000000000000000000000000000 --- a/rpc/v0/server/websocket.go +++ /dev/null @@ -1,440 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package server - -import ( - "context" - "fmt" - "net/http" - "sync" - "time" - - "github.com/gin-gonic/gin" - "github.com/gorilla/websocket" - "github.com/hyperledger/burrow/logging" -) - -// TODO too much fluff. Should probably phase gorilla out and move closer -// to net in connections/session management. At some point... - -const ( - // Time allowed to write a message to the peer. - writeWait = 0 * time.Second - // Maximum message size allowed from a peer. - maxMessageSize = 1000000 -) - -// Services requests. Message bytes are passed along with the session -// object. The service is expected to write any response back using -// the Write function on WSSession, which passes the message over -// a channel to the write pump. -type WebSocketService interface { - Process([]byte, *WSSession) -} - -// The websocket server handles incoming websocket connection requests, -// upgrading, reading, writing, and session management. Handling the -// actual requests is delegated to a websocket service. -type WebSocketServer struct { - upgrader websocket.Upgrader - running bool - maxSessions uint16 - sessionManager *SessionManager - config *ServerConfig - allOrigins bool - logger *logging.Logger -} - -// Create a new server. -// maxSessions is the maximum number of active websocket connections that is allowed. -// NOTE: This is not the total number of connections allowed - only those that are -// upgraded to websockets. Requesting a websocket connection will fail with a 503 if -// the server is at capacity. -func NewWebSocketServer(maxSessions uint16, service WebSocketService, - logger *logging.Logger) *WebSocketServer { - return &WebSocketServer{ - maxSessions: maxSessions, - sessionManager: NewSessionManager(maxSessions, service, logger), - logger: logger.WithScope("WebSocketServer"), - } -} - -// Start the server. Adds the handler to the router and sets everything up. -func (wsServer *WebSocketServer) Start(config *ServerConfig, router *gin.Engine) { - - wsServer.config = config - - wsServer.upgrader = websocket.Upgrader{ - ReadBufferSize: int(config.WebSocket.ReadBufferSize), - // TODO Will this be enough for massive "get blockchain" requests? - WriteBufferSize: int(config.WebSocket.WriteBufferSize), - } - wsServer.upgrader.CheckOrigin = func(r *http.Request) bool { return true } - router.GET(config.WebSocket.WebSocketEndpoint, wsServer.handleFunc) - wsServer.running = true -} - -// Is the server currently running. -func (wsServer *WebSocketServer) Running() bool { - return wsServer.running -} - -// Shut the server down. -func (wsServer *WebSocketServer) Shutdown(ctx context.Context) error { - wsServer.sessionManager.Shutdown() - wsServer.running = false - return nil -} - -// Get the session-manager. -func (wsServer *WebSocketServer) SessionManager() *SessionManager { - return wsServer.sessionManager -} - -// Handler for websocket requests. -func (wsServer *WebSocketServer) handleFunc(c *gin.Context) { - r := c.Request - w := c.Writer - // Upgrade to websocket. - wsConn, uErr := wsServer.upgrader.Upgrade(w, r, nil) - - if uErr != nil { - errMsg := "Failed to upgrade to websocket connection" - http.Error(w, fmt.Sprintf("%s: %s", errMsg, uErr.Error()), 400) - wsServer.logger.InfoMsg(errMsg, "error", uErr) - return - } - - session, cErr := wsServer.sessionManager.createSession(wsConn) - - if cErr != nil { - errMsg := "Failed to establish websocket connection" - http.Error(w, fmt.Sprintf("%s: %s", errMsg, cErr.Error()), 503) - wsServer.logger.InfoMsg(errMsg, "error", cErr) - return - } - - // Start the connection. - wsServer.logger.InfoMsg("New websocket connection", - "session_id", session.id) - session.Open() -} - -// Used to track sessions. Will notify when a session are opened -// and closed. -type SessionObserver interface { - NotifyOpened(*WSSession) - NotifyClosed(*WSSession) -} - -// WSSession wraps a gorilla websocket.Conn, which in turn wraps a -// net.Conn object. Writing is done using the 'Write([]byte)' method, -// which passes the bytes on to the write pump over a channel. -type WSSession struct { - sessionManager *SessionManager - id uint - wsConn *websocket.Conn - writeChan chan []byte - writeCloseChan chan struct{} - service WebSocketService - opened bool - closed bool - logger *logging.Logger -} - -// Write a text message to the client. -func (wsSession *WSSession) Write(msg []byte) error { - if wsSession.closed { - wsSession.logger.InfoMsg("Attempting to write to closed session.") - return fmt.Errorf("Session is closed") - } - wsSession.writeChan <- msg - return nil -} - -// Private. Helper for writing control messages. -func (wsSession *WSSession) write(mt int, payload []byte) error { - wsSession.wsConn.SetWriteDeadline(time.Now().Add(writeWait)) - return wsSession.wsConn.WriteMessage(mt, payload) -} - -// Get the session id number. -func (wsSession *WSSession) Id() uint { - return wsSession.id -} - -// Starts the read and write pumps. Blocks on the former. -// Notifies all the observers. -func (wsSession *WSSession) Open() { - wsSession.opened = true - wsSession.sessionManager.notifyOpened(wsSession) - go wsSession.writePump() - wsSession.readPump() -} - -// Closes the net connection and cleans up. Notifies all the observers. -func (wsSession *WSSession) Close() { - if !wsSession.closed { - wsSession.closed = true - wsSession.wsConn.Close() - wsSession.sessionManager.removeSession(wsSession.id) - wsSession.logger.InfoMsg("Closing websocket connection.", - "remaining_active_sessions", len(wsSession.sessionManager.activeSessions)) - wsSession.sessionManager.notifyClosed(wsSession) - } -} - -// Has the session been opened? -func (wsSession *WSSession) Opened() bool { - return wsSession.opened -} - -// Has the session been closed? -func (wsSession *WSSession) Closed() bool { - return wsSession.closed -} - -// Pump debugging -/* -var rp int = 0 -var wp int = 0 -var rpm *sync.Mutex = &sync.Mutex{} -var wpm *sync.Mutex = &sync.Mutex{} -*/ - -// Read loop. Will terminate on a failed read. -func (wsSession *WSSession) readPump() { - /* - rpm.Lock() - rp++ - log.Debug("readpump created", "total", rp) - rpm.Unlock() - defer func(){ - rpm.Lock() - rp-- - log.Debug("readpump removed", "total", rp) - rpm.Unlock() - }() - */ - wsSession.wsConn.SetReadLimit(maxMessageSize) - // this.wsConn.SetReadDeadline(time.Now().Add(pongWait)) - // this.wsConn.SetPongHandler(func(string) error { this.wsConn.SetReadDeadline(time.Now().Add(pongWait)); return nil }) - - for { - // Read - msgType, msg, err := wsSession.wsConn.ReadMessage() - - // Read error. - if err != nil { - // Socket could have been gracefully closed, so not really an error. - wsSession.logger.InfoMsg( - "Socket closed. Removing.", "error", err) - wsSession.writeCloseChan <- struct{}{} - return - } - - if msgType != websocket.TextMessage { - wsSession.logger.InfoMsg( - "Receiving non text-message from client, closing.") - wsSession.writeCloseChan <- struct{}{} - return - } - - go func() { - // Process the request. - wsSession.service.Process(msg, wsSession) - }() - } -} - -// Writes messages coming in on the write channel. Will terminate on failed writes, -// if pings are not responded to, or if a message comes in on the write close channel. -func (wsSession *WSSession) writePump() { - /* - wpm.Lock() - wp++ - log.Debug("writepump created", "total", wp) - wpm.Unlock() - defer func() { - wpm.Lock() - wp-- - log.Debug("writepump removed", "total", wp) - wpm.Unlock() - }() - */ - // ticker := time.NewTicker(pingPeriod) - - defer func() { - // ticker.Stop() - wsSession.Close() - }() - - // Write loop. Blocks while waiting for data to come in over a channel. - for { - select { - // Write request. - case msg := <-wsSession.writeChan: - - // Write the bytes to the socket. - err := wsSession.wsConn.WriteMessage(websocket.TextMessage, msg) - if err != nil { - // Could be due to the socket being closed so not really an error. - wsSession.logger.InfoMsg( - "Writing to socket failed. Closing.") - return - } - case <-wsSession.writeCloseChan: - return - // Ticker run out. Time for another ping message. - /* - case <-ticker.C: - if err := this.write(websocket.PingMessage, []byte{}); err != nil { - log.Debug("Failed to write ping message to socket. Closing.") - return - } - */ - } - - } -} - -// Session manager handles the adding, tracking and removing of session objects. -type SessionManager struct { - maxSessions uint16 - activeSessions map[uint]*WSSession - idPool *IdPool - mtx *sync.Mutex - service WebSocketService - openEventChans []chan *WSSession - closeEventChans []chan *WSSession - logger *logging.Logger -} - -// Create a new WebsocketManager. -func NewSessionManager(maxSessions uint16, wss WebSocketService, - logger *logging.Logger) *SessionManager { - return &SessionManager{ - maxSessions: maxSessions, - activeSessions: make(map[uint]*WSSession), - idPool: NewIdPool(uint(maxSessions)), - mtx: &sync.Mutex{}, - service: wss, - openEventChans: []chan *WSSession{}, - closeEventChans: []chan *WSSession{}, - logger: logger.WithScope("SessionManager"), - } -} - -// TODO -func (sessionManager *SessionManager) Shutdown() { - sessionManager.activeSessions = nil -} - -// Add a listener to session open events. -func (sessionManager *SessionManager) SessionOpenEventChannel() <-chan *WSSession { - lChan := make(chan *WSSession, 1) - sessionManager.openEventChans = append(sessionManager.openEventChans, lChan) - return lChan -} - -// Remove a listener from session open events. -func (sessionManager *SessionManager) RemoveSessionOpenEventChannel(lChan chan *WSSession) bool { - ec := sessionManager.openEventChans - if len(ec) == 0 { - return false - } - for _, c := range ec { - if lChan == c { - return true - } - } - return false -} - -// Add a listener to session close events -func (sessionManager *SessionManager) SessionCloseEventChannel() <-chan *WSSession { - lChan := make(chan *WSSession, 1) - sessionManager.closeEventChans = append(sessionManager.closeEventChans, lChan) - return lChan -} - -// Remove a listener from session close events. -func (sessionManager *SessionManager) RemoveSessionCloseEventChannel(lChan chan *WSSession) bool { - ec := sessionManager.closeEventChans - if len(ec) == 0 { - return false - } - for _, c := range ec { - if lChan == c { - return true - } - } - return false -} - -// Used to notify all observers that a new session was opened. -func (sessionManager *SessionManager) notifyOpened(session *WSSession) { - for _, lChan := range sessionManager.openEventChans { - lChan <- session - } -} - -// Used to notify all observers that a new session was closed. -func (sessionManager *SessionManager) notifyClosed(session *WSSession) { - for _, lChan := range sessionManager.closeEventChans { - lChan <- session - } -} - -// Creates a new session and adds it to the manager. -func (sessionManager *SessionManager) createSession(wsConn *websocket.Conn) (*WSSession, error) { - // Check that the capacity hasn't been exceeded. - sessionManager.mtx.Lock() - defer sessionManager.mtx.Unlock() - if sessionManager.atCapacity() { - return nil, fmt.Errorf("Already at capacity") - } - - // Create and start - newId, _ := sessionManager.idPool.GetId() - conn := &WSSession{ - sessionManager: sessionManager, - id: newId, - wsConn: wsConn, - writeChan: make(chan []byte, maxMessageSize), - writeCloseChan: make(chan struct{}), - service: sessionManager.service, - logger: sessionManager.logger.WithScope("WSSession").With("session_id", newId), - } - sessionManager.activeSessions[conn.id] = conn - return conn, nil -} - -// Remove a session from the list. -func (sessionManager *SessionManager) removeSession(id uint) { - sessionManager.mtx.Lock() - defer sessionManager.mtx.Unlock() - // Check that it exists. - _, ok := sessionManager.activeSessions[id] - if ok { - delete(sessionManager.activeSessions, id) - sessionManager.idPool.ReleaseId(id) - } -} - -// True if the number of active connections is at the maximum. -func (sessionManager *SessionManager) atCapacity() bool { - return len(sessionManager.activeSessions) >= int(sessionManager.maxSessions) -} diff --git a/rpc/v0/websocket_service.go b/rpc/v0/websocket_service.go deleted file mode 100644 index 259a3f13d6e8a01900eb098cd24489503c30d616..0000000000000000000000000000000000000000 --- a/rpc/v0/websocket_service.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2017 Monax Industries Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package v0 - -import ( - "context" - "encoding/json" - "fmt" - - "github.com/hyperledger/burrow/event" - "github.com/hyperledger/burrow/logging" - "github.com/hyperledger/burrow/logging/structure" - "github.com/hyperledger/burrow/rpc" - "github.com/hyperledger/burrow/rpc/v0/server" -) - -// Used for Burrow. Implements WebSocketService. -type WebsocketService struct { - codec rpc.Codec - service *rpc.Service - defaultHandlers map[string]RequestHandlerFunc - logger *logging.Logger -} - -// Create a new websocket service. -func NewWebsocketService(codec rpc.Codec, service *rpc.Service, logger *logging.Logger) server.WebSocketService { - tmwss := &WebsocketService{ - codec: codec, - service: service, - logger: logger.WithScope("NewWebsocketService"), - } - dhMap := GetMethods(codec, service, tmwss.logger) - // Events - dhMap[EVENT_SUBSCRIBE] = tmwss.EventSubscribe - dhMap[EVENT_UNSUBSCRIBE] = tmwss.EventUnsubscribe - tmwss.defaultHandlers = dhMap - return tmwss -} - -// Process a request. -func (ws *WebsocketService) Process(msg []byte, session *server.WSSession) { - defer func() { - if r := recover(); r != nil { - err := fmt.Errorf("panic in WebsocketService.Process(): %v", r) - ws.logger.InfoMsg("Panic in WebsocketService.Process()", structure.ErrorKey, err) - if !session.Closed() { - ws.writeError(err.Error(), "", rpc.INTERNAL_ERROR, session) - } - } - }() - // Create new request object and unmarshal. - req := &rpc.RPCRequest{} - errU := json.Unmarshal(msg, req) - - // Error when unmarshaling. - if errU != nil { - ws.writeError("Failed to parse request: "+errU.Error()+" . Raw: "+string(msg), - "", rpc.PARSE_ERROR, session) - return - } - - // Wrong protocol version. - if req.JSONRPC != "2.0" { - ws.writeError("Wrong protocol version: "+req.JSONRPC, req.Id, - rpc.INVALID_REQUEST, session) - return - } - - mName := req.Method - - if handler, ok := ws.defaultHandlers[mName]; ok { - resp, errCode, err := handler(req, session) - if err != nil { - ws.writeError(err.Error(), req.Id, errCode, session) - } else { - ws.writeResponse(req.Id, resp, session) - } - } else { - ws.writeError("Method not found: "+mName, req.Id, - rpc.METHOD_NOT_FOUND, session) - } -} - -// Convenience method for writing error responses. -func (ws *WebsocketService) writeError(msg, id string, code int, - session *server.WSSession) { - response := rpc.NewRPCErrorResponse(id, code, msg) - bts, err := ws.codec.EncodeBytes(response) - // If there's an error here all bets are off. - if err != nil { - panic("Failed to marshal standard error response." + err.Error()) - } - session.Write(bts) -} - -// Convenience method for writing responses. -func (ws *WebsocketService) writeResponse(id string, result interface{}, - session *server.WSSession) error { - response := rpc.NewRPCResponse(id, result) - bts, err := ws.codec.EncodeBytes(response) - if err != nil { - ws.writeError("Internal error: "+err.Error(), id, rpc.INTERNAL_ERROR, session) - return err - } - return session.Write(bts) -} - -// *************************************** Events ************************************ - -func (ws *WebsocketService) EventSubscribe(request *rpc.RPCRequest, - requester interface{}) (interface{}, int, error) { - session, ok := requester.(*server.WSSession) - if !ok { - return 0, rpc.INTERNAL_ERROR, - fmt.Errorf("Passing wrong object to websocket events") - } - param := &EventIdParam{} - err := ws.codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - eventId := param.EventId - subId, err := event.GenerateSubscriptionID() - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - - err = ws.service.Subscribe(context.Background(), subId, eventId, func(resultEvent *rpc.ResultEvent) (stop bool) { - ws.writeResponse(subId, resultEvent, session) - return - }) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return &EventSub{SubId: subId}, 0, nil -} - -func (ws *WebsocketService) EventUnsubscribe(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - param := &SubIdParam{} - err := ws.codec.DecodeBytes(param, request.Params) - if err != nil { - return nil, rpc.INVALID_PARAMS, err - } - - err = ws.service.Unsubscribe(context.Background(), param.SubId) - if err != nil { - return nil, rpc.INTERNAL_ERROR, err - } - return &EventUnsub{Result: true}, 0, nil -} - -func (ws *WebsocketService) EventPoll(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { - return nil, rpc.INTERNAL_ERROR, fmt.Errorf("Cannot poll with websockets") -} diff --git a/txs/amino_codec_test.go b/txs/amino_codec_test.go index 41c3e4885f691502c26641cbd907986075b76ada..536bfc06d4009a99edcd6cf795d67708de6411b5 100644 --- a/txs/amino_codec_test.go +++ b/txs/amino_codec_test.go @@ -3,7 +3,7 @@ package txs import ( "testing" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/txs/payload" "github.com/stretchr/testify/assert" diff --git a/txs/envelope.go b/txs/envelope.go index 107c7a6770a853de5a34e992ab39dd983653a071..06ed3832a145f30c86cfbe41d66a5b58bfb8bc01 100644 --- a/txs/envelope.go +++ b/txs/envelope.go @@ -3,9 +3,10 @@ package txs import ( "fmt" - acm "github.com/hyperledger/burrow/account" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/event/query" "github.com/hyperledger/burrow/txs/payload" ) @@ -22,12 +23,6 @@ type Decoder interface { DecodeTx(txBytes []byte) (*Envelope, error) } -// An envelope contains both the signable Tx and the signatures for each input (in signatories) -type Envelope struct { - Signatories []Signatory - Tx *Tx -} - // Enclose a Payload in an Envelope so it is ready to be signed by first wrapping the Payload // as a Tx (including ChainID) and writing it to the Tx field of the Envelope func Enclose(chainID string, payload payload.Payload) *Envelope { @@ -40,13 +35,6 @@ func (txEnv *Envelope) String() string { return fmt.Sprintf("TxEnvelope{Signatures: %v, Tx: %s}", len(txEnv.Signatories), txEnv.Tx) } -// Signatory contains signature and one or both of Address and PublicKey to identify the signer -type Signatory struct { - Address *crypto.Address - PublicKey *crypto.PublicKey - crypto.Signature -} - // Attempts to 'realise' the PublicKey and Address of a Signatory possibly referring to state // in the case where the Signatory contains an Address by no PublicKey. Checks consistency in other // cases, possibly generating the Address from the PublicKey @@ -150,3 +138,7 @@ func (txEnv *Envelope) Sign(signingAccounts ...acm.AddressableSigner) error { } return nil } + +func (txEnv *Envelope) Tagged() query.Tagged { + return query.MergeTags(query.MustReflectTags(txEnv, "Signatories"), txEnv.Tx.Tagged()) +} diff --git a/txs/json_codec_test.go b/txs/json_codec_test.go index f0056290c55d5efa285733fcb5831ad1138b936b..2a4527f490c011951e37a193f80ce5eb39ae766e 100644 --- a/txs/json_codec_test.go +++ b/txs/json_codec_test.go @@ -3,7 +3,7 @@ package txs import ( "testing" - "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/txs/payload" "github.com/stretchr/testify/assert" @@ -39,7 +39,7 @@ func TestJSONEncodeTxDecodeTx(t *testing.T) { func TestJSONEncodeTxDecodeTx_CallTx(t *testing.T) { codec := NewJSONCodec() - inputAccount := account.GeneratePrivateAccountFromSecret("fooo") + inputAccount := acm.GeneratePrivateAccountFromSecret("fooo") amount := uint64(2) sequence := uint64(3) tx := &payload.CallTx{ @@ -66,7 +66,7 @@ func TestJSONEncodeTxDecodeTx_CallTx(t *testing.T) { func TestJSONEncodeTxDecodeTx_CallTxNoData(t *testing.T) { codec := NewJSONCodec() - inputAccount := account.GeneratePrivateAccountFromSecret("fooo") + inputAccount := acm.GeneratePrivateAccountFromSecret("fooo") amount := uint64(2) sequence := uint64(3) tx := &payload.CallTx{ @@ -88,5 +88,11 @@ func TestJSONEncodeTxDecodeTx_CallTxNoData(t *testing.T) { } txEnvOut, err := codec.DecodeTx(txBytes) assert.NoError(t, err, "DecodeTx error") - assert.Equal(t, txEnv, txEnvOut) + + bs, err := codec.EncodeTx(txEnv) + require.NoError(t, err) + bsOut, err := codec.EncodeTx(txEnvOut) + require.NoError(t, err) + + assert.Equal(t, bs, bsOut) } diff --git a/txs/payload/bond_tx.go b/txs/payload/bond_tx.go index 7752b9411e23c338ae5996f1d3c19d2991f947f0..59585b6e01611c145006aaca73ed30701d92ad0c 100644 --- a/txs/payload/bond_tx.go +++ b/txs/payload/bond_tx.go @@ -3,16 +3,10 @@ package payload import ( "fmt" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" ) -type BondTx struct { - // At least one should have bond permission (even if 0 amount transfer) - Inputs []*TxInput - UnbondTo []*TxOutput -} - func NewBondTx(pubkey crypto.PublicKey) (*BondTx, error) { return &BondTx{ Inputs: []*TxInput{}, diff --git a/txs/payload/call_tx.go b/txs/payload/call_tx.go index 559e72e13b02cf8d632ff4e92897048bcd2037d2..68638de3e46eca620b55d658801dc54437b4f804 100644 --- a/txs/payload/call_tx.go +++ b/txs/payload/call_tx.go @@ -3,21 +3,10 @@ package payload import ( "fmt" - "github.com/hyperledger/burrow/account/state" - "github.com/hyperledger/burrow/binary" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" ) -type CallTx struct { - Input *TxInput - // Pointer since CallTx defines unset 'to' address as inducing account creation - Address *crypto.Address - GasLimit uint64 - Fee uint64 - // Signing normalisation needs omitempty - Data binary.HexBytes `json:",omitempty"` -} - func NewCallTx(st state.AccountGetter, from crypto.PublicKey, to *crypto.Address, data []byte, amt, gasLimit, fee uint64) (*CallTx, error) { @@ -59,5 +48,14 @@ func (tx *CallTx) GetInputs() []*TxInput { } func (tx *CallTx) String() string { - return fmt.Sprintf("CallTx{%v -> %s: %X}", tx.Input, tx.Address, tx.Data) + return fmt.Sprintf("CallTx{%v -> %s: %v}", tx.Input, tx.Address, tx.Data) +} + +// Returns the contract address that this CallTx would create if CallTx.Address == nil otherwise returns nil +func (tx *CallTx) CreatesContractAddress() *crypto.Address { + if tx.Address != nil { + return nil + } + address := crypto.NewContractAddress(tx.Input.Address, tx.Input.Sequence) + return &address } diff --git a/txs/payload/errors.go b/txs/payload/errors.go index 93a7f2feed1c4559812770b1ec99232a02eac10f..affd564371667d29d81218fdf8316182c5ff6a91 100644 --- a/txs/payload/errors.go +++ b/txs/payload/errors.go @@ -15,14 +15,6 @@ var ( ErrTxInvalidSignature = errors.New("error invalid signature") ) -type ErrTxInvalidString struct { - Msg string -} - -func (e ErrTxInvalidString) Error() string { - return e.Msg -} - type ErrTxInvalidSequence struct { Got uint64 Expected uint64 diff --git a/txs/payload/governance_tx.go b/txs/payload/governance_tx.go index 24c0cb48ad0a060d960345561057d4c39a55ac92..046f912916a4397f147ffbc717ac4c9c30bc38b1 100644 --- a/txs/payload/governance_tx.go +++ b/txs/payload/governance_tx.go @@ -3,17 +3,12 @@ package payload import ( "fmt" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/genesis/spec" ) -type GovernanceTx struct { - Input *TxInput - AccountUpdates []spec.TemplateAccount -} - -func NewGovTx(st state.AccountGetter, from crypto.Address, accounts ...spec.TemplateAccount) (*GovernanceTx, error) { +func NewGovTx(st state.AccountGetter, from crypto.Address, accounts ...*spec.TemplateAccount) (*GovernanceTx, error) { acc, err := st.GetAccount(from) if err != nil { return nil, err @@ -26,12 +21,12 @@ func NewGovTx(st state.AccountGetter, from crypto.Address, accounts ...spec.Temp return NewGovTxWithSequence(from, sequence, accounts), nil } -func NewGovTxWithSequence(from crypto.Address, sequence uint64, accounts []spec.TemplateAccount) *GovernanceTx { +func NewGovTxWithSequence(from crypto.Address, sequence uint64, accounts []*spec.TemplateAccount) *GovernanceTx { return &GovernanceTx{ - Input: &TxInput{ + Inputs: []*TxInput{{ Address: from, Sequence: sequence, - }, + }}, AccountUpdates: accounts, } } @@ -41,9 +36,9 @@ func (tx *GovernanceTx) Type() Type { } func (tx *GovernanceTx) GetInputs() []*TxInput { - return []*TxInput{tx.Input} + return tx.Inputs } func (tx *GovernanceTx) String() string { - return fmt.Sprintf("GovernanceTx{%v -> %v}", tx.Input, tx.AccountUpdates) + return fmt.Sprintf("GovernanceTx{%v -> %v}", tx.Inputs, tx.AccountUpdates) } diff --git a/txs/payload/name_tx.go b/txs/payload/name_tx.go index a1037fc5a9bef4b559dfd55d37b41fb781606506..334fa6df32d0a2d940be81e65ec935e9517d581d 100644 --- a/txs/payload/name_tx.go +++ b/txs/payload/name_tx.go @@ -2,25 +2,11 @@ package payload import ( "fmt" - "regexp" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/execution/names" ) -// Name should be file system lik -// Data should be anything permitted in JSON -var regexpAlphaNum = regexp.MustCompile("^[a-zA-Z0-9._/-@]*$") -var regexpJSON = regexp.MustCompile(`^[a-zA-Z0-9_/ \-+"':,\n\t.{}()\[\]]*$`) - -type NameTx struct { - Input *TxInput - Name string - Data string - Fee uint64 -} - func NewNameTx(st state.AccountGetter, from crypto.PublicKey, name, data string, amt, fee uint64) (*NameTx, error) { addr := from.Address() acc, err := st.GetAccount(addr) @@ -58,37 +44,6 @@ func (tx *NameTx) GetInputs() []*TxInput { return []*TxInput{tx.Input} } -func (tx *NameTx) ValidateStrings() error { - if len(tx.Name) == 0 { - return ErrTxInvalidString{"Name must not be empty"} - } - if len(tx.Name) > names.MaxNameLength { - return ErrTxInvalidString{fmt.Sprintf("Name is too long. Max %d bytes", names.MaxNameLength)} - } - if len(tx.Data) > names.MaxDataLength { - return ErrTxInvalidString{fmt.Sprintf("Data is too long. Max %d bytes", names.MaxDataLength)} - } - - if !validateNameRegEntryName(tx.Name) { - return ErrTxInvalidString{fmt.Sprintf("Invalid characters found in NameTx.Name (%s). Only alphanumeric, underscores, dashes, forward slashes, and @ are allowed", tx.Name)} - } - - if !validateNameRegEntryData(tx.Data) { - return ErrTxInvalidString{fmt.Sprintf("Invalid characters found in NameTx.Data (%s). Only the kind of things found in a JSON file are allowed", tx.Data)} - } - - return nil -} - func (tx *NameTx) String() string { return fmt.Sprintf("NameTx{%v -> %s: %s}", tx.Input, tx.Name, tx.Data) } - -// filter strings -func validateNameRegEntryName(name string) bool { - return regexpAlphaNum.Match([]byte(name)) -} - -func validateNameRegEntryData(data string) bool { - return regexpJSON.Match([]byte(data)) -} diff --git a/txs/payload/payload.go b/txs/payload/payload.go index cc0c5e181466e3d76eeb33da2495fb0f4e0faedf..f415d8f8331e06f85e3dc8d9488fe07a56ffcc74 100644 --- a/txs/payload/payload.go +++ b/txs/payload/payload.go @@ -16,7 +16,7 @@ Admin Txs: - PermissionsTx */ -type Type int8 +type Type uint32 // Types of Payload implementations const ( @@ -75,10 +75,21 @@ func (typ *Type) UnmarshalText(data []byte) error { return nil } +// Protobuf support +func (typ Type) Marshal() ([]byte, error) { + return typ.MarshalText() +} + +func (typ *Type) Unmarshal(data []byte) error { + return typ.UnmarshalText(data) +} + type Payload interface { String() string GetInputs() []*TxInput Type() Type + // The serialised size in bytes + Size() int } func New(txType Type) Payload { diff --git a/txs/payload/payload.pb.go b/txs/payload/payload.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..a5e27c742767e7080a284510272574ec29ecf60a --- /dev/null +++ b/txs/payload/payload.pb.go @@ -0,0 +1,2498 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: payload.proto + +/* + Package payload is a generated protocol buffer package. + + It is generated from these files: + payload.proto + + It has these top-level messages: + AnyPayload + TxInput + TxOutput + CallTx + SendTx + PermissionsTx + NameTx + BondTx + UnbondTx + GovernanceTx +*/ +package payload + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import permission "github.com/hyperledger/burrow/permission" +import spec "github.com/hyperledger/burrow/genesis/spec" + +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" +import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +type AnyPayload struct { + CallTx *CallTx `protobuf:"bytes,1,opt,name=CallTx" json:"CallTx,omitempty"` + SendTx *SendTx `protobuf:"bytes,2,opt,name=SendTx" json:"SendTx,omitempty"` + NameTx *NameTx `protobuf:"bytes,3,opt,name=NameTx" json:"NameTx,omitempty"` + PermissionsTx *PermissionsTx `protobuf:"bytes,4,opt,name=PermissionsTx" json:"PermissionsTx,omitempty"` + GovernanceTx *GovernanceTx `protobuf:"bytes,5,opt,name=GovernanceTx" json:"GovernanceTx,omitempty"` +} + +func (m *AnyPayload) Reset() { *m = AnyPayload{} } +func (m *AnyPayload) String() string { return proto.CompactTextString(m) } +func (*AnyPayload) ProtoMessage() {} +func (*AnyPayload) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{0} } + +func (m *AnyPayload) GetCallTx() *CallTx { + if m != nil { + return m.CallTx + } + return nil +} + +func (m *AnyPayload) GetSendTx() *SendTx { + if m != nil { + return m.SendTx + } + return nil +} + +func (m *AnyPayload) GetNameTx() *NameTx { + if m != nil { + return m.NameTx + } + return nil +} + +func (m *AnyPayload) GetPermissionsTx() *PermissionsTx { + if m != nil { + return m.PermissionsTx + } + return nil +} + +func (m *AnyPayload) GetGovernanceTx() *GovernanceTx { + if m != nil { + return m.GovernanceTx + } + return nil +} + +func (*AnyPayload) XXX_MessageName() string { + return "payload.AnyPayload" +} + +// An input to a transaction that may carry an Amount as a charge and whose sequence number must be one greater than +// that associated with the account at Address at the time of being received +type TxInput struct { + // The address from which this input flows + Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"` + // The amount of native token to transfer from the input address + Amount uint64 `protobuf:"varint,2,opt,name=Amount,proto3" json:"Amount,omitempty"` + // The sequence number that this transaction will induce (i.e. one greater than the input account's current sequence) + Sequence uint64 `protobuf:"varint,3,opt,name=Sequence,proto3" json:"Sequence,omitempty"` +} + +func (m *TxInput) Reset() { *m = TxInput{} } +func (*TxInput) ProtoMessage() {} +func (*TxInput) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{1} } + +func (m *TxInput) GetAmount() uint64 { + if m != nil { + return m.Amount + } + return 0 +} + +func (m *TxInput) GetSequence() uint64 { + if m != nil { + return m.Sequence + } + return 0 +} + +func (*TxInput) XXX_MessageName() string { + return "payload.TxInput" +} + +// An output from a transaction that may carry an amount as a charge +type TxOutput struct { + // The address to which this output flows + Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"` + // The amount of native token to transfer to the output address + Amount uint64 `protobuf:"varint,2,opt,name=Amount,proto3" json:"Amount,omitempty"` +} + +func (m *TxOutput) Reset() { *m = TxOutput{} } +func (*TxOutput) ProtoMessage() {} +func (*TxOutput) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{2} } + +func (m *TxOutput) GetAmount() uint64 { + if m != nil { + return m.Amount + } + return 0 +} + +func (*TxOutput) XXX_MessageName() string { + return "payload.TxOutput" +} + +// A instruction to run smart contract code in the EVM +type CallTx struct { + // The caller's input + Input *TxInput `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"` + // The contract address to call or nil if we are creating a contract + Address *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"` + // The upper bound on the amount of gas (and therefore EVM execution steps) this CallTx may generate + GasLimit uint64 `protobuf:"varint,3,opt,name=GasLimit,proto3" json:"GasLimit,omitempty"` + // Fee to offer validators for processing transaction + Fee uint64 `protobuf:"varint,4,opt,name=Fee,proto3" json:"Fee,omitempty"` + // EVM bytecode payload + Data github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,5,opt,name=Data,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"Data"` +} + +func (m *CallTx) Reset() { *m = CallTx{} } +func (*CallTx) ProtoMessage() {} +func (*CallTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{3} } + +func (m *CallTx) GetInput() *TxInput { + if m != nil { + return m.Input + } + return nil +} + +func (m *CallTx) GetGasLimit() uint64 { + if m != nil { + return m.GasLimit + } + return 0 +} + +func (m *CallTx) GetFee() uint64 { + if m != nil { + return m.Fee + } + return 0 +} + +func (*CallTx) XXX_MessageName() string { + return "payload.CallTx" +} + +// A payment between two sets of parties +type SendTx struct { + // The payers + Inputs []*TxInput `protobuf:"bytes,1,rep,name=Inputs" json:"Inputs,omitempty"` + // The payees + Outputs []*TxOutput `protobuf:"bytes,2,rep,name=Outputs" json:"Outputs,omitempty"` +} + +func (m *SendTx) Reset() { *m = SendTx{} } +func (*SendTx) ProtoMessage() {} +func (*SendTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{4} } + +func (*SendTx) XXX_MessageName() string { + return "payload.SendTx" +} + +// An update to the on-chain permissions +type PermissionsTx struct { + // The permission moderator + Input *TxInput `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"` + // The modified permissions + PermArgs permission.PermArgs `protobuf:"bytes,2,opt,name=PermArgs" json:"PermArgs"` +} + +func (m *PermissionsTx) Reset() { *m = PermissionsTx{} } +func (*PermissionsTx) ProtoMessage() {} +func (*PermissionsTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{5} } + +func (m *PermissionsTx) GetInput() *TxInput { + if m != nil { + return m.Input + } + return nil +} + +func (m *PermissionsTx) GetPermArgs() permission.PermArgs { + if m != nil { + return m.PermArgs + } + return permission.PermArgs{} +} + +func (*PermissionsTx) XXX_MessageName() string { + return "payload.PermissionsTx" +} + +// A request to claim a globally unique name across the entire chain with some optional data storage leased for a fee +type NameTx struct { + // The name updater + Input *TxInput `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"` + // The name to update or create + Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"` + // The data to store against the name + Data string `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"` + // The fee to provide that will determine the lenght of the name lease + Fee uint64 `protobuf:"varint,4,opt,name=Fee,proto3" json:"Fee,omitempty"` +} + +func (m *NameTx) Reset() { *m = NameTx{} } +func (*NameTx) ProtoMessage() {} +func (*NameTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{6} } + +func (m *NameTx) GetInput() *TxInput { + if m != nil { + return m.Input + } + return nil +} + +func (m *NameTx) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *NameTx) GetData() string { + if m != nil { + return m.Data + } + return "" +} + +func (m *NameTx) GetFee() uint64 { + if m != nil { + return m.Fee + } + return 0 +} + +func (*NameTx) XXX_MessageName() string { + return "payload.NameTx" +} + +type BondTx struct { + Inputs []*TxInput `protobuf:"bytes,1,rep,name=Inputs" json:"Inputs,omitempty"` + UnbondTo []*TxOutput `protobuf:"bytes,2,rep,name=UnbondTo" json:"UnbondTo,omitempty"` +} + +func (m *BondTx) Reset() { *m = BondTx{} } +func (*BondTx) ProtoMessage() {} +func (*BondTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{7} } + +func (*BondTx) XXX_MessageName() string { + return "payload.BondTx" +} + +type UnbondTx struct { + Input *TxInput `protobuf:"bytes,1,opt,name=Input" json:"Input,omitempty"` + Address github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,2,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address"` + Height uint64 `protobuf:"varint,3,opt,name=Height,proto3" json:"Height,omitempty"` +} + +func (m *UnbondTx) Reset() { *m = UnbondTx{} } +func (*UnbondTx) ProtoMessage() {} +func (*UnbondTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{8} } + +func (*UnbondTx) XXX_MessageName() string { + return "payload.UnbondTx" +} + +type GovernanceTx struct { + Inputs []*TxInput `protobuf:"bytes,1,rep,name=Inputs" json:"Inputs,omitempty"` + AccountUpdates []*spec.TemplateAccount `protobuf:"bytes,2,rep,name=AccountUpdates" json:"AccountUpdates,omitempty"` +} + +func (m *GovernanceTx) Reset() { *m = GovernanceTx{} } +func (*GovernanceTx) ProtoMessage() {} +func (*GovernanceTx) Descriptor() ([]byte, []int) { return fileDescriptorPayload, []int{9} } + +func (*GovernanceTx) XXX_MessageName() string { + return "payload.GovernanceTx" +} +func init() { + proto.RegisterType((*AnyPayload)(nil), "payload.AnyPayload") + golang_proto.RegisterType((*AnyPayload)(nil), "payload.AnyPayload") + proto.RegisterType((*TxInput)(nil), "payload.TxInput") + golang_proto.RegisterType((*TxInput)(nil), "payload.TxInput") + proto.RegisterType((*TxOutput)(nil), "payload.TxOutput") + golang_proto.RegisterType((*TxOutput)(nil), "payload.TxOutput") + proto.RegisterType((*CallTx)(nil), "payload.CallTx") + golang_proto.RegisterType((*CallTx)(nil), "payload.CallTx") + proto.RegisterType((*SendTx)(nil), "payload.SendTx") + golang_proto.RegisterType((*SendTx)(nil), "payload.SendTx") + proto.RegisterType((*PermissionsTx)(nil), "payload.PermissionsTx") + golang_proto.RegisterType((*PermissionsTx)(nil), "payload.PermissionsTx") + proto.RegisterType((*NameTx)(nil), "payload.NameTx") + golang_proto.RegisterType((*NameTx)(nil), "payload.NameTx") + proto.RegisterType((*BondTx)(nil), "payload.BondTx") + golang_proto.RegisterType((*BondTx)(nil), "payload.BondTx") + proto.RegisterType((*UnbondTx)(nil), "payload.UnbondTx") + golang_proto.RegisterType((*UnbondTx)(nil), "payload.UnbondTx") + proto.RegisterType((*GovernanceTx)(nil), "payload.GovernanceTx") + golang_proto.RegisterType((*GovernanceTx)(nil), "payload.GovernanceTx") +} +func (m *AnyPayload) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AnyPayload) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.CallTx != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.CallTx.Size())) + n1, err := m.CallTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if m.SendTx != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.SendTx.Size())) + n2, err := m.SendTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.NameTx != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.NameTx.Size())) + n3, err := m.NameTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + if m.PermissionsTx != nil { + dAtA[i] = 0x22 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.PermissionsTx.Size())) + n4, err := m.PermissionsTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + } + if m.GovernanceTx != nil { + dAtA[i] = 0x2a + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.GovernanceTx.Size())) + n5, err := m.GovernanceTx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + return i, nil +} + +func (m *TxInput) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TxInput) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size())) + n6, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n6 + if m.Amount != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Amount)) + } + if m.Sequence != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Sequence)) + } + return i, nil +} + +func (m *TxOutput) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TxOutput) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size())) + n7, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n7 + if m.Amount != 0 { + dAtA[i] = 0x10 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Amount)) + } + return i, nil +} + +func (m *CallTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CallTx) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Input != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) + n8, err := m.Input.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n8 + } + if m.Address != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size())) + n9, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n9 + } + if m.GasLimit != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.GasLimit)) + } + if m.Fee != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Fee)) + } + dAtA[i] = 0x2a + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Data.Size())) + n10, err := m.Data.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n10 + return i, nil +} + +func (m *SendTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SendTx) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Inputs) > 0 { + for _, msg := range m.Inputs { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.Outputs) > 0 { + for _, msg := range m.Outputs { + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *PermissionsTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PermissionsTx) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Input != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) + n11, err := m.Input.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n11 + } + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.PermArgs.Size())) + n12, err := m.PermArgs.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n12 + return i, nil +} + +func (m *NameTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NameTx) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Input != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) + n13, err := m.Input.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n13 + } + if len(m.Name) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(len(m.Name))) + i += copy(dAtA[i:], m.Name) + } + if len(m.Data) > 0 { + dAtA[i] = 0x1a + i++ + i = encodeVarintPayload(dAtA, i, uint64(len(m.Data))) + i += copy(dAtA[i:], m.Data) + } + if m.Fee != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Fee)) + } + return i, nil +} + +func (m *BondTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BondTx) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Inputs) > 0 { + for _, msg := range m.Inputs { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.UnbondTo) > 0 { + for _, msg := range m.UnbondTo { + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *UnbondTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UnbondTx) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Input != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Input.Size())) + n14, err := m.Input.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n14 + } + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Address.Size())) + n15, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n15 + if m.Height != 0 { + dAtA[i] = 0x18 + i++ + i = encodeVarintPayload(dAtA, i, uint64(m.Height)) + } + return i, nil +} + +func (m *GovernanceTx) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GovernanceTx) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Inputs) > 0 { + for _, msg := range m.Inputs { + dAtA[i] = 0xa + i++ + i = encodeVarintPayload(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if len(m.AccountUpdates) > 0 { + for _, msg := range m.AccountUpdates { + dAtA[i] = 0x12 + i++ + i = encodeVarintPayload(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func encodeVarintPayload(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *AnyPayload) Size() (n int) { + var l int + _ = l + if m.CallTx != nil { + l = m.CallTx.Size() + n += 1 + l + sovPayload(uint64(l)) + } + if m.SendTx != nil { + l = m.SendTx.Size() + n += 1 + l + sovPayload(uint64(l)) + } + if m.NameTx != nil { + l = m.NameTx.Size() + n += 1 + l + sovPayload(uint64(l)) + } + if m.PermissionsTx != nil { + l = m.PermissionsTx.Size() + n += 1 + l + sovPayload(uint64(l)) + } + if m.GovernanceTx != nil { + l = m.GovernanceTx.Size() + n += 1 + l + sovPayload(uint64(l)) + } + return n +} + +func (m *TxInput) Size() (n int) { + var l int + _ = l + l = m.Address.Size() + n += 1 + l + sovPayload(uint64(l)) + if m.Amount != 0 { + n += 1 + sovPayload(uint64(m.Amount)) + } + if m.Sequence != 0 { + n += 1 + sovPayload(uint64(m.Sequence)) + } + return n +} + +func (m *TxOutput) Size() (n int) { + var l int + _ = l + l = m.Address.Size() + n += 1 + l + sovPayload(uint64(l)) + if m.Amount != 0 { + n += 1 + sovPayload(uint64(m.Amount)) + } + return n +} + +func (m *CallTx) Size() (n int) { + var l int + _ = l + if m.Input != nil { + l = m.Input.Size() + n += 1 + l + sovPayload(uint64(l)) + } + if m.Address != nil { + l = m.Address.Size() + n += 1 + l + sovPayload(uint64(l)) + } + if m.GasLimit != 0 { + n += 1 + sovPayload(uint64(m.GasLimit)) + } + if m.Fee != 0 { + n += 1 + sovPayload(uint64(m.Fee)) + } + l = m.Data.Size() + n += 1 + l + sovPayload(uint64(l)) + return n +} + +func (m *SendTx) Size() (n int) { + var l int + _ = l + if len(m.Inputs) > 0 { + for _, e := range m.Inputs { + l = e.Size() + n += 1 + l + sovPayload(uint64(l)) + } + } + if len(m.Outputs) > 0 { + for _, e := range m.Outputs { + l = e.Size() + n += 1 + l + sovPayload(uint64(l)) + } + } + return n +} + +func (m *PermissionsTx) Size() (n int) { + var l int + _ = l + if m.Input != nil { + l = m.Input.Size() + n += 1 + l + sovPayload(uint64(l)) + } + l = m.PermArgs.Size() + n += 1 + l + sovPayload(uint64(l)) + return n +} + +func (m *NameTx) Size() (n int) { + var l int + _ = l + if m.Input != nil { + l = m.Input.Size() + n += 1 + l + sovPayload(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovPayload(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovPayload(uint64(l)) + } + if m.Fee != 0 { + n += 1 + sovPayload(uint64(m.Fee)) + } + return n +} + +func (m *BondTx) Size() (n int) { + var l int + _ = l + if len(m.Inputs) > 0 { + for _, e := range m.Inputs { + l = e.Size() + n += 1 + l + sovPayload(uint64(l)) + } + } + if len(m.UnbondTo) > 0 { + for _, e := range m.UnbondTo { + l = e.Size() + n += 1 + l + sovPayload(uint64(l)) + } + } + return n +} + +func (m *UnbondTx) Size() (n int) { + var l int + _ = l + if m.Input != nil { + l = m.Input.Size() + n += 1 + l + sovPayload(uint64(l)) + } + l = m.Address.Size() + n += 1 + l + sovPayload(uint64(l)) + if m.Height != 0 { + n += 1 + sovPayload(uint64(m.Height)) + } + return n +} + +func (m *GovernanceTx) Size() (n int) { + var l int + _ = l + if len(m.Inputs) > 0 { + for _, e := range m.Inputs { + l = e.Size() + n += 1 + l + sovPayload(uint64(l)) + } + } + if len(m.AccountUpdates) > 0 { + for _, e := range m.AccountUpdates { + l = e.Size() + n += 1 + l + sovPayload(uint64(l)) + } + } + return n +} + +func sovPayload(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozPayload(x uint64) (n int) { + return sovPayload(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *AnyPayload) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AnyPayload: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AnyPayload: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CallTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CallTx == nil { + m.CallTx = &CallTx{} + } + if err := m.CallTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SendTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SendTx == nil { + m.SendTx = &SendTx{} + } + if err := m.SendTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NameTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.NameTx == nil { + m.NameTx = &NameTx{} + } + if err := m.NameTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PermissionsTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PermissionsTx == nil { + m.PermissionsTx = &PermissionsTx{} + } + if err := m.PermissionsTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GovernanceTx", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.GovernanceTx == nil { + m.GovernanceTx = &GovernanceTx{} + } + if err := m.GovernanceTx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TxInput) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxInput: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxInput: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + m.Amount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Amount |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Sequence", wireType) + } + m.Sequence = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Sequence |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *TxOutput) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TxOutput: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TxOutput: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + m.Amount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Amount |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CallTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CallTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CallTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Input == nil { + m.Input = &TxInput{} + } + if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_hyperledger_burrow_crypto.Address + m.Address = &v + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GasLimit", wireType) + } + m.GasLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GasLimit |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Fee", wireType) + } + m.Fee = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Fee |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Data.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SendTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SendTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SendTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Inputs = append(m.Inputs, &TxInput{}) + if err := m.Inputs[len(m.Inputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Outputs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Outputs = append(m.Outputs, &TxOutput{}) + if err := m.Outputs[len(m.Outputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PermissionsTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PermissionsTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PermissionsTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Input == nil { + m.Input = &TxInput{} + } + if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PermArgs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.PermArgs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NameTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NameTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NameTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Input == nil { + m.Input = &TxInput{} + } + if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Fee", wireType) + } + m.Fee = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Fee |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BondTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BondTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BondTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Inputs = append(m.Inputs, &TxInput{}) + if err := m.Inputs[len(m.Inputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UnbondTo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UnbondTo = append(m.UnbondTo, &TxOutput{}) + if err := m.UnbondTo[len(m.UnbondTo)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UnbondTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UnbondTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UnbondTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Input", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Input == nil { + m.Input = &TxInput{} + } + if err := m.Input.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GovernanceTx) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GovernanceTx: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GovernanceTx: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Inputs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Inputs = append(m.Inputs, &TxInput{}) + if err := m.Inputs[len(m.Inputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AccountUpdates", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AccountUpdates = append(m.AccountUpdates, &spec.TemplateAccount{}) + if err := m.AccountUpdates[len(m.AccountUpdates)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPayload(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPayload + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPayload + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPayload + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthPayload + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowPayload + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipPayload(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthPayload = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPayload = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("payload.proto", fileDescriptorPayload) } +func init() { golang_proto.RegisterFile("payload.proto", fileDescriptorPayload) } + +var fileDescriptorPayload = []byte{ + // 652 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xbf, 0x6f, 0xd3, 0x40, + 0x14, 0xee, 0x35, 0x6e, 0x62, 0x8e, 0x16, 0xca, 0x89, 0x56, 0x51, 0x86, 0x04, 0x75, 0x80, 0x22, + 0xa8, 0x83, 0xf8, 0x25, 0x51, 0x21, 0xa1, 0xb8, 0x88, 0xb6, 0x08, 0x85, 0xea, 0xea, 0x2e, 0x6c, + 0xfe, 0x71, 0x38, 0x16, 0xb1, 0xcf, 0xd8, 0x67, 0xb0, 0x37, 0x36, 0xd8, 0x59, 0x18, 0x3b, 0xf0, + 0x87, 0x30, 0x66, 0x64, 0x66, 0xa8, 0x50, 0xfa, 0x67, 0xb0, 0xa0, 0x3b, 0x9f, 0x5d, 0x27, 0x40, + 0x95, 0x82, 0xc4, 0x76, 0xef, 0x7d, 0xdf, 0xbb, 0xf7, 0xde, 0x77, 0xef, 0xd9, 0x70, 0x29, 0x34, + 0xb3, 0x21, 0x35, 0x1d, 0x2d, 0x8c, 0x28, 0xa3, 0xa8, 0x21, 0xcd, 0xd6, 0x86, 0xeb, 0xb1, 0x41, + 0x62, 0x69, 0x36, 0xf5, 0xbb, 0x2e, 0x75, 0x69, 0x57, 0xe0, 0x56, 0xf2, 0x52, 0x58, 0xc2, 0x10, + 0xa7, 0x3c, 0xae, 0xb5, 0x1c, 0x92, 0xc8, 0xf7, 0xe2, 0xd8, 0xa3, 0x81, 0xf4, 0xc0, 0x38, 0x24, + 0x76, 0x7e, 0x5e, 0x7b, 0x37, 0x0f, 0x61, 0x2f, 0xc8, 0xf6, 0xf2, 0xbb, 0xd1, 0x35, 0x58, 0xdf, + 0x32, 0x87, 0x43, 0x23, 0x6d, 0x82, 0x2b, 0x60, 0xfd, 0xfc, 0xed, 0x8b, 0x5a, 0x51, 0x44, 0xee, + 0xc6, 0x12, 0xe6, 0xc4, 0x7d, 0x12, 0x38, 0x46, 0xda, 0x9c, 0x9f, 0x22, 0xe6, 0x6e, 0x2c, 0x61, + 0x4e, 0xec, 0x9b, 0x3e, 0x31, 0xd2, 0x66, 0x6d, 0x8a, 0x98, 0xbb, 0xb1, 0x84, 0xd1, 0x43, 0xb8, + 0xb4, 0x57, 0x56, 0x1a, 0x1b, 0x69, 0x53, 0x11, 0xfc, 0xd5, 0x92, 0x3f, 0x81, 0xe2, 0x49, 0x32, + 0x7a, 0x00, 0x17, 0xb7, 0xe9, 0x1b, 0x12, 0x05, 0x66, 0x60, 0xf3, 0x64, 0x0b, 0x22, 0x78, 0xa5, + 0x0c, 0xae, 0x82, 0x78, 0x82, 0xba, 0xf6, 0x11, 0xc0, 0x86, 0x91, 0xee, 0x06, 0x61, 0xc2, 0x50, + 0x1f, 0x36, 0x7a, 0x8e, 0x13, 0x91, 0x38, 0x16, 0x02, 0x2c, 0xea, 0x77, 0x47, 0x47, 0x9d, 0xb9, + 0x6f, 0x47, 0x9d, 0x9b, 0x15, 0xd1, 0x07, 0x59, 0x48, 0xa2, 0x21, 0x71, 0x5c, 0x12, 0x75, 0xad, + 0x24, 0x8a, 0xe8, 0xdb, 0xae, 0x1d, 0x65, 0x21, 0xa3, 0x9a, 0x8c, 0xc5, 0xc5, 0x25, 0x68, 0x15, + 0xd6, 0x7b, 0x3e, 0x4d, 0x02, 0x26, 0x64, 0x52, 0xb0, 0xb4, 0x50, 0x0b, 0xaa, 0xfb, 0xe4, 0x75, + 0x42, 0x02, 0x9b, 0x08, 0x5d, 0x14, 0x5c, 0xda, 0x9b, 0xca, 0xa7, 0xc3, 0xce, 0xdc, 0x5a, 0x0a, + 0x55, 0x23, 0x7d, 0x9e, 0xb0, 0xff, 0x58, 0x95, 0xcc, 0xfc, 0x03, 0x14, 0x43, 0x80, 0xae, 0xc2, + 0x05, 0xa1, 0x8b, 0x9c, 0x86, 0xe5, 0x52, 0x4e, 0xa9, 0x17, 0xce, 0x61, 0xf4, 0xf4, 0xa4, 0xc0, + 0x79, 0x51, 0xe0, 0xad, 0xbf, 0x2f, 0xae, 0x05, 0xd5, 0x6d, 0x33, 0x7e, 0xe6, 0xf9, 0x1e, 0x2b, + 0xa4, 0x29, 0x6c, 0xb4, 0x0c, 0x6b, 0x4f, 0x08, 0x11, 0x93, 0xa1, 0x60, 0x7e, 0x44, 0xbb, 0x50, + 0x79, 0x6c, 0x32, 0x53, 0xbc, 0xf7, 0xa2, 0x7e, 0x4f, 0xea, 0xb2, 0x71, 0x7a, 0x6a, 0xcb, 0x0b, + 0xcc, 0x28, 0xd3, 0x76, 0x48, 0xaa, 0x67, 0x8c, 0xc4, 0x58, 0x5c, 0x21, 0xbb, 0xf7, 0x8a, 0xc1, + 0x46, 0xeb, 0xb0, 0x2e, 0xba, 0xe3, 0xa2, 0xd7, 0x7e, 0xdb, 0xbd, 0xc4, 0xd1, 0x0d, 0xd8, 0xc8, + 0x5f, 0x8a, 0xb7, 0xcf, 0xa9, 0x97, 0x2a, 0xd4, 0x1c, 0xc1, 0x05, 0x63, 0x53, 0xfd, 0x70, 0xd8, + 0x99, 0x13, 0xa9, 0x92, 0xa9, 0x89, 0x9f, 0x59, 0xee, 0xfb, 0x50, 0xe5, 0x81, 0xbd, 0xc8, 0x8d, + 0xe5, 0xfa, 0x5d, 0xd6, 0x2a, 0x5b, 0x5e, 0x60, 0xba, 0xc2, 0xe5, 0xc0, 0x25, 0x57, 0x76, 0x18, + 0x16, 0x1b, 0x39, 0x73, 0x3e, 0x04, 0x15, 0x1e, 0x21, 0x72, 0x9d, 0xc3, 0xe2, 0xcc, 0x7d, 0x42, + 0xf8, 0x5a, 0xee, 0xe3, 0xe7, 0x5f, 0x9f, 0x47, 0x66, 0x7c, 0x05, 0xeb, 0x3a, 0x3d, 0xa3, 0xa6, + 0x1b, 0x50, 0x3d, 0x08, 0x2c, 0x1e, 0x45, 0xff, 0x2c, 0x6a, 0x49, 0xa9, 0xa8, 0xfa, 0x19, 0x94, + 0x91, 0xb3, 0x77, 0xd8, 0x9f, 0x1e, 0xe0, 0x7f, 0xdf, 0xb0, 0x1d, 0xe2, 0xb9, 0x83, 0x62, 0x84, + 0xa5, 0x55, 0x29, 0xf3, 0x3d, 0x98, 0xfc, 0x62, 0x9d, 0x41, 0x9a, 0x2d, 0x78, 0xa1, 0x67, 0xdb, + 0x7c, 0x63, 0x0f, 0x42, 0xc7, 0x64, 0xa4, 0x98, 0xba, 0x15, 0x4d, 0x7c, 0xd8, 0x0d, 0xe2, 0x87, + 0x43, 0x93, 0x11, 0xc9, 0x11, 0x53, 0x00, 0xf0, 0x54, 0xc8, 0x49, 0x25, 0xfa, 0xa3, 0xd1, 0xb8, + 0x0d, 0xbe, 0x8e, 0xdb, 0xe0, 0xfb, 0xb8, 0x0d, 0xbe, 0x1c, 0xb7, 0xc1, 0xe8, 0xb8, 0x0d, 0x5e, + 0x5c, 0x3f, 0xbd, 0x71, 0x96, 0xc6, 0x5d, 0x59, 0x9f, 0x55, 0x17, 0xbf, 0x92, 0x3b, 0x3f, 0x03, + 0x00, 0x00, 0xff, 0xff, 0xac, 0xa5, 0xe3, 0x1c, 0xb1, 0x06, 0x00, 0x00, +} diff --git a/txs/payload/permission_tx.go b/txs/payload/permission_tx.go index 9c219eecb4dff48e00e6d63634ae8d657232727f..d22984f93d4b03efac04f0ff469f3a7d0335daa6 100644 --- a/txs/payload/permission_tx.go +++ b/txs/payload/permission_tx.go @@ -3,31 +3,26 @@ package payload import ( "fmt" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/permission/snatives" + "github.com/hyperledger/burrow/permission" ) -type PermissionsTx struct { - Input *TxInput - PermArgs snatives.PermArgs -} - -func NewPermissionsTx(st state.AccountGetter, from crypto.PublicKey, args snatives.PermArgs) (*PermissionsTx, error) { +func NewPermissionsTx(st state.AccountGetter, from crypto.PublicKey, args permission.PermArgs) (*PermissionsTx, error) { addr := from.Address() acc, err := st.GetAccount(addr) if err != nil { return nil, err } if acc == nil { - return nil, fmt.Errorf("Invalid address %s from pubkey %s", addr, from) + return nil, fmt.Errorf("invalid address %s from pubkey %s", addr, from) } sequence := acc.Sequence() + 1 return NewPermissionsTxWithSequence(from, args, sequence), nil } -func NewPermissionsTxWithSequence(from crypto.PublicKey, args snatives.PermArgs, sequence uint64) *PermissionsTx { +func NewPermissionsTxWithSequence(from crypto.PublicKey, args permission.PermArgs, sequence uint64) *PermissionsTx { input := &TxInput{ Address: from.Address(), Amount: 1, // NOTE: amounts can't be 0 ... diff --git a/txs/payload/send_tx.go b/txs/payload/send_tx.go index 12dd7a54749d96359baf80d708130a53fa576296..f83fcf953956effa402bf5f0cbcdfe8d9f379fc6 100644 --- a/txs/payload/send_tx.go +++ b/txs/payload/send_tx.go @@ -3,15 +3,10 @@ package payload import ( "fmt" - "github.com/hyperledger/burrow/account/state" + "github.com/hyperledger/burrow/acm/state" "github.com/hyperledger/burrow/crypto" ) -type SendTx struct { - Inputs []*TxInput - Outputs []*TxOutput -} - func NewSendTx() *SendTx { return &SendTx{ Inputs: []*TxInput{}, diff --git a/txs/payload/tx_input.go b/txs/payload/tx_input.go index f435475f5af95cc54b69c37b1fcd6bd25b2d657c..0a69fa2c401b79f76df1c659b835a66c1b094cef 100644 --- a/txs/payload/tx_input.go +++ b/txs/payload/tx_input.go @@ -6,12 +6,6 @@ import ( "github.com/hyperledger/burrow/crypto" ) -type TxInput struct { - Address crypto.Address - Amount uint64 - Sequence uint64 -} - func (txIn *TxInput) ValidateBasic() error { if txIn.Address == crypto.ZeroAddress { return ErrTxInvalidAddress @@ -23,5 +17,5 @@ func (txIn *TxInput) ValidateBasic() error { } func (txIn *TxInput) String() string { - return fmt.Sprintf("TxInput{%s, Amt: %v, Seq:%v}", txIn.Address, txIn.Amount, txIn.Sequence) + return fmt.Sprintf("TxInput{%s, Amount: %v, Sequence:%v}", txIn.Address, txIn.Amount, txIn.Sequence) } diff --git a/txs/payload/tx_output.go b/txs/payload/tx_output.go index 0dbd6c6856578e811d2766585ef728956f409978..dcd6d73ce1604d1392e200a0d99aff62de51a31a 100644 --- a/txs/payload/tx_output.go +++ b/txs/payload/tx_output.go @@ -2,15 +2,8 @@ package payload import ( "fmt" - - "github.com/hyperledger/burrow/crypto" ) -type TxOutput struct { - Address crypto.Address - Amount uint64 -} - func (txOut *TxOutput) ValidateBasic() error { if len(txOut.Address) != 20 { return ErrTxInvalidAddress @@ -22,5 +15,5 @@ func (txOut *TxOutput) ValidateBasic() error { } func (txOut *TxOutput) String() string { - return fmt.Sprintf("TxOutput{%s,%v}", txOut.Address, txOut.Amount) + return fmt.Sprintf("TxOutput{%s, Amount: %v}", txOut.Address, txOut.Amount) } diff --git a/txs/payload/unbond_tx.go b/txs/payload/unbond_tx.go index 9975d590ceb481761fdf7c4efdbcfaa3a4dfdf56..c6fe036fa7bd07e813d8c1fe3cc3ece83df8ee82 100644 --- a/txs/payload/unbond_tx.go +++ b/txs/payload/unbond_tx.go @@ -6,15 +6,9 @@ import ( "github.com/hyperledger/burrow/crypto" ) -type UnbondTx struct { - Input *TxInput - Address crypto.Address - Height int -} - -func NewUnbondTx(addr crypto.Address, height int) *UnbondTx { +func NewUnbondTx(address crypto.Address, height uint64) *UnbondTx { return &UnbondTx{ - Address: addr, + Address: address, Height: height, } } diff --git a/txs/tx.go b/txs/tx.go index d099c892d1354f46c53d2c1ffd70bdcfd7d40b8d..ee773c3cce87d2feaea4d4f18f29f52dfa10042f 100644 --- a/txs/tx.go +++ b/txs/tx.go @@ -18,9 +18,10 @@ import ( "encoding/json" "fmt" - acm "github.com/hyperledger/burrow/account" + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/binary" "github.com/hyperledger/burrow/crypto" + "github.com/hyperledger/burrow/event/query" "github.com/hyperledger/burrow/txs/payload" "golang.org/x/crypto/ripemd160" ) @@ -53,6 +54,7 @@ func (tx *Tx) Sign(signingAccounts ...acm.AddressableSigner) (*Envelope, error) if err != nil { return nil, err } + tx.Rehash() return env, nil } @@ -105,6 +107,34 @@ func (tx *Tx) UnmarshalJSON(data []byte) error { return json.Unmarshal(w.Payload, tx.Payload) } +// Protobuf support +func (tx *Tx) Marshal() ([]byte, error) { + if tx == nil { + return nil, nil + } + return tx.MarshalJSON() +} + +func (tx *Tx) Unmarshal(data []byte) error { + if len(data) == 0 { + return nil + } + return tx.UnmarshalJSON(data) +} + +func (tx *Tx) MarshalTo(data []byte) (int, error) { + bs, err := tx.Marshal() + if err != nil { + return 0, err + } + return copy(data, bs), nil +} + +func (tx *Tx) Size() int { + bs, _ := tx.Marshal() + return len(bs) +} + func (tx *Tx) Type() payload.Type { if tx == nil { return payload.TypeUnknown @@ -114,7 +144,7 @@ func (tx *Tx) Type() payload.Type { // Generate a Hash for this transaction based on the SignBytes. The hash is memoized over the lifetime // of the Tx so repeated calls to Hash() are effectively free -func (tx *Tx) Hash() []byte { +func (tx *Tx) Hash() binary.HexBytes { if tx == nil { return nil } @@ -139,17 +169,15 @@ func (tx *Tx) Rehash() []byte { return tx.txHash } -// BroadcastTx or Transaction receipt -type Receipt struct { - TxHash binary.HexBytes - CreatesContract bool - ContractAddress crypto.Address +func (tx *Tx) Tagged() query.Tagged { + return query.MergeTags(query.MustReflectTags(tx), query.MustReflectTags(tx.Payload)) } // Generate a transaction Receipt containing the Tx hash and other information if the Tx is call. // Returned by ABCI methods. func (tx *Tx) GenerateReceipt() *Receipt { receipt := &Receipt{ + TxType: tx.Type(), TxHash: tx.Hash(), } if callTx, ok := tx.Payload.(*payload.CallTx); ok { @@ -162,3 +190,18 @@ func (tx *Tx) GenerateReceipt() *Receipt { } return receipt } + +var cdc = NewAminoCodec() + +func DecodeReceipt(bs []byte) (*Receipt, error) { + receipt := new(Receipt) + err := cdc.UnmarshalBinary(bs, receipt) + if err != nil { + return nil, err + } + return receipt, nil +} + +func (receipt *Receipt) Encode() ([]byte, error) { + return cdc.MarshalBinary(receipt) +} diff --git a/txs/tx_test.go b/txs/tx_test.go index bb916e86ab3a144dfaf9d170d1a195a8b7ac01ed..4716bc28d5a356878a3592bdea62578d5bb48750 100644 --- a/txs/tx_test.go +++ b/txs/tx_test.go @@ -19,10 +19,12 @@ import ( "runtime/debug" "testing" - acm "github.com/hyperledger/burrow/account" + "fmt" + + "github.com/hyperledger/burrow/acm" "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/permission/snatives" - ptypes "github.com/hyperledger/burrow/permission/types" + "github.com/hyperledger/burrow/event/query" + "github.com/hyperledger/burrow/permission" "github.com/hyperledger/burrow/txs/payload" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -32,13 +34,13 @@ var chainID = "myChainID" var privateAccounts = make(map[crypto.Address]acm.AddressableSigner) -func makePrivateAccount(str string) acm.PrivateAccount { +func makePrivateAccount(str string) *acm.PrivateAccount { acc := acm.GeneratePrivateAccountFromSecret(str) privateAccounts[acc.Address()] = acc return acc } -func TestSendTxSignable(t *testing.T) { +func TestSendTx(t *testing.T) { sendTx := &payload.SendTx{ Inputs: []*payload.TxInput{ { @@ -65,6 +67,16 @@ func TestSendTxSignable(t *testing.T) { } testTxMarshalJSON(t, sendTx) testTxSignVerify(t, sendTx) + + tx := Enclose("Foo", sendTx).Tx + value, ok := tx.Tagged().Get("Inputs") + require.True(t, ok) + assert.Equal(t, fmt.Sprintf("%v%s%v", sendTx.Inputs[0], query.MultipleValueTagSeparator, sendTx.Inputs[1]), + value) + + value, ok = tx.Tagged().Get("ChainID") + require.True(t, ok) + assert.Equal(t, "Foo", value) } func TestCallTxSignable(t *testing.T) { @@ -147,7 +159,7 @@ func TestPermissionsTxSignable(t *testing.T) { Amount: 12345, Sequence: 250, }, - PermArgs: snatives.SetBaseArgs(makePrivateAccount("address1").Address(), 1, true), + PermArgs: permission.SetBaseArgs(makePrivateAccount("address1").Address(), 1, true), } testTxMarshalJSON(t, permsTx) @@ -169,11 +181,16 @@ func TestTxWrapper_MarshalJSON(t *testing.T) { } testTxMarshalJSON(t, callTx) testTxSignVerify(t, callTx) + + tx := Enclose("Foo", callTx).Tx + value, ok := tx.Tagged().Get("Input") + require.True(t, ok) + assert.Equal(t, callTx.Input.String(), value) } func TestNewPermissionsTxWithSequence(t *testing.T) { privateAccount := makePrivateAccount("shhhhh") - args := snatives.SetBaseArgs(privateAccount.PublicKey().Address(), ptypes.HasRole, true) + args := permission.SetBaseArgs(privateAccount.PublicKey().Address(), permission.HasRole, true) permTx := payload.NewPermissionsTxWithSequence(privateAccount.PublicKey(), args, 1) testTxMarshalJSON(t, permTx) testTxSignVerify(t, permTx) diff --git a/txs/txs.pb.go b/txs/txs.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..ba524fc453f2da7f8d85e46d651d19c8145df44a --- /dev/null +++ b/txs/txs.pb.go @@ -0,0 +1,878 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: txs.proto + +/* + Package txs is a generated protocol buffer package. + + It is generated from these files: + txs.proto + + It has these top-level messages: + Envelope + Signatory + Receipt +*/ +package txs + +import proto "github.com/gogo/protobuf/proto" +import golang_proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import crypto "github.com/hyperledger/burrow/crypto" + +import github_com_hyperledger_burrow_crypto "github.com/hyperledger/burrow/crypto" +import github_com_hyperledger_burrow_txs_payload "github.com/hyperledger/burrow/txs/payload" +import github_com_hyperledger_burrow_binary "github.com/hyperledger/burrow/binary" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = golang_proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package + +// An envelope contains both the signable Tx and the signatures for each input (in signatories) +type Envelope struct { + Signatories []Signatory `protobuf:"bytes,1,rep,name=Signatories" json:"Signatories"` + // Canonical bytes of the Tx ready to be signed + Tx *Tx `protobuf:"bytes,2,opt,name=Tx,proto3,customtype=Tx" json:"Tx,omitempty"` +} + +func (m *Envelope) Reset() { *m = Envelope{} } +func (*Envelope) ProtoMessage() {} +func (*Envelope) Descriptor() ([]byte, []int) { return fileDescriptorTxs, []int{0} } + +func (m *Envelope) GetSignatories() []Signatory { + if m != nil { + return m.Signatories + } + return nil +} + +func (*Envelope) XXX_MessageName() string { + return "txs.Envelope" +} + +// Signatory contains signature and one or both of Address and PublicKey to identify the signer +type Signatory struct { + Address *github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,1,opt,name=Address,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"Address,omitempty"` + PublicKey *crypto.PublicKey `protobuf:"bytes,2,opt,name=PublicKey" json:"PublicKey,omitempty"` + Signature github_com_hyperledger_burrow_crypto.Signature `protobuf:"bytes,3,opt,name=Signature,proto3,customtype=github.com/hyperledger/burrow/crypto.Signature" json:"Signature"` +} + +func (m *Signatory) Reset() { *m = Signatory{} } +func (m *Signatory) String() string { return proto.CompactTextString(m) } +func (*Signatory) ProtoMessage() {} +func (*Signatory) Descriptor() ([]byte, []int) { return fileDescriptorTxs, []int{1} } + +func (m *Signatory) GetPublicKey() *crypto.PublicKey { + if m != nil { + return m.PublicKey + } + return nil +} + +func (*Signatory) XXX_MessageName() string { + return "txs.Signatory" +} + +// BroadcastTx or Transaction receipt +type Receipt struct { + // Transaction type + TxType github_com_hyperledger_burrow_txs_payload.Type `protobuf:"varint,1,opt,name=TxType,proto3,casttype=github.com/hyperledger/burrow/txs/payload.Type" json:"TxType,omitempty"` + // The hash of the transaction that caused this event to be generated + TxHash github_com_hyperledger_burrow_binary.HexBytes `protobuf:"bytes,2,opt,name=TxHash,proto3,customtype=github.com/hyperledger/burrow/binary.HexBytes" json:"TxHash"` + // Whether the transaction creates a contract + CreatesContract bool `protobuf:"varint,3,opt,name=CreatesContract,proto3" json:"CreatesContract,omitempty"` + // The address of the contract being called + ContractAddress github_com_hyperledger_burrow_crypto.Address `protobuf:"bytes,4,opt,name=ContractAddress,proto3,customtype=github.com/hyperledger/burrow/crypto.Address" json:"ContractAddress"` +} + +func (m *Receipt) Reset() { *m = Receipt{} } +func (m *Receipt) String() string { return proto.CompactTextString(m) } +func (*Receipt) ProtoMessage() {} +func (*Receipt) Descriptor() ([]byte, []int) { return fileDescriptorTxs, []int{2} } + +func (m *Receipt) GetTxType() github_com_hyperledger_burrow_txs_payload.Type { + if m != nil { + return m.TxType + } + return 0 +} + +func (m *Receipt) GetCreatesContract() bool { + if m != nil { + return m.CreatesContract + } + return false +} + +func (*Receipt) XXX_MessageName() string { + return "txs.Receipt" +} +func init() { + proto.RegisterType((*Envelope)(nil), "txs.Envelope") + golang_proto.RegisterType((*Envelope)(nil), "txs.Envelope") + proto.RegisterType((*Signatory)(nil), "txs.Signatory") + golang_proto.RegisterType((*Signatory)(nil), "txs.Signatory") + proto.RegisterType((*Receipt)(nil), "txs.Receipt") + golang_proto.RegisterType((*Receipt)(nil), "txs.Receipt") +} +func (m *Envelope) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Envelope) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Signatories) > 0 { + for _, msg := range m.Signatories { + dAtA[i] = 0xa + i++ + i = encodeVarintTxs(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.Tx != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintTxs(dAtA, i, uint64(m.Tx.Size())) + n1, err := m.Tx.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + return i, nil +} + +func (m *Signatory) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Signatory) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Address != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintTxs(dAtA, i, uint64(m.Address.Size())) + n2, err := m.Address.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + if m.PublicKey != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintTxs(dAtA, i, uint64(m.PublicKey.Size())) + n3, err := m.PublicKey.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n3 + } + dAtA[i] = 0x1a + i++ + i = encodeVarintTxs(dAtA, i, uint64(m.Signature.Size())) + n4, err := m.Signature.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n4 + return i, nil +} + +func (m *Receipt) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Receipt) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.TxType != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintTxs(dAtA, i, uint64(m.TxType)) + } + dAtA[i] = 0x12 + i++ + i = encodeVarintTxs(dAtA, i, uint64(m.TxHash.Size())) + n5, err := m.TxHash.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + if m.CreatesContract { + dAtA[i] = 0x18 + i++ + if m.CreatesContract { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i++ + } + dAtA[i] = 0x22 + i++ + i = encodeVarintTxs(dAtA, i, uint64(m.ContractAddress.Size())) + n6, err := m.ContractAddress.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n6 + return i, nil +} + +func encodeVarintTxs(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *Envelope) Size() (n int) { + var l int + _ = l + if len(m.Signatories) > 0 { + for _, e := range m.Signatories { + l = e.Size() + n += 1 + l + sovTxs(uint64(l)) + } + } + if m.Tx != nil { + l = m.Tx.Size() + n += 1 + l + sovTxs(uint64(l)) + } + return n +} + +func (m *Signatory) Size() (n int) { + var l int + _ = l + if m.Address != nil { + l = m.Address.Size() + n += 1 + l + sovTxs(uint64(l)) + } + if m.PublicKey != nil { + l = m.PublicKey.Size() + n += 1 + l + sovTxs(uint64(l)) + } + l = m.Signature.Size() + n += 1 + l + sovTxs(uint64(l)) + return n +} + +func (m *Receipt) Size() (n int) { + var l int + _ = l + if m.TxType != 0 { + n += 1 + sovTxs(uint64(m.TxType)) + } + l = m.TxHash.Size() + n += 1 + l + sovTxs(uint64(l)) + if m.CreatesContract { + n += 2 + } + l = m.ContractAddress.Size() + n += 1 + l + sovTxs(uint64(l)) + return n +} + +func sovTxs(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozTxs(x uint64) (n int) { + return sovTxs(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Envelope) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Envelope: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Envelope: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signatories", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTxs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signatories = append(m.Signatories, Signatory{}) + if err := m.Signatories[len(m.Signatories)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tx", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTxs + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v Tx + m.Tx = &v + if err := m.Tx.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTxs(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTxs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Signatory) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Signatory: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Signatory: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTxs + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_hyperledger_burrow_crypto.Address + m.Address = &v + if err := m.Address.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PublicKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTxs + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PublicKey == nil { + m.PublicKey = &crypto.PublicKey{} + } + if err := m.PublicKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signature", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTxs + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Signature.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTxs(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTxs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Receipt) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Receipt: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Receipt: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxType", wireType) + } + m.TxType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxType |= (github_com_hyperledger_burrow_txs_payload.Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TxHash", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTxs + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TxHash.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CreatesContract", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.CreatesContract = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTxs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTxs + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ContractAddress.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTxs(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTxs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTxs(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTxs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTxs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTxs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthTxs + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTxs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipTxs(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthTxs = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTxs = fmt.Errorf("proto: integer overflow") +) + +func init() { proto.RegisterFile("txs.proto", fileDescriptorTxs) } +func init() { golang_proto.RegisterFile("txs.proto", fileDescriptorTxs) } + +var fileDescriptorTxs = []byte{ + // 422 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xcf, 0x6e, 0xd4, 0x30, + 0x10, 0xc6, 0xeb, 0xec, 0x6a, 0xdb, 0xf5, 0x16, 0x2a, 0x7c, 0x40, 0xab, 0x1e, 0x92, 0xb2, 0xa7, + 0x3d, 0xd0, 0x04, 0x2d, 0x50, 0x24, 0x6e, 0xa4, 0x42, 0xaa, 0x8a, 0x90, 0x90, 0xc9, 0x89, 0x03, + 0x22, 0x7f, 0x86, 0x6c, 0xa4, 0x10, 0x47, 0xb6, 0x03, 0xf6, 0x9b, 0x70, 0xe4, 0x09, 0x78, 0x06, + 0x8e, 0x7b, 0xe4, 0xbc, 0x87, 0x08, 0x6d, 0xdf, 0x82, 0x13, 0x8a, 0x71, 0xb6, 0x55, 0x0f, 0x94, + 0xde, 0x3c, 0xf6, 0x7c, 0xbf, 0xf9, 0x66, 0xc6, 0x78, 0x2c, 0x95, 0xf0, 0x6b, 0xce, 0x24, 0x23, + 0x03, 0xa9, 0xc4, 0xe1, 0x71, 0x5e, 0xc8, 0x65, 0x93, 0xf8, 0x29, 0xfb, 0x14, 0xe4, 0x2c, 0x67, + 0x81, 0x79, 0x4b, 0x9a, 0x8f, 0x26, 0x32, 0x81, 0x39, 0xfd, 0xd5, 0x1c, 0xee, 0xa7, 0x5c, 0xd7, + 0xd2, 0x46, 0xb3, 0x0f, 0x78, 0xef, 0x65, 0xf5, 0x19, 0x4a, 0x56, 0x03, 0x39, 0xc1, 0x93, 0xb7, + 0x45, 0x5e, 0xc5, 0x92, 0xf1, 0x02, 0xc4, 0x14, 0x1d, 0x0d, 0xe6, 0x93, 0xc5, 0x5d, 0xbf, 0x2b, + 0xd7, 0xdf, 0xeb, 0x70, 0xb8, 0x6a, 0xbd, 0x1d, 0x7a, 0x35, 0x91, 0xdc, 0xc7, 0x4e, 0xa4, 0xa6, + 0xce, 0x11, 0x9a, 0xef, 0x87, 0xa3, 0x75, 0xeb, 0x39, 0x91, 0xa2, 0x4e, 0xa4, 0x9e, 0x0f, 0xbf, + 0x7e, 0xf3, 0x76, 0x66, 0x2d, 0xc2, 0xe3, 0xad, 0x9c, 0x9c, 0xe3, 0xdd, 0x17, 0x59, 0xc6, 0x41, + 0x74, 0xfc, 0x4e, 0xf0, 0x68, 0xdd, 0x7a, 0x0f, 0xaf, 0x74, 0xb0, 0xd4, 0x35, 0xf0, 0x12, 0xb2, + 0x1c, 0x78, 0x90, 0x34, 0x9c, 0xb3, 0x2f, 0x81, 0x35, 0x6c, 0x75, 0xb4, 0x07, 0x90, 0x00, 0x8f, + 0xdf, 0x34, 0x49, 0x59, 0xa4, 0xaf, 0x40, 0x9b, 0xf2, 0x93, 0xc5, 0x3d, 0xdf, 0x26, 0x6f, 0x1f, + 0xe8, 0x65, 0x0e, 0x89, 0x7a, 0x27, 0x0d, 0x87, 0xe9, 0xc0, 0x94, 0x3f, 0xe9, 0xda, 0x59, 0xb7, + 0x9e, 0xff, 0x5f, 0x16, 0xb6, 0x6a, 0x7a, 0x09, 0x9a, 0x7d, 0x77, 0xf0, 0x2e, 0x85, 0x14, 0x8a, + 0x5a, 0x92, 0x73, 0x3c, 0x8a, 0x54, 0xa4, 0x6b, 0x30, 0xdd, 0xdd, 0x09, 0x17, 0xbf, 0x6f, 0x44, + 0x4b, 0x25, 0x82, 0x3a, 0xd6, 0x25, 0x8b, 0x33, 0xbf, 0x53, 0x52, 0x4b, 0x20, 0xaf, 0x3b, 0xd6, + 0x59, 0x2c, 0x96, 0x76, 0xb4, 0x4f, 0xad, 0xd5, 0xe3, 0x7f, 0xf3, 0x92, 0xa2, 0x8a, 0xb9, 0xf6, + 0xcf, 0x40, 0x85, 0x5a, 0x82, 0xa0, 0x16, 0x42, 0xe6, 0xf8, 0xe0, 0x94, 0x43, 0x2c, 0x41, 0x9c, + 0xb2, 0x4a, 0xf2, 0x38, 0x95, 0x66, 0x04, 0x7b, 0xf4, 0xfa, 0x35, 0x79, 0x8f, 0x0f, 0xfa, 0x73, + 0xbf, 0xab, 0xa1, 0x71, 0xf0, 0xc4, 0x3a, 0xb8, 0xdd, 0xbe, 0xae, 0xc3, 0xc2, 0x67, 0xab, 0x8d, + 0x8b, 0x7e, 0x6e, 0x5c, 0xf4, 0x6b, 0xe3, 0xa2, 0x1f, 0x17, 0x2e, 0x5a, 0x5d, 0xb8, 0xe8, 0xdd, + 0x83, 0x1b, 0xc7, 0x94, 0x8c, 0xcc, 0x9f, 0x7d, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0xcd, 0x2f, + 0x9b, 0x0b, 0x02, 0x03, 0x00, 0x00, +}