solo

package
v2.0.3-0...-34c6bb6 Latest Latest
Warning

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

Go to latest
Published: Oct 13, 2025 License: Apache-2.0 Imports: 78 Imported by: 0

README

Package Solo

Package solo is a development tool for writing unit tests for IOTA Smart Contracts (ISC).

The package is intended for developers of smart contracts as well as contributors to the development of the ISC and the Wasp node itself.

Normally, the smart contract is developed and tested in the solo environment before trying it out on the network of Wasp nodes. Running and testing the smart contract on 'solo' does not require to run the Wasp nodes nor committee of nodes: just ordinary 'go test' environment. Same time, the smart contracts in solo is run in native environment, including transactions, tokens, signatures and virtual state access. This allows deployment of smart contracts on Wasp network without any changes.

See here the GoDoc documentation of the solo package: Go Reference

Documentation

Overview

Package solo is a development tool to write unit tests for IOTA Smart Contracts (ISC).

A development tool

The package is intended for developers of smart contracts as well as contributors to the development of the ISC and the Wasp node itself.

Normally, the smart contract is developed and tested in the 'solo' environment before trying it out on the network of Wasp nodes. Running and testing the smart contract on 'solo' does not require to run the Wasp nodes nor committee of nodes: just ordinary 'go test' environment.

Native environment

'solo' shares the same code of Virtual Machine with the Wasp node. This guarantees that smart contract programs can later be deployed on chains which are run by the network of Wasp nodes without any modifications.

The 'solo' environment uses in-memory UTXO ledger to validate and store transactions. The UTXODB mocks the Shimmer UTXO ledger, it uses same value transaction structure, colored tokens, signature schemes as well as transaction and signature validation as in the Value Tangle of Shimmer. The only difference with the Value Tangle is that UTXODB provides full synchronicity of ledger updates.

The virtual state (key/value database) in 'solo' is an in-memory database. It provides exactly the same interface of access to it as the database of the Wasp node.

Example test

The following example deploys chain and retrieves basic info from the deployed chain. It is expected 4 core contracts deployed on it by default and the test prints them.

func TestSolo1(t *testing.T) {
  env := solo.New(t, false, false)
  chain := env.NewChain(nil, "ex1")

  chainInfo, coreContracts := chain.GetInfo()   // calls view root::GetInfo
  require.EqualValues(t, 4, len(coreContracts)) // 4 core contracts deployed by default

  t.Logf("chainID: %s", chainInfo.ChainID)
  t.Logf("chain owner ID: %s", chainInfo.ChainOwnerID)
  for hname, rec := range coreContracts {
     t.Logf("    Core contract '%s': %s", rec.Name, isc.NewContractID(chain.ChainID, hname))
  }
}

will produce the following output:

      === RUN   TestSolo1
 34:37.415	INFO	TestSolo1	solo/solo.go:153	deploying new chain 'ex1'
	34:37.419	INFO	TestSolo1.ex1	vmcontext/runreq.go:177	eventlog -> '[req] [0]Ei4d6oUbcgSPnmpTupeLaTNoNf1hRu8ZfZfmw2KFKzZm: Ok'
	34:37.420	INFO	TestSolo1.ex1	solo/run.go:75	state transition #0 --> #1. Requests in the block: 1. Posted: 0
	34:37.420	INFO	TestSolo1	solo/clock.go:44	ClockStep: logical clock advanced by 1ms
	34:37.420	INFO	TestSolo1.ex1	solo/solo.go:233	chain 'ex1' deployed. Chain ID: aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3
	34:37.420	INFO	TestSolo1.ex1	solo/req.go:145	callView: root::getChainInfo
	solo_test.go:18: chainID: aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3
	solo_test.go:19: chain owner ID: A/UrYEv4Yh7WU1M29cKq73tb2CUx8EYXfJt6JZn5srw19U
	solo_test.go:21:     Core contract 'accounts': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::3c4b5e02
	solo_test.go:21:     Core contract 'blob': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::fd91bc63
	solo_test.go:21:     Core contract 'root': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::cebf5908
	solo_test.go:21:     Core contract 'eventlog': aEbE2vX6jrGhQ3AKHCPmQmn2qa11CpCRzaEgtVJRAje3::661aa7d8
	--- PASS: TestSolo1 (0.01s)

Index

Constants

View Source
const (
	DestroyTokensGasBudgetBaseTokens       = 1 * isc.Million
	SendToL2AccountGasBudgetBaseTokens     = 1 * isc.Million
	DestroyFoundryGasBudgetBaseTokens      = 1 * isc.Million
	TransferAllowanceToGasBudgetBaseTokens = 1 * isc.Million
)

CreateFoundryGasBudgetBaseTokens always takes 100000 base tokens as gas budget and ftokens for the call

Variables

