parser

package
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 27, 2020 License: Apache-2.0 Imports: 9 Imported by: 0

README

Parser

GoDoc

The Parser package provides support for parsing Rosetta blocks. This includes things like calculating all the balance changes that occurred in a block and grouping related operations.

Installation

go get github.com/HelloKashif/rosetta-sdk-go/parser

Documentation

Index

Constants

View Source
const (
	// AnyAmountSign is a positive or negative amount.
	AnyAmountSign = iota

	// NegativeAmountSign is a negative amount.
	NegativeAmountSign

	// PositiveAmountSign is a positive amount.
	PositiveAmountSign
)

Variables

View Source
var (
	ErrExpectedOperationAccountMismatch = errors.New(
		"intended account did not match observed account",
	)
	ErrExpectedOperationAmountMismatch = errors.New(
		"intended amount did not match observed amount",
	)
	ErrExpectedOperationTypeMismatch = errors.New(
		"intended type did not match observed type",
	)
	ErrExpectedOperationsExtraOperation = errors.New("found extra operation")
	ErrExpectedSignerUnexpectedSigner   = errors.New("found unexpected signers")
	ErrExpectedSignerMissing            = errors.New("missing expected signer")

	IntentErrs = []error{
		ErrExpectedOperationAccountMismatch,
		ErrExpectedOperationAmountMismatch,
		ErrExpectedOperationTypeMismatch,
		ErrExpectedOperationsExtraOperation,
		ErrExpectedSignerUnexpectedSigner,
		ErrExpectedSignerMissing,
	}
)

Intent Errors

View Source
var (
	ErrAccountMatchAccountMissing           = errors.New("account is missing")
	ErrAccountMatchSubAccountMissing        = errors.New("SubAccountIdentifier.Address is missing")
	ErrAccountMatchSubAccountPopulated      = errors.New("SubAccount is populated")
	ErrAccountMatchUnexpectedSubAccountAddr = errors.New("unexpected SubAccountIdentifier.Address")

	ErrMetadataMatchKeyNotFound      = errors.New("key is not present in metadata")
	ErrMetadataMatchKeyValueMismatch = errors.New("unexpected value associated with key")

	ErrAmountMatchAmountMissing      = errors.New("amount is missing")
	ErrAmountMatchAmountPopulated    = errors.New("amount is populated")
	ErrAmountMatchUnexpectedSign     = errors.New("unexpected amount sign")
	ErrAmountMatchUnexpectedCurrency = errors.New("unexpected currency")

	ErrCoinActionMatchCoinChangeIsNil      = errors.New("coin change is nil")
	ErrCoinActionMatchUnexpectedCoinAction = errors.New("unexpected coin action")

	ErrEqualAmountsNoOperations = errors.New("cannot check equality of 0 operations")
	ErrEqualAmountsNotEqual     = errors.New("amounts are not equal")

	ErrOppositeAmountsSameSign       = errors.New("operations have the same sign")
	ErrOppositeAmountsAbsValMismatch = errors.New("operation absolute values are not equal")

	ErrEqualAddressesTooFewOperations = errors.New("cannot check equality of <= 1 operations")
	ErrEqualAddressesAccountIsNil     = errors.New("account is nil")
	ErrEqualAddressesAddrMismatch     = errors.New("addresses do not match")

	ErrMatchIndexValidIndexOutOfRange = errors.New("match index out of range")
	ErrMatchIndexValidIndexIsNil      = errors.New("match index is nil")

	ErrMatchOperationsNoOperations          = errors.New("unable to match anything to 0 operations")
	ErrMatchOperationsDescriptionsMissing   = errors.New("no descriptions to match")
	ErrMatchOperationsMatchNotFound         = errors.New("unable to find match for operation")
	ErrMatchOperationsDescriptionNotMatched = errors.New("could not find match for description")

	MatchOpsErrs = []error{
		ErrAccountMatchAccountMissing,
		ErrAccountMatchSubAccountMissing,
		ErrAccountMatchSubAccountPopulated,
		ErrAccountMatchUnexpectedSubAccountAddr,
		ErrMetadataMatchKeyNotFound,
		ErrMetadataMatchKeyValueMismatch,
		ErrAmountMatchAmountMissing,
		ErrAmountMatchAmountPopulated,
		ErrAmountMatchUnexpectedSign,
		ErrAmountMatchUnexpectedCurrency,
		ErrCoinActionMatchCoinChangeIsNil,
		ErrCoinActionMatchUnexpectedCoinAction,
		ErrEqualAmountsNoOperations,
		ErrEqualAmountsNotEqual,
		ErrOppositeAmountsSameSign,
		ErrOppositeAmountsAbsValMismatch,
		ErrEqualAddressesTooFewOperations,
		ErrEqualAddressesAccountIsNil,
		ErrEqualAddressesAddrMismatch,
		ErrMatchIndexValidIndexOutOfRange,
		ErrMatchIndexValidIndexIsNil,
		ErrMatchOperationsNoOperations,
		ErrMatchOperationsDescriptionsMissing,
		ErrMatchOperationsMatchNotFound,
		ErrMatchOperationsDescriptionNotMatched,
	}
)

