From 7987fc93501a536f8f57ed9ef8d79b49278d7627 Mon Sep 17 00:00:00 2001 From: muXxer Date: Wed, 4 Oct 2023 17:12:41 +0200 Subject: [PATCH] Remove block issuance via API signed by the node itself --- components/blockissuer/component.go | 2 - components/inx/component.go | 16 +-- components/inx/params.go | 4 - components/inx/server_blocks.go | 2 +- components/restapi/core/blocks.go | 2 +- components/restapi/core/component.go | 9 +- components/restapi/params.go | 8 -- config_defaults.json | 9 +- .../templates/docker-compose-iota-core.yml.j2 | 6 - .../docs/references/configuration.md | 22 +--- pkg/blockfactory/blockissuer.go | 117 ++++++++---------- tools/docker-network/docker-compose.yml | 25 ---- 12 files changed, 64 insertions(+), 158 deletions(-) diff --git a/components/blockissuer/component.go b/components/blockissuer/component.go index eb6af3dec..4a9dc0de7 100644 --- a/components/blockissuer/component.go +++ b/components/blockissuer/component.go @@ -6,7 +6,6 @@ import ( "go.uber.org/dig" "github.com/iotaledger/hive.go/app" - "github.com/iotaledger/iota-core/components/restapi" "github.com/iotaledger/iota-core/pkg/blockfactory" "github.com/iotaledger/iota-core/pkg/daemon" "github.com/iotaledger/iota-core/pkg/protocol" @@ -47,7 +46,6 @@ func provide(c *dig.Container) error { return blockfactory.New(deps.Protocol, blockfactory.WithTipSelectionTimeout(ParamsBlockIssuer.TipSelectionTimeout), blockfactory.WithTipSelectionRetryInterval(ParamsBlockIssuer.TipSelectionRetryInterval), - blockfactory.WithIncompleteBlockAccepted(restapi.ParamsRestAPI.AllowIncompleteBlock), blockfactory.WithRateSetterEnabled(ParamsBlockIssuer.RateSetterEnabled), ) }) diff --git a/components/inx/component.go b/components/inx/component.go index 290dae5b5..5d9849863 100644 --- a/components/inx/component.go +++ b/components/inx/component.go @@ -22,16 +22,14 @@ func init() { IsEnabled: func(c *dig.Container) bool { return ParamsINX.Enabled }, - Provide: provide, - Configure: configure, - Run: run, + Provide: provide, + Run: run, } } var ( - Component *app.Component - deps dependencies - blockIssuerAccount blockfactory.Account + Component *app.Component + deps dependencies ) type dependencies struct { @@ -54,12 +52,6 @@ func provide(c *dig.Container) error { return nil } -func configure() error { - blockIssuerAccount = blockfactory.AccountFromParams(ParamsINX.BlockIssuerAccount, ParamsINX.BlockIssuerPrivateKey) - - return nil -} - func run() error { if err := Component.Daemon().BackgroundWorker("INX", func(ctx context.Context) { Component.LogInfo("Starting INX ... done") diff --git a/components/inx/params.go b/components/inx/params.go index 857d0eeb5..6f9eca990 100644 --- a/components/inx/params.go +++ b/components/inx/params.go @@ -10,10 +10,6 @@ type ParametersINX struct { Enabled bool `default:"false" usage:"whether the INX plugin is enabled"` // the bind address on which the INX can be accessed from BindAddress string `default:"localhost:9029" usage:"the bind address on which the INX can be accessed from"` - // BlockIssuerAccount the accountID of the account that will issue the blocks. - BlockIssuerAccount string `default:"" usage:"the accountID of the account that will issue the blocks"` - // BlockIssuerPrivateKey the private key of the account that will issue the blocks. - BlockIssuerPrivateKey string `default:"" usage:"the private key of the account that will issue the blocks"` } var ParamsINX = &ParametersINX{} diff --git a/components/inx/server_blocks.go b/components/inx/server_blocks.go index e41439fbb..b67be1f2f 100644 --- a/components/inx/server_blocks.go +++ b/components/inx/server_blocks.go @@ -130,7 +130,7 @@ func (s *Server) attachBlock(ctx context.Context, block *iotago.ProtocolBlock) ( mergedCtx, mergedCtxCancel := contextutils.MergeContexts(ctx, Component.Daemon().ContextStopped()) defer mergedCtxCancel() - blockID, err := deps.BlockIssuer.AttachBlock(mergedCtx, block, blockIssuerAccount) + blockID, err := deps.BlockIssuer.AttachBlock(mergedCtx, block) if err != nil { switch { case ierrors.Is(err, blockfactory.ErrBlockAttacherInvalidBlock): diff --git a/components/restapi/core/blocks.go b/components/restapi/core/blocks.go index dcff49cb9..2fd238995 100644 --- a/components/restapi/core/blocks.go +++ b/components/restapi/core/blocks.go @@ -110,7 +110,7 @@ func sendBlock(c echo.Context) (*apimodels.BlockCreatedResponse, error) { return nil, echo.ErrUnsupportedMediaType } - blockID, err := deps.BlockIssuer.AttachBlock(c.Request().Context(), iotaBlock, blockIssuerAccount) + blockID, err := deps.BlockIssuer.AttachBlock(c.Request().Context(), iotaBlock) if err != nil { switch { case ierrors.Is(err, blockfactory.ErrBlockAttacherInvalidBlock): diff --git a/components/restapi/core/component.go b/components/restapi/core/component.go index fd9a49214..d39d8b2b9 100644 --- a/components/restapi/core/component.go +++ b/components/restapi/core/component.go @@ -134,8 +134,7 @@ var ( Component *app.Component deps dependencies - blockIssuerAccount blockfactory.Account - features = []string{} + features = []string{} ) type dependencies struct { @@ -157,12 +156,6 @@ func configure() error { routeGroup := deps.RestRouteManager.AddRoute("core/v3") - if restapi.ParamsRestAPI.AllowIncompleteBlock { - AddFeature("allowIncompleteBlock") - } - - blockIssuerAccount = blockfactory.AccountFromParams(restapi.ParamsRestAPI.BlockIssuerAccount, restapi.ParamsRestAPI.BlockIssuerPrivateKey) - routeGroup.GET(RouteInfo, func(c echo.Context) error { resp := info() diff --git a/components/restapi/params.go b/components/restapi/params.go index a1fd8791e..440fdc102 100644 --- a/components/restapi/params.go +++ b/components/restapi/params.go @@ -16,8 +16,6 @@ type ParametersRestAPI struct { ProtectedRoutes []string `usage:"the HTTP REST routes which need to be called with authorization. Wildcards using * are allowed"` // whether the debug logging for requests should be enabled DebugRequestLoggerEnabled bool `default:"false" usage:"whether the debug logging for requests should be enabled"` - // AllowIncompleteBlock defines whether the node allows to fill in incomplete block and issue it for user. - AllowIncompleteBlock bool `default:"false" usage:"whether the node allows to fill in incomplete block and issue it for user"` // MaxPageSize defines the maximum number of results per page. MaxPageSize uint32 `default:"100" usage:"the maximum number of results per page"` // RequestsMemoryCacheGranularity defines per how many slots a cache is created for big API requests. @@ -36,12 +34,6 @@ type ParametersRestAPI struct { // the maximum number of results that may be returned by an endpoint MaxResults int `default:"1000" usage:"the maximum number of results that may be returned by an endpoint"` } - - // BlockIssuerAccount the accountID of the account that will issue the blocks. - BlockIssuerAccount string `default:"" usage:"the accountID of the account that will issue the blocks"` - - // BlockIssuerPrivateKey the private key of the account that will issue the blocks. - BlockIssuerPrivateKey string `default:"" usage:"the private key of the account that will issue the blocks"` } var ParamsRestAPI = &ParametersRestAPI{ diff --git a/config_defaults.json b/config_defaults.json index ee999ac24..e7577c2d2 100644 --- a/config_defaults.json +++ b/config_defaults.json @@ -65,7 +65,6 @@ "/api/*" ], "debugRequestLoggerEnabled": false, - "allowIncompleteBlock": false, "maxPageSize": 100, "requestsMemoryCacheGranularity": 10, "maxRequestedSlotAge": 10, @@ -75,9 +74,7 @@ "limits": { "maxBodyLength": "1M", "maxResults": 1000 - }, - "blockIssuerAccount": "", - "blockIssuerPrivateKey": "" + } }, "debugAPI": { "enabled": true, @@ -155,8 +152,6 @@ }, "inx": { "enabled": false, - "bindAddress": "localhost:9029", - "blockIssuerAccount": "", - "blockIssuerPrivateKey": "" + "bindAddress": "localhost:9029" } } diff --git a/deploy/ansible/roles/iota-core-node/templates/docker-compose-iota-core.yml.j2 b/deploy/ansible/roles/iota-core-node/templates/docker-compose-iota-core.yml.j2 index 979850857..e86b3be51 100644 --- a/deploy/ansible/roles/iota-core-node/templates/docker-compose-iota-core.yml.j2 +++ b/deploy/ansible/roles/iota-core-node/templates/docker-compose-iota-core.yml.j2 @@ -40,7 +40,6 @@ services: --profiling.bindAddress=0.0.0.0:6061 --profiling.enabled=true --protocol.snapshot.path=/app/data/snapshot.bin - --restAPI.allowIncompleteBlock=true {% if 'node-01' in inventory_hostname or 'node-02' in inventory_hostname or 'node-03' in inventory_hostname %} --validator.enabled=true --validator.account={{validatorAccount}} @@ -49,11 +48,6 @@ services: {% if 'node-01' in inventory_hostname %} --validator.ignoreBootstrapped=true {% endif %} - --restAPI.allowIncompleteBlock=true - --restAPI.blockIssuerAccount={{validatorAccount}} - --restAPI.blockIssuerPrivateKey={{validatorPrivKey}} - --inx.blockIssuerAccount={{validatorAccount}} - --inx.blockIssuerPrivateKey={{validatorPrivKey}} --p2p.peers=/dns/node-01.feature/tcp/14666/p2p/12D3KooWCrjmh4dUCWfGVQT6ivzArieJB9Z3eKdy2mdEEN95NDPS --p2p.externalMultiAddresses={{ ips | join(',') }} --p2p.identityPrivateKey={{p2pIdentityPrivateKey}} diff --git a/documentation/docs/references/configuration.md b/documentation/docs/references/configuration.md index 484cf55c4..bfe970cc5 100644 --- a/documentation/docs/references/configuration.md +++ b/documentation/docs/references/configuration.md @@ -179,14 +179,11 @@ Example: | publicRoutes | The HTTP REST routes which can be called without authorization. Wildcards using \* are allowed | array | /health
/api/routes
/api/core/v3/info
/api/core/v3/blocks\*
/api/core/v3/transactions\*
/api/core/v3/commitments\*
/api/core/v3/outputs\*
/api/core/v3/accounts\*
/api/core/v3/validators\*
/api/core/v3/rewards\*
/api/core/v3/committee
/api/debug/v2/\*
/api/indexer/v2/\*
/api/mqtt/v2 | | protectedRoutes | The HTTP REST routes which need to be called with authorization. Wildcards using \* are allowed | array | /api/\* | | debugRequestLoggerEnabled | Whether the debug logging for requests should be enabled | boolean | false | -| allowIncompleteBlock | Whether the node allows to fill in incomplete block and issue it for user | boolean | false | | maxPageSize | The maximum number of results per page | uint | 100 | | requestsMemoryCacheGranularity | Defines per how many slots a cache is created for big API requests | uint | 10 | | maxRequestedSlotAge | The maximum age of a request that will be processed | uint | 10 | | [jwtAuth](#restapi_jwtauth) | Configuration for jwtAuth | object | | | [limits](#restapi_limits) | Configuration for limits | object | | -| blockIssuerAccount | The accountID of the account that will issue the blocks | string | "" | -| blockIssuerPrivateKey | The private key of the account that will issue the blocks | string | "" | ### JwtAuth @@ -228,7 +225,6 @@ Example: "/api/*" ], "debugRequestLoggerEnabled": false, - "allowIncompleteBlock": false, "maxPageSize": 100, "requestsMemoryCacheGranularity": 10, "maxRequestedSlotAge": 10, @@ -238,9 +234,7 @@ Example: "limits": { "maxBodyLength": "1M", "maxResults": 1000 - }, - "blockIssuerAccount": "", - "blockIssuerPrivateKey": "" + } } } ``` @@ -499,12 +493,10 @@ Example: ## 14. Inx -| Name | Description | Type | Default value | -| --------------------- | --------------------------------------------------------- | ------- | ---------------- | -| enabled | Whether the INX plugin is enabled | boolean | false | -| bindAddress | The bind address on which the INX can be accessed from | string | "localhost:9029" | -| blockIssuerAccount | The accountID of the account that will issue the blocks | string | "" | -| blockIssuerPrivateKey | The private key of the account that will issue the blocks | string | "" | +| Name | Description | Type | Default value | +| ----------- | ------------------------------------------------------ | ------- | ---------------- | +| enabled | Whether the INX plugin is enabled | boolean | false | +| bindAddress | The bind address on which the INX can be accessed from | string | "localhost:9029" | Example: @@ -512,9 +504,7 @@ Example: { "inx": { "enabled": false, - "bindAddress": "localhost:9029", - "blockIssuerAccount": "", - "blockIssuerPrivateKey": "" + "bindAddress": "localhost:9029" } } ``` diff --git a/pkg/blockfactory/blockissuer.go b/pkg/blockfactory/blockissuer.go index eb1692261..bab90eccf 100644 --- a/pkg/blockfactory/blockissuer.go +++ b/pkg/blockfactory/blockissuer.go @@ -21,9 +21,8 @@ import ( ) var ( - ErrBlockAttacherInvalidBlock = ierrors.New("invalid block") - ErrBlockAttacherAttachingNotPossible = ierrors.New("attaching not possible") - ErrBlockAttacherIncompleteBlockNotAllowed = ierrors.New("incomplete block is not allowed on this node") + ErrBlockAttacherInvalidBlock = ierrors.New("invalid block") + ErrBlockAttacherAttachingNotPossible = ierrors.New("attaching not possible") ) // TODO: make sure an honest validator does not issue blocks within the same slot ratification period in two conflicting chains. @@ -42,8 +41,7 @@ type BlockIssuer struct { optsTipSelectionTimeout time.Duration optsTipSelectionRetryInterval time.Duration // optsIncompleteBlockAccepted defines whether the node allows filling in incomplete block and issuing it for user. - optsIncompleteBlockAccepted bool - optsRateSetterEnabled bool + optsRateSetterEnabled bool } func New(p *protocol.Protocol, opts ...options.Option[BlockIssuer]) *BlockIssuer { @@ -51,7 +49,6 @@ func New(p *protocol.Protocol, opts ...options.Option[BlockIssuer]) *BlockIssuer events: NewEvents(), workerPool: p.Workers.CreatePool("BlockIssuer"), protocol: p, - optsIncompleteBlockAccepted: false, optsRateSetterEnabled: false, optsTipSelectionTimeout: 5 * time.Second, optsTipSelectionRetryInterval: 200 * time.Millisecond, @@ -267,10 +264,21 @@ func (i *BlockIssuer) IssueBlockAndAwaitEvent(ctx context.Context, block *model. } } -func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.ProtocolBlock, optIssuerAccount ...Account) (iotago.BlockID, error) { - // if anything changes, need to make a new signature - var resign bool +func (i *BlockIssuer) getBlockRMC(api iotago.API, protocolBlock *iotago.ProtocolBlock) (iotago.Mana, error) { + rmcSlot, err := safemath.SafeSub(api.TimeProvider().SlotFromTime(protocolBlock.IssuingTime), api.ProtocolParameters().MaxCommittableAge()) + if err != nil { + rmcSlot = 0 + } + + rmc, err := i.protocol.MainEngineInstance().Ledger.RMCManager().RMC(rmcSlot) + if err != nil { + return 0, ierrors.Wrapf(err, "error loading commitment of slot %d from storage to get RMC", rmcSlot) + } + + return rmc, nil +} +func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.ProtocolBlock) (iotago.BlockID, error) { apiForVesion, err := i.protocol.APIForVersion(iotaBlock.ProtocolVersion) if err != nil { return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "protocolVersion invalid: %d", iotaBlock.ProtocolVersion) @@ -279,14 +287,28 @@ func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Protoco protoParams := apiForVesion.ProtocolParameters() if iotaBlock.NetworkID == 0 { - iotaBlock.NetworkID = protoParams.NetworkID() - resign = true + return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "invalid block, error: missing networkID") } - if iotaBlock.SlotCommitmentID == iotago.EmptyCommitmentID { - iotaBlock.SlotCommitmentID = i.protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID() - iotaBlock.LatestFinalizedSlot = i.protocol.MainEngineInstance().Storage.Settings().LatestFinalizedSlot() - resign = true + if iotaBlock.SlotCommitmentID.Empty() { + return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "invalid block, error: missing slotCommitmentID") + } + + if iotaBlock.IssuingTime.Equal(time.Unix(0, 0)) { + return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "invalid block, error: missing issuingTime") + } + + if iotaBlock.IssuerID.Empty() { + return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "invalid block, error: signature needed") + } + + // check the block signature + valid, err := iotaBlock.VerifySignature() + if err != nil { + return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "invalid block, error: unable to verify block signature: %w", err) + } + if !valid { + return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "invalid block, error: invalid signature") } switch innerBlock := iotaBlock.Block.(type) { @@ -294,26 +316,17 @@ func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Protoco switch payload := innerBlock.Payload.(type) { case *iotago.SignedTransaction: if payload.Transaction.NetworkID != protoParams.NetworkID() { - return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "invalid payload, error: wrong networkID: %d", payload.Transaction.NetworkID) + return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "invalid basic block payload, error: wrong networkID: %d", payload.Transaction.NetworkID) } } - if len(iotaBlock.Parents()) == 0 { - references, referencesErr := i.getReferences(ctx, innerBlock.Payload) - if referencesErr != nil { - return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherAttachingNotPossible, "tipselection failed, error: %w", referencesErr) - } - - innerBlock.StrongParents = references[iotago.StrongParentType] - innerBlock.WeakParents = references[iotago.WeakParentType] - innerBlock.ShallowLikeParents = references[iotago.ShallowLikeParentType] - resign = true + if len(innerBlock.StrongParentIDs()) == 0 { + return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "invalid basic block, error: missing strongParents") } case *iotago.ValidationBlock: - //nolint:revive,staticcheck //temporarily disable - if len(iotaBlock.Parents()) == 0 { - // TODO: implement tipselection for validator blocks + if len(innerBlock.StrongParentIDs()) == 0 { + return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "invalid validation block, error: missing strongParents") } } @@ -321,51 +334,25 @@ func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Protoco references[iotago.StrongParentType] = iotaBlock.Block.StrongParentIDs().RemoveDupsAndSort() references[iotago.WeakParentType] = iotaBlock.Block.WeakParentIDs().RemoveDupsAndSort() references[iotago.ShallowLikeParentType] = iotaBlock.Block.ShallowLikeParentIDs().RemoveDupsAndSort() - if iotaBlock.IssuingTime.Equal(time.Unix(0, 0)) { - iotaBlock.IssuingTime = time.Now().UTC() - resign = true - } if err = i.validateReferences(iotaBlock.IssuingTime, iotaBlock.SlotCommitmentID.Slot(), references); err != nil { return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherAttachingNotPossible, "invalid block references, error: %w", err) } - if basicBlock, isBasicBlock := iotaBlock.Block.(*iotago.BasicBlock); isBasicBlock && basicBlock.MaxBurnedMana == 0 { - rmcSlot, err := safemath.SafeSub(apiForVesion.TimeProvider().SlotFromTime(iotaBlock.IssuingTime), apiForVesion.ProtocolParameters().MaxCommittableAge()) + // check if the block burns enough mana + if basicBlock, isBasicBlock := iotaBlock.Block.(*iotago.BasicBlock); isBasicBlock { + rmc, err := i.getBlockRMC(apiForVesion, iotaBlock) if err != nil { - rmcSlot = 0 - } - rmc, err := i.protocol.MainEngineInstance().Ledger.RMCManager().RMC(rmcSlot) - if err != nil { - return iotago.EmptyBlockID(), ierrors.Wrapf(err, "error loading commitment of slot %d from storage to get RMC", rmcSlot) + return iotago.EmptyBlockID(), err } - // only set the burned Mana as the last step before signing, so workscore calculation is correct. - basicBlock.MaxBurnedMana, err = basicBlock.ManaCost(rmc, apiForVesion.ProtocolParameters().WorkScoreStructure()) + burnedMana, err := basicBlock.ManaCost(rmc, apiForVesion.ProtocolParameters().WorkScoreStructure()) if err != nil { return iotago.EmptyBlockID(), ierrors.Wrapf(err, "could not calculate Mana cost for block") } - resign = true - } - - if iotaBlock.IssuerID.Empty() || resign { - if i.optsIncompleteBlockAccepted && len(optIssuerAccount) > 0 { - issuerAccount := optIssuerAccount[0] - iotaBlock.IssuerID = issuerAccount.ID() - signature, signatureErr := iotaBlock.Sign(iotago.NewAddressKeysForEd25519Address(issuerAccount.Address().(*iotago.Ed25519Address), issuerAccount.PrivateKey())) - if signatureErr != nil { - return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "%w", signatureErr) - } - - edSig, isEdSig := signature.(*iotago.Ed25519Signature) - if !isEdSig { - return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherInvalidBlock, "unsupported signature type") - } - - iotaBlock.Signature = edSig - } else { - return iotago.EmptyBlockID(), ierrors.Wrap(ErrBlockAttacherIncompleteBlockNotAllowed, "signature needed") + if basicBlock.MaxBurnedMana < burnedMana { + return iotago.EmptyBlockID(), ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "invalid basic block, error: burnedMana lower than the required minimum to issue the block: %d<%d", basicBlock.MaxBurnedMana, burnedMana) } } @@ -517,12 +504,6 @@ func WithTipSelectionRetryInterval(interval time.Duration) options.Option[BlockI } } -func WithIncompleteBlockAccepted(accepted bool) options.Option[BlockIssuer] { - return func(i *BlockIssuer) { - i.optsIncompleteBlockAccepted = accepted - } -} - func WithRateSetterEnabled(enabled bool) options.Option[BlockIssuer] { return func(i *BlockIssuer) { i.optsRateSetterEnabled = enabled diff --git a/tools/docker-network/docker-compose.yml b/tools/docker-network/docker-compose.yml index b673e932c..ebc264856 100644 --- a/tools/docker-network/docker-compose.yml +++ b/tools/docker-network/docker-compose.yml @@ -16,13 +16,8 @@ services: --validator.ignoreBootstrapped=true --validator.account=0x907c02e9302e0f0571f10f885594e56d8c54ff0708ab7a39bc1b74d396b93b12 --validator.privateKey=443a988ea61797651217de1f4662d4d6da11fd78e67f94511453bf6576045a05293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b - --restAPI.allowIncompleteBlock=true - --restAPI.blockIssuerAccount=0x907c02e9302e0f0571f10f885594e56d8c54ff0708ab7a39bc1b74d396b93b12 - --restAPI.blockIssuerPrivateKey=443a988ea61797651217de1f4662d4d6da11fd78e67f94511453bf6576045a05293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b --inx.enabled=true --inx.bindAddress=0.0.0.0:9029 - --inx.blockIssuerAccount=0x907c02e9302e0f0571f10f885594e56d8c54ff0708ab7a39bc1b74d396b93b12 - --inx.blockIssuerPrivateKey=443a988ea61797651217de1f4662d4d6da11fd78e67f94511453bf6576045a05293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b volumes: - ./docker-network.snapshot:/app/data/snapshot.bin - ./config.json:/app/config.json:ro @@ -54,13 +49,8 @@ services: --validator.enabled=true --validator.account=0x375358f92cc94750669598b0aaa55a6ff73310b90710e1fad524c0f911be0fea --validator.privateKey=3a5d39f8b60367a17fd54dac2a32c172c8e1fd6cf74ce65f1e13edba565f281705c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064 - --restAPI.allowIncompleteBlock=true - --restAPI.blockIssuerAccount=0x375358f92cc94750669598b0aaa55a6ff73310b90710e1fad524c0f911be0fea - --restAPI.blockIssuerPrivateKey=3a5d39f8b60367a17fd54dac2a32c172c8e1fd6cf74ce65f1e13edba565f281705c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064 --inx.enabled=true --inx.bindAddress=0.0.0.0:9029 - --inx.blockIssuerAccount=0x375358f92cc94750669598b0aaa55a6ff73310b90710e1fad524c0f911be0fea - --inx.blockIssuerPrivateKey=3a5d39f8b60367a17fd54dac2a32c172c8e1fd6cf74ce65f1e13edba565f281705c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064 volumes: - ./docker-network.snapshot:/app/data/snapshot.bin - ./config.json:/app/config.json:ro @@ -84,13 +74,8 @@ services: --validator.enabled=true --validator.account=0x6aee704f25558e8aa7630fed0121da53074188abc423b3c5810f80be4936eb6e --validator.privateKey=db39d2fde6301d313b108dc9db1ee724d0f405f6fde966bd776365bc5f4a5fb31e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648 - --restAPI.allowIncompleteBlock=true - --restAPI.blockIssuerAccount=0x6aee704f25558e8aa7630fed0121da53074188abc423b3c5810f80be4936eb6e - --restAPI.blockIssuerPrivateKey=db39d2fde6301d313b108dc9db1ee724d0f405f6fde966bd776365bc5f4a5fb31e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648 --inx.enabled=true --inx.bindAddress=0.0.0.0:9029 - --inx.blockIssuerAccount=0x6aee704f25558e8aa7630fed0121da53074188abc423b3c5810f80be4936eb6e - --inx.blockIssuerPrivateKey=db39d2fde6301d313b108dc9db1ee724d0f405f6fde966bd776365bc5f4a5fb31e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648 volumes: - ./docker-network.snapshot:/app/data/snapshot.bin - ./config.json:/app/config.json:ro @@ -109,13 +94,8 @@ services: ${COMMON_CONFIG} ${MANUALPEERING_CONFIG} --p2p.identityPrivateKey=03feb3bcd25e57f75697bb329e6e0100680431e4c45c85bc013da2aea9e9d0345e08a0c37407dc62369deebc64cb0fb3ea26127d19d141ee7fb8eaa6b92019d7 - --restAPI.allowIncompleteBlock=true - --restAPI.blockIssuerAccount=0xd057230f48fdf59ae093e2179857c590e960b05389399399ce69ad169a9c7f37 - --restAPI.blockIssuerPrivateKey=dcf7adb000f03826f1964a3e5378874b1972c38229fb740a8e47f2c421cddcf9a54fafa44a88e4a6a37796526ea884f613a24d84337871226eb6360f022d8b39 --inx.enabled=true --inx.bindAddress=0.0.0.0:9029 - --inx.blockIssuerAccount=0xd057230f48fdf59ae093e2179857c590e960b05389399399ce69ad169a9c7f37 - --inx.blockIssuerPrivateKey=dcf7adb000f03826f1964a3e5378874b1972c38229fb740a8e47f2c421cddcf9a54fafa44a88e4a6a37796526ea884f613a24d84337871226eb6360f022d8b39 volumes: - ./docker-network.snapshot:/app/data/snapshot.bin - ./config.json:/app/config.json:ro @@ -134,13 +114,8 @@ services: ${COMMON_CONFIG} ${MANUALPEERING_CONFIG} --p2p.identityPrivateKey=7d1491df3ef334dee988d6cdfc4b430b996d520bd63375a01d6754f8cee979b855b200fbea8c936ea1937a27e6ad72a7c9a21c1b17c2bd3c11f1f6994d813446 - --restAPI.allowIncompleteBlock=true - --restAPI.blockIssuerAccount=0x7a9ec5d9c0c145bae03b20cbe481cfea306e688c00525b410eb8cb18a169ed7f - --restAPI.blockIssuerPrivateKey=0d8ecad4cefe927d2b6c64ee56576c52450f9a7a0113f96683cf8e8cc5c64264cb5ea14175ce649149ee41217c44aa70c3205b9939968449eae408727a71f91b --inx.enabled=true --inx.bindAddress=0.0.0.0:9029 - --inx.blockIssuerAccount=0x7a9ec5d9c0c145bae03b20cbe481cfea306e688c00525b410eb8cb18a169ed7f - --inx.blockIssuerPrivateKey=0d8ecad4cefe927d2b6c64ee56576c52450f9a7a0113f96683cf8e8cc5c64264cb5ea14175ce649149ee41217c44aa70c3205b9939968449eae408727a71f91b volumes: - ./docker-network.snapshot:/app/data/snapshot.bin - ./config.json:/app/config.json:ro