View Source
var (
	BaseTokensForL2Gas          = gas.FeeFromGasWithGasPerToken(gas.LimitsDefault.MaxGasPerRequest, gas.DefaultGasPerToken)
	DefaultChainAdminBaseTokens = 2 * BaseTokensForL2Gas
)
View Source
var EthereumAccounts [10]*ecdsa.PrivateKey

Functions

func EVMCallDataFromArtifacts

func EVMCallDataFromArtifacts(t require.TestingT, abiJSON string, bytecode []byte, args ...any) (abi.ABI, []byte)

func EthereumAccountByIndex

func EthereumAccountByIndex(i int) (*ecdsa.PrivateKey, common.Address)

func NewEthereumAccount

func NewEthereumAccount() (*ecdsa.PrivateKey, common.Address)

Types

type CallParams

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

func NewCallParams

func NewCallParams(msg isc.Message, contract ...any) *CallParams

NewCallParams creates a structure that wraps in one object call parameters, used in PostRequestSync and CallView

func NewCallParamsEx

func NewCallParamsEx(c, ep string, params ...isc.CallArguments) *CallParams

NewCallParamsEx is a shortcut for NewCallParams

func (*CallParams) AddAllowance

func (r *CallParams) AddAllowance(allowance *isc.Assets) *CallParams

func (*CallParams) AddAllowanceBaseTokens

func (r *CallParams) AddAllowanceBaseTokens(amount coin.Value) *CallParams

func (*CallParams) AddAllowanceCoins

func (r *CallParams) AddAllowanceCoins(coinType coin.Type, amount coin.Value) *CallParams

func (*CallParams) AddAllowanceObject

func (r *CallParams) AddAllowanceObject(obj isc.IotaObject) *CallParams

func (*CallParams) AddBaseTokens

func (r *CallParams) AddBaseTokens(amount coin.Value) *CallParams

AddBaseTokens adds base tokens to be sent (only applicable when the call is made via on-ledger request)

func (*CallParams) AddCoin

func (r *CallParams) AddCoin(coinType coin.Type, amount coin.Value) *CallParams

AddCoin adds a coin to be sent (only applicable when the call is made via on-ledger request)

func (*CallParams) AddFungibleTokens

func (r *CallParams) AddFungibleTokens(ftokens isc.CoinBalances) *CallParams

AddFungibleTokens adds tokens to be sent (only applicable when the call is made via on-ledger request)

func (*CallParams) AddObject

func (r *CallParams) AddObject(obj isc.IotaObject) *CallParams

AddObject adds an object to be sent (only applicable when the call is made via on-ledger request)

func (*CallParams) GasBudget

func (r *CallParams) GasBudget() uint64

func (*CallParams) NewRequestOffLedger

func (r *CallParams) NewRequestOffLedger(ch *Chain, keyPair *cryptolib.KeyPair) isc.OffLedgerRequest

NewRequestOffLedger creates off-ledger request from parameters

func (*CallParams) NewRequestOnLedger

func (r *CallParams) NewRequestOnLedger(ch *Chain, keyPair *cryptolib.KeyPair) (isc.OnLedgerRequest, error)

NewRequestOnLedger creates an on-ledger request without sending it to L1. It is intended mainly for estimating gas.

func (*CallParams) WithAllowance

func (r *CallParams) WithAllowance(allowance *isc.Assets) *CallParams

func (*CallParams) WithAssets

func (r *CallParams) WithAssets(assets *isc.Assets) *CallParams

WithAssets sets the assets to be sent (only applicable when the call is made via on-ledger request)

func (*CallParams) WithFungibleTokens

func (r *CallParams) WithFungibleTokens(ftokens isc.CoinBalances) *CallParams

WithFungibleTokens sets the tokens to be sent (only applicable when the call is made via on-ledger request)

func (*CallParams) WithGasBudget

func (r *CallParams) WithGasBudget(gasBudget uint64) *CallParams

func (*CallParams) WithMaxAffordableGasBudget

func (r *CallParams) WithMaxAffordableGasBudget() *CallParams

func (*CallParams) WithNonce

func (r *CallParams) WithNonce(nonce uint64) *CallParams

func (*CallParams) WithSender

func (r *CallParams) WithSender(sender *cryptolib.Address) *CallParams

func (*CallParams) WithTargetContract

func (r *CallParams) WithTargetContract(contract any) *CallParams

type Chain

type Chain struct {

	// Env is a pointer to the global structure of the 'solo' test
	Env *Solo
	// contains filtered or unexported fields
}

Chain represents state of individual chain. There may be several parallel instances of the chain in the 'solo' test

func (*Chain) AddMigration

func (ch *Chain) AddMigration(m migrations.Migration)

func (*Chain) AdminAddress

func (ch *Chain) AdminAddress() *cryptolib.Address

func (*Chain) AdminAgentID

func (ch *Chain) AdminAgentID() isc.AgentID

func (*Chain) AnchorOwnerAddress

func (ch *Chain) AnchorOwnerAddress() *cryptolib.Address

func (*Chain) AssertL2BaseTokens