Match Operations Errors

Functions

func Err

func Err(err error) (bool, string)

Err takes an error as an argument and returns whether or not the error is one thrown by the parser along with the specific source of the error

func ExpectedOperation

func ExpectedOperation(intent *types.Operation, observed *types.Operation) error

ExpectedOperation returns an error if an observed operation differs from the intended operation. An operation is considered to be different from the intent if the AccountIdentifier, Amount, or Type has changed.

func ExpectedSigners

func ExpectedSigners(intent []*types.SigningPayload, observed []*types.AccountIdentifier) error

ExpectedSigners returns an error if a slice of SigningPayload has different signers than what was observed (typically populated using the signers returned from parsing a transaction).

func MatchBalanceExemption

func MatchBalanceExemption(
	matchedExemptions []*types.BalanceExemption,
	difference string,
) *types.BalanceExemption

MatchBalanceExemption returns a *types.BalanceExemption associated with the *types.AccountIdentifier, *types.Currency, and difference, if it exists. The provided exemptions should be produced using FindExemptions.

Types

type AccountDescription

type AccountDescription struct {
	Exists                 bool
	SubAccountExists       bool
	SubAccountAddress      string
	SubAccountMetadataKeys []*MetadataDescription
}

AccountDescription is used to describe a *types.AccountIdentifier.

type AmountDescription

type AmountDescription struct {
	Exists   bool
	Sign     AmountSign
	Currency *types.Currency
}

AmountDescription is used to describe a *types.Amount.

type AmountSign

type AmountSign int

AmountSign is used to represent possible signedness of an amount.

func (AmountSign) Match

func (s AmountSign) Match(amount *types.Amount) bool

Match returns a boolean indicating if a *types.Amount has an AmountSign.

func (AmountSign) String

func (s AmountSign) String() string

String returns a description of an AmountSign.

type BalanceChange

type BalanceChange struct {
	Account    *types.AccountIdentifier `json:"account_identifier,omitempty"`
	Currency   *types.Currency          `json:"currency,omitempty"`
	Block      *types.BlockIdentifier   `json:"block_identifier,omitempty"`
	Difference string                   `json:"difference,omitempty"`
}

BalanceChange represents a balance change that affected a *types.AccountIdentifier and a *types.Currency.

type Descriptions

type Descriptions struct {
	OperationDescriptions []*OperationDescription

	// EqualAmounts are specified using the operation indicies of
	// OperationDescriptions to handle out of order matches. MatchOperations
	// will error if all groups of operations aren't equal.
	EqualAmounts [][]int

	// OppositeAmounts are specified using the operation indicies of
	// OperationDescriptions to handle out of order matches. MatchOperations
	// will error if all groups of operations aren't opposites.
	OppositeAmounts [][]int

	// EqualAddresses are specified using the operation indicies of
	// OperationDescriptions to handle out of order matches. MatchOperations
	// will error if all groups of operations addresses aren't equal.
	EqualAddresses [][]int

	// ErrUnmatched indicates that an error should be returned
	// if all operations cannot be matched to a description.
	ErrUnmatched bool
}

Descriptions contains a slice of OperationDescriptions and high-level requirements enforced across multiple *types.Operations.

