malicious

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2024 License: Apache-2.0 Imports: 35 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// BehaviorConfigKey is the key used to set the malicious config.
	BehaviorConfigKey = "behavior_config"

	// OutOfOrderHandlerKey is the key used to set the out of order prepare
	// proposal handler.
	OutOfOrderHandlerKey = "out_of_order"
)
View Source
const (
	LeafPrefix = 0
	NodePrefix = 1
)

Variables

View Source
var (
	ErrUnorderedSiblings         = errors.New("NMT sibling nodes should be ordered lexicographically by namespace IDs")
	ErrInvalidNodeLen            = errors.New("invalid NMT node size")
	ErrInvalidLeafLen            = errors.New("invalid NMT leaf size")
	ErrInvalidNodeNamespaceOrder = errors.New("invalid NMT node namespace order")
)

Functions

func Build

func Build(txs [][]byte, appVersion uint64, maxSquareSize int, efn ExportFn) (square.Square, [][]byte, error)

Build takes an arbitrary long list of (prioritized) transactions and builds a square that is never greater than maxSquareSize. It also returns the ordered list of transactions that are present in the square and which have all PFBs trailing regular transactions. Note, this function does not check the underlying validity of the transactions. Errors should not occur and would reflect a violation in an invariant.

func Construct

func Construct(txs [][]byte, appVersion uint64, maxSquareSize int, efn ExportFn) (square.Square, error)

Construct takes the exact list of ordered transactions and constructs a square. This mimics the functionality of the normal Construct function, but acts maliciously by not following some of the block validity rules.

func ExtendShares

func ExtendShares(s [][]byte) (*rsmt2d.ExtendedDataSquare, error)

func NewAppServer

func NewAppServer(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts servertypes.AppOptions) servertypes.Application

NewAppServer creates a new AppServer using the malicious application.

func NewConstructor

func NewConstructor(squareSize uint64, opts ...nmt.Option) rsmt2d.TreeConstructorFn

NewConstructor creates a tree constructor function as required by rsmt2d to calculate the data root. It creates that tree using a malicious version of the wrapper.ErasuredNamespacedMerkleTree.

func OutOfOrderExport

func OutOfOrderExport(b *square.Builder) (square.Square, error)

OutOfOrderExport constructs the square in a malicious and deterministic way by swapping the first two blobs with different namespaces.

func OutOfOrderNamespaceConfig

func OutOfOrderNamespaceConfig(startHeight int64) *testnode.Config

OutOfOrderNamesapceConfig returns a testnode config that will start producing blocks with out of order namespaces at the provided height.

Note: per the OutOfOrder go docs, the first two blobs with different namespaces will be swapped, resulting in an invalid block.

func TestNodeConfig

func TestNodeConfig(behavior BehaviorConfig) *testnode.Config

TestNodeConfig returns a testnode config with the malicous application and provided behavior set in the app options.

Types

type App

type App struct {
	*app.App
	// contains filtered or unexported fields
}

func New

func New(
	logger log.Logger,
	db dbm.DB,
	traceStore io.Writer,
	loadLatest bool,
	skipUpgradeHeights map[int64]bool,
	homePath string,
	invCheckPeriod uint,
	encodingConfig encoding.Config,
	appOpts servertypes.AppOptions,
	baseAppOptions ...func(*baseapp.BaseApp),
) *App

func NewTestApp

func NewTestApp(cparams *tmproto.ConsensusParams, mcfg BehaviorConfig, genAccounts ...string) *App

NewTestApp creates a new malicious application with the provided consensus params.

func (*App) OutOfOrderPrepareProposal

func (a *App) OutOfOrderPrepareProposal(req abci.RequestPrepareProposal) abci.ResponsePrepareProposal

OutOfOrderPrepareProposal fulfills the celestia-core version of the ABCI interface by preparing the proposal block data. This version of the method is used to create malicious block proposals that fraud proofs can be created for. It will swap the order of two blobs in the square and then use the modified nmt to create a commitment over the modified square.

func (*App) PrepareProposal

PrepareProposal overwrites the default app's method to use the configured malicious behavior after a given height.

func (*App) PrepareProposalHandlerMap

func (a *App) PrepareProposalHandlerMap() map[string]PrepareProposalHandler

PrepareProposalHandlerMap is a map of all the known prepare proposal handlers.

func (*App) ProcessProposal

func (a *App) ProcessProposal(_ abci.RequestProcessProposal) (resp abci.ResponseProcessProposal)

ProcessProposal overwrites the default app's method to auto accept any proposal.

func (*App) SetMaliciousBehavior

func (a *App) SetMaliciousBehavior(mcfg BehaviorConfig)

type BehaviorConfig

type BehaviorConfig struct {
	// HandlerName is the name of the malicious handler to use. All known
	// handlers are defined in the PrepareProposalHandlerMap.
	HandlerName string `json:"handler_name"`
	// StartHeight is the height at which the malicious behavior will start.
	StartHeight int64 `json:"start_height"`
}

BehaviorConfig defines the malicious behavior for the application. It dictates the height at which the malicious behavior will start along with what type of malicious behavior will be performed.

type BlindTree

type BlindTree struct {
	*nmt.NamespacedMerkleTree
}