func (ch *Chain) AssertL2BaseTokens(agentID isc.AgentID, bal coin.Value)

func (*Chain) AssertL2Coins

func (ch *Chain) AssertL2Coins(agentID isc.AgentID, coinType coin.Type, expected coin.Value)

func (*Chain) AssertL2TotalBaseTokens

func (ch *Chain) AssertL2TotalBaseTokens(bal coin.Value)

func (*Chain) AssertL2TotalCoins

func (ch *Chain) AssertL2TotalCoins(coinType coin.Type, bal coin.Value)

func (*Chain) CallView

func (ch *Chain) CallView(msg isc.Message) (isc.CallArguments, error)

CallView calls a view entry point of a smart contract.

func (*Chain) CallViewAtState

func (ch *Chain) CallViewAtState(chainState state.State, msg isc.Message) (isc.CallArguments, error)

func (*Chain) CallViewByHname

func (ch *Chain) CallViewByHname(msg isc.Message) (isc.CallArguments, error)

func (*Chain) CallViewEx

func (ch *Chain) CallViewEx(c, ep string, params ...isc.CallArguments) (isc.CallArguments, error)

CallViewEx is a shortcut for CallView

func (*Chain) CallViewWithContract

func (ch *Chain) CallViewWithContract(contract any, msg isc.Message) (isc.CallArguments, error)

func (*Chain) CheckAccountLedger

func (ch *Chain) CheckAccountLedger()

CheckAccountLedger checks the integrity of the on-chain ledger. Sum of all accounts must be equal to total ftokens

func (*Chain) CheckChain

func (ch *Chain) CheckChain()

CheckChain checks fundamental integrity of the chain

func (*Chain) DeployEVMContract

func (ch *Chain) DeployEVMContract(creator *ecdsa.PrivateKey, abiJSON string, bytecode []byte, value *big.Int, args ...any) (common.Address, abi.ABI)

DeployEVMContract deploys an evm contract on the chain

func (*Chain) DepositAssetsToL2

func (ch *Chain) DepositAssetsToL2(assets *isc.Assets, user *cryptolib.KeyPair) error

DepositAssetsToL2 deposits ftokens on user's on-chain account, if user is nil, then chain admin is assigned

func (*Chain) DepositBaseTokensToL2

func (ch *Chain) DepositBaseTokensToL2(amount coin.Value, user *cryptolib.KeyPair) error

DepositBaseTokensToL2 deposits ftokens on user's on-chain account

func (*Chain) DumpAccounts

func (ch *Chain) DumpAccounts() string

DumpAccounts dumps all account balances into the human-readable string

func (*Chain) EVM

func (ch *Chain) EVM() *jsonrpc.EVMChain

func (*Chain) EstimateGas

func (ch *Chain) EstimateGas(req isc.Request) (result *vm.RequestResult)

func (*Chain) EstimateGasOffLedger

func (ch *Chain) EstimateGasOffLedger(req *CallParams, keyPair *cryptolib.KeyPair) (isc.CallArguments, *blocklog.RequestReceipt, error)

EstimateGasOffLedger executes the given on-ledger request without committing any changes in the ledger. It returns the amount of gas consumed. WARNING: Gas estimation is just an "estimate", there is no guarantees that the real call will bear the same cost, due to the turing-completeness of smart contracts

func (*Chain) EstimateGasOnLedger

func (ch *Chain) EstimateGasOnLedger(req *CallParams, keyPair *cryptolib.KeyPair) (isc.CallArguments, *blocklog.RequestReceipt, error)