type ExemptOperation

type ExemptOperation func(*types.Operation) bool

ExemptOperation is a function that returns a boolean indicating if the operation should be skipped eventhough it passes other checks indiciating it should be considered a balance change.

type Match

type Match struct {
	Operations []*types.Operation

	// Amounts has the same length as Operations. If an operation has
	// a populate Amount, its corresponding *big.Int will be non-nil.
	Amounts []*big.Int
}

Match contains all *types.Operation matching a given OperationDescription and their parsed *big.Int amounts (if populated).

func MatchOperations

func MatchOperations(
	descriptions *Descriptions,
	operations []*types.Operation,
) ([]*Match, error)

MatchOperations attempts to match a slice of operations with a slice of OperationDescriptions (high-level descriptions of what operations are desired). If matching succeeds, a slice of matching operations in the mapped to the order of the descriptions is returned.

func (*Match) First

func (m *Match) First() (*types.Operation, *big.Int)

First is a convenience method that returns the first matched operation and amount (if they exist). This is used when parsing matches when AllowRepeats is set to false.

type MetadataDescription

type MetadataDescription struct {
	Key       string
	ValueKind reflect.Kind // ex: reflect.String
}

MetadataDescription is used to check if a map[string]interface{} has certain keys and values of a certain kind.

type OperationDescription

type OperationDescription struct {
	Account  *AccountDescription
	Amount   *AmountDescription
	Metadata []*MetadataDescription

	// Type is the operation.Type that must match. If this is left empty,
	// any type is considered a match.
	Type string

	// AllowRepeats indicates that multiple operations can be matched
	// to a particular description.
	AllowRepeats bool

	// Optional indicates that not finding any operations that meet
	// the description should not trigger an error.
	Optional bool

	// CoinAction indicates that an operation should have a CoinChange
	// and that it should have the CoinAction. If this is not populated,
	// CoinChange is not checked.
	CoinAction types.CoinAction
}

OperationDescription is used to describe a *types.Operation.

type OperationGroup

type OperationGroup struct {
	Type             string
	Operations       []*types.Operation
	Currencies       []*types.Currency
	NilAmountPresent bool
}

OperationGroup is a group of related operations If all operations in a group have the same operation.Type, the Type is also populated.

func GroupOperations

func GroupOperations(transaction *types.Transaction) []*OperationGroup

GroupOperations parses all of a transaction's opertations and returns a slice of each group of related operations (assuming transitive relatedness). This should ONLY be called on operations that have already been asserted for correctness. Assertion ensures there are no duplicate operation indexes, operations are sorted, and that operations only reference operations with an index less than theirs.

OperationGroups are returned in ascending order based on the lowest OperationIdentifier.Index in the group. The operations in each OperationGroup are also sorted.

type Parser

type Parser struct {
	Asserter          *asserter.Asserter
	ExemptFunc        ExemptOperation
	BalanceExemptions []*types.BalanceExemption
}

Parser provides support for parsing Rosetta blocks.

func New

func New(
	asserter *asserter.Asserter,
	exemptFunc ExemptOperation,
	balanceExemptions []*types.BalanceExemption,
) *Parser

New creates a new Parser.

func (*Parser) BalanceChanges

func (p *Parser) BalanceChanges(
	ctx context.Context,
	block *types.Block,
	blockRemoved bool,
) ([]*BalanceChange, error)

BalanceChanges returns all balance changes for a particular block. All balance changes for a particular account are summed into a single BalanceChanges struct. If a block is being orphaned, the opposite of each balance change is returned.

func (*Parser) ExpectedOperations

func (p *Parser) ExpectedOperations(
	intent []*types.Operation,
	observed []*types.Operation,
	errExtra bool,
	confirmSuccess bool,
) error

ExpectedOperations returns an error if a slice of intended operations differ from observed operations. Optionally, it is possible to error if any extra observed opertions are found or if operations matched are not considered successful.

func (*Parser) FindExemptions

func (p *Parser) FindExemptions(
	account *types.AccountIdentifier,
	currency *types.Currency,
) []*types.BalanceExemption

FindExemptions returns all matching *types.BalanceExemption for a particular *types.AccountIdentifier and *types.Currency.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL