diff --git a/clients/apiclient/CorecontractsApi.md b/clients/apiclient/CorecontractsApi.md index 91129b0716..036d8e77b5 100644 --- a/clients/apiclient/CorecontractsApi.md +++ b/clients/apiclient/CorecontractsApi.md @@ -965,7 +965,7 @@ No authorization required # **governanceGetChainInfo** > GovChainInfoResponse governanceGetChainInfo() -If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. +If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. ### Example diff --git a/clients/apiclient/api/openapi.yaml b/clients/apiclient/api/openapi.yaml index b9e1724231..a4cd120870 100644 --- a/clients/apiclient/api/openapi.yaml +++ b/clients/apiclient/api/openapi.yaml @@ -823,7 +823,7 @@ paths: /v1/chain/core/governance/chaininfo: get: description: "If you are using the common API functions, you most likely rather\ - \ want to use '/v1/chains/:chainID' to get information about a chain." + \ want to use '/v1/chain' to get information about a chain." operationId: governanceGetChainInfo parameters: - description: Block index or trie root diff --git a/clients/apiclient/api_corecontracts.go b/clients/apiclient/api_corecontracts.go index 67d7fae555..b4558211c0 100644 --- a/clients/apiclient/api_corecontracts.go +++ b/clients/apiclient/api_corecontracts.go @@ -2096,7 +2096,7 @@ func (r ApiGovernanceGetChainInfoRequest) Execute() (*GovChainInfoResponse, *htt /* GovernanceGetChainInfo Get the chain info -If you are using the common API functions, you most likely rather want to use '/v1/chains/:chainID' to get information about a chain. +If you are using the common API functions, you most likely rather want to use '/v1/chain' to get information about a chain. @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @return ApiGovernanceGetChainInfoRequest diff --git a/clients/apiclient/apis/CorecontractsApi.ts b/clients/apiclient/apis/CorecontractsApi.ts index 018b6968e5..f594a45db2 100644 --- a/clients/apiclient/apis/CorecontractsApi.ts +++ b/clients/apiclient/apis/CorecontractsApi.ts @@ -634,7 +634,7 @@ export class CorecontractsApiRequestFactory extends BaseAPIRequestFactory { } /** - * If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. + * If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. * Get the chain info * @param block Block index or trie root */ diff --git a/clients/apiclient/types/ObjectParamAPI.ts b/clients/apiclient/types/ObjectParamAPI.ts index b7aecad5a0..1094847ff6 100644 --- a/clients/apiclient/types/ObjectParamAPI.ts +++ b/clients/apiclient/types/ObjectParamAPI.ts @@ -1171,7 +1171,7 @@ export class ObjectCorecontractsApi { } /** - * If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. + * If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. * Get the chain info * @param param the request object */ @@ -1180,7 +1180,7 @@ export class ObjectCorecontractsApi { } /** - * If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. + * If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. * Get the chain info * @param param the request object */ diff --git a/clients/apiclient/types/ObservableAPI.ts b/clients/apiclient/types/ObservableAPI.ts index ae127cefd9..41fdc706aa 100644 --- a/clients/apiclient/types/ObservableAPI.ts +++ b/clients/apiclient/types/ObservableAPI.ts @@ -1326,7 +1326,7 @@ export class ObservableCorecontractsApi { } /** - * If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. + * If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. * Get the chain info * @param [block] Block index or trie root */ @@ -1350,7 +1350,7 @@ export class ObservableCorecontractsApi { } /** - * If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. + * If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. * Get the chain info * @param [block] Block index or trie root */ diff --git a/clients/apiclient/types/PromiseAPI.ts b/clients/apiclient/types/PromiseAPI.ts index d1919f31e3..61cec94b4a 100644 --- a/clients/apiclient/types/PromiseAPI.ts +++ b/clients/apiclient/types/PromiseAPI.ts @@ -830,7 +830,7 @@ export class PromiseCorecontractsApi { } /** - * If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. + * If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. * Get the chain info * @param [block] Block index or trie root */ @@ -840,7 +840,7 @@ export class PromiseCorecontractsApi { } /** - * If you are using the common API functions, you most likely rather want to use \'/v1/chains/:chainID\' to get information about a chain. + * If you are using the common API functions, you most likely rather want to use \'/v1/chain\' to get information about a chain. * Get the chain info * @param [block] Block index or trie root */ diff --git a/clients/iota-go/hw_ledger/ledger-go/ledger_test.go b/clients/iota-go/hw_ledger/ledger-go/ledger_test.go index 82060df119..8fe25a3aad 100644 --- a/clients/iota-go/hw_ledger/ledger-go/ledger_test.go +++ b/clients/iota-go/hw_ledger/ledger-go/ledger_test.go @@ -111,7 +111,6 @@ func Test_BasicExchange(t *testing.T) { for i := 0; i < 10; i++ { response, err := ledger.Exchange(message) - if err != nil { fmt.Printf("iteration %d\n", i) t.Fatalf("Error: %s", err.Error()) diff --git a/clients/iota-go/hw_ledger/ledger_test.go b/clients/iota-go/hw_ledger/ledger_test.go index 225c8e3cae..0015c1e73c 100644 --- a/clients/iota-go/hw_ledger/ledger_test.go +++ b/clients/iota-go/hw_ledger/ledger_test.go @@ -78,7 +78,6 @@ func TestDeployChain(t *testing.T) { require.NoError(t, err) fmt.Println(result) - } func TestSign(t *testing.T) { diff --git a/clients/iota-go/iotaclient/client.go b/clients/iota-go/iotaclient/client.go index 026de0aa77..f319136137 100644 --- a/clients/iota-go/iotaclient/client.go +++ b/clients/iota-go/iotaclient/client.go @@ -22,11 +22,13 @@ type WaitParams struct { DelayBetweenAttempts time.Duration } -var WaitForEffectsDisabled *WaitParams = nil -var WaitForEffectsEnabled *WaitParams = &WaitParams{ - Attempts: 5, - DelayBetweenAttempts: 2 * time.Second, -} +var ( + WaitForEffectsDisabled *WaitParams = nil + WaitForEffectsEnabled *WaitParams = &WaitParams{ + Attempts: 5, + DelayBetweenAttempts: 2 * time.Second, + } +) type transport interface { Call(ctx context.Context, v any, method iotaconn.JsonRPCMethod, args ...any) error diff --git a/clients/iota-go/iotaconn/websocket.go b/clients/iota-go/iotaconn/websocket.go index f54d8f92cd..c61d58611c 100644 --- a/clients/iota-go/iotaconn/websocket.go +++ b/clients/iota-go/iotaconn/websocket.go @@ -34,7 +34,6 @@ func NewWebsocketClient( url string, log log.Logger, ) (*WebsocketClient, error) { - c := &WebsocketClient{ url: url, writeQueue: make(chan *jsonrpcMessage), diff --git a/clients/iota-go/iotago/iotatest/test_values.go b/clients/iota-go/iotago/iotatest/test_values.go index 71c9317d08..e9a9d04163 100644 --- a/clients/iota-go/iotago/iotatest/test_values.go +++ b/clients/iota-go/iotago/iotatest/test_values.go @@ -35,8 +35,10 @@ func testTransactionData(packageAddr, senderAddr *iotago.Address) *iotago.Transa return &tx } -var TestAddress = iotago.AddressFromArray([iotago.AddressLen]byte(testval.TestBytes(iotago.AddressLen))) -var TestDigest = iotago.MustNewDigest(testval.TestHex(iotago.DigestSize)) +var ( + TestAddress = iotago.AddressFromArray([iotago.AddressLen]byte(testval.TestBytes(iotago.AddressLen))) + TestDigest = iotago.MustNewDigest(testval.TestHex(iotago.DigestSize)) +) var TestObjectRef = &iotago.ObjectRef{ ObjectID: TestAddress, diff --git a/clients/multiclient/reqstatus.go b/clients/multiclient/reqstatus.go index 361cc0c9c8..4515bd78ea 100644 --- a/clients/multiclient/reqstatus.go +++ b/clients/multiclient/reqstatus.go @@ -14,7 +14,7 @@ import ( ) // WaitUntilRequestProcessed blocks until the request has been processed by all nodes -func (m *MultiClient) WaitUntilRequestProcessed(ctx context.Context, chainID isc.ChainID, reqID isc.RequestID, waitForL1Confirmation bool, timeout time.Duration) (*apiclient.ReceiptResponse, error) { +func (m *MultiClient) WaitUntilRequestProcessed(ctx context.Context, reqID isc.RequestID, waitForL1Confirmation bool, timeout time.Duration) (*apiclient.ReceiptResponse, error) { oldTimeout := m.Timeout defer func() { m.Timeout = oldTimeout }() @@ -37,8 +37,8 @@ func (m *MultiClient) WaitUntilRequestProcessed(ctx context.Context, chainID isc // WaitUntilRequestProcessedSuccessfully is similar to WaitUntilRequestProcessed, // but also checks the receipt and return an error if the request was processed with an error -func (m *MultiClient) WaitUntilRequestProcessedSuccessfully(ctx context.Context, chainID isc.ChainID, reqID isc.RequestID, waitForL1Confirmation bool, timeout time.Duration) (*apiclient.ReceiptResponse, error) { - receipt, err := m.WaitUntilRequestProcessed(ctx, chainID, reqID, waitForL1Confirmation, timeout) +func (m *MultiClient) WaitUntilRequestProcessedSuccessfully(ctx context.Context, reqID isc.RequestID, waitForL1Confirmation bool, timeout time.Duration) (*apiclient.ReceiptResponse, error) { + receipt, err := m.WaitUntilRequestProcessed(ctx, reqID, waitForL1Confirmation, timeout) if err != nil { return receipt, err } @@ -50,9 +50,9 @@ func (m *MultiClient) WaitUntilRequestProcessedSuccessfully(ctx context.Context, // WaitUntilEVMRequestProcessedSuccessfully is similar to WaitUntilRequestProcessed, // but also checks the receipt and return an error if the request was processed with an error -func (m *MultiClient) WaitUntilEVMRequestProcessedSuccessfully(ctx context.Context, chainID isc.ChainID, txHash common.Hash, waitForL1Confirmation bool, timeout time.Duration) (*apiclient.ReceiptResponse, error) { +func (m *MultiClient) WaitUntilEVMRequestProcessedSuccessfully(ctx context.Context, txHash common.Hash, waitForL1Confirmation bool, timeout time.Duration) (*apiclient.ReceiptResponse, error) { requestID := isc.RequestIDFromEVMTxHash(txHash) - receipt, err := m.WaitUntilRequestProcessed(ctx, chainID, requestID, waitForL1Confirmation, timeout) + receipt, err := m.WaitUntilRequestProcessed(ctx, requestID, waitForL1Confirmation, timeout) if err != nil { return receipt, err } @@ -64,7 +64,7 @@ func (m *MultiClient) WaitUntilEVMRequestProcessedSuccessfully(ctx context.Conte // WaitUntilAllRequestsProcessed blocks until all requests in the given transaction have been processed // by all nodes -func (m *MultiClient) WaitUntilAllRequestsProcessed(ctx context.Context, chainID isc.ChainID, tx *iotajsonrpc.IotaTransactionBlockResponse, waitForL1Confirmation bool, timeout time.Duration) ([]*apiclient.ReceiptResponse, error) { +func (m *MultiClient) WaitUntilAllRequestsProcessed(ctx context.Context, tx *iotajsonrpc.IotaTransactionBlockResponse, waitForL1Confirmation bool, timeout time.Duration) ([]*apiclient.ReceiptResponse, error) { oldTimeout := m.Timeout defer func() { m.Timeout = oldTimeout }() @@ -82,8 +82,8 @@ func (m *MultiClient) WaitUntilAllRequestsProcessed(ctx context.Context, chainID // WaitUntilAllRequestsProcessedSuccessfully is similar to WaitUntilAllRequestsProcessed // but also checks the receipts and return an error if any of the requests was processed with an error -func (m *MultiClient) WaitUntilAllRequestsProcessedSuccessfully(ctx context.Context, chainID isc.ChainID, tx *iotajsonrpc.IotaTransactionBlockResponse, waitForL1Confirmation bool, timeout time.Duration) ([]*apiclient.ReceiptResponse, error) { - receipts, err := m.WaitUntilAllRequestsProcessed(ctx, chainID, tx, waitForL1Confirmation, timeout) +func (m *MultiClient) WaitUntilAllRequestsProcessedSuccessfully(ctx context.Context, tx *iotajsonrpc.IotaTransactionBlockResponse, waitForL1Confirmation bool, timeout time.Duration) ([]*apiclient.ReceiptResponse, error) { + receipts, err := m.WaitUntilAllRequestsProcessed(ctx, tx, waitForL1Confirmation, timeout) if err != nil { return receipts, err } diff --git a/components/app/app.go b/components/app/app.go index ccdb4f00f0..a1f903ebd3 100644 --- a/components/app/app.go +++ b/components/app/app.go @@ -8,7 +8,7 @@ import ( "github.com/iotaledger/hive.go/app/components/profiling" "github.com/iotaledger/hive.go/app/components/shutdown" "github.com/iotaledger/wasp/v2/components/cache" - "github.com/iotaledger/wasp/v2/components/chains" + "github.com/iotaledger/wasp/v2/components/chainrunner" "github.com/iotaledger/wasp/v2/components/database" "github.com/iotaledger/wasp/v2/components/dkg" "github.com/iotaledger/wasp/v2/components/logger" @@ -48,7 +48,7 @@ func App() *app.App { peering.Component, dkg.Component, processors.Component, - chains.Component, + chainrunner.Component, publisher.Component, webapi.Component, profiling.Component, diff --git a/components/chains/component.go b/components/chainrunner/component.go similarity index 72% rename from components/chains/component.go rename to components/chainrunner/component.go index 5e44af5bf8..ee9f83b206 100644 --- a/components/chains/component.go +++ b/components/chainrunner/component.go @@ -1,4 +1,4 @@ -package chains +package chainrunner import ( "context" @@ -13,7 +13,7 @@ import ( "github.com/iotaledger/wasp/v2/packages/chain" "github.com/iotaledger/wasp/v2/packages/chain/cmtlog" "github.com/iotaledger/wasp/v2/packages/chain/mempool" - "github.com/iotaledger/wasp/v2/packages/chains" + chainrunner "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/daemon" "github.com/iotaledger/wasp/v2/packages/database" "github.com/iotaledger/wasp/v2/packages/metrics" @@ -45,7 +45,7 @@ type dependencies struct { dig.In ShutdownHandler *hiveshutdown.ShutdownHandler - Chains *chains.Chains + Chains *chainrunner.ChainRunner ReadOnlyDBPath string } @@ -57,16 +57,16 @@ func initConfigParams(c *dig.Container) error { if err := c.Provide(func() cfgResult { return cfgResult{ - APICacheTTL: ParamsChains.APICacheTTL, + APICacheTTL: ParamsChainRunner.APICacheTTL, } }); err != nil { Component.LogPanic(err.Error()) } - chain.RedeliveryPeriod = ParamsChains.RedeliveryPeriod - chain.PrintStatusPeriod = ParamsChains.PrintStatusPeriod - chain.ConsensusInstsInAdvance = ParamsChains.ConsensusInstsInAdvance - chain.AwaitReceiptCleanupEvery = ParamsChains.AwaitReceiptCleanupEvery + chain.RedeliveryPeriod = ParamsChainRunner.RedeliveryPeriod + chain.PrintStatusPeriod = ParamsChainRunner.PrintStatusPeriod + chain.ConsensusInstsInAdvance = ParamsChainRunner.ConsensusInstsInAdvance + chain.AwaitReceiptCleanupEvery = ParamsChainRunner.AwaitReceiptCleanupEvery return nil } @@ -88,24 +88,24 @@ func provide(c *dig.Container) error { ChainMetricsProvider *metrics.ChainMetricsProvider } - type chainsResult struct { + type chainRunnerResult struct { dig.Out - Chains *chains.Chains + Runner *chainrunner.ChainRunner } - if err := c.Provide(func(deps chainsDeps) chainsResult { - return chainsResult{ - Chains: chains.New( + if err := c.Provide(func(deps chainsDeps) chainRunnerResult { + return chainRunnerResult{ + Runner: chainrunner.New( Component.Logger, deps.NodeConnection, deps.ProcessorsConfig, ParamsValidator.Address, - ParamsChains.DeriveAliasOutputByQuorum, - ParamsChains.PipeliningLimit, - ParamsChains.PostponeRecoveryMilestones, - ParamsChains.ConsensusDelay, - ParamsChains.RecoveryTimeout, + ParamsChainRunner.DeriveAliasOutputByQuorum, + ParamsChainRunner.PipeliningLimit, + ParamsChainRunner.PostponeRecoveryMilestones, + ParamsChainRunner.ConsensusDelay, + ParamsChainRunner.RecoveryTimeout, deps.NetworkProvider, deps.TrustedNetworkManager, deps.ChainStateDatabaseManager.ChainStateKVStore, @@ -122,7 +122,7 @@ func provide(c *dig.Container) error { ParamsStateManager.StateManagerTimerTickPeriod, ParamsStateManager.PruningMinStatesToKeep, ParamsStateManager.PruningMaxStatesToDelete, - ParamsSnapshotManager.SnapshotsToLoad, + ParamsSnapshotManager.SnapshotToLoad, ParamsSnapshotManager.Period, ParamsSnapshotManager.Delay, ParamsSnapshotManager.LocalPath, @@ -133,16 +133,16 @@ func provide(c *dig.Container) error { deps.ConsensusStateRegistry, deps.ChainListener, mempool.Settings{ - TTL: ParamsChains.MempoolTTL, - OnLedgerRefreshMinInterval: ParamsChains.MempoolOnLedgerRefreshMinInterval, - MaxOffledgerInPool: ParamsChains.MempoolMaxOffledgerInPool, - MaxOnledgerInPool: ParamsChains.MempoolMaxOnledgerInPool, - MaxTimedInPool: ParamsChains.MempoolMaxTimedInPool, - MaxOnledgerToPropose: ParamsChains.MempoolMaxOnledgerToPropose, - MaxOffledgerToPropose: ParamsChains.MempoolMaxOffledgerToPropose, - MaxOffledgerPerAccount: ParamsChains.MempoolMaxOffledgerPerAccount, + TTL: ParamsChainRunner.MempoolTTL, + OnLedgerRefreshMinInterval: ParamsChainRunner.MempoolOnLedgerRefreshMinInterval, + MaxOffledgerInPool: ParamsChainRunner.MempoolMaxOffledgerInPool, + MaxOnledgerInPool: ParamsChainRunner.MempoolMaxOnledgerInPool, + MaxTimedInPool: ParamsChainRunner.MempoolMaxTimedInPool, + MaxOnledgerToPropose: ParamsChainRunner.MempoolMaxOnledgerToPropose, + MaxOffledgerToPropose: ParamsChainRunner.MempoolMaxOffledgerToPropose, + MaxOffledgerPerAccount: ParamsChainRunner.MempoolMaxOffledgerPerAccount, }, - ParamsChains.BroadcastInterval, + ParamsChainRunner.BroadcastInterval, shutdown.NewCoordinator("chains", Component.NewChildLogger("Shutdown")), deps.ChainMetricsProvider, ), diff --git a/components/chains/params.go b/components/chainrunner/params.go similarity index 85% rename from components/chains/params.go rename to components/chainrunner/params.go index 88053a0b52..8ffd06d6f4 100644 --- a/components/chains/params.go +++ b/components/chainrunner/params.go @@ -1,7 +1,7 @@ -// Package chains provides functionality for managing IOTA Smart Contract chains, +// Package chainrunner provides functionality for managing IOTA Smart Contract chain runner, // including chain configuration parameters, write-ahead logging, validator settings, // state management, and snapshot capabilities. -package chains +package chainrunner import ( "time" @@ -9,7 +9,7 @@ import ( "github.com/iotaledger/hive.go/app" ) -type ParametersChains struct { +type ParametersChainRunner struct { BroadcastUpToNPeers int `default:"2" usage:"number of peers an offledger request is broadcasted to"` BroadcastInterval time.Duration `default:"0s" usage:"time between re-broadcast of offledger requests; 0 value means that re-broadcasting is disabled"` APICacheTTL time.Duration `default:"300s" usage:"time to keep processed offledger requests in api cache"` @@ -57,15 +57,15 @@ type ParametersStateManager struct { } type ParametersSnapshotManager struct { - SnapshotsToLoad []string `default:"" usage:"list of snapshots to load; can be either single block hash of a snapshot (if a single chain has to be configured) or list of ':' to configure many chains"` - Period uint32 `default:"0" usage:"how often state snapshots should be made: 1000 meaning \"every 1000th state\", 0 meaning \"making snapshots is disabled\""` - Delay uint32 `default:"20" usage:"how many states should pass before snapshot is produced"` - LocalPath string `default:"waspdb/snap" usage:"the path to the snapshots folder in this node's disk"` - NetworkPaths []string `default:"" usage:"the list of paths to the remote (http(s)) snapshot locations; each of listed locations must contain 'INDEX' file with list of snapshot files"` + SnapshotToLoad string `default:"" usage:"block hash of a snapshot to load"` + Period uint32 `default:"0" usage:"how often state snapshots should be made: 1000 meaning \"every 1000th state\", 0 meaning \"making snapshots is disabled\""` + Delay uint32 `default:"20" usage:"how many states should pass before snapshot is produced"` + LocalPath string `default:"waspdb/snap" usage:"the path to the snapshots folder in this node's disk"` + NetworkPaths []string `default:"" usage:"the list of paths to the remote (http(s)) snapshot locations; each of listed locations must contain 'INDEX' file with list of snapshot files"` } var ( - ParamsChains = &ParametersChains{} + ParamsChainRunner = &ParametersChainRunner{} ParamsWAL = &ParametersWAL{} ParamsValidator = &ParametersValidator{} ParamsStateManager = &ParametersStateManager{} @@ -74,7 +74,7 @@ var ( var params = &app.ComponentParams{ Params: map[string]any{ - "chains": ParamsChains, + "chain": ParamsChainRunner, "wal": ParamsWAL, "validator": ParamsValidator, "stateManager": ParamsStateManager, diff --git a/components/nodeconn/component.go b/components/nodeconn/component.go index ab073cd4ed..ad1525b5e8 100644 --- a/components/nodeconn/component.go +++ b/components/nodeconn/component.go @@ -13,7 +13,7 @@ import ( "github.com/iotaledger/hive.go/app/shutdown" "github.com/iotaledger/wasp/v2/clients/iota-go/iotago" - "github.com/iotaledger/wasp/v2/components/chains" + "github.com/iotaledger/wasp/v2/components/chainrunner" "github.com/iotaledger/wasp/v2/packages/chain" "github.com/iotaledger/wasp/v2/packages/daemon" "github.com/iotaledger/wasp/v2/packages/nodeconn" @@ -54,7 +54,7 @@ func provide(c *dig.Container) error { nodeConnection, err := nodeconn.New( Component.Daemon().ContextStopped(), *address, - chains.ParamsChains.MempoolMaxOnledgerInPool, + chainrunner.ParamsChainRunner.MempoolMaxOnledgerInPool, ParamsL1.WebsocketURL, ParamsL1.HTTPURL, Component.NewChildLogger("nc"), diff --git a/components/webapi/component.go b/components/webapi/component.go index 8c7522c0e0..8934c0e69f 100644 --- a/components/webapi/component.go +++ b/components/webapi/component.go @@ -23,7 +23,7 @@ import ( "github.com/iotaledger/hive.go/web/websockethub" "github.com/iotaledger/wasp/v2/packages/authentication" "github.com/iotaledger/wasp/v2/packages/chain" - "github.com/iotaledger/wasp/v2/packages/chains" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/daemon" "github.com/iotaledger/wasp/v2/packages/dkg" "github.com/iotaledger/wasp/v2/packages/evm/jsonrpc" @@ -114,8 +114,8 @@ func NewEcho(params *ParametersWebAPI, metrics *metrics.ChainMetricsProvider, lo // publish metrics to prometheus component (that exposes a separate http server on another port) e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - if strings.HasPrefix(c.Path(), "/chains/") { - // ignore metrics for all requests not related to "chains/"" + if strings.HasPrefix(c.Path(), "/chain/") { + // ignore metrics for all requests not related to "chain/"" return next(c) } start := time.Now() @@ -218,7 +218,7 @@ func provide(c *dig.Container) error { AppConfig *configuration.Configuration `name:"appConfig"` ShutdownHandler *shutdown.ShutdownHandler APICacheTTL time.Duration `name:"apiCacheTTL"` - Chains *chains.Chains + ChainRunner *chainrunner.ChainRunner ChainMetricsProvider *metrics.ChainMetricsProvider ChainRecordRegistryProvider registry.ChainRecordRegistryProvider DKShareRegistryProvider registry.DKShareRegistryProvider @@ -279,9 +279,7 @@ func provide(c *dig.Container) error { deps.ChainRecordRegistryProvider, deps.DKShareRegistryProvider, deps.NodeIdentityProvider, - func() *chains.Chains { - return deps.Chains - }, + deps.ChainRunner, func() *dkg.Node { return deps.Node }, diff --git a/components/webapi/webapi_test.go b/components/webapi/webapi_test.go index 700a0a48e4..93801b1d3d 100644 --- a/components/webapi/webapi_test.go +++ b/components/webapi/webapi_test.go @@ -46,8 +46,6 @@ func TestInternalServerErrors(t *testing.T) { log.NewLogger(log.WithHandler(logger)), ) - time.Sleep(5 * time.Second) - // Add an endpoint that just panics with "foobar" and start the server exceptionText := "foobar" e.GET("/test", func(c echo.Context) error { panic(exceptionText) }) @@ -57,6 +55,8 @@ func TestInternalServerErrors(t *testing.T) { }() defer e.Shutdown(context.Background()) + time.Sleep(5 * time.Second) + // query the endpoint req, err := http.NewRequest(http.MethodGet, "http://localhost:9999/test", http.NoBody) require.NoError(t, err) diff --git a/config.json b/config.json index 9ffb1be4fc..e4b95688a8 100644 --- a/config.json +++ b/config.json @@ -64,7 +64,7 @@ "peeringURL": "0.0.0.0:4000", "port": 4000 }, - "chains": { + "chain": { "broadcastUpToNPeers": 2, "broadcastInterval": "5s", "apiCacheTTL": "5m", diff --git a/config_defaults.json b/config_defaults.json index 407366db95..74c6978b4a 100755 --- a/config_defaults.json +++ b/config_defaults.json @@ -64,7 +64,7 @@ "peeringURL": "0.0.0.0:4000", "port": 4000 }, - "chains": { + "chain": { "broadcastUpToNPeers": 2, "broadcastInterval": "0s", "apiCacheTTL": "5m", @@ -88,7 +88,7 @@ "mempoolOnLedgerRefreshMinInterval": "10m" }, "snapshots": { - "snapshotsToLoad": [], + "snapshotToLoad": "", "period": 0, "delay": 20, "localPath": "waspdb/snap", diff --git a/documentation/docs/configuration.md b/documentation/docs/configuration.md index b01be0101a..772cff4d43 100755 --- a/documentation/docs/configuration.md +++ b/documentation/docs/configuration.md @@ -277,7 +277,7 @@ Example: } ``` -## 9. Chains +## 9. Chain | Name | Description | Type | Default value | | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------- | @@ -307,7 +307,7 @@ Example: ```json { - "chains": { + "chain": { "broadcastUpToNPeers": 2, "broadcastInterval": "0s", "apiCacheTTL": "5m", @@ -337,7 +337,7 @@ Example: | Name | Description | Type | Default value | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------------- | -| snapshotsToLoad | List of snapshots to load; can be either single block hash of a snapshot (if a single chain has to be configured) or list of ':' to configure many chains | array | | +| snapshotToLoad | Single block hash of a snapshot | string | | | period | How often state snapshots should be made: 1000 meaning "every 1000th state", 0 meaning "making snapshots is disabled" | uint | 0 | | delay | How many states should pass before snapshot is produced | uint | 20 | | localPath | The path to the snapshots folder in this node's disk | string | "waspdb/snap" | @@ -348,7 +348,7 @@ Example: ```json { "snapshots": { - "snapshotsToLoad": [], + "snapshotToLoad": "", "period": 0, "delay": 20, "localPath": "waspdb/snap", diff --git a/packages/chain/chain.go b/packages/chain/chain.go index 7227f39539..dfa065e951 100644 --- a/packages/chain/chain.go +++ b/packages/chain/chain.go @@ -44,15 +44,14 @@ type ChainNodeConn interface { // confirmed or an error is detected, or the ctx is canceled. PublishTX( ctx context.Context, - chainID isc.ChainID, tx iotasigner.SignedTransaction, callback TxPostHandler, ) error // RefreshOnLedgerRequests synchronously fetches all owned requests by the // previously attached chain, and calls recvRequest for each one. - RefreshOnLedgerRequests(ctx context.Context, chainID isc.ChainID) + RefreshOnLedgerRequests(ctx context.Context) - GetGasCoinRef(ctx context.Context, chainID isc.ChainID) (*coin.CoinWithRef, error) + GetGasCoinRef(ctx context.Context) (*coin.CoinWithRef, error) } type NodeConnection interface { diff --git a/packages/chain/chain_listener.go b/packages/chain/chain_listener.go index 48c92ea64b..3248b601d4 100644 --- a/packages/chain/chain_listener.go +++ b/packages/chain/chain_listener.go @@ -6,7 +6,6 @@ package chain import ( "github.com/iotaledger/wasp/v2/packages/chain/mempool" "github.com/iotaledger/wasp/v2/packages/cryptolib" - "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/kv" "github.com/iotaledger/wasp/v2/packages/state" ) @@ -16,8 +15,8 @@ import ( // All the function MUST NOT BLOCK. type ChainListener interface { mempool.ChainListener - AccessNodesUpdated(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) - ServerNodesUpdated(chainID isc.ChainID, serverNodes []*cryptolib.PublicKey) + AccessNodesUpdated(accessNodes []*cryptolib.PublicKey) + ServerNodesUpdated(serverNodes []*cryptolib.PublicKey) } //////////////////////////////////////////////////////////////////////////////// @@ -31,7 +30,7 @@ func NewEmptyChainListener() ChainListener { return &emptyChainListener{} } -func (ecl *emptyChainListener) BlockApplied(chainID isc.ChainID, block state.Block, latestState kv.KVStoreReader) { +func (ecl *emptyChainListener) BlockApplied(block state.Block, latestState kv.KVStoreReader) { } -func (ecl *emptyChainListener) AccessNodesUpdated(isc.ChainID, []*cryptolib.PublicKey) {} -func (ecl *emptyChainListener) ServerNodesUpdated(isc.ChainID, []*cryptolib.PublicKey) {} +func (ecl *emptyChainListener) AccessNodesUpdated([]*cryptolib.PublicKey) {} +func (ecl *emptyChainListener) ServerNodesUpdated([]*cryptolib.PublicKey) {} diff --git a/packages/chain/chainmanager/chain_manager.go b/packages/chain/chainmanager/chain_manager.go index 3b529aff63..734b3ba997 100644 --- a/packages/chain/chainmanager/chain_manager.go +++ b/packages/chain/chainmanager/chain_manager.go @@ -259,7 +259,7 @@ func New( needPublishTX: shrinkingmap.New[hashing.HashValue, *NeedPublishTX](), needPublishCB: needPublishCB, dkShareRegistryProvider: dkShareRegistryProvider, - varAccessNodeState: NewVarAccessNodeState(chainID, log.NewChildLogger("VAS")), + varAccessNodeState: NewVarAccessNodeState(log.NewChildLogger("VAS")), me: me, nodeIDFromPubKey: nodeIDFromPubKey, deriveAOByQuorum: deriveAOByQuorum, diff --git a/packages/chain/chainmanager/var_access_nodes_state.go b/packages/chain/chainmanager/var_access_nodes_state.go index 10bef34a78..1e5e865c90 100644 --- a/packages/chain/chainmanager/var_access_nodes_state.go +++ b/packages/chain/chainmanager/var_access_nodes_state.go @@ -24,16 +24,14 @@ type VarAccessNodeState interface { } type varAccessNodeStateImpl struct { - chainID isc.ChainID - tipAO *isc.StateAnchor - log log.Logger + tipAO *isc.StateAnchor + log log.Logger } -func NewVarAccessNodeState(chainID isc.ChainID, log log.Logger) VarAccessNodeState { +func NewVarAccessNodeState(log log.Logger) VarAccessNodeState { return &varAccessNodeStateImpl{ - chainID: chainID, - tipAO: nil, - log: log, + tipAO: nil, + log: log, } } diff --git a/packages/chain/cmtlog/cmt_log.go b/packages/chain/cmtlog/cmt_log.go index 4834ff24dd..57df27c2ad 100644 --- a/packages/chain/cmtlog/cmt_log.go +++ b/packages/chain/cmtlog/cmt_log.go @@ -60,7 +60,6 @@ type Output = map[LogIndex]*isc.StateAnchor // Protocol implementation. type cmtLogImpl struct { - chainID isc.ChainID // Chain, for which this log is maintained by this committee. cmtAddr *cryptolib.Address // Address of the committee running this chain. consensusStateRegistry ConsensusStateRegistry // Persistent storage. varLogIndex VarLogIndex // Calculates the current log index. @@ -129,7 +128,6 @@ func New( // // Create it. cl := &cmtLogImpl{ - chainID: chainID, cmtAddr: cmtAddr, consensusStateRegistry: consensusStateRegistry, varLogIndex: nil, // Set bellow. diff --git a/packages/chain/cons/cons_test.go b/packages/chain/cons/cons_test.go index fca55e7e4e..4a1b344685 100644 --- a/packages/chain/cons/cons_test.go +++ b/packages/chain/cons/cons_test.go @@ -377,7 +377,7 @@ func testChained(t *testing.T, n, f, b int) { testChainInsts[ii+1].input(nextInput) } testChainInsts[i] = *newTestConsInst( - t, chainID, committeeAddress, i, procCache, nodeIDs, + t, committeeAddress, i, procCache, nodeIDs, testNodeStates, peerIdentities, dkShareProviders, allRequests[i], doneCB, log, ) @@ -459,7 +459,7 @@ type testConsInst struct { func newTestConsInst( t *testing.T, - chainID isc.ChainID, + committeeAddress *cryptolib.Address, stateIndex int, procCache *processors.Cache, @@ -478,7 +478,7 @@ func newTestConsInst( nodeSK := peerIdentities[i].GetPrivateKey() nodeDKShare, err := dkShareRegistryProviders[i].LoadDKShare(committeeAddress) require.NoError(t, err) - nodes[nid] = cons.New(chainID, nodeStates[nid], nid, nodeSK, nodeDKShare, procCache, consInstID, gpa.NodeIDFromPublicKey, accounts.CommonAccount(), nodeLog).AsGPA() + nodes[nid] = cons.New(nodeStates[nid], nid, nodeSK, nodeDKShare, procCache, consInstID, gpa.NodeIDFromPublicKey, accounts.CommonAccount(), nodeLog).AsGPA() } tci := &testConsInst{ t: t, diff --git a/packages/chain/mempool/mempool.go b/packages/chain/mempool/mempool.go index 57835f3e5d..50c4eb6691 100644 --- a/packages/chain/mempool/mempool.go +++ b/packages/chain/mempool/mempool.go @@ -87,7 +87,7 @@ type ChainListener interface { // This function is called by the chain when new block is applied to the // state. This block might be not confirmed yet, but the chain is going // to build the next block on top of this one. - BlockApplied(chainID isc.ChainID, block state.Block, latestState kv.KVStoreReader) + BlockApplied(block state.Block, latestState kv.KVStoreReader) } type Mempool interface { @@ -833,7 +833,7 @@ func (mpi *mempoolImpl) handleTrackNewChainHead(req *reqTrackNewChainHead) { panic(fmt.Errorf("cannot extract receipts from block: %w", err)) } mpi.metrics.IncBlocksPerChain() - mpi.listener.BlockApplied(mpi.chainID, block, mpi.chainHeadState) + mpi.listener.BlockApplied(block, mpi.chainHeadState) for _, receipt := range blockReceipts { mpi.metrics.IncRequestsProcessed() mpi.tryRemoveRequest(receipt.Request) diff --git a/packages/chain/node.go b/packages/chain/node.go index 27e214603d..9af16811f4 100644 --- a/packages/chain/node.go +++ b/packages/chain/node.go @@ -705,7 +705,7 @@ func (cni *chainNodeImpl) handleNeedPublishTX(ctx context.Context, upd *chainman cni.publishingTXes.Set(txDigest.HashValue(), subCancel) publishStart := time.Now() cni.log.LogDebugf("XXX: PublishTX %s ..., consumed anchor=%v", txDigest, needPublishTx.BaseAnchorRef) - if err := cni.nodeConn.PublishTX(subCtx, cni.chainID, *txToPost.Tx, func(_ iotasigner.SignedTransaction, newStateAnchor *isc.StateAnchor, err error) { + if err := cni.nodeConn.PublishTX(subCtx, *txToPost.Tx, func(_ iotasigner.SignedTransaction, newStateAnchor *isc.StateAnchor, err error) { cni.log.LogDebugf("XXX: PublishTX %s done, next anchor=%v, err=%v", txDigest, newStateAnchor, err) cni.chainMetrics.NodeConn.TXPublishResult(err == nil, time.Since(publishStart)) @@ -896,7 +896,7 @@ func (cni *chainNodeImpl) updateAccessNodes(update func()) { cnSame := util.Same(oldCommitteeNodes, activeCommitteeNodes) if !anSame { cni.log.LogInfof("Access nodes updated, active=%+v", activeAccessNodes) - cni.listener.AccessNodesUpdated(cni.chainID, activeAccessNodes) + cni.listener.AccessNodesUpdated(activeAccessNodes) } if !anSame || !cnSame { if !cnSame { @@ -918,7 +918,7 @@ func (cni *chainNodeImpl) updateServerNodes(serverNodes []*cryptolib.PublicKey) cni.log.LogInfof("Server nodes updated, servers=%+v", serverNodes) cni.mempool.ServerNodesUpdated(activeCommitteeNodes, serverNodes) cni.stateMgr.ChainNodesUpdated(serverNodes, activeAccessNodes, activeCommitteeNodes) - cni.listener.ServerNodesUpdated(cni.chainID, serverNodes) + cni.listener.ServerNodesUpdated(serverNodes) } } @@ -985,7 +985,7 @@ func (cni *chainNodeImpl) LatestAnchor(freshness StateFreshness) (*isc.StateAnch } func (cni *chainNodeImpl) LatestGasCoin(freshness StateFreshness) (*coin.CoinWithRef, error) { - return cni.nodeConn.GetGasCoinRef(context.Background(), cni.chainID) + return cni.nodeConn.GetGasCoinRef(context.Background()) } func (cni *chainNodeImpl) LatestState(freshness StateFreshness) (state.State, error) { @@ -1456,7 +1456,7 @@ func createMempool( cni.listener, mempoolSettings, mempoolBroadcastInterval, - func() { nodeConn.RefreshOnLedgerRequests(ctx, chainID) }, + func() { nodeConn.RefreshOnLedgerRequests(ctx) }, ) } diff --git a/packages/chain/node_test.go b/packages/chain/node_test.go index ec94c9c0a8..292a2fe823 100644 --- a/packages/chain/node_test.go +++ b/packages/chain/node_test.go @@ -292,7 +292,7 @@ func (tnc *testNodeConn) L1ParamsFetcher() parameters.L1ParamsFetcher { return tnc.l1ParamsFetcher } -func (tnc *testNodeConn) GetGasCoinRef(ctx context.Context, chainID isc.ChainID) (*coin.CoinWithRef, error) { +func (tnc *testNodeConn) GetGasCoinRef(ctx context.Context) (*coin.CoinWithRef, error) { panic("implement me") } @@ -314,16 +314,12 @@ func newTestNodeConn(t *testing.T, l1Client clients.L1Client, iscPackageID iotag func (tnc *testNodeConn) PublishTX( ctx context.Context, - chainID isc.ChainID, tx iotasigner.SignedTransaction, callback chain.TxPostHandler, ) error { if tnc.chainID.Empty() { tnc.t.Error("NodeConn::PublishTX before attach.") } - if !tnc.chainID.Equals(chainID) { - tnc.t.Error("unexpected chain id") - } txBytes, err := bcs.Marshal(tx.Data) if err != nil { @@ -371,7 +367,7 @@ func (tnc *testNodeConn) PublishTX( tnc.t.Logf("PublishTX, GetTransactionBlock, result=%+v", res) - anchorInfo, err := res.GetMutatedObjectByID(chainID.AsObjectID()) + anchorInfo, err := res.GetMutatedObjectByID(tnc.chainID.AsObjectID()) if err != nil { return err } @@ -479,7 +475,7 @@ func (tgi *testNodeConnL1Info) GetGasCoins() []*coin.CoinWithRef { return tgi.g func (tgi *testNodeConnL1Info) GetL1Params() *parameters.L1Params { return tgi.l1params } // RefreshOnLedgerRequests implements chain.NodeConnection. -func (tnc *testNodeConn) RefreshOnLedgerRequests(ctx context.Context, chainID isc.ChainID) { +func (tnc *testNodeConn) RefreshOnLedgerRequests(ctx context.Context) { // noop } diff --git a/packages/chain/statemanager/gpa/state_manager_gpa.go b/packages/chain/statemanager/gpa/state_manager_gpa.go index 2de2901d8b..88c774562f 100644 --- a/packages/chain/statemanager/gpa/state_manager_gpa.go +++ b/packages/chain/statemanager/gpa/state_manager_gpa.go @@ -15,7 +15,6 @@ import ( gpautils "github.com/iotaledger/wasp/v2/packages/chain/statemanager/gpa/utils" "github.com/iotaledger/wasp/v2/packages/chain/statemanager/utils" "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/metrics" "github.com/iotaledger/wasp/v2/packages/state" "github.com/iotaledger/wasp/v2/packages/trie" @@ -31,7 +30,6 @@ type blockInfo struct { type stateManagerGPA struct { log log.Logger - chainID isc.ChainID blockCache gpautils.BlockCache blocksToFetch blockFetchers blocksFetched blockFetchers @@ -51,7 +49,6 @@ type stateManagerGPA struct { var _ gpa.GPA = &stateManagerGPA{} func New( - chainID isc.ChainID, loadedSnapshotStateIndex uint32, nr utils.NodeRandomiser, wal gpautils.BlockWAL, @@ -68,7 +65,6 @@ func New( } result := &stateManagerGPA{ log: smLog, - chainID: chainID, blockCache: blockCache, blocksToFetch: newBlockFetchers(newBlockFetchersMetrics(metrics.IncBlocksFetching, metrics.DecBlocksFetching, metrics.StateManagerBlockFetched)), blocksFetched: newBlockFetchers(newBlockFetchersMetrics(metrics.IncBlocksPending, metrics.DecBlocksPending, bfmNopDurationFun)), diff --git a/packages/chain/statemanager/gpa/state_manager_gpa_cob_test.go b/packages/chain/statemanager/gpa/state_manager_gpa_cob_test.go index 00139d9114..474c02eab7 100644 --- a/packages/chain/statemanager/gpa/state_manager_gpa_cob_test.go +++ b/packages/chain/statemanager/gpa/state_manager_gpa_cob_test.go @@ -29,7 +29,7 @@ func initTestChainOfBlocks(t *testing.T) ( bf := utils.NewBlockFactory(t) log := testlogger.NewLogger(t) store := statetest.NewStoreWithUniqueWriteMutex(mapdb.NewMapDB()) - smGPA, err := New(bf.GetChainID(), 0, nil, nil, store, mockStateManagerMetrics(), log, NewStateManagerParameters()) + smGPA, err := New(0, nil, nil, store, mockStateManagerMetrics(), log, NewStateManagerParameters()) require.NoError(t, err) sm, ok := smGPA.(*stateManagerGPA) require.True(t, ok) diff --git a/packages/chain/statemanager/gpa/test_env.go b/packages/chain/statemanager/gpa/test_env.go index fb29947caf..ad53d54761 100644 --- a/packages/chain/statemanager/gpa/test_env.go +++ b/packages/chain/statemanager/gpa/test_env.go @@ -119,7 +119,6 @@ func (teT *testEnv) addVariedNodes( sms := make(map[gpa.NodeID]gpa.GPA) stores := make(map[gpa.NodeID]state.Store) snapms := make(map[gpa.NodeID]snapshots.SnapshotManager) - chainID := teT.bf.GetChainID() for _, nodeID := range nodeIDs { var err error smLog := teT.log.NewChildLogger(nodeID.ShortString()) @@ -129,7 +128,7 @@ func (teT *testEnv) addVariedNodes( snapshotManager := createSnapMFun(nodeID, teT.bf.GetStore(), store, teT.parameters.TimeProvider, smLog) loadedSnapshotStateIndex := snapshotManager.GetLoadedSnapshotStateIndex() stores[nodeID] = store - sms[nodeID], err = New(chainID, loadedSnapshotStateIndex, nr, wal, store, mockStateManagerMetrics(), smLog, teT.parameters) + sms[nodeID], err = New(loadedSnapshotStateIndex, nr, wal, store, mockStateManagerMetrics(), smLog, teT.parameters) require.NoError(teT.t, err) snapms[nodeID] = snapshotManager origin.InitChain(allmigrations.LatestSchemaVersion, store, teT.bf.GetChainInitParameters(), iotago.ObjectID{}, 0, parameterstest.L1Mock) diff --git a/packages/chain/statemanager/state_manager.go b/packages/chain/statemanager/state_manager.go index 7cae334448..8d64ff08e4 100644 --- a/packages/chain/statemanager/state_manager.go +++ b/packages/chain/statemanager/state_manager.go @@ -80,7 +80,6 @@ func (r *reqPreliminaryBlock) Respond(err error) { type stateManager struct { log log.Logger - chainID isc.ChainID stateManagerGPA gpa.GPA nodeRandomiser utils.NodeRandomiser nodeIDToPubKey map[gpa.NodeID]*cryptolib.PublicKey @@ -125,14 +124,13 @@ func New( ) (StateMgr, error) { smLog := log.NewChildLogger("SM") nr := utils.NewNodeRandomiserNoInit(gpa.NodeIDFromPublicKey(me), smLog) - stateManagerGPA, err := smgpa.New(chainID, snapshotManager.GetLoadedSnapshotStateIndex(), nr, wal, store, metrics, smLog, parameters) + stateManagerGPA, err := smgpa.New(snapshotManager.GetLoadedSnapshotStateIndex(), nr, wal, store, metrics, smLog, parameters) if err != nil { smLog.LogErrorf("failed to create state manager GPA: %w", err) return nil, err } result := &stateManager{ log: smLog, - chainID: chainID, stateManagerGPA: stateManagerGPA, nodeRandomiser: nr, inputPipe: pipe.NewInfinitePipe[gpa.Input](), diff --git a/packages/chains/accessmanager/access_manager.go b/packages/chainrunner/accessmanager/access_manager.go similarity index 84% rename from packages/chains/accessmanager/access_manager.go rename to packages/chainrunner/accessmanager/access_manager.go index 6baa410b0b..9270a2dc79 100644 --- a/packages/chains/accessmanager/access_manager.go +++ b/packages/chainrunner/accessmanager/access_manager.go @@ -11,10 +11,9 @@ import ( "github.com/samber/lo" "github.com/iotaledger/hive.go/log" - "github.com/iotaledger/wasp/v2/packages/chains/accessmanager/dist" + "github.com/iotaledger/wasp/v2/packages/chainrunner/accessmanager/dist" "github.com/iotaledger/wasp/v2/packages/cryptolib" "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/peering" "github.com/iotaledger/wasp/v2/packages/util" "github.com/iotaledger/wasp/v2/packages/util/pipe" @@ -22,8 +21,8 @@ import ( type AccessMgr interface { TrustedNodes(trusted []*cryptolib.PublicKey) - ChainAccessNodes(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) - ChainDismissed(chainID isc.ChainID) + ChainAccessNodes(accessNodes []*cryptolib.PublicKey) + ChainDismissed() } type accessMgrImpl struct { @@ -44,13 +43,10 @@ type reqTrustedNodes struct { } type reqChainAccessNodes struct { - chainID isc.ChainID accessNodes []*cryptolib.PublicKey } -type reqChainDismissed struct { - chainID isc.ChainID -} +type reqChainDismissed struct{} var _ AccessMgr = &accessMgrImpl{} @@ -66,7 +62,7 @@ const ( func New( ctx context.Context, - serversUpdatedCB func(chainID isc.ChainID, servers []*cryptolib.PublicKey), + serversUpdatedCB func(servers []*cryptolib.PublicKey), nodeIdentity *cryptolib.KeyPair, net peering.NetworkProvider, log log.Logger, @@ -109,13 +105,13 @@ func (ami *accessMgrImpl) TrustedNodes(trusted []*cryptolib.PublicKey) { } // Implements the AccessMgr interface. -func (ami *accessMgrImpl) ChainAccessNodes(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) { - ami.reqChainAccessNodesPipe.In() <- &reqChainAccessNodes{chainID: chainID, accessNodes: accessNodes} +func (ami *accessMgrImpl) ChainAccessNodes(accessNodes []*cryptolib.PublicKey) { + ami.reqChainAccessNodesPipe.In() <- &reqChainAccessNodes{accessNodes: accessNodes} } // Implements the AccessMgr interface. -func (ami *accessMgrImpl) ChainDismissed(chainID isc.ChainID) { - ami.reqChainDismissedPipe.In() <- &reqChainDismissed{chainID: chainID} +func (ami *accessMgrImpl) ChainDismissed() { + ami.reqChainDismissedPipe.In() <- &reqChainDismissed{} } // A callback for amDist. @@ -179,13 +175,13 @@ func (ami *accessMgrImpl) handleReqTrustedNodes(recv *reqTrustedNodes) { } func (ami *accessMgrImpl) handleReqChainAccessNodes(recv *reqChainAccessNodes) { - ami.log.LogDebugf("handleReqChainAccessNodes: chainID=%v, access=%v", recv.chainID, recv.accessNodes) - ami.sendMessages(ami.dist.Input(dist.NewInputAccessNodes(recv.chainID, recv.accessNodes))) + ami.log.LogDebugf("handleReqChainAccessNodes: access=%v", recv.accessNodes) + ami.sendMessages(ami.dist.Input(dist.NewInputAccessNodes(recv.accessNodes))) } -func (ami *accessMgrImpl) handleReqChainDismissed(recv *reqChainDismissed) { - ami.log.LogDebugf("handleReqChainDismissed: chainID=%v", recv.chainID) - ami.sendMessages(ami.dist.Input(dist.NewInputChainDisabled(recv.chainID))) +func (ami *accessMgrImpl) handleReqChainDismissed(_ *reqChainDismissed) { + ami.log.LogDebugf("handleReqChainDismissed") + ami.sendMessages(ami.dist.Input(dist.NewInputChainDisabled())) } func (ami *accessMgrImpl) handleDistDebugTick() { diff --git a/packages/chains/accessmanager/access_manager_test.go b/packages/chainrunner/accessmanager/access_manager_test.go similarity index 89% rename from packages/chains/accessmanager/access_manager_test.go rename to packages/chainrunner/accessmanager/access_manager_test.go index 7f45674161..81ef9b2e25 100644 --- a/packages/chains/accessmanager/access_manager_test.go +++ b/packages/chainrunner/accessmanager/access_manager_test.go @@ -14,10 +14,8 @@ import ( "github.com/stretchr/testify/require" hivelog "github.com/iotaledger/hive.go/log" - "github.com/iotaledger/wasp/v2/packages/chains/accessmanager" + "github.com/iotaledger/wasp/v2/packages/chainrunner/accessmanager" "github.com/iotaledger/wasp/v2/packages/cryptolib" - "github.com/iotaledger/wasp/v2/packages/isc" - "github.com/iotaledger/wasp/v2/packages/isc/isctest" "github.com/iotaledger/wasp/v2/packages/testutil" "github.com/iotaledger/wasp/v2/packages/testutil/testlogger" "github.com/iotaledger/wasp/v2/packages/testutil/testpeers" @@ -81,8 +79,8 @@ func testBasic(t *testing.T, n int, reliable bool) { nodeServers := make([][]*cryptolib.PublicKey, len(peerIdentities)) // That's the output. for i := range accessMgrs { ii := i - serversUpdatedCB := func(chainID isc.ChainID, servers []*cryptolib.PublicKey) { - t.Logf("servers updated, ChainID=%v, servers=%+v", chainID, servers) + serversUpdatedCB := func(servers []*cryptolib.PublicKey) { + t.Logf("servers updated, servers=%+v", servers) nodeServers[ii] = servers } accessMgrs[i] = accessmanager.New(ctx, serversUpdatedCB, peerIdentities[i], networkProviders[i], log.NewChildLogger(fmt.Sprintf("N#%v", i))) @@ -94,9 +92,8 @@ func testBasic(t *testing.T, n int, reliable bool) { } // // Everyone gives access to everyone. - chainID := isctest.RandomChainID() for _, am := range accessMgrs { - am.ChainAccessNodes(chainID, peerPubKeys) + am.ChainAccessNodes(peerPubKeys) } ctx, cancel := context.WithTimeout(context.Background(), testmisc.GetTimeout(1*time.Minute)) diff --git a/packages/chains/accessmanager/dist/.gitignore b/packages/chainrunner/accessmanager/dist/.gitignore similarity index 100% rename from packages/chains/accessmanager/dist/.gitignore rename to packages/chainrunner/accessmanager/dist/.gitignore diff --git a/packages/chains/accessmanager/dist/Makefile b/packages/chainrunner/accessmanager/dist/Makefile similarity index 100% rename from packages/chains/accessmanager/dist/Makefile rename to packages/chainrunner/accessmanager/dist/Makefile diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodes.png b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodes.png similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodes.png rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodes.png diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodes.xopp b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodes.xopp similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodes.xopp rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodes.xopp diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodesV4.tla b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4.tla similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodesV4.tla rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4.tla diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R0.cfg b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R0.cfg similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R0.cfg rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R0.cfg diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R1.cfg b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R1.cfg similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R1.cfg rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L3R1.cfg diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R0.cfg b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R0.cfg similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R0.cfg rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R0.cfg diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R1.cfg b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R1.cfg similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R1.cfg rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L4R1.cfg diff --git a/packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L5R0.cfg b/packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L5R0.cfg similarity index 100% rename from packages/chains/accessmanager/dist/WaspChainAccessNodesV4_N2C1L5R0.cfg rename to packages/chainrunner/accessmanager/dist/WaspChainAccessNodesV4_N2C1L5R0.cfg diff --git a/packages/chains/accessmanager/dist/access_manager_dist.go b/packages/chainrunner/accessmanager/dist/access_manager_dist.go similarity index 59% rename from packages/chains/accessmanager/dist/access_manager_dist.go rename to packages/chainrunner/accessmanager/dist/access_manager_dist.go index bbaa6ceeb5..6645256d9d 100644 --- a/packages/chains/accessmanager/dist/access_manager_dist.go +++ b/packages/chainrunner/accessmanager/dist/access_manager_dist.go @@ -19,8 +19,6 @@ import ( "github.com/iotaledger/wasp/v2/packages/cryptolib" "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" - "github.com/iotaledger/wasp/v2/packages/util" ) type AccessMgr interface { @@ -28,15 +26,15 @@ type AccessMgr interface { } type Output interface { - ChainServerNodes(chainID isc.ChainID) []*cryptolib.PublicKey + ChainServerNodes() []*cryptolib.PublicKey } type accessMgrDist struct { - nodes *shrinkingmap.ShrinkingMap[gpa.NodeID, *accessMgrNode] // State for each peer. - chains *shrinkingmap.ShrinkingMap[isc.ChainID, *accessMgrChain] // State for each chain. - pubKeyToNodeID func(*cryptolib.PublicKey) gpa.NodeID // Convert PubKeys to NodeIDs. - serversUpdatedCB func(isc.ChainID, []*cryptolib.PublicKey) // Called when a set of servers has changed for a chain. - dismissPeerCB func(*cryptolib.PublicKey) // To stop redelivery at the upper layer. + nodes *shrinkingmap.ShrinkingMap[gpa.NodeID, *accessMgrNode] // State for each peer. + chain *accessMgrChain // State of chain. + pubKeyToNodeID func(*cryptolib.PublicKey) gpa.NodeID // Convert PubKeys to NodeIDs. + serversUpdatedCB func([]*cryptolib.PublicKey) // Called when a set of servers has changed for a chain. + dismissPeerCB func(*cryptolib.PublicKey) // To stop redelivery at the upper layer. log log.Logger } @@ -44,13 +42,12 @@ var _ gpa.GPA = &accessMgrDist{} func NewAccessMgr( pubKeyToNodeID func(*cryptolib.PublicKey) gpa.NodeID, - serversUpdatedCB func(chainID isc.ChainID, servers []*cryptolib.PublicKey), + serversUpdatedCB func(servers []*cryptolib.PublicKey), dismissPeerCB func(*cryptolib.PublicKey), log log.Logger, ) AccessMgr { return &accessMgrDist{ nodes: shrinkingmap.New[gpa.NodeID, *accessMgrNode](), - chains: shrinkingmap.New[isc.ChainID, *accessMgrChain](), pubKeyToNodeID: pubKeyToNodeID, serversUpdatedCB: serversUpdatedCB, dismissPeerCB: dismissPeerCB, @@ -64,9 +61,9 @@ func (amd *accessMgrDist) AsGPA() gpa.GPA { } // Implements the Output interface. -func (amd *accessMgrDist) ChainServerNodes(chainID isc.ChainID) []*cryptolib.PublicKey { - if chain, exists := amd.chains.Get(chainID); exists { - return chain.server.Values() +func (amd *accessMgrDist) ChainServerNodes() []*cryptolib.PublicKey { + if amd.chain != nil { + return amd.chain.server.Values() } return []*cryptolib.PublicKey{} } @@ -99,20 +96,19 @@ func (amd *accessMgrDist) Output() gpa.Output { // Implements the gpa.GPA interface. func (amd *accessMgrDist) StatusString() string { - return fmt.Sprintf("{accessMgr, |nodes|=%v, |chains|=%v}", amd.nodes.Size(), amd.chains.Size()) + return fmt.Sprintf("{accessMgr, |nodes|=%v, |hasChain|=%v}", amd.nodes.Size(), amd.chain != nil) } // > Notify all the trusted access nodes, that we will not serve the requests anymore. -func (amd *accessMgrDist) handleInputChainDisabled(input *inputChainDisabled) gpa.OutMessages { - chain, exists := amd.chains.Get(input.chainID) - if !exists { +func (amd *accessMgrDist) handleInputChainDisabled(_ *inputChainDisabled) gpa.OutMessages { + if amd.chain == nil { return nil // Already disabled. } - chain.Disabled() - amd.chains.Delete(input.chainID) + amd.chain.Disabled() + amd.chain = nil msgs := gpa.NoMessages() amd.nodes.ForEach(func(_ gpa.NodeID, node *accessMgrNode) bool { - msgs.AddAll(node.SetChainAccess(input.chainID, false)) + msgs.AddAll(node.SetChainAccess(false)) return true }) return msgs @@ -125,24 +121,22 @@ func (amd *accessMgrDist) handleInputChainDisabled(input *inputChainDisabled) gp func (amd *accessMgrDist) handleInputAccessNodes(input *inputAccessNodes) gpa.OutMessages { // // Update the info from the chain perspective. - chain, exists := amd.chains.Get(input.chainID) - if !exists { + if amd.chain == nil { initialServers := []*cryptolib.PublicKey{} amd.nodes.ForEach(func(_ gpa.NodeID, node *accessMgrNode) bool { - if node.serverFor.Has(input.chainID) { + if node.isServer { initialServers = append(initialServers, node.pubKey) } return true }) - chain = newAccessMgrChain(input.chainID, amd.pubKeyToNodeID, initialServers, amd.serversUpdatedCB, amd.log) - amd.chains.Set(input.chainID, chain) + amd.chain = newAccessMgrChain(amd.pubKeyToNodeID, initialServers, amd.serversUpdatedCB, amd.log) } - chain.AccessGrantedFor(input.accessNodes) + amd.chain.AccessGrantedFor(input.accessNodes) // // Update the info for each node. msgs := gpa.NoMessages() amd.nodes.ForEach(func(nodeID gpa.NodeID, node *accessMgrNode) bool { - msgs.AddAll(node.SetChainAccess(input.chainID, chain.IsAccessGrantedFor(nodeID))) + msgs.AddAll(node.SetChainAccess(amd.chain.IsAccessGrantedFor(nodeID))) return true }) return msgs @@ -159,14 +153,11 @@ func (amd *accessMgrDist) handleInputTrustedNodes(input *inputTrustedNodes) gpa. if amd.nodes.Has(trustedNodeID) { continue } - accessFor := newChainSet() - amd.chains.ForEach(func(chainID isc.ChainID, chain *accessMgrChain) bool { - if chain.IsAccessGrantedFor(trustedNodeID) { - accessFor.Add(chainID) - } - return true - }) - trustedNode, trustedNodeMsgs := newAccessMgrNode(trustedNodeID, trustedNodePubKey, accessFor) + hasAccess := false + if amd.chain != nil && amd.chain.IsAccessGrantedFor(trustedNodeID) { + hasAccess = true + } + trustedNode, trustedNodeMsgs := newAccessMgrNode(trustedNodeID, trustedNodePubKey, hasAccess) msgs.AddAll(trustedNodeMsgs) amd.nodes.Set(trustedNodeID, trustedNode) } @@ -176,11 +167,10 @@ func (amd *accessMgrDist) handleInputTrustedNodes(input *inputTrustedNodes) gpa. if _, ok := trustedIndex[nodeID]; ok { return true } - amd.chains.ForEach(func(_ isc.ChainID, chain *accessMgrChain) bool { - chain.MarkAsServerFor(node.pubKey, false) - msgs.AddAll(node.SetChainAccess(chain.chainID, false)) - return true - }) + if amd.chain != nil { + amd.chain.MarkAsServerFor(node.pubKey, false) + msgs.AddAll(node.SetChainAccess(false)) + } amd.nodes.Delete(nodeID) amd.dismissPeerCB(node.pubKey) return true @@ -195,10 +185,9 @@ func (amd *accessMgrDist) handleMsgAccess(msg *msgAccess) gpa.OutMessages { } msgs := node.handleMsgAccess(msg) - amd.chains.ForEach(func(chainID isc.ChainID, chain *accessMgrChain) bool { - chain.MarkAsServerFor(node.pubKey, node.serverFor.Has(chainID)) - return true - }) + if amd.chain != nil { + amd.chain.MarkAsServerFor(node.pubKey, node.isServer) + } return msgs } @@ -206,23 +195,20 @@ func (amd *accessMgrDist) handleMsgAccess(msg *msgAccess) gpa.OutMessages { //////////////////////////////////////////////////////////////////////////////// type accessMgrChain struct { - chainID isc.ChainID access map[gpa.NodeID]*cryptolib.PublicKey server *shrinkingmap.ShrinkingMap[gpa.NodeID, *cryptolib.PublicKey] pubKeyToNodeID func(*cryptolib.PublicKey) gpa.NodeID - serversUpdatedCB func(isc.ChainID, []*cryptolib.PublicKey) + serversUpdatedCB func([]*cryptolib.PublicKey) log log.Logger } func newAccessMgrChain( - chainID isc.ChainID, pubKeyToNodeID func(*cryptolib.PublicKey) gpa.NodeID, initialServers []*cryptolib.PublicKey, - serversUpdatedCB func(isc.ChainID, []*cryptolib.PublicKey), + serversUpdatedCB func([]*cryptolib.PublicKey), log log.Logger, ) *accessMgrChain { amc := &accessMgrChain{ - chainID: chainID, access: map[gpa.NodeID]*cryptolib.PublicKey{}, server: shrinkingmap.New[gpa.NodeID, *cryptolib.PublicKey](), pubKeyToNodeID: pubKeyToNodeID, @@ -235,8 +221,8 @@ func newAccessMgrChain( } serverNodes := amc.server.Values() - amc.log.LogDebugf("Chain %v server nodes updated to %+v on init.", amc.chainID.ShortString(), serverNodes) - amc.serversUpdatedCB(amc.chainID, serverNodes) + amc.log.LogDebugf("Chain server nodes updated to %+v on init.", serverNodes) + amc.serversUpdatedCB(serverNodes) return amc } @@ -258,8 +244,8 @@ func (amc *accessMgrChain) MarkAsServerFor(nodePubKey *cryptolib.PublicKey, gran } if wasServer != granted { serverNodes := amc.server.Values() - amc.log.LogDebugf("Chain %v server nodes updated to %+v.", amc.chainID.ShortString(), serverNodes) - amc.serversUpdatedCB(amc.chainID, serverNodes) + amc.log.LogDebugf("Chain server nodes updated to %+v.", serverNodes) + amc.serversUpdatedCB(serverNodes) } } @@ -272,8 +258,8 @@ func (amc *accessMgrChain) Disabled() { if amc.server.Size() == 0 { return } - amc.log.LogDebugf("Chain %v server nodes updated to [] on dismiss.", amc.chainID.ShortString()) - amc.serversUpdatedCB(amc.chainID, []*cryptolib.PublicKey{}) + amc.log.LogDebugf("Chain server nodes updated to [] on dismiss.") + amc.serversUpdatedCB([]*cryptolib.PublicKey{}) } //////////////////////////////////////////////////////////////////////////////// @@ -283,83 +269,81 @@ type accessMgrNode struct { pubKey *cryptolib.PublicKey ourLC int peerLC int - accessFor *chainSet - serverFor *chainSet + hasAccess bool + isServer bool } func newAccessMgrNode( nodeID gpa.NodeID, pubKey *cryptolib.PublicKey, - accessFor *chainSet, + hasAccess bool, ) (*accessMgrNode, gpa.OutMessages) { amn := &accessMgrNode{ nodeID: nodeID, pubKey: pubKey, ourLC: 1, peerLC: 0, - accessFor: accessFor, - serverFor: newChainSet(), + hasAccess: hasAccess, + isServer: false, } msgs := gpa.NoMessages() - msgs.Add(newMsgAccess(amn.nodeID, amn.ourLC, amn.peerLC, amn.accessFor.AsSlice(), amn.serverFor.AsSlice())) + msgs.Add(newMsgAccess(amn.nodeID, amn.ourLC, amn.peerLC, amn.hasAccess, amn.isServer)) return amn, msgs } -func (amn *accessMgrNode) SetChainAccess(chainID isc.ChainID, access bool) gpa.OutMessages { +func (amn *accessMgrNode) SetChainAccess(access bool) gpa.OutMessages { if access { - return amn.grantAccess(chainID) + return amn.grantAccess() } - return amn.revokeAccess(chainID) + return amn.revokeAccess() } -func (amn *accessMgrNode) grantAccess(chainID isc.ChainID) gpa.OutMessages { - if amn.accessFor.Has(chainID) { +func (amn *accessMgrNode) grantAccess() gpa.OutMessages { + if amn.hasAccess { return nil } - amn.accessFor.Add(chainID) + amn.hasAccess = true amn.ourLC++ msgs := gpa.NoMessages() - msgs.Add(newMsgAccess(amn.nodeID, amn.ourLC, amn.peerLC, amn.accessFor.AsSlice(), amn.serverFor.AsSlice())) + msgs.Add(newMsgAccess(amn.nodeID, amn.ourLC, amn.peerLC, amn.hasAccess, amn.isServer)) return msgs } -func (amn *accessMgrNode) revokeAccess(chainID isc.ChainID) gpa.OutMessages { - if !amn.accessFor.Has(chainID) { +func (amn *accessMgrNode) revokeAccess() gpa.OutMessages { + if !amn.hasAccess { return nil } - amn.accessFor.Delete(chainID) + amn.hasAccess = false amn.ourLC++ msgs := gpa.NoMessages() - msgs.Add(newMsgAccess(amn.nodeID, amn.ourLC, amn.peerLC, amn.accessFor.AsSlice(), amn.serverFor.AsSlice())) + msgs.Add(newMsgAccess(amn.nodeID, amn.ourLC, amn.peerLC, amn.hasAccess, amn.isServer)) return msgs } func (amn *accessMgrNode) handleMsgAccess(msg *msgAccess) gpa.OutMessages { // This has to be checked before updating the state. - // > IF /\ m.access = serverForChains(n, m.src) \* Peer's info hasn't changed, so we don't need to ack it. - // > /\ m.server = H(accessForChains(n, m.src)) \* Our info echoed, so that was an ack. + // > IF /\ m.access = isServer(n, m.src) \* Peer's info hasn't changed, so we don't need to ack it. + // > /\ m.server = H(hasAccess(n, m.src)) \* Our info echoed, so that was an ack. // > /\ m.src_lc >= lClock[n][m.src] \* Peer's clock is not outdated, we don't need to push it forward. // > /\ m.dst_lc <= lClock[n][n] \* And the echoed clock don't exceed our clock, so we don't need to push it. // > THEN sendAndAck(m, {}) // > ELSE sendAndAck(m, accessMsgs(n)) sendDone := true && - util.Same(msg.accessForChains, amn.serverFor.AsSlice()) && - util.Same(msg.serverForChains, amn.accessFor.AsSlice()) && + msg.hasAccess == amn.isServer && + msg.isServer == amn.hasAccess && msg.senderLClock >= amn.peerLC && msg.receiverLClock <= amn.ourLC // - // Update serverFor and peerLC. + // Update isServer and peerLC. if msg.senderLClock > amn.peerLC { - amn.serverFor.FromSlice(msg.accessForChains) + amn.isServer = msg.hasAccess amn.peerLC = msg.senderLClock } // // Update ourLC. if amn.ourLC <= msg.receiverLClock { amn.ourLC = msg.receiverLClock - msgServerFor := newChainSet() - msgServerFor.FromSlice(msg.serverForChains) - if !amn.accessFor.Equals(msgServerFor) { + if !amn.hasAccess == msg.isServer { amn.ourLC++ } } @@ -367,58 +351,10 @@ func (amn *accessMgrNode) handleMsgAccess(msg *msgAccess) gpa.OutMessages { // Send message back, if needed. if !sendDone { return gpa.NoMessages().Add( - newMsgAccess(msg.Sender(), amn.ourLC, amn.peerLC, amn.accessFor.AsSlice(), amn.serverFor.AsSlice()), + newMsgAccess(msg.Sender(), amn.ourLC, amn.peerLC, amn.hasAccess, amn.isServer), ) } return nil } //////////////////////////////////////////////////////////////////////////////// - -type chainSet struct { - elements *shrinkingmap.ShrinkingMap[isc.ChainID, struct{}] -} - -func newChainSet() *chainSet { - return &chainSet{elements: shrinkingmap.New[isc.ChainID, struct{}]()} -} - -func (cs *chainSet) Add(elem isc.ChainID) { - cs.elements.Set(elem, struct{}{}) -} - -func (cs *chainSet) Delete(elem isc.ChainID) { - cs.elements.Delete(elem) -} - -func (cs *chainSet) Has(elem isc.ChainID) bool { - return cs.elements.Has(elem) -} - -func (cs *chainSet) AsSlice() []isc.ChainID { - return cs.elements.Keys() -} - -func (cs *chainSet) FromSlice(els []isc.ChainID) { - cs.elements = shrinkingmap.New[isc.ChainID, struct{}]() - for _, el := range els { - cs.elements.Set(el, struct{}{}) - } -} - -func (cs *chainSet) Equals(other *chainSet) bool { - if cs.elements.Size() != other.elements.Size() { - return false - } - - equal := true - cs.elements.ForEach(func(ci isc.ChainID, s struct{}) bool { - if !other.elements.Has(ci) { - equal = false - return false - } - return true - }) - - return equal -} diff --git a/packages/chains/accessmanager/dist/access_manager_dist_test.go b/packages/chainrunner/accessmanager/dist/access_manager_dist_test.go similarity index 81% rename from packages/chains/accessmanager/dist/access_manager_dist_test.go rename to packages/chainrunner/accessmanager/dist/access_manager_dist_test.go index 030e34500d..5bae4106c3 100644 --- a/packages/chains/accessmanager/dist/access_manager_dist_test.go +++ b/packages/chainrunner/accessmanager/dist/access_manager_dist_test.go @@ -9,11 +9,9 @@ import ( "github.com/stretchr/testify/require" - "github.com/iotaledger/wasp/v2/packages/chains/accessmanager/dist" + "github.com/iotaledger/wasp/v2/packages/chainrunner/accessmanager/dist" "github.com/iotaledger/wasp/v2/packages/cryptolib" "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" - "github.com/iotaledger/wasp/v2/packages/isc/isctest" "github.com/iotaledger/wasp/v2/packages/testutil/testlogger" "github.com/iotaledger/wasp/v2/packages/testutil/testpeers" "github.com/iotaledger/wasp/v2/packages/util" @@ -30,7 +28,6 @@ func testBasic(t *testing.T, n int) { _, peerIdentities := testpeers.SetupKeys(uint16(n)) nodePubs := testpeers.PublicKeys(peerIdentities) nodeIDs := gpa.NodeIDsFromPublicKeys(nodePubs) - chainID := isctest.RandomChainID() servers := map[gpa.NodeID][]*cryptolib.PublicKey{} nodes := map[gpa.NodeID]gpa.GPA{} @@ -38,7 +35,7 @@ func testBasic(t *testing.T, n int) { nidCopy := nid nodes[nid] = dist.NewAccessMgr( gpa.NodeIDFromPublicKey, - func(ci isc.ChainID, pks []*cryptolib.PublicKey) { + func(pks []*cryptolib.PublicKey) { servers[nidCopy] = pks }, func(pk *cryptolib.PublicKey) {}, @@ -49,7 +46,7 @@ func testBasic(t *testing.T, n int) { tc := gpa.NewTestContext(nodes) for _, nid := range nodeIDs { tc.WithInput(nid, dist.NewInputTrustedNodes(nodePubs)) - tc.WithInput(nid, dist.NewInputAccessNodes(chainID, nodePubs)) + tc.WithInput(nid, dist.NewInputAccessNodes(nodePubs)) } tc.RunAll() for nid := range nodes { diff --git a/packages/chains/accessmanager/dist/access_manager_rapid_test.go b/packages/chainrunner/accessmanager/dist/access_manager_rapid_test.go similarity index 53% rename from packages/chains/accessmanager/dist/access_manager_rapid_test.go rename to packages/chainrunner/accessmanager/dist/access_manager_rapid_test.go index 44b46d6b68..98c558fdde 100644 --- a/packages/chains/accessmanager/dist/access_manager_rapid_test.go +++ b/packages/chainrunner/accessmanager/dist/access_manager_rapid_test.go @@ -12,11 +12,9 @@ import ( "pgregory.net/rapid" "github.com/iotaledger/hive.go/log" - "github.com/iotaledger/wasp/v2/packages/chains/accessmanager/dist" + "github.com/iotaledger/wasp/v2/packages/chainrunner/accessmanager/dist" "github.com/iotaledger/wasp/v2/packages/cryptolib" "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" - "github.com/iotaledger/wasp/v2/packages/isc/isctest" "github.com/iotaledger/wasp/v2/packages/testutil/testlogger" "github.com/iotaledger/wasp/v2/packages/testutil/testpeers" "github.com/iotaledger/wasp/v2/packages/util" @@ -30,59 +28,49 @@ type accessMgrSM struct { nodeKeys []*cryptolib.KeyPair nodePubs []*cryptolib.PublicKey nodeIDs []gpa.NodeID - chainIDs []isc.ChainID genNodeID *rapid.Generator[gpa.NodeID] genNodePub *rapid.Generator[*cryptolib.PublicKey] genNodePubSlice *rapid.Generator[[]*cryptolib.PublicKey] - genChainID *rapid.Generator[isc.ChainID] // // These are set up for each scenario. tc *gpa.TestContext nodes map[gpa.NodeID]gpa.GPA - servers map[gpa.NodeID]map[isc.ChainID][]*cryptolib.PublicKey + servers map[gpa.NodeID][]*cryptolib.PublicKey // // Model. mTrusted map[gpa.NodeID][]*cryptolib.PublicKey - mActive map[gpa.NodeID]map[isc.ChainID]bool - mAccess map[gpa.NodeID]map[isc.ChainID][]*cryptolib.PublicKey + mActive map[gpa.NodeID]bool + mAccess map[gpa.NodeID][]*cryptolib.PublicKey } var _ rapid.StateMachine = &accessMgrSM{} -func newAccessMgrSM(t *rapid.T, nodeCount, chainCount int) *accessMgrSM { +func newAccessMgrSM(t *rapid.T, nodeCount int) *accessMgrSM { sm := new(accessMgrSM) if !sm.initialized { sm.log = testlogger.NewLogger(t) _, sm.nodeKeys = testpeers.SetupKeys(uint16(nodeCount)) sm.nodePubs = testpeers.PublicKeys(sm.nodeKeys) sm.nodeIDs = gpa.NodeIDsFromPublicKeys(sm.nodePubs) - sm.chainIDs = make([]isc.ChainID, chainCount) - for i := range sm.chainIDs { - sm.chainIDs[i] = isctest.RandomChainID([]byte{byte(i)}) - } sm.genNodeID = rapid.SampledFrom(sm.nodeIDs) sm.genNodePub = rapid.SampledFrom(sm.nodePubs) sm.genNodePubSlice = rapid.SliceOfDistinct( sm.genNodePub, func(pub *cryptolib.PublicKey) cryptolib.PublicKeyKey { return pub.AsKey() }, ) - sm.genChainID = rapid.SampledFrom(sm.chainIDs) sm.initialized = true } - sm.servers = map[gpa.NodeID]map[isc.ChainID][]*cryptolib.PublicKey{} + sm.servers = map[gpa.NodeID][]*cryptolib.PublicKey{} sm.nodes = map[gpa.NodeID]gpa.GPA{} for _, nid := range sm.nodeIDs { - sm.servers[nid] = map[isc.ChainID][]*cryptolib.PublicKey{} - for _, chainID := range sm.chainIDs { - sm.servers[nid][chainID] = []*cryptolib.PublicKey{} - } + sm.servers[nid] = []*cryptolib.PublicKey{} nidCopy := nid sm.nodes[nid] = dist.NewAccessMgr( gpa.NodeIDFromPublicKey, - func(chainID isc.ChainID, servers []*cryptolib.PublicKey) { - t.Logf("serversUpdatedCB: nodeID=%v, chainID=%v, servers=%v", nidCopy, chainID, servers) - sm.servers[nidCopy][chainID] = servers + func(servers []*cryptolib.PublicKey) { + t.Logf("serversUpdatedCB: nodeID=%v, servers=%v", nidCopy, servers) + sm.servers[nidCopy] = servers }, func(pk *cryptolib.PublicKey) {}, sm.log.NewChildLogger(nid.ShortString()), @@ -91,16 +79,13 @@ func newAccessMgrSM(t *rapid.T, nodeCount, chainCount int) *accessMgrSM { sm.tc = gpa.NewTestContext(sm.nodes) sm.mTrusted = map[gpa.NodeID][]*cryptolib.PublicKey{} - sm.mActive = map[gpa.NodeID]map[isc.ChainID]bool{} - sm.mAccess = map[gpa.NodeID]map[isc.ChainID][]*cryptolib.PublicKey{} + sm.mActive = map[gpa.NodeID]bool{} + sm.mAccess = map[gpa.NodeID][]*cryptolib.PublicKey{} for _, nid := range sm.nodeIDs { sm.mTrusted[nid] = []*cryptolib.PublicKey{} - sm.mAccess[nid] = map[isc.ChainID][]*cryptolib.PublicKey{} - sm.mActive[nid] = map[isc.ChainID]bool{} - for _, ch := range sm.chainIDs { - sm.mAccess[nid][ch] = []*cryptolib.PublicKey{} - sm.mActive[nid][ch] = false - } + sm.mAccess[nid] = []*cryptolib.PublicKey{} + sm.mAccess[nid] = []*cryptolib.PublicKey{} + sm.mActive[nid] = false } return sm } @@ -114,18 +99,16 @@ func (sm *accessMgrSM) InputTrustedNodes(t *rapid.T) { func (sm *accessMgrSM) InputAccessNodes(t *rapid.T) { nodeID := sm.genNodeID.Draw(t, "nodeID") - chainID := sm.genChainID.Draw(t, "chainID") accessNodes := sm.genNodePubSlice.Draw(t, "accessNodes") - sm.tc.WithInput(nodeID, dist.NewInputAccessNodes(chainID, accessNodes)).RunAll() - sm.mActive[nodeID][chainID] = true - sm.mAccess[nodeID][chainID] = accessNodes + sm.tc.WithInput(nodeID, dist.NewInputAccessNodes(accessNodes)).RunAll() + sm.mActive[nodeID] = true + sm.mAccess[nodeID] = accessNodes } func (sm *accessMgrSM) InputChainDisabled(t *rapid.T) { nodeID := sm.genNodeID.Draw(t, "nodeID") - chainID := sm.genChainID.Draw(t, "chainID") - sm.tc.WithInput(nodeID, dist.NewInputChainDisabled(chainID)).RunAll() - sm.mActive[nodeID][chainID] = false + sm.tc.WithInput(nodeID, dist.NewInputChainDisabled()).RunAll() + sm.mActive[nodeID] = false } func (sm *accessMgrSM) Reboot(t *rapid.T) { @@ -134,9 +117,9 @@ func (sm *accessMgrSM) Reboot(t *rapid.T) { // Just recreate a node. sm.nodes[nodeID] = dist.NewAccessMgr( gpa.NodeIDFromPublicKey, - func(chainID isc.ChainID, servers []*cryptolib.PublicKey) { - t.Logf("serversUpdatedCB: nodeID=%v, chainID=%v, servers=%v", nodeID, chainID, servers) - sm.servers[nodeID][chainID] = servers + func(servers []*cryptolib.PublicKey) { + t.Logf("serversUpdatedCB: nodeID=%v, servers=%v", nodeID, servers) + sm.servers[nodeID] = servers }, func(pk *cryptolib.PublicKey) {}, sm.log.NewChildLogger(nodeID.ShortString()), @@ -145,11 +128,8 @@ func (sm *accessMgrSM) Reboot(t *rapid.T) { // Re-initialize all the persistent info: access information, active chains, trusted nodes. // But the servers are not restored here. The algorithm has to restore that. sm.tc.WithInput(nodeID, dist.NewInputTrustedNodes(sm.mTrusted[nodeID])) - for _, chainID := range sm.chainIDs { - if !sm.mActive[nodeID][chainID] { - continue - } - sm.tc.WithInput(nodeID, dist.NewInputAccessNodes(chainID, sm.mAccess[nodeID][chainID])) + if sm.mActive[nodeID] { + sm.tc.WithInput(nodeID, dist.NewInputAccessNodes(sm.mAccess[nodeID])) } sm.tc.RunAll() } @@ -157,24 +137,22 @@ func (sm *accessMgrSM) Reboot(t *rapid.T) { func (sm *accessMgrSM) Check(t *rapid.T) { for _, nodePub := range sm.nodePubs { nodeID := gpa.NodeIDFromPublicKey(nodePub) - for _, chainID := range sm.chainIDs { - shouldBeServers := []*cryptolib.PublicKey{} - for _, peerPub := range sm.nodePubs { - peerID := gpa.NodeIDFromPublicKey(peerPub) - if sm.mActive[nodeID][chainID] && - sm.mActive[peerID][chainID] && - lo.Contains(sm.mTrusted[peerID], nodePub) && - lo.Contains(sm.mTrusted[nodeID], peerPub) && - lo.Contains(sm.mAccess[peerID][chainID], nodePub) { - shouldBeServers = append(shouldBeServers, peerPub) - } + shouldBeServers := []*cryptolib.PublicKey{} + for _, peerPub := range sm.nodePubs { + peerID := gpa.NodeIDFromPublicKey(peerPub) + if sm.mActive[nodeID] && + sm.mActive[peerID] && + lo.Contains(sm.mTrusted[peerID], nodePub) && + lo.Contains(sm.mTrusted[nodeID], peerPub) && + lo.Contains(sm.mAccess[peerID], nodePub) { + shouldBeServers = append(shouldBeServers, peerPub) } - require.True(t, - util.Same(sm.servers[nodeID][chainID], shouldBeServers), - "nodeID=%v, chainID=%v, have=%v, expect=%v", - nodeID, chainID, sm.servers[nodeID][chainID], shouldBeServers, - ) } + require.True(t, + util.Same(sm.servers[nodeID], shouldBeServers), + "nodeID=%v, chainID=%v, have=%v, expect=%v", + nodeID, sm.servers[nodeID], shouldBeServers, + ) } } @@ -183,15 +161,14 @@ func (sm *accessMgrSM) Check(t *rapid.T) { func TestAccessMgrRapid(t *testing.T) { tests := []struct { n int - c int }{ - {n: 1, c: 1}, - {n: 2, c: 1}, - {n: 4, c: 3}, + {n: 1}, + {n: 2}, + {n: 4}, } for _, test := range tests { - t.Run(fmt.Sprintf("N%d C%d", test.n, test.c), rapid.MakeCheck(func(t *rapid.T) { - sm := newAccessMgrSM(t, test.n, test.c) + t.Run(fmt.Sprintf("N%d", test.n), rapid.MakeCheck(func(t *rapid.T) { + sm := newAccessMgrSM(t, test.n) t.Repeat(rapid.StateMachineActions(sm)) })) } diff --git a/packages/chains/accessmanager/dist/input_access_nodes.go b/packages/chainrunner/accessmanager/dist/input_access_nodes.go similarity index 56% rename from packages/chains/accessmanager/dist/input_access_nodes.go rename to packages/chainrunner/accessmanager/dist/input_access_nodes.go index f0f8d92a33..4c9f03ede5 100644 --- a/packages/chains/accessmanager/dist/input_access_nodes.go +++ b/packages/chainrunner/accessmanager/dist/input_access_nodes.go @@ -6,16 +6,14 @@ package dist import ( "github.com/iotaledger/wasp/v2/packages/cryptolib" "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" ) type inputAccessNodes struct { - chainID isc.ChainID accessNodes []*cryptolib.PublicKey } var _ gpa.Input = &inputAccessNodes{} -func NewInputAccessNodes(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) gpa.Input { - return &inputAccessNodes{chainID: chainID, accessNodes: accessNodes} +func NewInputAccessNodes(accessNodes []*cryptolib.PublicKey) gpa.Input { + return &inputAccessNodes{accessNodes: accessNodes} } diff --git a/packages/chainrunner/accessmanager/dist/input_chain_disabled.go b/packages/chainrunner/accessmanager/dist/input_chain_disabled.go new file mode 100644 index 0000000000..4f202b1742 --- /dev/null +++ b/packages/chainrunner/accessmanager/dist/input_chain_disabled.go @@ -0,0 +1,11 @@ +package dist + +import ( + "github.com/iotaledger/wasp/v2/packages/gpa" +) + +type inputChainDisabled struct{} + +func NewInputChainDisabled() gpa.Input { + return &inputChainDisabled{} +} diff --git a/packages/chains/accessmanager/dist/input_trusted_nodes.go b/packages/chainrunner/accessmanager/dist/input_trusted_nodes.go similarity index 100% rename from packages/chains/accessmanager/dist/input_trusted_nodes.go rename to packages/chainrunner/accessmanager/dist/input_trusted_nodes.go diff --git a/packages/chains/accessmanager/dist/msg.go b/packages/chainrunner/accessmanager/dist/msg.go similarity index 100% rename from packages/chains/accessmanager/dist/msg.go rename to packages/chainrunner/accessmanager/dist/msg.go diff --git a/packages/chainrunner/accessmanager/dist/msg_access.go b/packages/chainrunner/accessmanager/dist/msg_access.go new file mode 100644 index 0000000000..011683c688 --- /dev/null +++ b/packages/chainrunner/accessmanager/dist/msg_access.go @@ -0,0 +1,38 @@ +// Copyright 2020 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +package dist + +import ( + "github.com/iotaledger/wasp/v2/packages/gpa" +) + +// Send by a node which has a chain enabled to a node it considers an access node. +type msgAccess struct { + gpa.BasicMessage + senderLClock int `bcs:"export,type=u32"` + receiverLClock int `bcs:"export,type=u32"` + hasAccess bool `bcs:"export"` + isServer bool `bcs:"export"` +} + +var _ gpa.Message = new(msgAccess) + +func newMsgAccess( + recipient gpa.NodeID, + senderLClock, receiverLClock int, + hasAccess bool, + isServer bool, +) gpa.Message { + return &msgAccess{ + BasicMessage: gpa.NewBasicMessage(recipient), + senderLClock: senderLClock, + receiverLClock: receiverLClock, + hasAccess: hasAccess, + isServer: isServer, + } +} + +func (msg *msgAccess) MsgType() gpa.MessageType { + return msgTypeAccess +} diff --git a/packages/chains/accessmanager/dist/msg_access_test.go b/packages/chainrunner/accessmanager/dist/msg_access_test.go similarity index 57% rename from packages/chains/accessmanager/dist/msg_access_test.go rename to packages/chainrunner/accessmanager/dist/msg_access_test.go index e1d0318528..d18b223546 100644 --- a/packages/chains/accessmanager/dist/msg_access_test.go +++ b/packages/chainrunner/accessmanager/dist/msg_access_test.go @@ -10,8 +10,6 @@ import ( bcs "github.com/iotaledger/bcs-go" "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" - "github.com/iotaledger/wasp/v2/packages/isc/isctest" ) func TestMsgAccessSerialization(t *testing.T) { @@ -19,8 +17,8 @@ func TestMsgAccessSerialization(t *testing.T) { gpa.BasicMessage{}, rand.Intn(math.MaxUint32 + 1), rand.Intn(math.MaxUint32 + 1), - []isc.ChainID{isctest.RandomChainID(), isctest.RandomChainID()}, - []isc.ChainID{isctest.RandomChainID(), isctest.RandomChainID()}, + true, + true, } bcs.TestCodec(t, msg) @@ -29,8 +27,8 @@ func TestMsgAccessSerialization(t *testing.T) { gpa.BasicMessage{}, math.MaxUint32, math.MaxUint32, - []isc.ChainID{isctest.RandomChainID(), isctest.RandomChainID()}, - []isc.ChainID{isctest.RandomChainID(), isctest.RandomChainID()}, + true, + true, } bcs.TestCodec(t, msg) diff --git a/packages/chainrunner/chain_listener.go b/packages/chainrunner/chain_listener.go new file mode 100644 index 0000000000..8e9b3fb886 --- /dev/null +++ b/packages/chainrunner/chain_listener.go @@ -0,0 +1,33 @@ +// Copyright 2020 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +package chainrunner + +import ( + "github.com/iotaledger/wasp/v2/packages/chain" + "github.com/iotaledger/wasp/v2/packages/cryptolib" + "github.com/iotaledger/wasp/v2/packages/kv" + "github.com/iotaledger/wasp/v2/packages/state" +) + +type chainsListener struct { + parent chain.ChainListener + accessNodesCB func(accessNodes []*cryptolib.PublicKey) +} + +func NewChainsListener(parent chain.ChainListener, accessNodesCB func(accessNodes []*cryptolib.PublicKey)) chain.ChainListener { + return &chainsListener{parent: parent, accessNodesCB: accessNodesCB} +} + +func (cl *chainsListener) BlockApplied(block state.Block, latestState kv.KVStoreReader) { + cl.parent.BlockApplied(block, latestState) +} + +func (cl *chainsListener) AccessNodesUpdated(accessNodes []*cryptolib.PublicKey) { + cl.accessNodesCB(accessNodes) + cl.parent.AccessNodesUpdated(accessNodes) +} + +func (cl *chainsListener) ServerNodesUpdated(serverNodes []*cryptolib.PublicKey) { + cl.parent.ServerNodesUpdated(serverNodes) +} diff --git a/packages/chains/chains.go b/packages/chainrunner/runner.go similarity index 75% rename from packages/chains/chains.go rename to packages/chainrunner/runner.go index ed00a5eea4..eb88a91b6d 100644 --- a/packages/chains/chains.go +++ b/packages/chainrunner/runner.go @@ -1,8 +1,8 @@ // Copyright 2020 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -// Package chains provides functionality for managing multiple blockchain instances. -package chains +// Package chainrunner provides functionality for managing blockchain instance +package chainrunner import ( "context" @@ -10,11 +10,9 @@ import ( "fmt" "os" "path/filepath" - "strings" "sync" "time" - "github.com/iotaledger/hive.go/ds/shrinkingmap" "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/hive.go/log" @@ -24,7 +22,7 @@ import ( "github.com/iotaledger/wasp/v2/packages/chain/statemanager/gpa" "github.com/iotaledger/wasp/v2/packages/chain/statemanager/gpa/utils" "github.com/iotaledger/wasp/v2/packages/chain/statemanager/snapshots" - "github.com/iotaledger/wasp/v2/packages/chains/accessmanager" + "github.com/iotaledger/wasp/v2/packages/chainrunner/accessmanager" "github.com/iotaledger/wasp/v2/packages/cryptolib" "github.com/iotaledger/wasp/v2/packages/database" "github.com/iotaledger/wasp/v2/packages/isc" @@ -78,11 +76,7 @@ type ChainComponents struct { Metrics *metrics.ChainMetrics // Performance metrics (nil in read-only mode) } -type Provider func() *Chains // TODO: Use DI instead of that. - -type ChainProvider func(chainID isc.ChainID) chain.Chain - -type Chains struct { +type ChainRunner struct { ctx context.Context log log.Logger nodeConnection chain.NodeConnection @@ -111,8 +105,7 @@ type Chains struct { smStateManagerTimerTickPeriod time.Duration smPruningMinStatesToKeep int smPruningMaxStatesToDelete int - defaultSnapshotToLoad *state.BlockHash - snapshotsToLoad map[isc.ChainIDKey]state.BlockHash + snapshotToLoad *state.BlockHash snapshotPeriod uint32 snapshotDelay uint32 snapshotFolderPath string @@ -124,9 +117,10 @@ type Chains struct { consensusStateRegistry cmtlog.ConsensusStateRegistry chainListener chain.ChainListener - mutex *sync.RWMutex - allChains *shrinkingmap.ShrinkingMap[isc.ChainID, *activeChain] - accessMgr accessmanager.AccessMgr + mutex *sync.RWMutex + chain chain.Chain + chainCancelFunc context.CancelFunc + accessMgr accessmanager.AccessMgr cleanupFunc context.CancelFunc shutdownCoordinator *shutdown.Coordinator @@ -139,11 +133,6 @@ type Chains struct { mempoolBroadcastInterval time.Duration } -type activeChain struct { - chain chain.Chain - cancelFunc context.CancelFunc -} - func New( log log.Logger, nodeConnection chain.NodeConnection, @@ -170,7 +159,7 @@ func New( smStateManagerTimerTickPeriod time.Duration, smPruningMinStatesToKeep int, smPruningMaxStatesToDelete int, - snapshotsToLoad []string, + snapshotToLoad string, snapshotPeriod uint32, snapshotDelay uint32, snapshotFolderPath string, @@ -184,7 +173,7 @@ func New( mempoolBroadcastInterval time.Duration, shutdownCoordinator *shutdown.Coordinator, chainMetricsProvider *metrics.ChainMetricsProvider, -) *Chains { +) *ChainRunner { var validatorFeeAddr *cryptolib.Address if validatorAddrStr != "" { addr, err := cryptolib.NewAddressFromHexString(validatorAddrStr) @@ -193,10 +182,9 @@ func New( } validatorFeeAddr = addr } - ret := &Chains{ + ret := &ChainRunner{ log: log, mutex: &sync.RWMutex{}, - allChains: shrinkingmap.New[isc.ChainID, *activeChain](), nodeConnection: nodeConnection, processorConfig: processorConfig, deriveAliasOutputByQuorum: deriveAliasOutputByQuorum, @@ -234,44 +222,25 @@ func New( chainMetricsProvider: chainMetricsProvider, validatorFeeAddr: validatorFeeAddr, } - ret.initSnapshotsToLoad(snapshotsToLoad) + ret.initSnapshotToLoad(snapshotToLoad) ret.chainListener = NewChainsListener(chainListener, ret.chainAccessUpdatedCB) return ret } -func (c *Chains) initSnapshotsToLoad(configs []string) { - c.defaultSnapshotToLoad = nil - c.snapshotsToLoad = make(map[isc.ChainIDKey]state.BlockHash) - for _, config := range configs { - configSplit := strings.Split(config, ":") - // NOTE: Split does not return 0 length slice if second parameter is not zero length string; this is not checked - if len(configSplit) == 1 { - blockHash, err := state.BlockHashFromString(configSplit[0]) - if err != nil { - c.log.LogWarnf("Parsing snapshots to load: %s is not a block hash: %v", configSplit[0], err) - continue - } - c.defaultSnapshotToLoad = &blockHash - } else { - chainID, err := isc.ChainIDFromString(configSplit[0]) - if err != nil { - c.log.LogWarnf("Parsing snapshots to load: %s in %s is not a chain ID: %v", configSplit[0], config, err) - continue - } - blockHash, err := state.BlockHashFromString(configSplit[1]) - if err != nil { - c.log.LogWarnf("Parsing snapshots to load: %s in %s is not a block hash: %v", configSplit[1], config, err) - continue - } - c.snapshotsToLoad[chainID.Key()] = blockHash - } +func (c *ChainRunner) initSnapshotToLoad(config string) { + c.snapshotToLoad = nil + blockHash, err := state.BlockHashFromString(config) + if err != nil { + c.log.LogErrorf("Parsing snapshots to load: %s is not a block hash: %v", config, err) + return } + c.snapshotToLoad = &blockHash } -// Run starts the chains manager with the specified mode. +// Run starts the chain runner with the specified mode. // If readOnlyPath is empty, runs in full operational mode. // If readOnlyPath is provided, runs in read-only mode using the specified database path. -func (c *Chains) Run(ctx context.Context, readOnlyPath string) error { +func (c *ChainRunner) Run(ctx context.Context, readOnlyPath string) error { mode := ChainMode{ReadOnlyPath: readOnlyPath} if err := mode.Validate(); err != nil { return fmt.Errorf("invalid chain mode: %w", err) @@ -279,7 +248,7 @@ func (c *Chains) Run(ctx context.Context, readOnlyPath string) error { return c.runWithMode(ctx, mode) } -func (c *Chains) runWithMode(ctx context.Context, mode ChainMode) error { +func (c *ChainRunner) runWithMode(ctx context.Context, mode ChainMode) error { if !mode.IsReadOnly() { if err := c.nodeConnection.WaitUntilInitiallySynced(ctx); err != nil { return fmt.Errorf("waiting for L1 node to become sync failed, error: %w", err) @@ -289,7 +258,7 @@ func (c *Chains) runWithMode(ctx context.Context, mode ChainMode) error { defer c.mutex.Unlock() if c.ctx != nil { - return errors.New("chains already running") + return errors.New("chain already running") } c.ctx = ctx @@ -299,8 +268,8 @@ func (c *Chains) runWithMode(ctx context.Context, mode ChainMode) error { unhook := c.chainRecordRegistryProvider.Events().ChainRecordModified.Hook(func(event *registry.ChainRecordModifiedEvent) { c.mutex.RLock() defer c.mutex.RUnlock() - if chain, exists := c.allChains.Get(event.ChainRecord.ChainID()); exists { - chain.chain.ConfigUpdated(event.ChainRecord.AccessNodes) + if c.chain != nil { + c.chain.ConfigUpdated(event.ChainRecord.AccessNodes) } }).Unhook c.cleanupFunc = unhook @@ -309,51 +278,46 @@ func (c *Chains) runWithMode(ctx context.Context, mode ChainMode) error { defer c.mutex.Unlock() if c.ctx != nil { - return errors.New("chains already running") + return errors.New("chain already running") } c.ctx = ctx } - return c.activateAllFromRegistry(mode) //nolint:contextcheck + return c.activateFromRegistry(mode) //nolint:contextcheck } -func (c *Chains) Close() { +func (c *ChainRunner) Close() { util.ExecuteIfNotNil(c.cleanupFunc) c.mutex.RLock() defer c.mutex.RUnlock() - c.allChains.ForEach(func(_ isc.ChainID, ac *activeChain) bool { - ac.cancelFunc() - return true - }) + c.chainCancelFunc() c.shutdownCoordinator.WaitNestedWithLogging(1 * time.Second) c.shutdownCoordinator.Done() util.ExecuteIfNotNil(c.trustedNetworkListenerCancel) c.trustedNetworkListenerCancel = nil } -func (c *Chains) trustedPeersUpdatedCB(trustedPeers []*peering.TrustedPeer) { +func (c *ChainRunner) trustedPeersUpdatedCB(trustedPeers []*peering.TrustedPeer) { trustedPubKeys := lo.Map(trustedPeers, func(tp *peering.TrustedPeer) *cryptolib.PublicKey { return tp.PubKey() }) c.accessMgr.TrustedNodes(trustedPubKeys) } -func (c *Chains) chainServersUpdatedCB(chainID isc.ChainID, servers []*cryptolib.PublicKey) { +func (c *ChainRunner) chainServersUpdatedCB(servers []*cryptolib.PublicKey) { c.mutex.RLock() defer c.mutex.RUnlock() - ch, exists := c.allChains.Get(chainID) - if !exists { + if c.chain == nil { return } - ch.chain.ServersUpdated(servers) + c.chain.ServersUpdated(servers) } -func (c *Chains) chainAccessUpdatedCB(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) { - c.accessMgr.ChainAccessNodes(chainID, accessNodes) +func (c *ChainRunner) chainAccessUpdatedCB(accessNodes []*cryptolib.PublicKey) { + c.accessMgr.ChainAccessNodes(accessNodes) } -func (c *Chains) activateAllFromRegistry(mode ChainMode) error { +func (c *ChainRunner) activateFromRegistry(mode ChainMode) error { var innerErr error - if err := c.chainRecordRegistryProvider.ForEachActiveChainRecord(func(chainRecord *registry.ChainRecord) bool { - chainID := chainRecord.ChainID() - if err := c.activateWithoutLocking(chainID, mode); err != nil { + if err := c.chainRecordRegistryProvider.ForActiveChainRecord(func(chainRecord *registry.ChainRecord) bool { + if err := c.activateWithoutLocking(mode); err != nil { innerErr = fmt.Errorf("cannot activate chain %s: %w", chainRecord.ChainID(), err) return false } @@ -365,7 +329,7 @@ func (c *Chains) activateAllFromRegistry(mode ChainMode) error { } // activateWithoutLocking activates a chain in the node. -func (c *Chains) activateWithoutLocking(chainID isc.ChainID, mode ChainMode) error { +func (c *ChainRunner) activateWithoutLocking(mode ChainMode) error { if c.ctx == nil { return errors.New("run chains first") } @@ -374,22 +338,24 @@ func (c *Chains) activateWithoutLocking(chainID isc.ChainID, mode ChainMode) err } // Check, maybe it is already running. - if c.allChains.Has(chainID) { - c.log.LogDebugf("Chain %v = %v is already activated", chainID.ShortString(), chainID.String()) + if c.chain != nil { + c.log.LogDebugf("Chain is already activated") return nil } // Activate the chain in the persistent store, if it is not activated yet. - chainRecord, err := c.chainRecordRegistryProvider.ChainRecord(chainID) - if err != nil { - return fmt.Errorf("cannot get chain record for %v: %w", chainID, err) + chainRecord := c.chainRecordRegistryProvider.ChainRecord() + if chainRecord == nil { + return fmt.Errorf("chain record does not exist") } if !chainRecord.Active { - if _, err2 := c.chainRecordRegistryProvider.ActivateChainRecord(chainID); err2 != nil { + if _, err2 := c.chainRecordRegistryProvider.ActivateChainRecord(); err2 != nil { return fmt.Errorf("cannot activate chain: %w", err2) } } + chainID := chainRecord.ChainID() + chainKVStore, writeMutex, err := c.chainStateStoreProvider(chainID) if err != nil { return fmt.Errorf("error when creating chain KV store: %w", err) @@ -455,16 +421,14 @@ func (c *Chains) activateWithoutLocking(chainID isc.ChainID, mode ChainMode) err chainCancel() return fmt.Errorf("Chains.Activate: failed to create chain object: %w", err) } - c.allChains.Set(chainID, &activeChain{ - chain: newChain, - cancelFunc: chainCancel, - }) + c.chain = newChain + c.chainCancelFunc = chainCancel c.log.LogInfof("activated chain: %v = %s", chainID.ShortString(), chainID.String()) return nil } -func (c *Chains) setStateManagerParameters(stateManagerParameters gpa.StateManagerParameters) gpa.StateManagerParameters { +func (c *ChainRunner) setStateManagerParameters(stateManagerParameters gpa.StateManagerParameters) gpa.StateManagerParameters { stateManagerParameters.BlockCacheMaxSize = c.smBlockCacheMaxSize stateManagerParameters.BlockCacheBlocksInCacheDuration = c.smBlockCacheBlocksInCacheDuration stateManagerParameters.BlockCacheBlockCleaningPeriod = c.smBlockCacheBlockCleaningPeriod @@ -479,7 +443,7 @@ func (c *Chains) setStateManagerParameters(stateManagerParameters gpa.StateManag } // createChainStore creates the appropriate store based on the chain mode -func (c *Chains) createChainStore(chainKVStore kvstore.KVStore, writeMutex *sync.Mutex, mode ChainMode, chainMetrics *metrics.ChainMetrics) (indexedstore.IndexedStore, error) { +func (c *ChainRunner) createChainStore(chainKVStore kvstore.KVStore, writeMutex *sync.Mutex, mode ChainMode, chainMetrics *metrics.ChainMetrics) (indexedstore.IndexedStore, error) { if mode.IsReadOnly() { readOnlyDBStore, err := state.NewStoreReadonly(chainKVStore) if err != nil { @@ -499,7 +463,7 @@ func (c *Chains) createChainStore(chainKVStore kvstore.KVStore, writeMutex *sync // initializeChainComponents initializes all chain components based on the mode. // For full operational mode, creates all components including WAL, metrics, and snapshot manager. // For read-only mode, creates minimal components with read-only store access. -func (c *Chains) initializeChainComponents( +func (c *ChainRunner) initializeChainComponents( chainID isc.ChainID, chainKVStore kvstore.KVStore, writeMutex *sync.Mutex, @@ -558,7 +522,7 @@ func (c *Chains) initializeChainComponents( }, nil } -func (c *Chains) setSnapshotManager( +func (c *ChainRunner) setSnapshotManager( chainID isc.ChainID, chainCtx context.Context, chainShutdownCoordinator *shutdown.Coordinator, @@ -566,18 +530,11 @@ func (c *Chains) setSnapshotManager( chainMetrics *metrics.ChainMetrics, chainLog log.Logger, ) snapshots.SnapshotManager { - blockHash, ok := c.snapshotsToLoad[chainID.Key()] - var snapshotToLoad *state.BlockHash - if ok { - snapshotToLoad = &blockHash - } else { - snapshotToLoad = c.defaultSnapshotToLoad - } chainSnapshotManager, err := snapshots.NewSnapshotManager( chainCtx, chainShutdownCoordinator.Nested("SnapMgr"), chainID, - snapshotToLoad, + c.snapshotToLoad, c.snapshotPeriod, c.snapshotDelay, c.snapshotFolderPath, @@ -593,62 +550,52 @@ func (c *Chains) setSnapshotManager( } // Activate activates a chain in the node. -func (c *Chains) Activate(chainID isc.ChainID) error { +func (c *ChainRunner) Activate() error { c.mutex.Lock() defer c.mutex.Unlock() - return c.activateWithoutLocking(chainID, ChainMode{}) + return c.activateWithoutLocking(ChainMode{}) } // Deactivate a chain in the node. -func (c *Chains) Deactivate(chainID isc.ChainID) error { +func (c *ChainRunner) Deactivate() error { c.mutex.Lock() defer c.mutex.Unlock() - if _, err := c.chainRecordRegistryProvider.DeactivateChainRecord(chainID); err != nil { - return fmt.Errorf("cannot deactivate chain %v: %w", chainID, err) + if c.chain == nil { + c.log.LogDebugf("chain is not active") + return nil } - ch, exists := c.allChains.Get(chainID) - if !exists { - c.log.LogDebugf("chain is not active: %v = %s", chainID.ShortString(), chainID.String()) - return nil + if _, err := c.chainRecordRegistryProvider.DeactivateChainRecord(); err != nil { + return fmt.Errorf("cannot deactivate chain %v: %w", c.chain.ID(), err) } - ch.cancelFunc() - c.accessMgr.ChainDismissed(chainID) - c.allChains.Delete(chainID) - c.log.LogDebugf("chain has been deactivated: %v = %s", chainID.ShortString(), chainID.String()) - return nil -} -// Get returns active chain object or nil if it doesn't exist -// lazy unsubscribing -func (c *Chains) Get(chainID isc.ChainID) (chain.Chain, error) { - c.mutex.RLock() - defer c.mutex.RUnlock() + c.chainCancelFunc() + c.accessMgr.ChainDismissed() - ret, exists := c.allChains.Get(chainID) - if !exists { - return nil, interfaces.ErrChainNotFound - } - return ret.chain, nil + c.log.LogDebugf("chain has been deactivated: %v = %s", c.chain.ID().ShortString(), c.chain.ID().String()) + c.chain = nil + c.chainCancelFunc = nil + + return nil } -func (c *Chains) GetFirst() (chain.Chain, error) { +// Chain returns active chain object or nil if it doesn't exist +// lazy unsubscribing +func (c *ChainRunner) Chain() (chain.Chain, error) { c.mutex.RLock() defer c.mutex.RUnlock() - if c.allChains.Size() == 0 { + if c.chain == nil { return nil, interfaces.ErrChainNotFound } - - ret := c.allChains.Values()[0] - return ret.chain, nil + return c.chain, nil } -func (c *Chains) ValidatorAddress() *cryptolib.Address { +func (c *ChainRunner) ValidatorAddress() *cryptolib.Address { return c.validatorFeeAddr } -func (c *Chains) IsArchiveNode() bool { +func (c *ChainRunner) IsArchiveNode() bool { return c.smPruningMinStatesToKeep < 1 } diff --git a/packages/chains/accessmanager/dist/input_chain_disabled.go b/packages/chains/accessmanager/dist/input_chain_disabled.go deleted file mode 100644 index bcd9ff432c..0000000000 --- a/packages/chains/accessmanager/dist/input_chain_disabled.go +++ /dev/null @@ -1,14 +0,0 @@ -package dist - -import ( - "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" -) - -type inputChainDisabled struct { - chainID isc.ChainID -} - -func NewInputChainDisabled(chainID isc.ChainID) gpa.Input { - return &inputChainDisabled{chainID: chainID} -} diff --git a/packages/chains/accessmanager/dist/msg_access.go b/packages/chains/accessmanager/dist/msg_access.go deleted file mode 100644 index e68274e437..0000000000 --- a/packages/chains/accessmanager/dist/msg_access.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -package dist - -import ( - "github.com/iotaledger/wasp/v2/packages/gpa" - "github.com/iotaledger/wasp/v2/packages/isc" -) - -// Send by a node which has a chain enabled to a node it considers an access node. -type msgAccess struct { - gpa.BasicMessage - senderLClock int `bcs:"export,type=u32"` - receiverLClock int `bcs:"export,type=u32"` - accessForChains []isc.ChainID `bcs:"export,len_bytes=2"` - serverForChains []isc.ChainID `bcs:"export,len_bytes=2"` -} - -var _ gpa.Message = new(msgAccess) - -func newMsgAccess( - recipient gpa.NodeID, - senderLClock, receiverLClock int, - accessForChains []isc.ChainID, - serverForChains []isc.ChainID, -) gpa.Message { - return &msgAccess{ - BasicMessage: gpa.NewBasicMessage(recipient), - senderLClock: senderLClock, - receiverLClock: receiverLClock, - accessForChains: accessForChains, - serverForChains: serverForChains, - } -} - -func (msg *msgAccess) MsgType() gpa.MessageType { - return msgTypeAccess -} diff --git a/packages/chains/chains_listener.go b/packages/chains/chains_listener.go deleted file mode 100644 index a9011514ec..0000000000 --- a/packages/chains/chains_listener.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2020 IOTA Stiftung -// SPDX-License-Identifier: Apache-2.0 - -package chains - -import ( - "github.com/iotaledger/wasp/v2/packages/chain" - "github.com/iotaledger/wasp/v2/packages/cryptolib" - "github.com/iotaledger/wasp/v2/packages/isc" - "github.com/iotaledger/wasp/v2/packages/kv" - "github.com/iotaledger/wasp/v2/packages/state" -) - -type chainsListener struct { - parent chain.ChainListener - accessNodesCB func(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) -} - -func NewChainsListener(parent chain.ChainListener, accessNodesCB func(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey)) chain.ChainListener { - return &chainsListener{parent: parent, accessNodesCB: accessNodesCB} -} - -func (cl *chainsListener) BlockApplied(chainID isc.ChainID, block state.Block, latestState kv.KVStoreReader) { - cl.parent.BlockApplied(chainID, block, latestState) -} - -func (cl *chainsListener) AccessNodesUpdated(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) { - cl.accessNodesCB(chainID, accessNodes) - cl.parent.AccessNodesUpdated(chainID, accessNodes) -} - -func (cl *chainsListener) ServerNodesUpdated(chainID isc.ChainID, serverNodes []*cryptolib.PublicKey) { - cl.parent.ServerNodesUpdated(chainID, serverNodes) -} diff --git a/packages/database/manager.go b/packages/database/manager.go index 2c51c76b64..127673fdee 100644 --- a/packages/database/manager.go +++ b/packages/database/manager.go @@ -61,7 +61,7 @@ func NewChainStateDatabaseManager(chainRecordRegistryProvider registry.ChainReco // load all active chain state databases var innerErr error - if err := chainRecordRegistryProvider.ForEachActiveChainRecord(func(cr *registry.ChainRecord) bool { + if err := chainRecordRegistryProvider.ForActiveChainRecord(func(cr *registry.ChainRecord) bool { _, err := m.createDatabase(cr.ChainID()) if err != nil { innerErr = err diff --git a/packages/database/manager_test.go b/packages/database/manager_test.go index 536bde2c08..a6f25c23d7 100644 --- a/packages/database/manager_test.go +++ b/packages/database/manager_test.go @@ -60,7 +60,10 @@ func TestWriteAmplification(t *testing.T) { chainRecordRegistry, err := registry.NewChainRecordRegistryImpl("") require.NoError(t, err) - chainRecordRegistry.ActivateChainRecord(chainID) + rec, err := chainRecordRegistry.ActivateChainRecord() + require.NoError(t, err) + require.NotNil(t, rec) + require.Equal(t, chainID, rec.ChainID()) tempDir := fmt.Sprintf("/tmp/TestWriteAmplification-%v", time.Now().UnixMilli()) diff --git a/packages/evm/jsonrpc/evmchain.go b/packages/evm/jsonrpc/evmchain.go index 722a817709..1355724020 100644 --- a/packages/evm/jsonrpc/evmchain.go +++ b/packages/evm/jsonrpc/evmchain.go @@ -92,9 +92,6 @@ func NewEVMChain( blocksFromPublisher := pipe.NewInfinitePipe[*publisher.BlockWithTrieRoot]() pub.Events.NewBlock.Hook(func(ev *publisher.ISCEvent[*publisher.BlockWithTrieRoot]) { - if !ev.ChainID.Equals(*e.backend.ISCChainID()) { - return - } blocksFromPublisher.In() <- ev.Payload }) diff --git a/packages/nodeconn/nodeconn.go b/packages/nodeconn/nodeconn.go index 7f5f47a4e4..fa81cd0ec6 100644 --- a/packages/nodeconn/nodeconn.go +++ b/packages/nodeconn/nodeconn.go @@ -12,7 +12,6 @@ import ( "time" "github.com/iotaledger/hive.go/app/shutdown" - "github.com/iotaledger/hive.go/ds/shrinkingmap" "github.com/iotaledger/hive.go/log" "github.com/iotaledger/wasp/v2/clients" "github.com/iotaledger/wasp/v2/clients/iota-go/iotaclient" @@ -29,11 +28,6 @@ import ( "github.com/iotaledger/wasp/v2/packages/util" ) -const ( - chainsCleanupThresholdRatio = 50.0 - chainsCleanupThresholdCount = 10 -) - var ErrOperationAborted = errors.New("operation was aborted") type SingleL1Info struct { @@ -61,8 +55,9 @@ type nodeConnection struct { wsURL string httpURL string maxNumberOfRequests int - chainsLock sync.RWMutex - chainsMap *shrinkingmap.ShrinkingMap[isc.ChainID, *ncChain] + chainLock sync.RWMutex + chainID isc.ChainID + chain *ncChain shutdownHandler *shutdown.ShutdownHandler } @@ -91,11 +86,7 @@ func New( httpClient: httpClient, l1ParamsFetcher: parameters.NewL1ParamsFetcher(httpClient.IotaClient(), log), maxNumberOfRequests: maxNumberOfRequests, - chainsMap: shrinkingmap.New[isc.ChainID, *ncChain]( - shrinkingmap.WithShrinkingThresholdRatio(chainsCleanupThresholdRatio), - shrinkingmap.WithShrinkingThresholdCount(chainsCleanupThresholdCount), - ), - shutdownHandler: shutdownHandler, + shutdownHandler: shutdownHandler, }, nil } @@ -122,23 +113,20 @@ func (nc *nodeConnection) AttachChain( <-ctx.Done() ncc.WaitUntilStopped() - nc.chainsLock.Lock() - defer nc.chainsLock.Unlock() + nc.chainLock.Lock() + defer nc.chainLock.Unlock() - nc.chainsMap.Delete(chainID) + nc.chain = nil + nc.chainID = isc.ChainID{} util.ExecuteIfNotNil(onChainDisconnect) - nc.LogDebugf("chain unregistered: %s = %s, |remaining|=%v", chainID.ShortString(), chainID, nc.chainsMap.Size()) + nc.LogDebugf("chain unregistered: %s = %s", chainID.ShortString()) }() return nil } -func (nc *nodeConnection) GetGasCoinRef(ctx context.Context, chainID isc.ChainID) (*coin.CoinWithRef, error) { - ncChain, ok := nc.chainsMap.Get(chainID) - if !ok { - panic("unexpected chainID") - } - gasCoinRef, gasCoinBal, err := ncChain.feed.GetChainGasCoin(ctx) +func (nc *nodeConnection) GetGasCoinRef(ctx context.Context) (*coin.CoinWithRef, error) { + gasCoinRef, gasCoinBal, err := nc.chain.feed.GetChainGasCoin(ctx) if err != nil { return nil, err } @@ -197,13 +185,9 @@ func (nc *nodeConnection) ConsensusL1InfoProposal( return t } -func (nc *nodeConnection) RefreshOnLedgerRequests(ctx context.Context, chainID isc.ChainID) { - ncChain, ok := nc.chainsMap.Get(chainID) - if !ok { - panic("unexpected chainID") - } - if err := ncChain.syncChainState(ctx); err != nil { - nc.LogErrorf("error refreshing outputs: %s", err.Error()) +func (nc *nodeConnection) RefreshOnLedgerRequests(ctx context.Context) { + if err := nc.chain.syncChainState(ctx); err != nil { + nc.LogError(fmt.Sprintf("error refreshing outputs: %s", err.Error())) } } @@ -239,30 +223,16 @@ func (nc *nodeConnection) L1ParamsFetcher() parameters.L1ParamsFetcher { return nc.l1ParamsFetcher } -// GetChain returns the chain if it was registered, otherwise it returns an error. -func (nc *nodeConnection) getChain(chainID isc.ChainID) (*ncChain, error) { - nc.chainsLock.RLock() - defer nc.chainsLock.RUnlock() - - ncc, exists := nc.chainsMap.Get(chainID) - if !exists { - return nil, fmt.Errorf("chain %v is not connected", chainID.String()) - } - return ncc, nil -} - func (nc *nodeConnection) PublishTX( ctx context.Context, - chainID isc.ChainID, tx iotasigner.SignedTransaction, callback chain.TxPostHandler, ) error { // check if the chain exists - ncc, err := nc.getChain(chainID) - if err != nil { - return err + if nc.chain == nil { + return fmt.Errorf("chain not attached") } - ncc.publishTxQueue <- publishTxTask{ + nc.chain.publishTxQueue <- publishTxTask{ ctx: ctx, tx: tx, cb: callback, @@ -279,8 +249,8 @@ func (nc *nodeConnection) createChain( readOnly bool, onChainConnect func(), ) (*ncChain, error) { - nc.chainsLock.Lock() - defer nc.chainsLock.Unlock() + nc.chainLock.Lock() + defer nc.chainLock.Unlock() var ncc *ncChain var err error @@ -294,7 +264,8 @@ func (nc *nodeConnection) createChain( } } - nc.chainsMap.Set(chainID, ncc) + nc.chainID = chainID + nc.chain = ncc util.ExecuteIfNotNil(onChainConnect) nc.LogDebugf("chain registered: %s = %s", chainID.ShortString(), chainID) diff --git a/packages/publisher/events.go b/packages/publisher/events.go index 5d0a015cfe..5b1681df92 100644 --- a/packages/publisher/events.go +++ b/packages/publisher/events.go @@ -27,7 +27,6 @@ type ISCEvent[T any] struct { Kind ISCEventType `json:"kind"` Issuer isc.AgentID `json:"issuer"` // (AgentID) nil means issued by the VM RequestID isc.RequestID `json:"requestID"` // (isc.RequestID) - ChainID isc.ChainID `json:"chainID"` // (isc.ChainID) Payload T `json:"payload"` } @@ -38,7 +37,7 @@ func (e *ISCEvent[T]) String() string { issuerStr = e.Issuer.String() } - return fmt.Sprintf("%s | %s (%s)", e.ChainID, issuerStr, e.Kind) + return fmt.Sprintf("%s (%s)", issuerStr, e.Kind) } type BlockWithTrieRoot struct { @@ -62,7 +61,6 @@ func triggerEvent[T any](events *Events, event *event.Event1[*ISCEvent[T]], obj Kind: obj.Kind, Issuer: obj.Issuer, RequestID: obj.RequestID, - ChainID: obj.ChainID, Payload: obj.Payload, }) } @@ -70,7 +68,6 @@ func triggerEvent[T any](events *Events, event *event.Event1[*ISCEvent[T]], obj // PublishBlockEvents extracts the events from a block, its returns a chan of ISCEventType, so they can be filtered func PublishBlockEvents(blockApplied *blockApplied, events *Events, log log.Logger) { block := blockApplied.block - chainID := blockApplied.chainID // // Publish notifications about the state change (new block). blockIndex := block.StateIndex() @@ -87,7 +84,6 @@ func PublishBlockEvents(blockApplied *blockApplied, events *Events, log log.Logg BlockInfo: blockInfo, TrieRoot: block.TrieRoot(), }, - ChainID: chainID, }) // @@ -114,7 +110,6 @@ func PublishBlockEvents(blockApplied *blockApplied, events *Events, log log.Logg Issuer: receipt.Request.SenderAccount(), Payload: &ReceiptWithError{RequestReceipt: parsedReceipt, Error: vmError}, RequestID: receipt.Request.ID(), - ChainID: chainID, }) } } @@ -133,6 +128,5 @@ func PublishBlockEvents(blockApplied *blockApplied, events *Events, log log.Logg Kind: ISCEventKindBlockEvents, Issuer: &isc.NilAgentID{}, Payload: payload, - ChainID: chainID, }) } diff --git a/packages/publisher/publisher.go b/packages/publisher/publisher.go index da1d19faff..b5a1158ead 100644 --- a/packages/publisher/publisher.go +++ b/packages/publisher/publisher.go @@ -36,7 +36,6 @@ type Publisher struct { // var _ chain.ChainListener = &Publisher{} type blockApplied struct { - chainID isc.ChainID block state.Block latestState kv.KVStoreReader } @@ -59,19 +58,19 @@ func New(log log.Logger) *Publisher { // BlockApplied implements the chain.ChainListener interface. // NOTE: Do not block the caller! -func (p *Publisher) BlockApplied(chainID isc.ChainID, block state.Block, latestState kv.KVStoreReader) { - p.blockAppliedPipe.In() <- &blockApplied{chainID: chainID, block: block, latestState: latestState} +func (p *Publisher) BlockApplied(block state.Block, latestState kv.KVStoreReader) { + p.blockAppliedPipe.In() <- &blockApplied{block: block, latestState: latestState} } // AccessNodesUpdated implements the chain.ChainListener interface. // NOTE: Do not block the caller! -func (p *Publisher) AccessNodesUpdated(chainID isc.ChainID, accessNodes []*cryptolib.PublicKey) { +func (p *Publisher) AccessNodesUpdated(accessNodes []*cryptolib.PublicKey) { // We don't need this event. } // ServerNodesUpdated implements the chain.ChainListener interface. // NOTE: Do not block the caller! -func (p *Publisher) ServerNodesUpdated(chainID isc.ChainID, serverNodes []*cryptolib.PublicKey) { +func (p *Publisher) ServerNodesUpdated(serverNodes []*cryptolib.PublicKey) { // We don't need this event. } diff --git a/packages/registry/chain_registry.go b/packages/registry/chain_registry.go index 7c84468936..1bdc68ea9a 100644 --- a/packages/registry/chain_registry.go +++ b/packages/registry/chain_registry.go @@ -144,6 +144,10 @@ type ChainRecordRegistryEvents struct { } type ChainRecordRegistryImpl struct { + // We only have one chain. Multi-chain code left for backwards compatibility. + // This field is automatically updated inside OnChangeMap's callback. + chainID isc.ChainID + onChangeMap *onchangemap.OnChangeMap[isc.ChainIDKey, isc.ChainID, *ChainRecord] events *ChainRecordRegistryEvents @@ -167,16 +171,36 @@ func NewChainRecordRegistryImpl(filePath string) (*ChainRecordRegistryImpl, erro }, } + // Upon initialization we dont need to store records onto disk, as they just were read from the disk. + // But we still do need callback to be called for chain ID to be updated. + writeChainRecordsUponUpdate := false + registry.onChangeMap = onchangemap.NewOnChangeMap( - onchangemap.WithChangedCallback[isc.ChainIDKey, isc.ChainID](registry.writeChainRecordsJSON), + onchangemap.WithChangedCallback[isc.ChainIDKey, isc.ChainID](func(chainRecords []*ChainRecord) error { + // Saving chain ID + if len(chainRecords) > 1 { + return fmt.Errorf("multiple chain records found, expected <= 1: %d", len(chainRecords)) + } else if len(chainRecords) != 0 { + registry.chainID = chainRecords[0].ID() + } else { + registry.chainID = isc.ChainID{} + } + + if writeChainRecordsUponUpdate { + return registry.writeChainRecordsJSON(chainRecords) + } + + return nil + }), ) + registry.onChangeMap.CallbacksEnabled(true) // load chain records on startup if err := registry.loadChainRecordsJSON(); err != nil { return nil, fmt.Errorf("unable to read chain records configuration (%s): %w", filePath, err) } - registry.onChangeMap.CallbacksEnabled(true) + writeChainRecordsUponUpdate = true return registry, nil } @@ -193,7 +217,7 @@ func (p *ChainRecordRegistryImpl) loadChainRecordsJSON() error { } for i := range tmpChainRecords.ChainRecords { - if err := p.AddChainRecord(tmpChainRecords.ChainRecords[i]); err != nil { + if err := p.SetChainRecord(tmpChainRecords.ChainRecords[i]); err != nil { return fmt.Errorf("unable to add ChainRecord to registry: %w", err) } } @@ -222,24 +246,20 @@ func (p *ChainRecordRegistryImpl) Events() *ChainRecordRegistryEvents { return p.events } -func (p *ChainRecordRegistryImpl) ChainRecord(chainID isc.ChainID) (*ChainRecord, error) { - chainRecord, err := p.onChangeMap.Get(chainID) +func (p *ChainRecordRegistryImpl) ChainRecord() *ChainRecord { + chainRecord, err := p.onChangeMap.Get(p.chainID) if err != nil { // chain record doesn't exist - return nil, nil + return nil } - return chainRecord, nil -} - -func (p *ChainRecordRegistryImpl) ChainRecords() ([]*ChainRecord, error) { - return lo.Values(p.onChangeMap.All()), nil + return chainRecord } -func (p *ChainRecordRegistryImpl) ForEachActiveChainRecord(consumer func(*ChainRecord) bool) error { - chainRecords, err := p.ChainRecords() - if err != nil { - return err +func (p *ChainRecordRegistryImpl) ForActiveChainRecord(consumer func(*ChainRecord) bool) error { + chainRecords := lo.Values(p.onChangeMap.All()) + if len(chainRecords) > 1 { + return fmt.Errorf("multiple chain records found, expected <= 1: %d", len(chainRecords)) } for _, chainRecord := range chainRecords { @@ -255,7 +275,7 @@ func (p *ChainRecordRegistryImpl) ForEachActiveChainRecord(consumer func(*ChainR return nil } -func (p *ChainRecordRegistryImpl) AddChainRecord(chainRecord *ChainRecord) error { +func (p *ChainRecordRegistryImpl) SetChainRecord(chainRecord *ChainRecord) error { chains := len(p.onChangeMap.All()) // Only allow a single chain if chains != 0 { @@ -265,19 +285,19 @@ func (p *ChainRecordRegistryImpl) AddChainRecord(chainRecord *ChainRecord) error return p.onChangeMap.Add(chainRecord) } -func (p *ChainRecordRegistryImpl) DeleteChainRecord(chainID isc.ChainID) error { - return p.onChangeMap.Delete(chainID) +func (p *ChainRecordRegistryImpl) DeleteChainRecord() error { + return p.onChangeMap.Delete(p.chainID) } // UpdateChainRecord modifies a ChainRecord in the Registry. -func (p *ChainRecordRegistryImpl) UpdateChainRecord(chainID isc.ChainID, callback func(*ChainRecord) bool) (*ChainRecord, error) { +func (p *ChainRecordRegistryImpl) UpdateChainRecord(callback func(*ChainRecord) bool) (*ChainRecord, error) { var modified bool callbackHook := func(chainRecord *ChainRecord) bool { modified = callback(chainRecord) return modified } - chainRecord, err := p.onChangeMap.Modify(chainID, callbackHook) + chainRecord, err := p.onChangeMap.Modify(p.chainID, callbackHook) if err != nil { return chainRecord, err } @@ -291,8 +311,8 @@ func (p *ChainRecordRegistryImpl) UpdateChainRecord(chainID isc.ChainID, callbac return chainRecord, nil } -func (p *ChainRecordRegistryImpl) ActivateChainRecord(chainID isc.ChainID) (*ChainRecord, error) { - return p.UpdateChainRecord(chainID, func(r *ChainRecord) bool { +func (p *ChainRecordRegistryImpl) ActivateChainRecord() (*ChainRecord, error) { + return p.UpdateChainRecord(func(r *ChainRecord) bool { if r.Active { // chain was already active return false @@ -302,8 +322,8 @@ func (p *ChainRecordRegistryImpl) ActivateChainRecord(chainID isc.ChainID) (*Cha }) } -func (p *ChainRecordRegistryImpl) DeactivateChainRecord(chainID isc.ChainID) (*ChainRecord, error) { - return p.UpdateChainRecord(chainID, func(r *ChainRecord) bool { +func (p *ChainRecordRegistryImpl) DeactivateChainRecord() (*ChainRecord, error) { + return p.UpdateChainRecord(func(r *ChainRecord) bool { if !r.Active { // chain was already disabled return false diff --git a/packages/registry/chain_registry_test.go b/packages/registry/chain_registry_test.go index dcc1a9ef83..44a23e2de9 100644 --- a/packages/registry/chain_registry_test.go +++ b/packages/registry/chain_registry_test.go @@ -15,7 +15,7 @@ func TestNewChainStateDatabaseManager(t *testing.T) { chainID := isctest.RandomChainID() - err = chainRecordRegistry.AddChainRecord(registry.NewChainRecord(chainID, false, nil)) + err = chainRecordRegistry.SetChainRecord(registry.NewChainRecord(chainID, false, nil)) require.NoError(t, err) modified := false @@ -28,8 +28,10 @@ func TestNewChainStateDatabaseManager(t *testing.T) { unhook := chainRecordRegistry.Events().ChainRecordModified.Hook(chainRecordModified).Unhook defer unhook() - _, err = chainRecordRegistry.ActivateChainRecord(chainID) + rec, err := chainRecordRegistry.ActivateChainRecord() require.NoError(t, err) + require.NotNil(t, rec) + require.Equal(t, chainID, rec.ChainID()) require.True(t, modified) require.True(t, active) diff --git a/packages/registry/providers.go b/packages/registry/providers.go index 2c0fa4ef6a..ee3b23cb0c 100644 --- a/packages/registry/providers.go +++ b/packages/registry/providers.go @@ -7,7 +7,6 @@ import ( "context" "github.com/iotaledger/wasp/v2/packages/cryptolib" - "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/peering" "github.com/iotaledger/wasp/v2/packages/tcrypto" ) @@ -24,14 +23,13 @@ type DKShareRegistryProvider interface { type ChainRecordRegistryProvider interface { Events() *ChainRecordRegistryEvents - ChainRecord(chainID isc.ChainID) (*ChainRecord, error) - ChainRecords() ([]*ChainRecord, error) - ForEachActiveChainRecord(consumer func(*ChainRecord) bool) error - AddChainRecord(chainRecord *ChainRecord) error - DeleteChainRecord(chainID isc.ChainID) error - UpdateChainRecord(chainID isc.ChainID, f func(*ChainRecord) bool) (*ChainRecord, error) - ActivateChainRecord(chainID isc.ChainID) (*ChainRecord, error) - DeactivateChainRecord(chainID isc.ChainID) (*ChainRecord, error) + ChainRecord() *ChainRecord + ForActiveChainRecord(consumer func(*ChainRecord) bool) error + SetChainRecord(chainRecord *ChainRecord) error + DeleteChainRecord() error + UpdateChainRecord(f func(*ChainRecord) bool) (*ChainRecord, error) + ActivateChainRecord() (*ChainRecord, error) + DeactivateChainRecord() (*ChainRecord, error) } type TrustedPeersRegistryProvider interface { diff --git a/packages/solo/run.go b/packages/solo/run.go index f2c0a87a13..47821524cb 100644 --- a/packages/solo/run.go +++ b/packages/solo/run.go @@ -137,7 +137,7 @@ func (ch *Chain) settleStateTransition(stateDraft state.StateDraft) { lo.Must0(ch.store.SetLatest(block.TrieRoot())) latestState := lo.Must(ch.LatestState()) - ch.Env.Publisher().BlockApplied(ch.ChainID, block, latestState) + ch.Env.Publisher().BlockApplied(block, latestState) blockReceipts, err := blocklog.RequestReceiptsFromBlock(block) if err != nil { diff --git a/packages/solo/solo.go b/packages/solo/solo.go index 91bb5255f3..c480808d27 100644 --- a/packages/solo/solo.go +++ b/packages/solo/solo.go @@ -173,7 +173,7 @@ func New(t Context, initOptions ...*InitOptions) *Solo { ctx: ctx, } _ = ret.publisher.Events.Published.Hook(func(ev *publisher.ISCEvent[any]) { - ret.logger.LogInfof("solo publisher: %s %s %v", ev.Kind, ev.ChainID, ev.String()) + ret.logger.LogInfof("solo publisher: %s %v", ev.Kind, ev.String()) }) go ret.publisher.Run(ctx) diff --git a/packages/testutil/chain_record_registry_provider.go b/packages/testutil/chain_record_registry_provider.go index 913fb3ba2e..6bde74f972 100644 --- a/packages/testutil/chain_record_registry_provider.go +++ b/packages/testutil/chain_record_registry_provider.go @@ -4,28 +4,24 @@ package testutil import ( - "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/registry" ) // Mock implementation of a ChainRecordRegistryProvider for testing purposes type ChainRecordRegistryProvider struct { - DB map[isc.ChainID]*registry.ChainRecord + rec *registry.ChainRecord } func NewChainRecordRegistryProvider() *ChainRecordRegistryProvider { - return &ChainRecordRegistryProvider{ - DB: map[isc.ChainID]*registry.ChainRecord{}, - } + return &ChainRecordRegistryProvider{} } -func (p *ChainRecordRegistryProvider) AddChainRecord(chainRecord *registry.ChainRecord) error { - p.DB[chainRecord.ChainID()] = chainRecord +func (p *ChainRecordRegistryProvider) SetChainRecord(chainRecord *registry.ChainRecord) error { + p.rec = chainRecord return nil } -func (p *ChainRecordRegistryProvider) LoadChainRecord(chainID isc.ChainID) (*registry.ChainRecord, error) { - ret := p.DB[chainID] - return ret, nil +func (p *ChainRecordRegistryProvider) LoadChainRecord() (*registry.ChainRecord, error) { + return p.rec, nil } diff --git a/packages/testutil/mocked_cnsensus_state_registry.go b/packages/testutil/mocked_cnsensus_state_registry.go index 9f9a5f7e60..c24403fa1d 100644 --- a/packages/testutil/mocked_cnsensus_state_registry.go +++ b/packages/testutil/mocked_cnsensus_state_registry.go @@ -24,14 +24,14 @@ func NewConsensusStateRegistry() cmtlog.ConsensusStateRegistry { return &mockedConsensusStateRegistry{data: map[cryptolib.AddressKey]*cmtlog.State{}} } -func (s *mockedConsensusStateRegistry) Get(chainID isc.ChainID, cmtAddr *cryptolib.Address) (*cmtlog.State, error) { +func (s *mockedConsensusStateRegistry) Get(_ isc.ChainID, cmtAddr *cryptolib.Address) (*cmtlog.State, error) { if store, ok := s.data[cmtAddr.Key()]; ok { return store, nil } return nil, cmtlog.ErrCmtLogStateNotFound } -func (s *mockedConsensusStateRegistry) Set(chainID isc.ChainID, cmtAddr *cryptolib.Address, state *cmtlog.State) error { +func (s *mockedConsensusStateRegistry) Set(_ isc.ChainID, cmtAddr *cryptolib.Address, state *cmtlog.State) error { s.data[cmtAddr.Key()] = state return nil } diff --git a/packages/transaction/change_gov_controller.go b/packages/transaction/change_gov_controller.go index e8c8d18e92..3b52d66c80 100644 --- a/packages/transaction/change_gov_controller.go +++ b/packages/transaction/change_gov_controller.go @@ -4,11 +4,9 @@ package transaction import ( "github.com/iotaledger/wasp/v2/clients/iota-go/iotago" "github.com/iotaledger/wasp/v2/packages/cryptolib" - "github.com/iotaledger/wasp/v2/packages/isc" ) func NewChangeGovControllerTx( - chainID isc.ChainID, newGovController iotago.Address, // utxos iotago.OutputSet, wallet cryptolib.Signer, diff --git a/packages/vm/core/evm/emulator/emulator.go b/packages/vm/core/evm/emulator/emulator.go index 67a6f1e410..c52df5b720 100644 --- a/packages/vm/core/evm/emulator/emulator.go +++ b/packages/vm/core/evm/emulator/emulator.go @@ -7,6 +7,7 @@ import ( "bytes" "fmt" "math/big" + "sync/atomic" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -19,7 +20,6 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - lru "github.com/hashicorp/golang-lru/v2" "github.com/iotaledger/wasp/v2/packages/evm/evmutil" "github.com/iotaledger/wasp/v2/packages/kv" @@ -57,20 +57,13 @@ type GasLimits struct { Call uint64 } -var configCache *lru.Cache[int, *params.ChainConfig] - -func init() { - var err error - configCache, err = lru.New[int, *params.ChainConfig](100) - if err != nil { - panic(err) - } -} +var configCache atomic.Pointer[params.ChainConfig] func getConfig(chainID int) *params.ChainConfig { - if c, ok := configCache.Get(chainID); ok { + if c := configCache.Load(); c != nil { return c } + c := ¶ms.ChainConfig{ ChainID: big.NewInt(int64(chainID)), HomesteadBlock: big.NewInt(0), @@ -91,7 +84,7 @@ func getConfig(chainID int) *params.ChainConfig { if !c.IsShanghai(common.Big0, 0) { panic("ChainConfig should report EVM version as Shanghai") } - configCache.Add(chainID, c) + configCache.Store(c) return c } diff --git a/packages/vm/core/testcore/root_test.go b/packages/vm/core/testcore/root_test.go index 2cb5ccc909..fd3cf46b88 100644 --- a/packages/vm/core/testcore/root_test.go +++ b/packages/vm/core/testcore/root_test.go @@ -44,7 +44,7 @@ func TestGetInfo(t *testing.T) { chainID, admin, contracts := chain.GetInfo() - require.EqualValues(t, chain.ChainID, chainID) + require.EqualValues(t, chainID, chain.ChainID) require.EqualValues(t, chain.AdminAgentID(), admin) require.GreaterOrEqual(t, len(contracts), len(corecontracts.All)) diff --git a/packages/webapi/api.go b/packages/webapi/api.go index f6bb532390..44dd1f451c 100644 --- a/packages/webapi/api.go +++ b/packages/webapi/api.go @@ -13,7 +13,7 @@ import ( "github.com/iotaledger/hive.go/log" "github.com/iotaledger/wasp/v2/clients" "github.com/iotaledger/wasp/v2/packages/authentication" - "github.com/iotaledger/wasp/v2/packages/chains" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/dkg" "github.com/iotaledger/wasp/v2/packages/evm/jsonrpc" "github.com/iotaledger/wasp/v2/packages/metrics" @@ -87,7 +87,7 @@ func Init( chainRecordRegistryProvider registry.ChainRecordRegistryProvider, dkShareRegistryProvider registry.DKShareRegistryProvider, nodeIdentityProvider registry.NodeIdentityProvider, - chainsProvider chains.Provider, + chainRunner *chainrunner.ChainRunner, dkgNodeProvider dkg.NodeProvider, shutdownHandler *shutdown.ShutdownHandler, chainMetricsProvider *metrics.ChainMetricsProvider, @@ -105,14 +105,14 @@ func Init( mocker := NewMocker() mocker.LoadMockFiles() - chainService := services.NewChainService(logger, chainsProvider, chainMetricsProvider, chainRecordRegistryProvider) - committeeService := services.NewCommitteeService(chainsProvider, networkProvider, dkShareRegistryProvider) - registryService := services.NewRegistryService(chainsProvider, chainRecordRegistryProvider) + chainService := services.NewChainService(logger, chainRunner, chainMetricsProvider, chainRecordRegistryProvider) + committeeService := services.NewCommitteeService(chainRunner, networkProvider, dkShareRegistryProvider) + registryService := services.NewRegistryService(chainRunner, chainRecordRegistryProvider) offLedgerService := services.NewOffLedgerService(chainService, networkProvider, requestCacheTTL) - metricsService := services.NewMetricsService(chainsProvider, chainMetricsProvider) - peeringService := services.NewPeeringService(chainsProvider, networkProvider, trustedNetworkManager) - evmService := services.NewEVMService(chainsProvider, chainService, networkProvider, pub, indexDBPath, chainMetricsProvider, jsonrpcParams, logger.NewChildLogger("EVMService")) - nodeService := services.NewNodeService(chainRecordRegistryProvider, nodeIdentityProvider, chainsProvider, shutdownHandler, trustedNetworkManager, l1ParamsFetcher) + metricsService := services.NewMetricsService(chainRunner, chainMetricsProvider) + peeringService := services.NewPeeringService(chainRunner, networkProvider, trustedNetworkManager) + evmService := services.NewEVMService(chainRunner, chainService, networkProvider, pub, indexDBPath, chainMetricsProvider, jsonrpcParams, logger.NewChildLogger("EVMService")) + nodeService := services.NewNodeService(chainRecordRegistryProvider, nodeIdentityProvider, chainRunner, shutdownHandler, trustedNetworkManager, l1ParamsFetcher) dkgService := services.NewDKGService(dkShareRegistryProvider, dkgNodeProvider, trustedNetworkManager) userService := services.NewUserService(userManager) // -- diff --git a/packages/webapi/controllers/chain/access_nodes.go b/packages/webapi/controllers/chain/access_nodes.go index ba7580e8ca..9bd45ad075 100644 --- a/packages/webapi/controllers/chain/access_nodes.go +++ b/packages/webapi/controllers/chain/access_nodes.go @@ -14,17 +14,13 @@ import ( func (c *Controller) addAccessNode(e echo.Context) error { controllerutils.SetOperation(e, "add_access_node") - chain, err := c.chainService.GetChain() - if err != nil { - return err - } peer := e.Param(params.ParamPeer) if peer == "" { return errors.New("no peer provided") } - if err := c.nodeService.AddAccessNode(chain.ID(), peer); err != nil { + if err := c.nodeService.AddAccessNode(peer); err != nil { if errors.Is(err, interfaces.ErrPeerNotFound) { return apierrors.PeerNameNotFoundError(peer) } @@ -37,17 +33,13 @@ func (c *Controller) addAccessNode(e echo.Context) error { func (c *Controller) removeAccessNode(e echo.Context) error { controllerutils.SetOperation(e, "remove_access_node") - chain, err := c.chainService.GetChain() - if err != nil { - return err - } peer := e.Param(params.ParamPeer) if peer == "" { return errors.New("no peer provided") } - if err := c.nodeService.DeleteAccessNode(chain.ID(), peer); err != nil { + if err := c.nodeService.DeleteAccessNode(peer); err != nil { return err } diff --git a/packages/webapi/controllers/chain/chain.go b/packages/webapi/controllers/chain/chain.go index b385300527..6549ccaddc 100644 --- a/packages/webapi/controllers/chain/chain.go +++ b/packages/webapi/controllers/chain/chain.go @@ -34,7 +34,7 @@ func (c *Controller) getCommitteeInfo(e echo.Context) error { return apierrors.ChainNotFoundError() } - chainNodeInfo, err := c.committeeService.GetCommitteeInfo(chain.ChainID) + chainNodeInfo, err := c.committeeService.GetCommitteeInfo() if err != nil { if errors.Is(err, services.ErrNotInCommittee) { return e.JSON(http.StatusOK, models.CommitteeInfoResponse{}) diff --git a/packages/webapi/controllers/chain/management.go b/packages/webapi/controllers/chain/management.go index 3435239065..76e9e744f5 100644 --- a/packages/webapi/controllers/chain/management.go +++ b/packages/webapi/controllers/chain/management.go @@ -16,12 +16,8 @@ import ( func (c *Controller) activateChain(e echo.Context) error { controllerutils.SetOperation(e, "activate_chain") - chainID, err := controllerutils.ChainIDFromParams(e) - if err != nil { - return err - } - if err := c.chainService.ActivateChain(chainID); err != nil { + if err := c.chainService.ActivateChain(); err != nil { return err } @@ -30,12 +26,8 @@ func (c *Controller) activateChain(e echo.Context) error { func (c *Controller) deactivateChain(e echo.Context) error { controllerutils.SetOperation(e, "deactivate_chain") - chain, err := c.chainService.GetChain() - if err != nil { - return err - } - if err := c.chainService.DeactivateChain(chain.ID()); err != nil { + if err := c.chainService.DeactivateChain(); err != nil { return err } diff --git a/packages/webapi/controllers/corecontracts/controller.go b/packages/webapi/controllers/corecontracts/controller.go index bbd9e8f66e..bd825678df 100644 --- a/packages/webapi/controllers/corecontracts/controller.go +++ b/packages/webapi/controllers/corecontracts/controller.go @@ -102,7 +102,7 @@ func (c *Controller) addGovernanceContractRoutes(api echoswagger.ApiGroup, mocke AddResponse(http.StatusUnauthorized, "Unauthorized (Wrong permissions, missing token)", authentication.ValidationError{}, nil). AddResponse(http.StatusOK, "The chain info", mocker.Get(models.GovChainInfoResponse{}), nil). SetOperationId("governanceGetChainInfo"). - SetDescription("If you are using the common API functions, you most likely rather want to use '/v1/chains/:chainID' to get information about a chain."). + SetDescription("If you are using the common API functions, you most likely rather want to use '/v1/chain' to get information about a chain."). SetSummary("Get the chain info") api.GET("chain/core/governance/chainadmin", c.getChainAdmin). diff --git a/packages/webapi/controllers/metrics/chain.go b/packages/webapi/controllers/metrics/chain.go index ba813be86b..bef6f2d7a8 100644 --- a/packages/webapi/controllers/metrics/chain.go +++ b/packages/webapi/controllers/metrics/chain.go @@ -9,35 +9,20 @@ import ( ) func (c *Controller) getChainMessageMetrics(e echo.Context) error { - ch, err := c.chainService.GetChain() - if err != nil { - return err - } - - metricsReport := c.metricsService.GetChainMessageMetrics(ch.ID()) + metricsReport := c.metricsService.GetChainMessageMetrics() mappedMetrics := models.MapChainMessageMetrics(metricsReport) return e.JSON(http.StatusOK, mappedMetrics) } func (c *Controller) getChainWorkflowMetrics(e echo.Context) error { - ch, err := c.chainService.GetChain() - if err != nil { - return err - } - - metricsReport := c.metricsService.GetChainConsensusWorkflowMetrics(ch.ID()) + metricsReport := c.metricsService.GetChainConsensusWorkflowMetrics() return e.JSON(http.StatusOK, metricsReport) } func (c *Controller) getChainPipeMetrics(e echo.Context) error { - ch, err := c.chainService.GetChain() - if err != nil { - return err - } - - metricsReport := c.metricsService.GetChainConsensusPipeMetrics(ch.ID()) + metricsReport := c.metricsService.GetChainConsensusPipeMetrics() return e.JSON(http.StatusOK, metricsReport) } diff --git a/packages/webapi/controllers/requests/offledger.go b/packages/webapi/controllers/requests/offledger.go index 2a12d87658..53f7ea8bb7 100644 --- a/packages/webapi/controllers/requests/offledger.go +++ b/packages/webapi/controllers/requests/offledger.go @@ -32,7 +32,7 @@ func (c *Controller) handleOffLedgerRequest(e echo.Context) error { return apierrors.InvalidPropertyError("Request", err) } - err = c.offLedgerService.EnqueueOffLedgerRequest(ch.ID(), requestDecoded) + err = c.offLedgerService.EnqueueOffLedgerRequest(requestDecoded) if err != nil { return apierrors.InvalidOffLedgerRequestError(err) } diff --git a/packages/webapi/interfaces/interfaces.go b/packages/webapi/interfaces/interfaces.go index f7e2b0bd69..46a9058797 100644 --- a/packages/webapi/interfaces/interfaces.go +++ b/packages/webapi/interfaces/interfaces.go @@ -34,10 +34,9 @@ type APIController interface { } type ChainService interface { - ActivateChain(chainID isc.ChainID) error + ActivateChain() error SetChainRecord(chainRecord *registry.ChainRecord) error - DeactivateChain(chainID isc.ChainID) error - GetAllChainIDs() ([]isc.ChainID, error) + DeactivateChain() error GetChain() (chain.Chain, error) GetChainInfo(blockIndexOrTrieRoot string) (*dto.ChainInfo, error) GetContracts(blockIndexOrTrieRoot string) ([]lo.Tuple2[*isc.Hname, *root.ContractRecord], error) @@ -54,28 +53,28 @@ type EVMService interface { type MetricsService interface { GetNodeMessageMetrics() *dto.NodeMessageMetrics - GetChainMessageMetrics(chainID isc.ChainID) *dto.ChainMessageMetrics - GetChainConsensusPipeMetrics(chainID isc.ChainID) *models.ConsensusPipeMetrics - GetChainConsensusWorkflowMetrics(chainID isc.ChainID) *models.ConsensusWorkflowMetrics + GetChainMessageMetrics() *dto.ChainMessageMetrics + GetChainConsensusPipeMetrics() *models.ConsensusPipeMetrics + GetChainConsensusWorkflowMetrics() *models.ConsensusWorkflowMetrics GetMaxChainConfirmedStateLag() uint32 } var ErrPeerNotFound = errors.New("couldn't find peer") type NodeService interface { - AddAccessNode(chainID isc.ChainID, peer string) error - DeleteAccessNode(chainID isc.ChainID, peer string) error + AddAccessNode(peer string) error + DeleteAccessNode(peer string) error NodeOwnerCertificate() []byte ShutdownNode() L1Params(context.Context) (*parameters.L1Params, error) } type RegistryService interface { - GetChainRecordByChainID(chainID isc.ChainID) (*registry.ChainRecord, error) + GetChainRecord() (*registry.ChainRecord, error) } type CommitteeService interface { - GetCommitteeInfo(chainID isc.ChainID) (*dto.ChainNodeInfo, error) + GetCommitteeInfo() (*dto.ChainNodeInfo, error) GetPublicKey() *cryptolib.PublicKey } @@ -89,7 +88,7 @@ type PeeringService interface { } type OffLedgerService interface { - EnqueueOffLedgerRequest(chainID isc.ChainID, request []byte) error + EnqueueOffLedgerRequest(request []byte) error ParseRequest(payload []byte) (isc.Request, error) } diff --git a/packages/webapi/services/chain.go b/packages/webapi/services/chain.go index 4b70f56582..e1265129d4 100644 --- a/packages/webapi/services/chain.go +++ b/packages/webapi/services/chain.go @@ -3,6 +3,7 @@ package services import ( "context" "errors" + "fmt" "time" "github.com/samber/lo" @@ -11,7 +12,7 @@ import ( "github.com/iotaledger/wasp/v2/clients/iota-go/iotago" chainpkg "github.com/iotaledger/wasp/v2/packages/chain" - "github.com/iotaledger/wasp/v2/packages/chains" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/kv" "github.com/iotaledger/wasp/v2/packages/metrics" @@ -27,54 +28,55 @@ import ( type ChainService struct { log log.Logger - chainsProvider chains.Provider + chainRunner *chainrunner.ChainRunner chainMetricsProvider *metrics.ChainMetricsProvider chainRecordRegistryProvider registry.ChainRecordRegistryProvider } func NewChainService( logger log.Logger, - chainsProvider chains.Provider, + chainRunner *chainrunner.ChainRunner, chainMetricsProvider *metrics.ChainMetricsProvider, chainRecordRegistryProvider registry.ChainRecordRegistryProvider, ) interfaces.ChainService { return &ChainService{ log: logger, - chainsProvider: chainsProvider, + chainRunner: chainRunner, chainMetricsProvider: chainMetricsProvider, chainRecordRegistryProvider: chainRecordRegistryProvider, } } -func (c *ChainService) ActivateChain(chainID isc.ChainID) error { - _, err := c.chainRecordRegistryProvider.ActivateChainRecord(chainID) +func (c *ChainService) ActivateChain() error { + _, err := c.chainRecordRegistryProvider.ActivateChainRecord() if err != nil { return err } - return c.chainsProvider().Activate(chainID) + return c.chainRunner.Activate() } -func (c *ChainService) DeactivateChain(chainID isc.ChainID) error { - _, err := c.chainRecordRegistryProvider.DeactivateChainRecord(chainID) +func (c *ChainService) DeactivateChain() error { + _, err := c.chainRecordRegistryProvider.DeactivateChainRecord() if err != nil { return err } - return c.chainsProvider().Deactivate(chainID) + return c.chainRunner.Deactivate() } func (c *ChainService) SetChainRecord(chainRecord *registry.ChainRecord) error { - storedChainRec, err := c.chainRecordRegistryProvider.ChainRecord(chainRecord.ChainID()) - if err != nil { - return err - } + storedChainRec := c.chainRecordRegistryProvider.ChainRecord() - c.log.LogInfof("StoredChainRec %v %v", storedChainRec, err) + c.log.LogInfof("StoredChainRec %v", storedChainRec) if storedChainRec != nil { - _, err = c.chainRecordRegistryProvider.UpdateChainRecord( - chainRecord.ChainID(), + if storedChainRec.ChainID() != chainRecord.ChainID() { + return fmt.Errorf("cannot update chain record with different chain ID: %v != %v", + storedChainRec.ChainID().String(), chainRecord.ChainID().String()) + } + + _, err := c.chainRecordRegistryProvider.UpdateChainRecord( func(rec *registry.ChainRecord) bool { rec.AccessNodes = chainRecord.AccessNodes rec.Active = chainRecord.Active @@ -87,7 +89,7 @@ func (c *ChainService) SetChainRecord(chainRecord *registry.ChainRecord) error { return err } } else { - if err := c.chainRecordRegistryProvider.AddChainRecord(chainRecord); err != nil { + if err := c.chainRecordRegistryProvider.SetChainRecord(chainRecord); err != nil { c.log.LogInfof("AddChainRec %v %v", chainRecord, err) return err @@ -98,11 +100,11 @@ func (c *ChainService) SetChainRecord(chainRecord *registry.ChainRecord) error { c.log.LogInfof("Chainrecord active %v", chainRecord.Active) if chainRecord.Active { - if err := c.chainsProvider().Activate(chainRecord.ChainID()); err != nil { + if err := c.chainRunner.Activate(); err != nil { return err } } else if storedChainRec != nil { - if err := c.chainsProvider().Deactivate(chainRecord.ChainID()); err != nil { + if err := c.chainRunner.Deactivate(); err != nil { return err } } @@ -111,7 +113,7 @@ func (c *ChainService) SetChainRecord(chainRecord *registry.ChainRecord) error { } func (c *ChainService) GetChain() (chainpkg.Chain, error) { - return c.chainsProvider().GetFirst() + return c.chainRunner.Chain() } func (c *ChainService) GetEVMChainID(blockIndexOrTrieRoot string) (uint16, error) { @@ -126,31 +128,13 @@ func (c *ChainService) GetEVMChainID(blockIndexOrTrieRoot string) (uint16, error return evm.ViewGetChainID.DecodeOutput(ret) } -func (c *ChainService) GetAllChainIDs() ([]isc.ChainID, error) { - records, err := c.chainRecordRegistryProvider.ChainRecords() - if err != nil { - return nil, err - } - - chainIDs := make([]isc.ChainID, 0, len(records)) - - for _, chainRecord := range records { - chainIDs = append(chainIDs, chainRecord.ChainID()) - } - - return chainIDs, nil -} - func (c *ChainService) GetChainInfo(blockIndexOrTrieRoot string) (*dto.ChainInfo, error) { ch, err := c.GetChain() if err != nil { return nil, err } - chainRecord, err := c.chainRecordRegistryProvider.ChainRecord(ch.ID()) - if err != nil { - return nil, err - } + chainRecord := c.chainRecordRegistryProvider.ChainRecord() governanceChainInfo, err := corecontracts.GetChainInfo(ch, blockIndexOrTrieRoot) if err != nil { @@ -161,7 +145,7 @@ func (c *ChainService) GetChainInfo(blockIndexOrTrieRoot string) (*dto.ChainInfo return nil, err } - chainInfo := dto.MapChainInfo(governanceChainInfo, chainRecord.Active) + chainInfo := dto.MapChainInfo(governanceChainInfo, chainRecord != nil && chainRecord.Active) return chainInfo, nil } diff --git a/packages/webapi/services/committee.go b/packages/webapi/services/committee.go index e05ecce831..90d9c8bfe6 100644 --- a/packages/webapi/services/committee.go +++ b/packages/webapi/services/committee.go @@ -3,9 +3,8 @@ package services import ( "errors" - "github.com/iotaledger/wasp/v2/packages/chains" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/cryptolib" - "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/peering" "github.com/iotaledger/wasp/v2/packages/registry" "github.com/iotaledger/wasp/v2/packages/tcrypto" @@ -17,14 +16,14 @@ import ( var ErrNotInCommittee = errors.New("this node is not in the committee for the chain") type CommitteeService struct { - chainsProvider chains.Provider + chainRunner *chainrunner.ChainRunner networkProvider peering.NetworkProvider dkShareRegistryProvider registry.DKShareRegistryProvider } -func NewCommitteeService(chainsProvider chains.Provider, networkProvider peering.NetworkProvider, dkShareRegistryProvider registry.DKShareRegistryProvider) interfaces.CommitteeService { +func NewCommitteeService(chainRunner *chainrunner.ChainRunner, networkProvider peering.NetworkProvider, dkShareRegistryProvider registry.DKShareRegistryProvider) interfaces.CommitteeService { return &CommitteeService{ - chainsProvider: chainsProvider, + chainRunner: chainRunner, networkProvider: networkProvider, dkShareRegistryProvider: dkShareRegistryProvider, } @@ -34,8 +33,8 @@ func (c *CommitteeService) GetPublicKey() *cryptolib.PublicKey { return c.networkProvider.Self().PubKey() } -func (c *CommitteeService) GetCommitteeInfo(chainID isc.ChainID) (*dto.ChainNodeInfo, error) { - chain, err := c.chainsProvider().Get(chainID) +func (c *CommitteeService) GetCommitteeInfo() (*dto.ChainNodeInfo, error) { + chain, err := c.chainRunner.Chain() if err != nil { return nil, err } diff --git a/packages/webapi/services/evm.go b/packages/webapi/services/evm.go index 171a3c4ba0..4f66f14bf7 100644 --- a/packages/webapi/services/evm.go +++ b/packages/webapi/services/evm.go @@ -10,7 +10,7 @@ import ( hivedb "github.com/iotaledger/hive.go/db" "github.com/iotaledger/hive.go/log" - "github.com/iotaledger/wasp/v2/packages/chains" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/evm/jsonrpc" "github.com/iotaledger/wasp/v2/packages/isc" "github.com/iotaledger/wasp/v2/packages/metrics" @@ -29,9 +29,9 @@ type EVMService struct { evmChainServers map[isc.ChainID]*chainServer websocketContextMutex sync.Mutex - websocketContexts map[isc.ChainID]*websocketContext + websocketContext *websocketContext - chainsProvider chains.Provider + chainRunner *chainrunner.ChainRunner chainService interfaces.ChainService networkProvider peering.NetworkProvider publisher *publisher.Publisher @@ -42,7 +42,7 @@ type EVMService struct { } func NewEVMService( - chainsProvider chains.Provider, + chainRunner *chainrunner.ChainRunner, chainService interfaces.ChainService, networkProvider peering.NetworkProvider, pub *publisher.Publisher, @@ -52,11 +52,10 @@ func NewEVMService( log log.Logger, ) interfaces.EVMService { return &EVMService{ - chainsProvider: chainsProvider, + chainRunner: chainRunner, chainService: chainService, evmChainServers: map[isc.ChainID]*chainServer{}, evmBackendMutex: sync.Mutex{}, - websocketContexts: map[isc.ChainID]*websocketContext{}, websocketContextMutex: sync.Mutex{}, networkProvider: networkProvider, publisher: pub, @@ -92,7 +91,7 @@ func (e *EVMService) getEVMBackend() (*chainServer, error) { jsonrpc.NewEVMChain( backend, e.publisher, - e.chainsProvider().IsArchiveNode(), + e.chainRunner.IsArchiveNode(), hivedb.EngineRocksDB, e.indexDBPath, e.log.NewChildLogger("EVMChain"), @@ -124,18 +123,18 @@ func (e *EVMService) HandleJSONRPC(request *http.Request, response *echo.Respons return nil } -func (e *EVMService) getWebsocketContext(ctx context.Context, chainID isc.ChainID) *websocketContext { +func (e *EVMService) getWebsocketContext(ctx context.Context) *websocketContext { e.websocketContextMutex.Lock() defer e.websocketContextMutex.Unlock() - if e.websocketContexts[chainID] != nil { - return e.websocketContexts[chainID] + if e.websocketContext != nil { + return e.websocketContext } - e.websocketContexts[chainID] = newWebsocketContext(e.log, e.jsonrpcParams) - go e.websocketContexts[chainID].runCleanupTimer(ctx) + e.websocketContext = newWebsocketContext(e.log, e.jsonrpcParams) + go e.websocketContext.runCleanupTimer(ctx) - return e.websocketContexts[chainID] + return e.websocketContext } func (e *EVMService) HandleWebsocket(ctx context.Context, echoCtx echo.Context) error { @@ -144,12 +143,7 @@ func (e *EVMService) HandleWebsocket(ctx context.Context, echoCtx echo.Context) return err } - ch, err := e.chainService.GetChain() - if err != nil { - return err - } - - wsContext := e.getWebsocketContext(ctx, ch.ID()) + wsContext := e.getWebsocketContext(ctx) websocketHandler(evmServer, wsContext, echoCtx.RealIP()).ServeHTTP(echoCtx.Response(), echoCtx.Request()) return nil } diff --git a/packages/webapi/services/metrics.go b/packages/webapi/services/metrics.go index 9f8f192697..f519437b80 100644 --- a/packages/webapi/services/metrics.go +++ b/packages/webapi/services/metrics.go @@ -1,8 +1,7 @@ package services import ( - "github.com/iotaledger/wasp/v2/packages/chains" - "github.com/iotaledger/wasp/v2/packages/isc" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/metrics" "github.com/iotaledger/wasp/v2/packages/webapi/dto" "github.com/iotaledger/wasp/v2/packages/webapi/interfaces" @@ -10,13 +9,13 @@ import ( ) type MetricsService struct { - chainProvider chains.Provider + chainRunner *chainrunner.ChainRunner chainMetricsProvider *metrics.ChainMetricsProvider } -func NewMetricsService(chainProvider chains.Provider, chainMetricsProvider *metrics.ChainMetricsProvider) interfaces.MetricsService { +func NewMetricsService(chainRunner *chainrunner.ChainRunner, chainMetricsProvider *metrics.ChainMetricsProvider) interfaces.MetricsService { return &MetricsService{ - chainProvider: chainProvider, + chainRunner: chainRunner, chainMetricsProvider: chainMetricsProvider, } } @@ -30,8 +29,8 @@ func (c *MetricsService) GetNodeMessageMetrics() *dto.NodeMessageMetrics { } } -func (c *MetricsService) GetChainMessageMetrics(chainID isc.ChainID) *dto.ChainMessageMetrics { - chain, err := c.chainProvider().Get(chainID) +func (c *MetricsService) GetChainMessageMetrics() *dto.ChainMessageMetrics { + chain, err := c.chainRunner.Chain() if err != nil { return nil } @@ -45,8 +44,8 @@ func (c *MetricsService) GetChainMessageMetrics(chainID isc.ChainID) *dto.ChainM } } -func (c *MetricsService) GetChainConsensusWorkflowMetrics(chainID isc.ChainID) *models.ConsensusWorkflowMetrics { - chain, err := c.chainProvider().Get(chainID) +func (c *MetricsService) GetChainConsensusWorkflowMetrics() *models.ConsensusWorkflowMetrics { + chain, err := c.chainRunner.Chain() if err != nil { return nil } @@ -59,8 +58,8 @@ func (c *MetricsService) GetChainConsensusWorkflowMetrics(chainID isc.ChainID) * return models.MapConsensusWorkflowStatus(metrics) } -func (c *MetricsService) GetChainConsensusPipeMetrics(chainID isc.ChainID) *models.ConsensusPipeMetrics { - chain, err := c.chainProvider().Get(chainID) +func (c *MetricsService) GetChainConsensusPipeMetrics() *models.ConsensusPipeMetrics { + chain, err := c.chainRunner.Chain() if err != nil { return nil } diff --git a/packages/webapi/services/node.go b/packages/webapi/services/node.go index 51bd37e9e1..111c6e8ee6 100644 --- a/packages/webapi/services/node.go +++ b/packages/webapi/services/node.go @@ -5,8 +5,7 @@ import ( "errors" "github.com/iotaledger/hive.go/app/shutdown" - "github.com/iotaledger/wasp/v2/packages/chains" - "github.com/iotaledger/wasp/v2/packages/isc" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/parameters" "github.com/iotaledger/wasp/v2/packages/peering" "github.com/iotaledger/wasp/v2/packages/registry" @@ -17,7 +16,7 @@ import ( type NodeService struct { chainRecordRegistryProvider registry.ChainRecordRegistryProvider nodeIdentityProvider registry.NodeIdentityProvider - chainsProvider chains.Provider + chainRunner *chainrunner.ChainRunner shutdownHandler *shutdown.ShutdownHandler trustedNetworkManager peering.TrustedNetworkManager l1ParamsFetcher parameters.L1ParamsFetcher @@ -26,7 +25,7 @@ type NodeService struct { func NewNodeService( chainRecordRegistryProvider registry.ChainRecordRegistryProvider, nodeIdentityProvider registry.NodeIdentityProvider, - chainsProvider chains.Provider, + chainRunner *chainrunner.ChainRunner, shutdownHandler *shutdown.ShutdownHandler, trustedNetworkManager peering.TrustedNetworkManager, l1ParamsFetcher parameters.L1ParamsFetcher, @@ -34,20 +33,20 @@ func NewNodeService( return &NodeService{ chainRecordRegistryProvider: chainRecordRegistryProvider, nodeIdentityProvider: nodeIdentityProvider, - chainsProvider: chainsProvider, + chainRunner: chainRunner, shutdownHandler: shutdownHandler, trustedNetworkManager: trustedNetworkManager, l1ParamsFetcher: l1ParamsFetcher, } } -func (n *NodeService) AddAccessNode(chainID isc.ChainID, peerPubKeyOrName string) error { +func (n *NodeService) AddAccessNode(peerPubKeyOrName string) error { peers, err := n.trustedNetworkManager.TrustedPeersByPubKeyOrName([]string{peerPubKeyOrName}) if err != nil { return err } - if _, err = n.chainRecordRegistryProvider.UpdateChainRecord(chainID, func(rec *registry.ChainRecord) bool { + if _, err = n.chainRecordRegistryProvider.UpdateChainRecord(func(rec *registry.ChainRecord) bool { return rec.AddAccessNode(peers[0].PubKey()) }); err != nil { return errors.New("error saving chain record") @@ -56,13 +55,13 @@ func (n *NodeService) AddAccessNode(chainID isc.ChainID, peerPubKeyOrName string return nil } -func (n *NodeService) DeleteAccessNode(chainID isc.ChainID, peerPubKeyOrName string) error { +func (n *NodeService) DeleteAccessNode(peerPubKeyOrName string) error { peers, err := n.trustedNetworkManager.TrustedPeersByPubKeyOrName([]string{peerPubKeyOrName}) if err != nil { return err } - if _, err := n.chainRecordRegistryProvider.UpdateChainRecord(chainID, func(rec *registry.ChainRecord) bool { + if _, err := n.chainRecordRegistryProvider.UpdateChainRecord(func(rec *registry.ChainRecord) bool { return rec.RemoveAccessNode(peers[0].PubKey()) }); err != nil { return errors.New("error saving chain record") @@ -73,7 +72,7 @@ func (n *NodeService) DeleteAccessNode(chainID isc.ChainID, peerPubKeyOrName str func (n *NodeService) NodeOwnerCertificate() []byte { nodeIdentity := n.nodeIdentityProvider.NodeIdentity() - return governance.NewNodeOwnershipCertificate(nodeIdentity, n.chainsProvider().ValidatorAddress()) + return governance.NewNodeOwnershipCertificate(nodeIdentity, n.chainRunner.ValidatorAddress()) } func (n *NodeService) ShutdownNode() { diff --git a/packages/webapi/services/offledger.go b/packages/webapi/services/offledger.go index 2c3d6b6974..2ea92c867f 100644 --- a/packages/webapi/services/offledger.go +++ b/packages/webapi/services/offledger.go @@ -38,7 +38,7 @@ func (c *OffLedgerService) ParseRequest(binaryRequest []byte) (isc.Request, erro return request, nil } -func (c *OffLedgerService) EnqueueOffLedgerRequest(chainID isc.ChainID, binaryRequest []byte) error { +func (c *OffLedgerService) EnqueueOffLedgerRequest(binaryRequest []byte) error { request, err := c.ParseRequest(binaryRequest) if err != nil { return err @@ -67,7 +67,7 @@ func (c *OffLedgerService) EnqueueOffLedgerRequest(chainID isc.ChainID, binaryRe } // check req is for the correct chain - if !asOffLedgerRequest.ChainID().Equals(chainID) { + if !asOffLedgerRequest.ChainID().Equals(chain.ID()) { // do not add to cache, it can still be sent to the correct chain return errors.New("request is for a different chain") } diff --git a/packages/webapi/services/peering.go b/packages/webapi/services/peering.go index d7df90cc0f..92c80af658 100644 --- a/packages/webapi/services/peering.go +++ b/packages/webapi/services/peering.go @@ -3,7 +3,7 @@ package services import ( "github.com/samber/lo" - "github.com/iotaledger/wasp/v2/packages/chains" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/cryptolib" "github.com/iotaledger/wasp/v2/packages/peering" "github.com/iotaledger/wasp/v2/packages/webapi/dto" @@ -11,14 +11,14 @@ import ( ) type PeeringService struct { - chainsProvider chains.Provider + chainRunner *chainrunner.ChainRunner networkProvider peering.NetworkProvider trustedNetworkManager peering.TrustedNetworkManager } -func NewPeeringService(chainsProvider chains.Provider, networkProvider peering.NetworkProvider, trustedNetworkManager peering.TrustedNetworkManager) *PeeringService { +func NewPeeringService(chainRunner *chainrunner.ChainRunner, networkProvider peering.NetworkProvider, trustedNetworkManager peering.TrustedNetworkManager) *PeeringService { return &PeeringService{ - chainsProvider: chainsProvider, + chainRunner: chainRunner, networkProvider: networkProvider, trustedNetworkManager: trustedNetworkManager, } diff --git a/packages/webapi/services/registry.go b/packages/webapi/services/registry.go index 847f57cc6a..d60d0d4fb5 100644 --- a/packages/webapi/services/registry.go +++ b/packages/webapi/services/registry.go @@ -1,24 +1,23 @@ package services import ( - "github.com/iotaledger/wasp/v2/packages/chains" - "github.com/iotaledger/wasp/v2/packages/isc" + "github.com/iotaledger/wasp/v2/packages/chainrunner" "github.com/iotaledger/wasp/v2/packages/registry" "github.com/iotaledger/wasp/v2/packages/webapi/interfaces" ) type RegistryService struct { - chainsProvider chains.Provider + chainRunner *chainrunner.ChainRunner chainRecordRegistryProvider registry.ChainRecordRegistryProvider } -func NewRegistryService(chainsProvider chains.Provider, chainRecordRegistryProvider registry.ChainRecordRegistryProvider) interfaces.RegistryService { +func NewRegistryService(chainRunner *chainrunner.ChainRunner, chainRecordRegistryProvider registry.ChainRecordRegistryProvider) interfaces.RegistryService { return &RegistryService{ - chainsProvider: chainsProvider, + chainRunner: chainRunner, chainRecordRegistryProvider: chainRecordRegistryProvider, } } -func (c *RegistryService) GetChainRecordByChainID(chainID isc.ChainID) (*registry.ChainRecord, error) { - return c.chainRecordRegistryProvider.ChainRecord(chainID) +func (c *RegistryService) GetChainRecord() (*registry.ChainRecord, error) { + return c.chainRecordRegistryProvider.ChainRecord(), nil } diff --git a/packages/webapi/websocket/eventhandler.go b/packages/webapi/websocket/eventhandler.go index 38574bd4d4..30a3c2115e 100644 --- a/packages/webapi/websocket/eventhandler.go +++ b/packages/webapi/websocket/eventhandler.go @@ -13,7 +13,6 @@ type ISCEvent struct { Kind publisher.ISCEventType `json:"kind"` Issuer string `json:"issuer"` // (isc.AgentID) nil means issued by the VM RequestID string `json:"requestID"` // (isc.RequestID) - ChainID string `json:"chainID"` // (isc.ChainID) Payload any `json:"payload"` } @@ -27,7 +26,6 @@ func MapISCEvent[T any](iscEvent *publisher.ISCEvent[T], mappedPayload any) *ISC return &ISCEvent{ Kind: iscEvent.Kind, - ChainID: iscEvent.ChainID.String(), RequestID: iscEvent.RequestID.String(), Issuer: issuer, Payload: mappedPayload, @@ -61,7 +59,7 @@ func batch(callbacks ...func()) func() { func (p *EventHandler) AttachToEvents() context.CancelFunc { return batch( p.publisher.Events.NewBlock.Hook(func(block *publisher.ISCEvent[*publisher.BlockWithTrieRoot]) { - if !p.subscriptionValidator.shouldProcessEvent(block.ChainID.String(), block.Kind) { + if !p.subscriptionValidator.shouldProcessEvent(block.Kind) { return } @@ -71,7 +69,7 @@ func (p *EventHandler) AttachToEvents() context.CancelFunc { }).Unhook, p.publisher.Events.RequestReceipt.Hook(func(block *publisher.ISCEvent[*publisher.ReceiptWithError]) { - if !p.subscriptionValidator.shouldProcessEvent(block.ChainID.String(), block.Kind) { + if !p.subscriptionValidator.shouldProcessEvent(block.Kind) { return } @@ -81,7 +79,7 @@ func (p *EventHandler) AttachToEvents() context.CancelFunc { }).Unhook, p.publisher.Events.BlockEvents.Hook(func(block *publisher.ISCEvent[[]*isc.Event]) { - if !p.subscriptionValidator.shouldProcessEvent(block.ChainID.String(), block.Kind) { + if !p.subscriptionValidator.shouldProcessEvent(block.Kind) { return } diff --git a/packages/webapi/websocket/eventhandler_test.go b/packages/webapi/websocket/eventhandler_test.go index 74c6e988d4..f5e1b68e82 100644 --- a/packages/webapi/websocket/eventhandler_test.go +++ b/packages/webapi/websocket/eventhandler_test.go @@ -51,17 +51,13 @@ func TestSuccessfulEventHandling(t *testing.T) { subscriptionManager.Subscribe(1, string(publisher.ISCEventKindNewBlock)) - chainID := isctest.RandomChainID() - publisherEvent.Hook(func(iscEvent *ISCEvent) { - require.Exactly(t, iscEvent.ChainID, chainID.String()) cancel() }) pub.Events.NewBlock.Trigger(&publisher.ISCEvent[*publisher.BlockWithTrieRoot]{ - Kind: publisher.ISCEventKindNewBlock, - ChainID: chainID, - Issuer: isctest.NewRandomAgentID(), + Kind: publisher.ISCEventKindNewBlock, + Issuer: isctest.NewRandomAgentID(), Payload: &publisher.BlockWithTrieRoot{ BlockInfo: &blocklog.BlockInfo{}, TrieRoot: trie.Hash{}, diff --git a/packages/webapi/websocket/service.go b/packages/webapi/websocket/service.go index cca00b6d09..460cb73055 100644 --- a/packages/webapi/websocket/service.go +++ b/packages/webapi/websocket/service.go @@ -72,7 +72,7 @@ func (p *Service) onClientCreated(client *websockethub.Client) { go func() { unhook := p.publisherEvent.Hook(func(iscEvent *ISCEvent) { - if !p.subscriptionValidator.isClientAllowed(client, iscEvent.ChainID, iscEvent.Kind) { + if !p.subscriptionValidator.isClientAllowed(client, iscEvent.Kind) { return } diff --git a/packages/webapi/websocket/subscriptionvalidator.go b/packages/webapi/websocket/subscriptionvalidator.go index 34148d96f7..879ed04077 100644 --- a/packages/webapi/websocket/subscriptionvalidator.go +++ b/packages/webapi/websocket/subscriptionvalidator.go @@ -2,8 +2,6 @@ package websocket import ( - "fmt" - "github.com/iotaledger/hive.go/web/subscriptionmanager" "github.com/iotaledger/hive.go/web/websockethub" "github.com/iotaledger/wasp/v2/packages/publisher" @@ -21,35 +19,14 @@ func NewSubscriptionValidator(messageTypes map[publisher.ISCEventType]bool, subs } } -func (p *SubscriptionValidator) hasClientSubscribedToAllChains(client *websockethub.Client) bool { - return p.subscriptionManager.ClientSubscribedToTopic(client.ID(), "chains") -} - -func (p *SubscriptionValidator) hasAnyoneSubscribedToAllChains() bool { - return p.subscriptionManager.TopicHasSubscribers("chains") -} - -func (p *SubscriptionValidator) hasClientSubscribedToSingleChain(client *websockethub.Client, chainID string) bool { - return p.subscriptionManager.ClientSubscribedToTopic(client.ID(), fmt.Sprintf("chains/%s", chainID)) -} - -func (p *SubscriptionValidator) hasAnyoneSubscribedToSingleChain(chainID string) bool { - return p.subscriptionManager.TopicHasSubscribers(fmt.Sprintf("chains/%s", chainID)) -} - // shouldProcessEvent validates if any subscriber has subscribed to a certain chainID and messageType. // it returns false if no one has subscribed to those parameters // this usually means, that there is no need to process a certain incoming event. -func (p *SubscriptionValidator) shouldProcessEvent(chainID string, messageType publisher.ISCEventType) bool { +func (p *SubscriptionValidator) shouldProcessEvent(messageType publisher.ISCEventType) bool { if !p.messageTypes[messageType] { return false } - // Check if any client has either subscribed to all chains [chains], or the supplied single chain id [chains/] - if !p.hasAnyoneSubscribedToAllChains() && !p.hasAnyoneSubscribedToSingleChain(chainID) { - return false - } - if !p.subscriptionManager.TopicHasSubscribers(string(messageType)) { return false } @@ -60,16 +37,11 @@ func (p *SubscriptionValidator) shouldProcessEvent(chainID string, messageType p // isClientAllowed validates if a certain subscriber has subscribed to a certain chainID and messageType. // it returns false if the client has not subscribed to those parameters // this usually means, that there is no need to process a certain outgoing event. -func (p *SubscriptionValidator) isClientAllowed(client *websockethub.Client, chainID string, messageType publisher.ISCEventType) bool { +func (p *SubscriptionValidator) isClientAllowed(client *websockethub.Client, messageType publisher.ISCEventType) bool { if !p.messageTypes[messageType] { return false } - // Check a client has either subscribed to all chains [chains], or the supplied single chain id [chains/] - if !p.hasClientSubscribedToAllChains(client) && !p.hasClientSubscribedToSingleChain(client, chainID) { - return false - } - if !p.subscriptionManager.ClientSubscribedToTopic(client.ID(), string(messageType)) { return false } diff --git a/packages/webapi/websocket/websocket_test.go b/packages/webapi/websocket/websocket_test.go index b276f292a6..e57705fa38 100644 --- a/packages/webapi/websocket/websocket_test.go +++ b/packages/webapi/websocket/websocket_test.go @@ -66,8 +66,6 @@ func TestWebsocketEvents(t *testing.T) { // It's the last step before the events get send via the websocket to the client. // It's also the last step to validate the events without actually connecting with a websocket client. ws.publisherEvent.Hook(func(iscEvent *ISCEvent) { - require.Exactly(t, iscEvent.ChainID, chain.ChainID.String()) - if iscEvent.Kind == publisher.ISCEventKindNewBlock { cancel() } else { diff --git a/test/config.json b/test/config.json index e0f0dce174..6d9da17037 100755 --- a/test/config.json +++ b/test/config.json @@ -69,7 +69,7 @@ "peeringURL": "0.0.0.0:4000", "port": 4000 }, - "chains": { + "chain": { "broadcastUpToNPeers": 2, "broadcastInterval": "5s", "apiCacheTTL": "5m", diff --git a/tools/cluster/cluster.go b/tools/cluster/cluster.go index 19514b7028..0785504a62 100644 --- a/tools/cluster/cluster.go +++ b/tools/cluster/cluster.go @@ -422,7 +422,7 @@ func (clu *Cluster) addAllAccessNodes(chain *Chain, accessNodes []int) error { for _, tx := range addAccessNodesTxs { // ---------- wait until the requests are processed in all committee nodes - if _, err := peers.WaitUntilAllRequestsProcessedSuccessfully(context.Background(), chain.ChainID, tx, true, 30*time.Second); err != nil { + if _, err := peers.WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, true, 30*time.Second); err != nil { return fmt.Errorf("WaitAddAccessNode: %w", err) } } @@ -455,7 +455,7 @@ func (clu *Cluster) addAllAccessNodes(chain *Chain, accessNodes []int) error { if err != nil { return err } - _, err = peers.WaitUntilAllRequestsProcessedSuccessfully(context.Background(), chain.ChainID, tx, true, 30*time.Second) + _, err = peers.WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, true, 30*time.Second) if err != nil { return err } diff --git a/tools/cluster/tests/access_nodes_test.go b/tools/cluster/tests/access_nodes_test.go index b036769e3a..cbd2ad15a6 100644 --- a/tools/cluster/tests/access_nodes_test.go +++ b/tools/cluster/tests/access_nodes_test.go @@ -98,7 +98,7 @@ func (e *ChainEnv) testPermissionlessAccessNode(t *testing.T) { require.NoError(t, err) // request has been processed - _, err = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, req.ID(), false, 1*time.Minute) + _, err = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), false, 1*time.Minute) require.NoError(t, err) // remove the access node from cluster1 node 0 diff --git a/tools/cluster/tests/account_test.go b/tools/cluster/tests/account_test.go index 88cc138d96..39489244a3 100644 --- a/tools/cluster/tests/account_test.go +++ b/tools/cluster/tests/account_test.go @@ -111,7 +111,7 @@ func (e *ChainEnv) testBasic2Accounts(t *testing.T) { require.NoError(t, err) time.Sleep(3 * time.Second) - reqceipt, err := e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, req.ID(), false, 30*time.Second) + reqceipt, err := e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), false, 30*time.Second) require.NoError(t, err) user1L2Bal2 := e.GetL2Balance(isc.NewAddressAgentID(addressUser1), coin.BaseTokenType) diff --git a/tools/cluster/tests/advanced_account_test.go b/tools/cluster/tests/advanced_account_test.go index 162b5bd424..769f79134b 100644 --- a/tools/cluster/tests/advanced_account_test.go +++ b/tools/cluster/tests/advanced_account_test.go @@ -125,7 +125,7 @@ func testAccessNodesOffLedger(t *testing.T, numRequests, numValidatorNodes, clus }) require.NoError(t, err) - _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx, true, 30*time.Second) + _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, true, 30*time.Second) require.NoError(t, err) someRandomsAddress := isc.NewEthereumAddressAgentID(common.MaxAddress) diff --git a/tools/cluster/tests/env.go b/tools/cluster/tests/env.go index cd0072a845..05655055ee 100644 --- a/tools/cluster/tests/env.go +++ b/tools/cluster/tests/env.go @@ -83,7 +83,7 @@ func (e *ChainEnv) DepositFunds(amount coin.Value, keyPair *cryptolib.KeyPair) { } tx, err := client.PostRequest(context.Background(), accounts.FuncDeposit.Message(), params) require.NoError(e.t, err) - _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx, true, 30*time.Second) + _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, true, 30*time.Second) require.NoError(e.t, err, "Error while WaitUntilAllRequestsProcessedSuccessfully for tx.ID=%v", tx.Digest) } @@ -98,7 +98,7 @@ func (e *ChainEnv) TransferFundsTo(assets *isc.Assets, keyPair *cryptolib.KeyPai L2GasBudget: uint64(l2GasFee), }) require.NoError(e.t, err) - _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx, false, 30*time.Second) + _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, false, 30*time.Second) require.NoError(e.t, err, "Error while WaitUntilAllRequestsProcessedSuccessfully for tx.ID=%v", tx.Digest) } @@ -140,7 +140,7 @@ func (e *ChainEnv) DeploySolidityContract(creator *ecdsa.PrivateKey, abiJSON str require.NoError(e.t, err) // await tx confirmed - _, err = e.Chain.CommitteeMultiClient().WaitUntilEVMRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx.Hash(), false, 30*time.Second) + _, err = e.Chain.CommitteeMultiClient().WaitUntilEVMRequestProcessedSuccessfully(context.Background(), tx.Hash(), false, 30*time.Second) require.NoError(e.t, err) return crypto.CreateAddress(creatorAddress, nonce), contractABI @@ -229,7 +229,7 @@ func (e *ChainEnv) CallStore(archiveClient, lightClient *ethclient.Client, input require.NoError(e.t, err) // await tx confirmed for i := 0; i < 3; i++ { - _, err = e.Clu.MultiClient().WaitUntilEVMRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx.Hash(), false, 30*time.Second) + _, err = e.Clu.MultiClient().WaitUntilEVMRequestProcessedSuccessfully(context.Background(), tx.Hash(), false, 30*time.Second) if err == nil { break } diff --git a/tools/cluster/tests/estimategas_test.go b/tools/cluster/tests/estimategas_test.go index 81618d1a89..ee5d924494 100644 --- a/tools/cluster/tests/estimategas_test.go +++ b/tools/cluster/tests/estimategas_test.go @@ -47,7 +47,7 @@ func (e *ChainEnv) testEstimateGasOnLedger(t *testing.T) { GasBudget: iotaclient.DefaultGasBudget, }) require.NoError(t, err) - _, err = e.Clu.MultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx, true, 10*time.Second) + _, err = e.Clu.MultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, true, 10*time.Second) require.NoError(t, err) // Create tx sender with some funds @@ -234,7 +234,7 @@ func (e *ChainEnv) testEstimateGasOnLedger(t *testing.T) { require.Equal(t, estimatedStorageFee, res.Effects.Data.V1.GasUsed.StorageCost.Int.Uint64()) require.LessOrEqual(t, estimatedStorageRebate, res.Effects.Data.V1.GasUsed.StorageRebate.Int.Uint64()) - recs, err := e.Clu.MultiClient().WaitUntilAllRequestsProcessed(context.Background(), e.Chain.ChainID, res, false, 10*time.Second) + recs, err := e.Clu.MultiClient().WaitUntilAllRequestsProcessed(context.Background(), res, false, 10*time.Second) require.NoError(t, err, recs) require.Empty(t, recs[0].ErrorMessage, lo.FromPtr(recs[0].ErrorMessage)) require.Equal(t, recs[0].GasBurned, estimatedReceipt.L2.GasBurned) @@ -254,7 +254,7 @@ func (e *ChainEnv) testEstimateGasOnLedger(t *testing.T) { require.NoError(t, err) require.Empty(t, res.Errors) require.Empty(t, res.Effects.Data.V1.Status.Error, res.Effects.Data.V1.Status.Status) - recs, _ = e.Clu.MultiClient().WaitUntilAllRequestsProcessed(context.Background(), e.Chain.ChainID, res, false, 10*time.Second) + recs, _ = e.Clu.MultiClient().WaitUntilAllRequestsProcessed(context.Background(), res, false, 10*time.Second) require.Equal(t, "gas budget exceeded", lo.FromPtr(recs[0].ErrorMessage)) } @@ -301,7 +301,7 @@ func (e *ChainEnv) testEstimateGasOffLedger(t *testing.T) { par, ) require.NoError(t, err) - rec, err := e.Clu.MultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, req.ID(), false, 30*time.Second) + rec, err := e.Clu.MultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), false, 30*time.Second) require.NoError(t, err) require.Equal(t, rec.GasBurned, estimatedReceipt.GasBurned) require.Equal(t, rec.GasFeeCharged, estimatedReceipt.GasFeeCharged) diff --git a/tools/cluster/tests/evm_jsonrpc_test.go b/tools/cluster/tests/evm_jsonrpc_test.go index d343a0d127..8f1ebb646d 100644 --- a/tools/cluster/tests/evm_jsonrpc_test.go +++ b/tools/cluster/tests/evm_jsonrpc_test.go @@ -97,7 +97,7 @@ func (e *clusterTestEnv) newEthereumAccountWithL2Funds(baseTokens ...coin.Value) require.NoError(e.T, err) // We have to wait not only for the committee to process the request, but also for access nodes to get that info. - _, err = e.Chain.AllNodesMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx, false, 30*time.Second) + _, err = e.Chain.AllNodesMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, false, 30*time.Second) require.NoError(e.T, err) return ethKey, ethAddr @@ -140,7 +140,7 @@ func TestEVMJsonRPCZeroGasFee(t *testing.T) { GasBudget: iotaclient.DefaultGasBudget, }) require.NoError(t, err) - _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, reqTx, false, 30*time.Second) + _, err = e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), reqTx, false, 30*time.Second) require.NoError(t, err) d, err := govClient.CallView(context.Background(), governance.ViewGetFeePolicy.Message()) diff --git a/tools/cluster/tests/nodeconn_test.go b/tools/cluster/tests/nodeconn_test.go index 6ccd4ce70f..617a44215b 100644 --- a/tools/cluster/tests/nodeconn_test.go +++ b/tools/cluster/tests/nodeconn_test.go @@ -126,7 +126,7 @@ func TestNodeConn(t *testing.T) { // require.NoError(t, err) // ctxPublish, cancelPublish := context.WithCancel(context.Background()) - // nc.PublishTX(ctxPublish, chainID, tx, func(tx *iotago.Transaction, confirmed bool) { + // nc.PublishTX(ctxPublish, tx, func(tx *iotago.Transaction, confirmed bool) { // require.True(t, confirmed) // cancelPublish() // }) diff --git a/tools/cluster/tests/offledger_requests_test.go b/tools/cluster/tests/offledger_requests_test.go index 8cf991ad65..ac87362d20 100644 --- a/tools/cluster/tests/offledger_requests_test.go +++ b/tools/cluster/tests/offledger_requests_test.go @@ -80,7 +80,7 @@ func (e *ChainEnv) testOffledgerNonce(t *testing.T) { }, ) require.NoError(t, err) - _, err = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, offledgerReq.ID(), false, 30*time.Second) + _, err = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), offledgerReq.ID(), false, 30*time.Second) require.Error(t, err) // wont' be processed // send off-ledger requests with the correct nonce @@ -93,7 +93,7 @@ func (e *ChainEnv) testOffledgerNonce(t *testing.T) { }, ) require.NoError(t, err2) - _, err2 = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, req.ID(), false, 10*time.Second) + _, err2 = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), false, 10*time.Second) require.NoError(t, err2) } @@ -124,7 +124,7 @@ func (e *ChainEnv) newWalletWithL2Funds(waspnode int, waitOnNodes ...int) *chain }) require.NoError(e.t, err) - receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, reqTx, false, 30*time.Second) + receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), reqTx, false, 30*time.Second) require.NoError(e.t, err) gasFeeCharged, err := util.DecodeUint64(receipts[0].GasFeeCharged) diff --git a/tools/cluster/tests/post_test.go b/tools/cluster/tests/post_test.go index 45f7657adc..502f1a582f 100644 --- a/tools/cluster/tests/post_test.go +++ b/tools/cluster/tests/post_test.go @@ -30,7 +30,7 @@ func (e *ChainEnv) testPost1Request(t *testing.T) { }) require.NoError(t, err) - receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, reqTx, true, 30*time.Second) + receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), reqTx, true, 30*time.Second) require.NoError(t, err) balance2 := e.GetL2Balance(isc.NewAddressAgentID(userAddr), coin.BaseTokenType) @@ -55,7 +55,7 @@ func (e *ChainEnv) testPost3Requests(t *testing.T) { }) require.NoError(t, err) - recs, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx, true, 30*time.Second) + recs, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx, true, 30*time.Second) require.NoError(t, err) receipts[i] = recs[0] } @@ -90,7 +90,7 @@ func (e *ChainEnv) testPost5AsyncRequests(t *testing.T) { } for i := 0; i < 5; i++ { - receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx[i], false, 30*time.Second) + receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), tx[i], false, 30*time.Second) require.NoError(t, err) gasFeeCharged, err := util.DecodeUint64(receipts[0].GasFeeCharged) diff --git a/tools/cluster/tests/pruning_test.go b/tools/cluster/tests/pruning_test.go index 5d5ca38ed9..abae289cd2 100644 --- a/tools/cluster/tests/pruning_test.go +++ b/tools/cluster/tests/pruning_test.go @@ -52,7 +52,7 @@ func TestPruning(t *testing.T) { }, ) require.NoError(t, err) - _, err = chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), chain.ChainID, req.ID(), true, 30*time.Second) + _, err = chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), true, 30*time.Second) require.NoError(t, err) // let's send 100 EVM requests (wait for each request individually, so that the chain height increases as much as possible) diff --git a/tools/cluster/tests/reboot_test.go b/tools/cluster/tests/reboot_test.go index 12068c533e..aba094cd15 100644 --- a/tools/cluster/tests/reboot_test.go +++ b/tools/cluster/tests/reboot_test.go @@ -292,7 +292,7 @@ func TestRebootDuringTasks(t *testing.T) { chainclient.PostRequestParams{Allowance: isc.NewAssets(5000)}, ) require.NoError(t, err) - _, err = env.Clu.MultiClient().WaitUntilRequestProcessed(context.Background(), env.Chain.ChainID, req.ID(), true, 10*time.Second) + _, err = env.Clu.MultiClient().WaitUntilRequestProcessed(context.Background(), req.ID(), true, 10*time.Second) require.NoError(t, err) env.checkBalanceOnChain(targetAgentID, coin.BaseTokenType, 5000) } diff --git a/tools/cluster/tests/spam_test.go b/tools/cluster/tests/spam_test.go index e90cedea8a..ccf3f215d9 100644 --- a/tools/cluster/tests/spam_test.go +++ b/tools/cluster/tests/spam_test.go @@ -98,7 +98,7 @@ func (e *ChainEnv) testSpamOnledger(t *testing.T) { for range numRequests { tx := <-txCh - _, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, &tx, false, 30*time.Second) + _, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), &tx, false, 30*time.Second) require.NoError(t, err) } @@ -154,7 +154,7 @@ func (e *ChainEnv) testSpamOffLedger(t *testing.T) { } reqSentTime := time.Now() // wait for the request to be processed - _, err = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, req.ID(), false, 1*time.Minute) + _, err = e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), false, 1*time.Minute) if err != nil { reqErrorChan <- err return @@ -241,7 +241,7 @@ func (e *ChainEnv) testSpamEVM(t *testing.T) { // await txs confirmed for _, tx := range transactions { - _, err2 := e.Clu.MultiClient().WaitUntilEVMRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, tx.Hash(), false, 30*time.Second) + _, err2 := e.Clu.MultiClient().WaitUntilEVMRequestProcessedSuccessfully(context.Background(), tx.Hash(), false, 30*time.Second) require.NoError(t, err2) } diff --git a/tools/cluster/tests/transfer_test.go b/tools/cluster/tests/transfer_test.go index 7fafd20197..4bba182e86 100644 --- a/tools/cluster/tests/transfer_test.go +++ b/tools/cluster/tests/transfer_test.go @@ -37,7 +37,7 @@ func TestDepositWithdraw(t *testing.T) { reqTx, err := chClient.PostRequest(context.Background(), accounts.FuncDeposit.Message(), params) require.NoError(t, err) - receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), e.Chain.ChainID, reqTx, true, 30*time.Second) + receipts, err := e.Chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), reqTx, true, 30*time.Second) require.NoError(t, err) gasFees1, err := util.DecodeUint64(receipts[0].GasFeeCharged) @@ -57,7 +57,7 @@ func TestDepositWithdraw(t *testing.T) { }, ) require.NoError(t, err) - receipt, err := e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), e.Chain.ChainID, req.ID(), true, 30*time.Second) + receipt, err := e.Chain.CommitteeMultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), true, 30*time.Second) require.NoError(t, err) gasFees2, err := util.DecodeUint64(receipt.GasFeeCharged) diff --git a/tools/cluster/tests/validator_fees_test.go b/tools/cluster/tests/validator_fees_test.go index 2a027535e7..45f649aaa0 100644 --- a/tools/cluster/tests/validator_fees_test.go +++ b/tools/cluster/tests/validator_fees_test.go @@ -55,7 +55,7 @@ func TestValidatorFees(t *testing.T) { chainclient.PostRequestParams{Nonce: 0}, ) require.NoError(t, err2) - _, err2 = clu.MultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), chain.ChainID, req.ID(), false, 30*time.Second) + _, err2 = clu.MultiClient().WaitUntilRequestProcessedSuccessfully(context.Background(), req.ID(), false, 30*time.Second) require.NoError(t, err2) } // send a bunch of requests @@ -70,7 +70,7 @@ func TestValidatorFees(t *testing.T) { GasBudget: iotaclient.DefaultGasBudget, }) require.NoError(t, err) - _, err = chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), chainID, reqTx, false, 30*time.Second) + _, err = chain.CommitteeMultiClient().WaitUntilAllRequestsProcessedSuccessfully(context.Background(), reqTx, false, 30*time.Second) require.NoError(t, err) } for _, validatorKp := range validatorKps { diff --git a/tools/cluster/tests/wasp-cli.go b/tools/cluster/tests/wasp-cli.go index bf1f84c2d1..461c94591e 100644 --- a/tools/cluster/tests/wasp-cli.go +++ b/tools/cluster/tests/wasp-cli.go @@ -42,7 +42,7 @@ func newWaspCLITest(t *testing.T, opt ...waspClusterOpts) *WaspCLITest { }) // creating a config in a temp dir per test. If not provided, wasp-cli will reuse the config from HOME dir, which could mess up other tests or local configuration. - err = os.WriteFile(path.Join(dir, "wasp-cli.json"), []byte("{}"), 0644) + err = os.WriteFile(path.Join(dir, "wasp-cli.json"), []byte("{}"), 0o644) require.NoError(t, err) w := &WaspCLITest{ diff --git a/tools/cluster/tests/wasp-cli_rotation_test.go b/tools/cluster/tests/wasp-cli_rotation_test.go index 671a71f4fa..62c59cdadc 100644 --- a/tools/cluster/tests/wasp-cli_rotation_test.go +++ b/tools/cluster/tests/wasp-cli_rotation_test.go @@ -68,8 +68,8 @@ func testWaspCLIExternalRotation(t *testing.T, addAccessNode func(*WaspCLITest, fmt.Sprintf("--gov-controller=%s", w.WaspCliAddress.String()), "--node=0", ) - matches := regexp.MustCompile(`.*ChainID:\s*([a-zA-Z0-9_]*)\s+.*`).FindStringSubmatch(strings.Join(out, " ")) - chainID := matches[1] + // matches := regexp.MustCompile(`.*ChainID:\s*([a-zA-Z0-9_]*)\s+.*`).FindStringSubmatch(strings.Join(out, " ")) + // chainID := matches[1] w.ActivateChainOnAllNodes("chain1", 0) // start a new wasp cluster @@ -120,7 +120,7 @@ func testWaspCLIExternalRotation(t *testing.T, addAccessNode func(*WaspCLITest, } // activate the chain on the new nodes - w2.MustRun("chain", "add", "chain1", chainID) + w2.MustRun("chain", "add", "chain1") for _, idx := range w2.Cluster.AllNodes() { w2.MustRun("chain", "activate", fmt.Sprintf("--node=%d", idx)) } diff --git a/tools/cluster/waspconfig.go b/tools/cluster/waspconfig.go index 5627c4dc38..459a238085 100644 --- a/tools/cluster/waspconfig.go +++ b/tools/cluster/waspconfig.go @@ -92,7 +92,7 @@ var waspConfigTemplate = ` "peeringURL": "localhost:{{.PeeringPort}}", "port": {{.PeeringPort}} }, - "chains": { + "chain": { "broadcastUpToNPeers": 2, "broadcastInterval": "5s", "apiCacheTTL": "5m", diff --git a/tools/wasp-cli/chain/metadata.go b/tools/wasp-cli/chain/metadata.go index 96dee7baf3..d1b8833be6 100644 --- a/tools/wasp-cli/chain/metadata.go +++ b/tools/wasp-cli/chain/metadata.go @@ -106,7 +106,7 @@ func initMetadataCmd() *cobra.Command { ) cmd.Flags().BoolVarP(&useCliURL, "use-cli-url", "u", false, "use the configured cli wasp api url as public url (overrides --public-url)") - cmd.Flags().Var(&metadataArgs.PublicURL, "public-url", "the url leading to chain metadata f.e. (https://chain.network/v1/chains/:chainID)") + cmd.Flags().Var(&metadataArgs.PublicURL, "public-url", "the url leading to chain metadata f.e. (https://chain.network/v1/chain)") cmd.Flags().Var(&metadataArgs.EvmJSONRPCURL, "evm-rpc-url", "the public facing evm json rpc url") cmd.Flags().Var(&metadataArgs.EvmWSURL, "evm-ws-url", "the public facing evm websocket url")