BlindTree is a wrapper around the erasured NMT that skips verification of namespace ordering when hashing and adding leaves to the tree. It does this by using a custom malicious hahser and wraps using the ForceAddLeaf method instead of the normal Push.

func (*BlindTree) Push

func (bt *BlindTree) Push(data namespace.PrefixedData) error

Push overwrites the nmt method to skip namespace verification.

type ExportFn

type ExportFn func(builder *square.Builder) (square.Square, error)

type Hasher

type Hasher interface {
	IsMaxNamespaceIDIgnored() bool
	NamespaceSize() namespace.IDSize
	HashLeaf(data []byte) ([]byte, error)
	HashNode(leftChild, rightChild []byte) ([]byte, error)
	EmptyRoot() []byte
}

Hasher describes the interface nmts use to hash leafs and nodes.

Note: it is not advised to create alternative hashers if following the specification is desired. The main reason this exists is to not follow the specification for testing purposes.

type NmtHasher

type NmtHasher struct {
	NamespaceLen namespace.IDSize
	// contains filtered or unexported fields
}

NmtHasher is the default hasher. It follows the description of the original hashing function described in the LazyLedger white paper.

func NewNmtHasher

func NewNmtHasher(baseHasher hash.Hash, nidLen namespace.IDSize, ignoreMaxNamespace bool) *NmtHasher

func (*NmtHasher) BlockSize

func (n *NmtHasher) BlockSize() int

BlockSize returns the hash's underlying block size.

func (*NmtHasher) EmptyRoot

func (n *NmtHasher) EmptyRoot() []byte

func (*NmtHasher) HashLeaf

func (n *NmtHasher) HashLeaf(ndata []byte) ([]byte, error)

HashLeaf computes namespace hash of the namespaced data item `ndata` as ns(ndata) || ns(ndata) || hash(leafPrefix || ndata), where ns(ndata) is the namespaceID inside the data item namely leaf[:n.NamespaceLen]). Note that for leaves minNs = maxNs = ns(leaf) = leaf[:NamespaceLen]. HashLeaf can return the ErrInvalidNodeLen error if the input is not namespaced.

func (*NmtHasher) HashNode

func (n *NmtHasher) HashNode(left, right []byte) ([]byte, error)

HashNode calculates a namespaced hash of a node using the supplied left and right children. The input values, `left` and `right,` are namespaced hash values with the format `minNID || maxNID || hash.` The HashNode function returns an error if the provided inputs are invalid. Specifically, it returns the ErrInvalidNodeLen error if the left and right inputs are not in the namespaced hash format, and the ErrUnorderedSiblings error if left.maxNID is greater than right.minNID. By default, the normal namespace hash calculation is followed, which is `res = min(left.minNID, right.minNID) || max(left.maxNID, right.maxNID) || H(NodePrefix, left, right)`. `res` refers to the return value of the HashNode. However, if the `ignoreMaxNs` property of the Hasher is set to true, the calculation of the namespace ID range of the node slightly changes. Let MAXNID be the maximum possible namespace ID value i.e., 2^NamespaceIDSize-1. If the namespace range of the right child is start=end=MAXNID, indicating that it represents the root of a subtree whose leaves all have the namespace ID of `MAXNID`, then exclude the right child from the namespace range calculation. Instead, assign the namespace range of the left child as the parent's namespace range.

func (*NmtHasher) IsMaxNamespaceIDIgnored

func (n *NmtHasher) IsMaxNamespaceIDIgnored() bool

func (*NmtHasher) MustHashLeaf

func (n *NmtHasher) MustHashLeaf(ndata []byte) []byte

MustHashLeaf is a wrapper around HashLeaf that panics if an error is encountered. The ndata must be a valid leaf node.

func (*NmtHasher) NamespaceSize

func (n *NmtHasher) NamespaceSize() namespace.IDSize

func (*NmtHasher) Reset

func (n *NmtHasher) Reset()

Reset resets the Hash to its initial state.

func (*NmtHasher) Size

func (n *NmtHasher) Size() int

Size returns the number of bytes Sum will return.

func (*NmtHasher) Sum

func (n *NmtHasher) Sum([]byte) []byte

Sum computes the hash. Does not append the given suffix, violating the interface. It may panic if the data being hashed is invalid. This should never happen since the Write method refuses an invalid data and errors out.

func (*NmtHasher) ValidateLeaf

func (n *NmtHasher) ValidateLeaf(data []byte) (err error)

ValidateLeaf verifies if data is namespaced and returns an error if not.

func (*NmtHasher) ValidateNodeFormat

func (n *NmtHasher) ValidateNodeFormat(node []byte) (err error)

ValidateNodeFormat checks whether the supplied node conforms to the namespaced hash format and returns ErrInvalidNodeLen if not.

func (*NmtHasher) ValidateNodes

func (n *NmtHasher) ValidateNodes(left, right []byte) error

ValidateNodes is a helper function to verify the validity of the inputs of HashNode. It verifies whether left and right comply by the namespace hash format, and are correctly ordered according to their namespace IDs.

func (*NmtHasher) Write

func (n *NmtHasher) Write(data []byte) (int, error)

Write writes the namespaced data to be hashed.

Requires data of fixed size to match leaf or inner NMT nodes. Only a single write is allowed. It panics if more than one single write is attempted. If the data does not match the format of an NMT non-leaf node or leaf node, an error will be returned.

Jump to

Keyboard shortcuts

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