reconciler

package
v0.5.1 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2020 License: Apache-2.0 Imports: 11 Imported by: 4

README

Reconciler

GoDoc

The Reconciler package is used to ensure that balance changes derived from parsing Rosetta blocks are equivalent to the balance changes computed by the node. If you want to see an example of how to use this package, take a look at rosetta-cli.

Features

  • Customizable Helper and Handler to define your own logic for retrieving calculated balance changes and handling successful/unsuccessful comparisons
  • Perform balance lookup at either historical blocks or the current block (if historical balance query is not supported)
  • Provide a list of accounts to compare at each block (for quick and easy debugging)

Installation

go get github.com/coinbase/rosetta-sdk-go/reconciler

Reconciliation Strategies

Active Addresses

The reconciler checks that the balance of an account computed by its operations is equal to the balance of the account according to the node. If this balance is not identical, the reconciler will error.

Inactive Addresses

The reconciler randomly checks the balances of accounts that aren't involved in any transactions. The balances of accounts could change on the blockchain node without being included in an operation returned by the Rosetta Data API. Recall that all balance-changing operations must be returned by the Rosetta Data API.

Documentation

Index

Constants

View Source
const (
	// ActiveReconciliation is included in the reconciliation
	// error message if reconciliation failed during active
	// reconciliation.
	ActiveReconciliation = "ACTIVE"

	// InactiveReconciliation is included in the reconciliation
	// error message if reconciliation failed during inactive
	// reconciliation.
	InactiveReconciliation = "INACTIVE"
)

Variables

View Source
var (
	// ErrHeadBlockBehindLive is returned when the processed
	// head is behind the live head. Sometimes, it is
	// preferable to sleep and wait to catch up when
	// we are close to the live head (waitToCheckDiff).
	ErrHeadBlockBehindLive = errors.New("head block behind")

	// ErrAccountUpdated is returned when the
	// account was updated at a height later than
	// the live height (when the account balance was fetched).
	ErrAccountUpdated = errors.New("account updated")

	// ErrBlockGone is returned when the processed block
	// head is greater than the live head but the block
	// does not exist in the store. This likely means
	// that the block was orphaned.
	ErrBlockGone = errors.New("block gone")

	ErrGetCurrentBlockFailed    = errors.New("unable to get current block for reconciliation")
	ErrBlockExistsFailed        = errors.New("unable to check if block exists")
	ErrGetComputedBalanceFailed = errors.New("unable to get computed balance")
	ErrLiveBalanceLookupFailed  = errors.New("unable to lookup live balance")
)

Named error types for Reconciler errors

Functions

func ContainsAccountCurrency

func ContainsAccountCurrency(
	m map[string]struct{},
	change *AccountCurrency,
) bool

ContainsAccountCurrency returns a boolean indicating if a AccountCurrency set already contains an Account and Currency combination.

func Err added in v0.4.1

func Err(err error) bool

Err takes an error as an argument and returns whether or not the error is one thrown by the reconciler package

Types

type AccountCurrency

type AccountCurrency struct {
	Account  *types.AccountIdentifier `json:"account_identifier,omitempty"`
	Currency *types.Currency          `json:"currency,omitempty"`
}

AccountCurrency is a simple struct combining a *types.Account and *types.Currency. This can be useful for looking up balances.

type Handler

type Handler interface {
	ReconciliationFailed(
		ctx context.Context,
		reconciliationType string,
		account *types.AccountIdentifier,
		currency *types.Currency,
		computedBalance string,
		liveBalance string,
		block *types.BlockIdentifier,
	) error

	ReconciliationSucceeded(
		ctx context.Context,
		reconciliationType string,
		account *types.AccountIdentifier,
		currency *types.Currency,
		balance string,
		block *types.BlockIdentifier,
	) error

	ReconciliationExempt(
		ctx context.Context,
		reconciliationType string,
		account *types.AccountIdentifier,
		currency *types.Currency,
		computedBalance string,
		liveBalance string,
		block *types.BlockIdentifier,
		exemption *types.BalanceExemption,
	) error
}