EstimateGasOnLedger executes the given on-ledger request without committing any changes in the ledger. It returns the amount of gas consumed. WARNING: Gas estimation is just an "estimate", there is no guarantees that the real call will bear the same cost, due to the turing-completeness of smart contracts TODO only a senderAddr, not a keyPair should be necessary to estimate (it definitely shouldn't fallback to the chain originator)

func (*Chain) EstimateOnLedgerRequest

func (ch *Chain) EstimateOnLedgerRequest(dryRunRes *iotajsonrpc.DryRunTransactionBlockResponse) (result *vm.RequestResult, err error)

EstimateOnLedgerRequest estimates total Gas Fee, which is composed of L1 gas fee (user spent on creating onledger request) and L2 gas fee (wasp gas fee for proccesing request on L2)

func (*Chain) EthereumAccountByIndexWithL2Funds

func (ch *Chain) EthereumAccountByIndexWithL2Funds(i int, baseTokens ...coin.Value) (*ecdsa.PrivateKey, common.Address)

func (*Chain) EthereumAccountByIndexWithL2FundsRandDepositor

func (ch *Chain) EthereumAccountByIndexWithL2FundsRandDepositor(i int, baseTokens ...coin.Value) (*ecdsa.PrivateKey, common.Address)

func (*Chain) FindContract

func (ch *Chain) FindContract(scName string) (*root.ContractRecord, error)

FindContract is a view call to the 'root' smart contract on the chain. It returns blobCache record of the deployed smart contract with the given name

func (*Chain) GetAnchor

func (ch *Chain) GetAnchor(stateIndex uint32) (*isc.StateAnchor, error)

func (*Chain) GetBlockInfo

func (ch *Chain) GetBlockInfo(blockIndex ...uint32) (*blocklog.BlockInfo, error)

GetBlockInfo return BlockInfo for the particular block index in the chain

func (*Chain) GetBlockProof

func (ch *Chain) GetBlockProof(blockIndex uint32) (*blocklog.BlockInfo, *trie.MerkleProof, error)

GetBlockProof returns Merkle proof of the key in the state

func (*Chain) GetContractStateCommitment

func (ch *Chain) GetContractStateCommitment(hn isc.Hname) ([]byte, error)

GetContractStateCommitment returns commitment to the state of the specific contract, if possible

func (*Chain) GetErrorMessageFormat

func (ch *Chain) GetErrorMessageFormat(code isc.VMErrorCode) (string, error)

func (*Chain) GetEventsForBlock

func (ch *Chain) GetEventsForBlock(blockIndex uint32) ([]*isc.Event, error)

GetEventsForBlock calls the view in the 'blocklog' core smart contract to retrieve events for a given block.

func (*Chain) GetEventsForRequest

func (ch *Chain) GetEventsForRequest(reqID isc.RequestID) ([]*isc.Event, error)

GetEventsForRequest calls the view in the 'blocklog' core smart contract to retrieve events for a given request.

func (*Chain) GetGasFeePolicy

func (ch *Chain) GetGasFeePolicy() *gas.FeePolicy

func (*Chain) GetGasLimits

func (ch *Chain) GetGasLimits() *gas.Limits

func (*Chain) GetInfo

func (ch *Chain) GetInfo() (isc.ChainID, isc.AgentID, map[isc.Hname]*root.ContractRecord)

GetInfo returns information about the chain:

  • chainID
  • agentID of the chain admin
  • list of contracts deployed on the chain

func (*Chain) GetL1Commitment

func (ch *Chain) GetL1Commitment() *state.L1Commitment

GetL1Commitment returns state commitment taken from the anchor output

func (*Chain) GetL1RequestData

func (ch *Chain) GetL1RequestData(objectID iotago.ObjectID) isc.OnLedgerRequest

func (*Chain) GetL2FundsFromFaucet

func (ch *Chain) GetL2FundsFromFaucet(agentID isc.AgentID, baseTokens ...coin.Value)

func (*Chain) GetL2FundsFromFaucetWithDepositor

func (ch *Chain) GetL2FundsFromFaucetWithDepositor(agentID isc.AgentID, depositorSeed []byte, baseTokens ...coin.Value)

GetL2FundsFromFaucetWithDepositor is for multiple concurrent calls scenarios. This function uses given depositorSeed to generate the depositor to call TransferAllowanceTo()

func (*Chain) GetLatestAnchor

func (ch *Chain) GetLatestAnchor() *isc.StateAnchor

func (*Chain) GetLatestAnchorWithBalances

func (ch *Chain) GetLatestAnchorWithBalances() (*isc.StateAnchor, *isc.Assets)

func (*Chain) GetLatestBlockInfo

func (ch *Chain) GetLatestBlockInfo() *blocklog.BlockInfo

GetLatestBlockInfo return BlockInfo for the latest block in the chain

func (*Chain) GetLatestGasCoin

func (ch *Chain) GetLatestGasCoin() *coin.CoinWithRef

func (*Chain) GetMerkleProof

func (ch *Chain) GetMerkleProof(scHname isc.Hname, key []byte) *trie.MerkleProof

GetMerkleProof return the merkle proof of the key in the smart contract. Assumes Merkle model is used

func (*Chain) GetMerkleProofRaw

func (ch *Chain) GetMerkleProofRaw(key []byte) *trie.MerkleProof

GetMerkleProofRaw returns Merkle proof of the key in the state

func (*Chain) GetRequestIDsForBlock

func (ch *Chain) GetRequestIDsForBlock(blockIndex uint32) []isc.RequestID

GetRequestIDsForBlock returns the list of requestIDs settled in a particular block

func (*Chain) GetRequestReceipt

func (ch *Chain) GetRequestReceipt(reqID isc.RequestID) (*blocklog.RequestReceipt, bool)

GetRequestReceipt gets the log records for a particular request, the block index and request index in the block

func (*Chain) GetRequestReceiptsForBlock

func (ch *Chain) GetRequestReceiptsForBlock(blockIndex ...uint32) []*blocklog.RequestReceipt

GetRequestReceiptsForBlock returns all request log records for a particular block

func (*Chain) GetRequestReceiptsForBlockRange

func (ch *Chain) GetRequestReceiptsForBlockRange(fromBlockIndex, toBlockIndex uint32) []*blocklog.RequestReceipt

GetRequestReceiptsForBlockRange returns all request log records for range of blocks, inclusively. Upper bound is 'latest block' is set to 0

func (*Chain) GetRootCommitment

func (ch *Chain) GetRootCommitment() trie.Hash

GetRootCommitment returns the root commitment of the latest state index

func (*Chain) HasL2Object

func (ch *Chain) HasL2Object(agentID isc.AgentID, objID iotago.ObjectID) bool

func (*Chain) ID

func (ch *Chain) ID() isc.ChainID

func (*Chain) IsRequestProcessed

func (ch *Chain) IsRequestProcessed(reqID isc.RequestID) bool

IsRequestProcessed checks if the request is booked on the chain as processed

func (*Chain) L1L2Funds

func (ch *Chain) L1L2Funds(addr *cryptolib.Address) *L1L2CoinBalances

func (*Chain) L2Accounts

func (ch *Chain) L2Accounts() []isc.AgentID

L2Accounts returns all accounts on the chain with non-zero balances

func (*Chain) L2Assets

func (ch *Chain) L2Assets(agentID isc.AgentID) *isc.Assets

L2Assets return all tokens contained in the on-chain account controlled by the 'agentID'

func (*Chain) L2AssetsAtStateIndex

func (ch *Chain) L2AssetsAtStateIndex(agentID isc.AgentID, stateIndex uint32) *isc.Assets

func (*Chain) L2BaseTokens

func (ch *Chain) L2BaseTokens(agentID isc.AgentID) coin.Value

func (*Chain) L2BaseTokensAtStateIndex

func (ch *Chain) L2BaseTokensAtStateIndex(agentID isc.AgentID, stateIndex uint32) coin.Value

func (*Chain) L2CoinBalance

func (ch *Chain) L2CoinBalance(agentID isc.AgentID, coinType coin.Type) coin.Value

func (*Chain) L2CommonAccountAssets

func (ch *Chain) L2CommonAccountAssets() *isc.Assets

func (*Chain) L2CommonAccountBaseTokens

func (ch *Chain) L2CommonAccountBaseTokens() coin.Value

func (*Chain) L2CommonAccountNativeTokens

func (ch *Chain) L2CommonAccountNativeTokens(coinType coin.Type) coin.Value

func (*Chain) L2Ledger

func (ch *Chain) L2Ledger() map[string]*isc.Assets

func (*Chain) L2LedgerString

func (ch *Chain) L2LedgerString() string

func (*Chain) L2Objects

func (ch *Chain) L2Objects(agentID isc.AgentID) []isc.IotaObject

func (*Chain) L2TotalAssets

func (ch *Chain) L2TotalAssets() *isc.Assets

L2TotalAssets return total sum of ftokens contained in the on-chain accounts

func (*Chain) L2TotalBaseTokens

func (ch *Chain) L2TotalBaseTokens() coin.Value

L2TotalBaseTokens return total sum of base tokens in L2 (all accounts)

func (*Chain) LastReceipt

func (ch *Chain) LastReceipt() *isc.Receipt

LastReceipt returns the receipt for the latest request processed by the chain, will return nil if the last block is empty

func (*Chain) LatestBlock

func (ch *Chain) LatestBlock() state.Block

func (*Chain) LatestBlockIndex

func (ch *Chain) LatestBlockIndex() uint32

func (*Chain) LatestState

func (ch *Chain) LatestState() (state.State, error)

func (*Chain) Log

func (ch *Chain) Log() log.Logger

func (*Chain) MustDepositBaseTokensToL2

func (ch *Chain) MustDepositBaseTokensToL2(amount coin.Value, user *cryptolib.KeyPair)

func (*Chain) NewEthereumAccountWithL2Funds

func (ch *Chain) NewEthereumAccountWithL2Funds(baseTokens ...coin.Value) (*ecdsa.PrivateKey, common.Address)

func (*Chain) Nonce

func (ch *Chain) Nonce(agentID isc.AgentID) uint64

func (*Chain) PostEthereumTransaction

func (ch *Chain) PostEthereumTransaction(tx *types.Transaction) (isc.CallArguments, error)

func (*Chain) PostRequestOffLedger

func (ch *Chain) PostRequestOffLedger(req *CallParams, keyPair *cryptolib.KeyPair) (isc.CallArguments, error)

func (*Chain) PostRequestSync

func (ch *Chain) PostRequestSync(req *CallParams, keyPair *cryptolib.KeyPair) (isc.CallArguments, error)

PostRequestSync posts a request synchronously sent by the test program to the smart contract on the same or another chain.

Note that in a real network of Wasp nodes, posting a transaction is completely asynchronous, i.e. result of the call is not available to the originator of the post. Instead, the Solo environment makes PostRequestSync a synchronous call, making it possible to step-by-step debug the smart contract logic.

func (*Chain) PostRequestSyncExt

func (ch *Chain) PostRequestSyncExt(
	callParams *CallParams,
	keyPair *cryptolib.KeyPair,
) (
	req isc.OnLedgerRequest,
	l1Res *iotajsonrpc.IotaTransactionBlockResponse,
	vmRes *vm.RequestResult,
	anchorTransitionPTBRes *iotajsonrpc.IotaTransactionBlockResponse,
	err error,
)

func (*Chain) PostRequestSyncTx

func (ch *Chain) PostRequestSyncTx(req *CallParams, keyPair *cryptolib.KeyPair) (
	onLedregReq isc.OnLedgerRequest,
	l1Res *iotajsonrpc.IotaTransactionBlockResponse,
	vmRes *vm.RequestResult,
	anchorTransitionPTBRes *iotajsonrpc.IotaTransactionBlockResponse,
	err error,
)

func (*Chain) Processors

func (ch *Chain) Processors() *processors.Config

func (*Chain) ResolveVMError

func (ch *Chain) ResolveVMError(e *isc.UnresolvedVMError) *isc.VMError

func (*Chain) RunAllReceivedRequests

func (ch *Chain) RunAllReceivedRequests(maxRequestsInBlock int) int

func (*Chain) RunOffLedgerRequest

func (ch *Chain) RunOffLedgerRequest(r isc.Request) (
	*iotajsonrpc.IotaTransactionBlockResponse,
	isc.CallArguments,
	error,
)

func (*Chain) RunOffLedgerRequests

func (ch *Chain) RunOffLedgerRequests(reqs []isc.Request) (
	*iotajsonrpc.IotaTransactionBlockResponse,
	[]*vm.RequestResult,
)

func (*Chain) RunRequestBatch

func (ch *Chain) RunRequestBatch(maxRequestsInBlock int) (
	*iotajsonrpc.IotaTransactionBlockResponse,
	[]*vm.RequestResult,
)

RunRequestBatch runs a batch of requests pending to be processed

func (*Chain) RunRequestsSync

func (ch *Chain) RunRequestsSync(reqs []isc.Request) (
	*iotajsonrpc.IotaTransactionBlockResponse,
	[]*vm.RequestResult,
)

func (*Chain) SaveDB

func (ch *Chain) SaveDB(path string)

SaveDB saves a RocksDB database with the contents of the chain DB

func (*Chain) SendFromL1ToL2Account

func (ch *Chain) SendFromL1ToL2Account(toSend isc.CoinBalances, extraDeposit coin.Value, target isc.AgentID, user *cryptolib.KeyPair) error

SendFromL1ToL2Account sends ftokens from L1 address to the target account on L2 Sender pays the gas fee

func (*Chain) SendFromL1ToL2AccountBaseTokens

func (ch *Chain) SendFromL1ToL2AccountBaseTokens(toSend, extraDeposit coin.Value, target isc.AgentID, user *cryptolib.KeyPair) error

func (*Chain) SendFromL2ToL2Account

func (ch *Chain) SendFromL2ToL2Account(transfer *isc.Assets, target isc.AgentID, user *cryptolib.KeyPair) error

SendFromL2ToL2Account moves ftokens on L2 from user's account to the target

func (*Chain) SendFromL2ToL2AccountBaseTokens

func (ch *Chain) SendFromL2ToL2AccountBaseTokens(baseTokens coin.Value, target isc.AgentID, user *cryptolib.KeyPair) error

func (*Chain) SendFromL2ToL2AccountNativeTokens

func (ch *Chain) SendFromL2ToL2AccountNativeTokens(coinType coin.Type, target isc.AgentID, amount coin.Value, user *cryptolib.KeyPair) error

func (*Chain) SendRequest

SendRequest creates a request based on parameters and sigScheme, then send it to the anchor.

func (*Chain) SendRequestWithL1GasBudget

func (ch *Chain) SendRequestWithL1GasBudget(
	req *CallParams,
	keyPair *cryptolib.KeyPair,
	l1GasBudget uint64,
) (
	isc.OnLedgerRequest,
	*iotajsonrpc.IotaTransactionBlockResponse,
	error,
)

func (*Chain) SetGasFeePolicy

func (ch *Chain) SetGasFeePolicy(user *cryptolib.KeyPair, fp *gas.FeePolicy)

func (*Chain) SetGasLimits

func (ch *Chain) SetGasLimits(user *cryptolib.KeyPair, gl *gas.Limits)

func (*Chain) Store

func (ch *Chain) Store() indexedstore.IndexedStore

func (*Chain) String

func (ch *Chain) String() string

String is string representation for main parameters of the chain

func (*Chain) TransferAllowanceTo

func (ch *Chain) TransferAllowanceTo(
	allowance *isc.Assets,
	targetAccount isc.AgentID,
	wallet *cryptolib.KeyPair,
) error

TransferAllowanceTo sends an on-ledger request to transfer funds to target account (sends extra base tokens to the sender account to cover gas)

func (*Chain) Withdraw

func (ch *Chain) Withdraw(assets *isc.Assets, user *cryptolib.KeyPair) error

Withdraw sends assets from the L2 account to L1

type ChainSnapshot

type ChainSnapshot struct {
	Name                   string
	StateControllerKeyPair []byte
	ChainID                []byte
	OwnerPrivateKey        []byte
	ValidatorFeeTarget     []byte
	DB                     [][]byte
}

type Context

type Context interface {
	require.TestingT
	Name() string
	Cleanup(func())
	Helper()
	Logf(string, ...any)
	Fatalf(string, ...any)
}

type InitOptions

type InitOptions struct {
	L1Config          *L1Config
	Debug             bool
	PrintStackTrace   bool
	GasBurnLogEnabled bool
	Log               log.Logger
}

func DefaultInitOptions

func DefaultInitOptions() *InitOptions

type L1Config

type L1Config struct {
	IotaRPCURL    string
	IotaFaucetURL string
	ISCPackageID  iotago.PackageID
}

type L1L2CoinBalances

type L1L2CoinBalances struct {
	Address *cryptolib.Address
	L1      isc.CoinBalances
	L2      isc.CoinBalances
}

func (*L1L2CoinBalances) String

func (a *L1L2CoinBalances) String() string

type Snapshot

type Snapshot struct {
	// UtxoDB *utxodb.UtxoDBState
	Chains []*ChainSnapshot
}

type Solo

type Solo struct {
	// instance of the test
	T Context
	// contains filtered or unexported fields
}

Solo is a structure which contains global parameters of the test: one per test instance

func New

func New(t Context, initOptions ...*InitOptions) *Solo

New creates an instance of the Solo environment If solo is used for unit testing, 't' should be the *testing.T instance; otherwise it can be either nil or an instance created with NewTestContext.

func (*Solo) AdvanceClockBy

func (env *Solo) AdvanceClockBy(step time.Duration)

AdvanceClockBy advances logical clock by time step

func (*Solo) AssertL1BaseTokens

func (env *Solo) AssertL1BaseTokens(addr *cryptolib.Address, expected coin.Value)

func (*Solo) AssertL1Coins

func (env *Solo) AssertL1Coins(addr *cryptolib.Address, coinType coin.Type, expected coin.Value)

func (*Solo) Ctx

func (env *Solo) Ctx() context.Context

func (*Solo) GetChainByName

func (env *Solo) GetChainByName(name string) *Chain

func (*Solo) GetCoin

func (env *Solo) GetCoin(id *iotago.ObjectID) *coin.CoinWithRef

func (*Solo) GetFundsFromFaucet

func (env *Solo) GetFundsFromFaucet(target *cryptolib.Address)

func (*Solo) GlobalTime

func (env *Solo) GlobalTime() time.Time

GlobalTime return current logical clock time on the 'solo' instance

func (*Solo) ISCMoveClient

func (env *Solo) ISCMoveClient() *iscmoveclient.Client

func (*Solo) ISCPackageID

func (env *Solo) ISCPackageID() iotago.PackageID

func (*Solo) IotaFaucetURL

func (env *Solo) IotaFaucetURL() string

func (*Solo) IterateChainLatestStates

func (env *Solo) IterateChainLatestStates(
	prefix kv.Key,
	f func(chainID *isc.ChainID, k []byte, v []byte),
)

func (*Solo) IterateChainTrieDBs

func (env *Solo) IterateChainTrieDBs(
	f func(chainID *isc.ChainID, k []byte, v []byte),
)

func (*Solo) L1AllCoins

func (env *Solo) L1AllCoins(addr *cryptolib.Address) iotajsonrpc.Coins

func (*Solo) L1BaseTokenCoins

func (env *Solo) L1BaseTokenCoins(addr *cryptolib.Address) []*iotajsonrpc.Coin

func (*Solo) L1BaseTokens

func (env *Solo) L1BaseTokens(addr *cryptolib.Address) coin.Value

func (*Solo) L1Client

func (env *Solo) L1Client() clients.L1Client

func (*Solo) L1CoinBalance

func (env *Solo) L1CoinBalance(addr *cryptolib.Address, coinType coin.Type) coin.Value

func (*Solo) L1CoinBalances

func (env *Solo) L1CoinBalances(addr *cryptolib.Address) isc.CoinBalances

L1CoinBalances returns all ftokens of the address contained in the UTXODB ledger

func (*Solo) L1CoinInfo

func (env *Solo) L1CoinInfo(coinType coin.Type) *parameters.IotaCoinInfo

func (*Solo) L1Coins

func (env *Solo) L1Coins(addr *cryptolib.Address, coinType coin.Type) []*iotajsonrpc.Coin

func (*Solo) L1DeployCoinPackage

func (env *Solo) L1DeployCoinPackage(keyPair cryptolib.Signer) (
	packageID *iotago.PackageID,
	treasuryCap *iotago.ObjectRef,
)

func (*Solo) L1MintCoin

func (env *Solo) L1MintCoin(
	keyPair cryptolib.Signer,
	packageID *iotago.PackageID,
	moduleName iotago.Identifier,
	typeTag iotago.Identifier,
	treasuryCapObject *iotago.ObjectRef,
	mintAmount uint64,
) (coinRef *iotago.ObjectRef)

func (*Solo) L1MintObject

func (env *Solo) L1MintObject(owner *cryptolib.KeyPair) isc.IotaObject

func (*Solo) L1Params

func (env *Solo) L1Params() *parameters.L1Params

func (*Solo) LoadSnapshot

func (env *Solo) LoadSnapshot(fname string) *Snapshot

LoadSnapshot loads a snapshot previously saved with SaveSnapshot

func (*Solo) MustWithWaitForNextVersion

func (env *Solo) MustWithWaitForNextVersion(currentRef *iotago.ObjectRef, cb func()) *iotago.ObjectRef

MustWithWaitForNextVersion waits for an object to change its version and panics on timeouts This tries to make sure that an object meant to be used multiple times, does not get referenced twice with the same ref. Handle with care. Only use it on objects that are expected to be used again, like a GasCoin/Generic coin/Requests

func (*Solo) NewChain

func (env *Solo) NewChain(depositFundsForAdmin ...bool) *Chain

NewChain deploys a new default chain instance.

func (*Solo) NewChainExt

func (env *Solo) NewChainExt(
	chainOriginator *cryptolib.KeyPair,
	initCommonAccountBaseTokens coin.Value,
	name string,
	evmChainID uint16,
	blockKeepAmount int32,
) (*Chain, *isc.StateAnchor)

NewChainExt returns also origin and init transactions. Used for core testing

If 'chainOriginator' is nil, new one is generated and utxodb.FundsFromFaucetAmount (many) base tokens are loaded from the UTXODB faucet. ValidatorFeeTarget will be set to OriginatorAgentID, and can be changed after initialization. To deploy a chain instance the following steps are performed:

  • chain signature scheme (private key), chain address and chain ID are created
  • empty virtual state is initialized
  • origin transaction is created by the originator and added to the UTXODB
  • 'init' request transaction to the 'root' contract is created and added to UTXODB
  • backlog processing threads (goroutines) are started
  • VM processor cache is initialized
  • 'init' request is run by the VM. The 'root' contracts deploys the rest of the core contracts:

Upon return, the chain is fully functional to process requests

func (*Solo) NewKeyPair

func (env *Solo) NewKeyPair(seedOpt ...*cryptolib.Seed) (*cryptolib.KeyPair, *cryptolib.Address)

func (*Solo) NewKeyPairFromIndex

func (env *Solo) NewKeyPairFromIndex(index int) *cryptolib.KeyPair

func (*Solo) NewKeyPairWithFunds

func (env *Solo) NewKeyPairWithFunds(seed ...*cryptolib.Seed) (*cryptolib.KeyPair, *cryptolib.Address)

NewKeyPairWithFunds generates new ed25519 signature scheme and requests some tokens from the UTXODB faucet. The amount of tokens is equal to utxodb.FundsFromFaucetAmount (=1000Mi) base tokens Returns signature scheme interface and public key in binary form

func (*Solo) NewSeedFromIndex

func (env *Solo) NewSeedFromIndex(index int) *cryptolib.Seed

func (*Solo) NewSeedFromTestNameAndTimestamp

func (env *Solo) NewSeedFromTestNameAndTimestamp(testName string) *cryptolib.Seed

func (*Solo) Publisher

func (env *Solo) Publisher() *publisher.Publisher

func (*Solo) RestoreSnapshot

func (env *Solo) RestoreSnapshot(snapshot *Snapshot)

RestoreSnapshot restores the Solo environment from the given snapshot

func (*Solo) SaveSnapshot

func (env *Solo) SaveSnapshot(snapshot *Snapshot, fname string)

SaveSnapshot saves the given snapshot to a file

func (*Solo) SelectCoinsForGas

func (env *Solo) SelectCoinsForGas(
	addr *cryptolib.Address,
	targetPTB *iotago.ProgrammableTransaction,
	gasBudget uint64,
) []*iotago.ObjectRef

func (*Solo) TakeSnapshot

func (env *Solo) TakeSnapshot() *Snapshot

TakeSnapshot generates a snapshot of the Solo environment

func (*Solo) WaitForNewBalance

func (env *Solo) WaitForNewBalance(address *cryptolib.Address, startBalance coin.Value)

func (*Solo) WithWaitForNextVersion

func (env *Solo) WithWaitForNextVersion(currentRef *iotago.ObjectRef, cb func()) (*iotago.ObjectRef, error)

WithWaitForNextVersion waits for an object to change its version. This tries to make sure that an object meant to be used multiple times, does not get referenced twice with the same ref. Handle with care. Only use it on objects that are expected to be used again, like a GasCoin/Generic coin/Requests

Directories

Path Synopsis
Package solobench provides tools to benchmark contracts running under solo
Package solobench provides tools to benchmark contracts running under solo

Jump to

Keyboard shortcuts

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