Documentation ¶
Index ¶
- func Hash(txab Transactable) string
- func Marshal(txab Transactable, idMap TxIDMap) ([]byte, error)
- func NameOf(txab Transactable) string
- func Sign(txab Transactable, key signature.PrivateKey) signature.Signature
- func Verify(txab Transactable, sig signature.Signature, key signature.PublicKey) bool
- type Transactable
- type Transaction
- func (tx *Transaction) AsTransactable(idMap TxIDMap) (Transactable, error)
- func (z *Transaction) DecodeMsg(dc *msgp.Reader) (err error)
- func (z *Transaction) EncodeMsg(en *msgp.Writer) (err error)
- func (z *Transaction) MarshalMsg(b []byte) (o []byte, err error)
- func (z *Transaction) Msgsize() (s int)
- func (z *Transaction) UnmarshalMsg(bts []byte) (o []byte, err error)
- type TxID
- type TxIDMap
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Hash ¶
func Hash(txab Transactable) string
Hash deterministically computes a probably-unique hash of the Transactable.
This is intended for event tracing: it allows the Transactable to be followed in logs through the complete round-trip of actions.
func Marshal ¶
func Marshal(txab Transactable, idMap TxIDMap) ([]byte, error)
Marshal serializes a Transactable into a byte slice
func NameOf ¶
func NameOf(txab Transactable) string
NameOf uses reflection to get the name associated with a Transactable
func Sign ¶
func Sign(txab Transactable, key signature.PrivateKey) signature.Signature
Sign the Transactable with the given private key
Types ¶
type Transactable ¶
type Transactable interface { // transactable types need to be able to marshal and unmarshal themselves msgp.Marshaler msgp.Unmarshaler // Validate returns nil if the Transactable is valid, or an error otherwise. // // `app` will always be an instance of your app; it is expected that the // first line of most implementations will be // // “`go // app := appInt.(*MyApp) // ““ Validate(app interface{}) error // Apply applies this transaction to the supplied application, updating its // internal state as required. // // If anything but nil is returned, the internal state of the input App // must be unchanged. // // `app` will always be an instance of your app; it is expected that the // first line of most implementations will be // // “`go // app := appInt.(*MyApp) // “` Apply(app interface{}) error // SignableBytes must return a representation of all the data in the // transactable, except the signature. No particular ordering or schema // is required, only that the bytes are computed deterministically and // contain a complete representation of the transactable. // // For transactables with a signature field, this must _not_ include the // signature. // // For transactables without a signature field, this must include all data. // In that case, it is probably simplest to delegate this function // to `.MarshalMsg(nil)`. // // Unfortunately, we can't enforce the above two restrictions in code; just // trust that if you don't write your implementation with those semantics, // you will encounter weird, hard-to-debug errors eventually. // // This is designed to support two use cases: // // 1. Most transactables must be signed. Using this method simplifies // the problem of generating and validating signatures. // 2. For error tracing, we desire a short and unique-ish string which // can be computed for every transaction. We can get there from here. SignableBytes() []byte }
Transactable is the transaction type that the app actually cares about.
Whereas Transaction is the type that tendermint cares about, with nonces etc designed to keep consensus running, Transactables handle application- specific transaction logic.
Transactables are defined in terms of abci.Application. This is a convenience abstraction: expected behavior is to simply cast the received value to the type of the actual application being written.
An alternative API was considered: writing a TransactableHandler interface with methods ValidateTransactable and ApplyTransactable, which would both receive the transactable. The idea was that the logic could be placed in whichever portion of the interface was simpler. However, that approach was not actually more typesafe (as it would require casting the Transactable to a concrete type), and would require more busywork to implement, so it was decided against.
func Clone ¶
func Clone(original Transactable) Transactable
Clone makes a shallow copy of a transactable
type Transaction ¶
A Transaction is a transaction as recognized by Tendermint
func AsTransaction ¶
func AsTransaction(txab Transactable, idMap TxIDMap) (*Transaction, error)
AsTransaction builds a Transaction from any Transactable
func (*Transaction) AsTransactable ¶
func (tx *Transaction) AsTransactable(idMap TxIDMap) (Transactable, error)
AsTransactable converts a Transaction into a Transactable instance
func (*Transaction) DecodeMsg ¶
func (z *Transaction) DecodeMsg(dc *msgp.Reader) (err error)
DecodeMsg implements msgp.Decodable
func (*Transaction) EncodeMsg ¶
func (z *Transaction) EncodeMsg(en *msgp.Writer) (err error)
EncodeMsg implements msgp.Encodable
func (*Transaction) MarshalMsg ¶
func (z *Transaction) MarshalMsg(b []byte) (o []byte, err error)
MarshalMsg implements msgp.Marshaler
func (*Transaction) Msgsize ¶
func (z *Transaction) Msgsize() (s int)
Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (*Transaction) UnmarshalMsg ¶
func (z *Transaction) UnmarshalMsg(bts []byte) (o []byte, err error)
UnmarshalMsg implements msgp.Unmarshaler
type TxID ¶
type TxID uint8
A TxID is a unique identity for this transaction type.
This eases disambiguation for deserialization.
func TxIDOf ¶
func TxIDOf(txab Transactable, idMap TxIDMap) (TxID, error)
TxIDOf uses reflection to get the ID associated with a Transactable type.
We're stuck with linear scan here, which isn't ideal, but for the size of transactables we expect, the penalty shouldn't be too bad.
func (TxID) MarshalMsg ¶
MarshalMsg implements msgp.Marshaler
type TxIDMap ¶
type TxIDMap map[TxID]Transactable
A TxIDMap is a map of unique IDs to Transactable example objects
It should never be mutated by code.
Example objects should be empty objects of the relevant Transactable type.