Handler is called by Reconciler after a reconciliation is performed. When a reconciliation failure is observed, it is up to the client to halt syncing or log the result.

type Helper

type Helper interface {
	BlockExists(
		ctx context.Context,
		block *types.BlockIdentifier,
	) (bool, error)

	CurrentBlock(
		ctx context.Context,
	) (*types.BlockIdentifier, error)

	ComputedBalance(
		ctx context.Context,
		account *types.AccountIdentifier,
		currency *types.Currency,
		headBlock *types.BlockIdentifier,
	) (*types.Amount, *types.BlockIdentifier, error)

	LiveBalance(
		ctx context.Context,
		account *types.AccountIdentifier,
		currency *types.Currency,
		block *types.BlockIdentifier,
	) (*types.Amount, *types.BlockIdentifier, error)
}

Helper functions are used by Reconciler to compare computed balances from a block with the balance calculated by the node. Defining an interface allows the client to determine what sort of storage layer they want to use to provide the required information.

type InactiveEntry added in v0.3.0

type InactiveEntry struct {
	Entry     *AccountCurrency
	LastCheck *types.BlockIdentifier
}

InactiveEntry is used to track the last time that an *AccountCurrency was reconciled.

type Option added in v0.3.0

type Option func(r *Reconciler)

Option is used to overwrite default values in Reconciler construction. Any Option not provided falls back to the default value.

func WithActiveConcurrency added in v0.3.0

func WithActiveConcurrency(concurrency int) Option

WithActiveConcurrency overrides the default active concurrency.

func WithBalanceExemptions added in v0.5.0

func WithBalanceExemptions(exemptions []*types.BalanceExemption) Option

WithBalanceExemptions is which reconciliation errors to skip.

func WithDebugLogging added in v0.3.1

func WithDebugLogging(debug bool) Option

WithDebugLogging determines if verbose logs should be printed.

func WithInactiveConcurrency added in v0.3.0

func WithInactiveConcurrency(concurrency int) Option

WithInactiveConcurrency overrides the default inactive concurrency.

func WithInactiveFrequency added in v0.3.1

func WithInactiveFrequency(blocks int64) Option

WithInactiveFrequency is how many blocks the reconciler should wait between inactive reconciliations on each account.

func WithInterestingAccounts added in v0.3.0

func WithInterestingAccounts(interesting []*AccountCurrency) Option

WithInterestingAccounts adds interesting accounts to check at each block.

func WithLookupBalanceByBlock added in v0.3.0

func WithLookupBalanceByBlock(lookup bool) Option

WithLookupBalanceByBlock sets lookupBlockByBalance and instantiates the correct changeQueue.

func WithSeenAccounts added in v0.3.0

func WithSeenAccounts(seen []*AccountCurrency) Option

WithSeenAccounts adds accounts to the seenAccounts slice and inactiveQueue for inactive reconciliation.

type Reconciler

type Reconciler struct {
	// contains filtered or unexported fields
}

Reconciler contains all logic to reconcile balances of types.AccountIdentifiers returned in types.Operations by a Rosetta Server.

func New added in v0.3.0

func New(
	helper Helper,
	handler Handler,
	options ...Option,
) *Reconciler

New creates a new Reconciler.

func (*Reconciler) CompareBalance

func (r *Reconciler) CompareBalance(
	ctx context.Context,
	account *types.AccountIdentifier,
	currency *types.Currency,
	amount string,
	liveBlock *types.BlockIdentifier,
) (string, string, int64, error)

CompareBalance checks to see if the computed balance of an account is equal to the live balance of an account. This function ensures balance is checked correctly in the case of orphaned blocks.

func (*Reconciler) QueueChanges

func (r *Reconciler) QueueChanges(
	ctx context.Context,
	block *types.BlockIdentifier,
	balanceChanges []*parser.BalanceChange,
) error

QueueChanges enqueues a slice of *BalanceChanges for reconciliation.

func (*Reconciler) Reconcile

func (r *Reconciler) Reconcile(ctx context.Context) error

Reconcile starts the active and inactive Reconciler goroutines. If any goroutine errors, the function will return an error.

Jump to

Keyboard shortcuts

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