diff --git a/.github/workflows/feature-network-deploy.yml b/.github/workflows/feature-network-deploy.yml
index c4c71e425..812411683 100644
--- a/.github/workflows/feature-network-deploy.yml
+++ b/.github/workflows/feature-network-deploy.yml
@@ -70,7 +70,7 @@ jobs:
- name: Ansible deploy
env:
CUSTOM_SNAPSHOT_URL: '${{ github.event.inputs.snapshotUrl }}'
- DEFAULT_SNAPSHOT_URL: 'https://0x0.st/HJXh.bin'
+ DEFAULT_SNAPSHOT_URL: 'https://0x0.st/HywH.bin'
NETWORK_ENVIRONMENT: '${{ secrets.NETWORK_ENVIRONMENT }}'
IOTA_CORE_DOCKER_IMAGE_REPO: 'iotaledger/iota-core'
IOTA_CORE_DOCKER_IMAGE_TAG: 'feature'
diff --git a/.gitignore b/.gitignore
index fea8c46c9..56ae79587 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,8 +15,7 @@ iota-core
# IDE related files
.vscode/
.idea/
-go.work
-go.work.sum
+go.work*
# dist packages
dist/
diff --git a/components/app/app.go b/components/app/app.go
index 5c4b42957..5f840eb4c 100644
--- a/components/app/app.go
+++ b/components/app/app.go
@@ -17,7 +17,6 @@ import (
"github.com/iotaledger/iota-core/components/protocol"
"github.com/iotaledger/iota-core/components/restapi"
coreapi "github.com/iotaledger/iota-core/components/restapi/core"
- "github.com/iotaledger/iota-core/components/validator"
"github.com/iotaledger/iota-core/pkg/toolset"
)
@@ -48,7 +47,6 @@ Command line flags:
debugapi.Component,
metricstracker.Component,
protocol.Component,
- validator.Component,
dashboardmetrics.Component,
dashboard.Component,
metrics.Component,
diff --git a/components/dashboard/component.go b/components/dashboard/component.go
index 62326f082..360702aaa 100644
--- a/components/dashboard/component.go
+++ b/components/dashboard/component.go
@@ -155,7 +155,7 @@ func currentNodeStatus() *nodestatus {
status.TangleTime = tangleTime{
Synced: syncStatus.NodeSynced,
- Bootstrapped: deps.Protocol.MainEngineInstance().SyncManager.IsBootstrapped(),
+ Bootstrapped: syncStatus.NodeBootstrapped,
AcceptedBlockSlot: int64(syncStatus.LastAcceptedBlockSlot),
ConfirmedBlockSlot: int64(syncStatus.LastConfirmedBlockSlot),
CommittedSlot: int64(syncStatus.LatestCommitment.Slot()),
diff --git a/components/inx/server_accounts.go b/components/inx/server_accounts.go
new file mode 100644
index 000000000..6e8585be6
--- /dev/null
+++ b/components/inx/server_accounts.go
@@ -0,0 +1,53 @@
+package inx
+
+import (
+ "context"
+
+ "github.com/iotaledger/hive.go/ierrors"
+ inx "github.com/iotaledger/inx/go"
+ iotago "github.com/iotaledger/iota.go/v4"
+)
+
+func (s *Server) ReadIsValidatorAccount(_ context.Context, accountInfoRequest *inx.AccountInfoRequest) (*inx.BoolResponse, error) {
+ slot := iotago.SlotIndex(accountInfoRequest.GetAccountSlot())
+ accountID, _, err := iotago.AccountIDFromBytes(accountInfoRequest.AccountId)
+ if err != nil {
+ return nil, ierrors.Wrap(err, "error when parsing account id")
+ }
+
+ account, exists, err := deps.Protocol.MainEngineInstance().Ledger.Account(accountID, slot)
+ if err != nil {
+ return nil, ierrors.Wrapf(err, "error when retrieving account data for %s", accountID)
+ }
+
+ return inx.WrapBoolResponse(exists && account.StakeEndEpoch <= deps.Protocol.APIForSlot(slot).TimeProvider().EpochFromSlot(slot)), nil
+}
+
+func (s *Server) ReadIsCommitteeMember(_ context.Context, accountInfoRequest *inx.AccountInfoRequest) (*inx.BoolResponse, error) {
+ slot := iotago.SlotIndex(accountInfoRequest.GetAccountSlot())
+ accountID, _, err := iotago.AccountIDFromBytes(accountInfoRequest.AccountId)
+ if err != nil {
+ return nil, ierrors.Wrap(err, "error when parsing account id")
+ }
+ committee, exists := deps.Protocol.MainEngineInstance().SybilProtection.SeatManager().CommitteeInSlot(slot)
+ if !exists {
+ return nil, ierrors.Errorf("committee does not exist for slot %d", slot)
+ }
+
+ return inx.WrapBoolResponse(committee.HasAccount(accountID)), nil
+}
+
+func (s *Server) ReadIsCandidate(_ context.Context, accountInfoRequest *inx.AccountInfoRequest) (*inx.BoolResponse, error) {
+ slot := iotago.SlotIndex(accountInfoRequest.GetAccountSlot())
+ accountID, _, err := iotago.AccountIDFromBytes(accountInfoRequest.AccountId)
+ if err != nil {
+ return nil, ierrors.Wrap(err, "error when parsing account id")
+ }
+
+ isCandidateActive, err := deps.Protocol.MainEngineInstance().SybilProtection.IsCandidateActive(accountID, deps.Protocol.APIForSlot(slot).TimeProvider().EpochFromSlot(slot))
+ if err != nil {
+ return nil, ierrors.Wrap(err, "error when checking if candidate is active")
+ }
+
+ return inx.WrapBoolResponse(isCandidateActive), nil
+}
diff --git a/components/inx/server_blocks.go b/components/inx/server_blocks.go
index 63b6b076e..0565e94b8 100644
--- a/components/inx/server_blocks.go
+++ b/components/inx/server_blocks.go
@@ -16,6 +16,12 @@ import (
iotago "github.com/iotaledger/iota.go/v4"
)
+func (s *Server) ReadActiveRootBlocks(_ context.Context, _ *inx.NoParams) (*inx.RootBlocksResponse, error) {
+ activeRootBlocks := deps.Protocol.MainEngineInstance().EvictionState.ActiveRootBlocks()
+
+ return inx.WrapRootBlocks(activeRootBlocks), nil
+}
+
func (s *Server) ReadBlock(_ context.Context, blockID *inx.BlockId) (*inx.RawBlock, error) {
blkID := blockID.Unwrap()
block, exists := deps.Protocol.MainEngineInstance().Block(blkID) // block +1
diff --git a/components/inx/server_commitments.go b/components/inx/server_commitments.go
index 7dd44ba84..b16713f48 100644
--- a/components/inx/server_commitments.go
+++ b/components/inx/server_commitments.go
@@ -22,6 +22,14 @@ func inxCommitment(commitment *model.Commitment) *inx.Commitment {
}
}
+func (s *Server) ForceCommitUntil(_ context.Context, slot *inx.SlotIndex) (*inx.NoParams, error) {
+ err := deps.Protocol.MainEngineInstance().Notarization.ForceCommitUntil(slot.Unwrap())
+ if err != nil {
+ return nil, ierrors.Wrapf(err, "error while performing force commit until %d", slot.Index)
+ }
+
+ return &inx.NoParams{}, nil
+}
func (s *Server) ReadCommitment(_ context.Context, req *inx.CommitmentRequest) (*inx.Commitment, error) {
commitmentSlot := iotago.SlotIndex(req.GetCommitmentSlot())
diff --git a/components/inx/server_node.go b/components/inx/server_node.go
index 9a2f8386e..0039cad2b 100644
--- a/components/inx/server_node.go
+++ b/components/inx/server_node.go
@@ -25,6 +25,7 @@ func inxNodeStatus(status *syncmanager.SyncStatus) *inx.NodeStatus {
return &inx.NodeStatus{
IsHealthy: status.NodeSynced,
+ IsBootstrapped: status.NodeBootstrapped,
LastAcceptedBlockSlot: uint32(status.LastAcceptedBlockSlot),
LastConfirmedBlockSlot: uint32(status.LastConfirmedBlockSlot),
LatestCommitment: inxCommitment(status.LatestCommitment),
diff --git a/components/validator/component.go b/components/validator/component.go
deleted file mode 100644
index 5d8bb7926..000000000
--- a/components/validator/component.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package validator
-
-import (
- "context"
- "sync/atomic"
- "time"
-
- "go.uber.org/dig"
-
- "github.com/iotaledger/hive.go/app"
- "github.com/iotaledger/hive.go/runtime/event"
- "github.com/iotaledger/hive.go/runtime/timed"
- "github.com/iotaledger/iota-core/pkg/blockhandler"
- "github.com/iotaledger/iota-core/pkg/daemon"
- "github.com/iotaledger/iota-core/pkg/protocol"
- "github.com/iotaledger/iota-core/pkg/protocol/engine/notarization"
- iotago "github.com/iotaledger/iota.go/v4"
-)
-
-func init() {
- Component = &app.Component{
- Name: "Validator",
- DepsFunc: func(cDeps dependencies) { deps = cDeps },
- Params: params,
- Run: run,
- IsEnabled: func(_ *dig.Container) bool {
- return ParamsValidator.Enabled
- },
- }
-}
-
-var (
- Component *app.Component
- deps dependencies
-
- isValidator atomic.Bool
- executor *timed.TaskExecutor[iotago.AccountID]
- validatorAccount blockhandler.Account
-)
-
-type dependencies struct {
- dig.In
-
- Protocol *protocol.Protocol
- BlockHandler *blockhandler.BlockHandler
-}
-
-func run() error {
- validatorAccount = blockhandler.AccountFromParams(ParamsValidator.Account, ParamsValidator.PrivateKey)
-
- executor = timed.NewTaskExecutor[iotago.AccountID](1)
-
- return Component.Daemon().BackgroundWorker(Component.Name, func(ctx context.Context) {
- Component.LogInfof("Starting Validator with IssuerID: %s", validatorAccount.ID())
-
- checkValidatorStatus(ctx)
-
- deps.Protocol.Events.Engine.Notarization.SlotCommitted.Hook(func(details *notarization.SlotCommittedDetails) {
- checkValidatorStatus(ctx)
- }, event.WithWorkerPool(Component.WorkerPool))
-
- <-ctx.Done()
-
- executor.Shutdown()
-
- Component.LogInfo("Stopping Validator... done")
- }, daemon.PriorityActivity)
-}
-
-func checkValidatorStatus(ctx context.Context) {
- account, exists, err := deps.Protocol.MainEngineInstance().Ledger.Account(validatorAccount.ID(), deps.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Slot())
- if err != nil {
- Component.LogErrorf("error when retrieving BlockIssuer account %s: %w", validatorAccount.ID(), err)
-
- return
- }
-
- if !exists || account.StakeEndEpoch <= deps.Protocol.CommittedAPI().TimeProvider().EpochFromSlot(deps.Protocol.CommittedAPI().TimeProvider().SlotFromTime(time.Now())) {
- if prevValue := isValidator.Swap(false); prevValue {
- // If the account stops being a validator, don't issue any blocks.
- Component.LogInfof("BlockIssuer account %s stopped being a validator", validatorAccount.ID())
- executor.Cancel(validatorAccount.ID())
- }
-
- return
- }
-
- if prevValue := isValidator.Swap(true); !prevValue {
- Component.LogInfof("BlockIssuer account %s became a validator", validatorAccount.ID())
- // If the account becomes a validator, start issue validator blocks.
- executor.ExecuteAfter(validatorAccount.ID(), func() { issueValidatorBlock(ctx) }, ParamsValidator.CommitteeBroadcastInterval)
- }
-}
diff --git a/components/validator/issuer.go b/components/validator/issuer.go
deleted file mode 100644
index 038fb9e78..000000000
--- a/components/validator/issuer.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package validator
-
-import (
- "context"
- "time"
-
- "github.com/iotaledger/hive.go/ierrors"
- "github.com/iotaledger/iota-core/pkg/model"
- iotago "github.com/iotaledger/iota.go/v4"
- "github.com/iotaledger/iota.go/v4/builder"
-)
-
-var ErrBlockTooRecent = ierrors.New("block is too recent compared to latest commitment")
-
-func issueValidatorBlock(ctx context.Context) {
- // Get the main engine instance in case it changes mid-execution.
- engineInstance := deps.Protocol.MainEngineInstance()
-
- blockIssuingTime := time.Now()
- nextBroadcast := blockIssuingTime.Add(ParamsValidator.CommitteeBroadcastInterval)
-
- // Use 'defer' because nextBroadcast is updated during function execution, and the value at the end needs to be used.
- defer func() {
- executor.ExecuteAt(validatorAccount.ID(), func() { issueValidatorBlock(ctx) }, nextBroadcast)
- }()
-
- if !ParamsValidator.IgnoreBootstrapped && !engineInstance.SyncManager.IsBootstrapped() {
- Component.LogDebug("Not issuing validator block because node is not bootstrapped yet.")
-
- return
- }
-
- protocolParametersHash, err := deps.Protocol.CommittedAPI().ProtocolParameters().Hash()
- if err != nil {
- Component.LogWarnf("failed to get protocol parameters hash: %s", err.Error())
-
- return
- }
-
- parents := engineInstance.TipSelection.SelectTips(iotago.BlockTypeValidationMaxParents)
-
- addressableCommitment, err := getAddressableCommitment(deps.Protocol.CommittedAPI().TimeProvider().SlotFromTime(blockIssuingTime))
- if err != nil && ierrors.Is(err, ErrBlockTooRecent) {
- commitment, parentID, reviveChainErr := reviveChain(blockIssuingTime)
- if reviveChainErr != nil {
- Component.LogError("error reviving chain: %s", reviveChainErr.Error())
- return
- }
-
- addressableCommitment = commitment
- parents = make(model.ParentReferences)
- parents[iotago.StrongParentType] = []iotago.BlockID{parentID}
- } else if err != nil {
- Component.LogWarnf("error getting commitment: %s", err.Error())
-
- return
- }
-
- // create the validation block here using the validation block builder from iota.go
- validationBlock, err := builder.NewValidationBlockBuilder(deps.Protocol.CommittedAPI()).
- IssuingTime(blockIssuingTime).
- ProtocolParametersHash(protocolParametersHash).
- SlotCommitmentID(addressableCommitment.MustID()).
- HighestSupportedVersion(deps.Protocol.LatestAPI().Version()).
- LatestFinalizedSlot(engineInstance.SyncManager.LatestFinalizedSlot()).
- StrongParents(parents[iotago.StrongParentType]).
- WeakParents(parents[iotago.WeakParentType]).
- ShallowLikeParents(parents[iotago.ShallowLikeParentType]).
- Sign(validatorAccount.ID(), validatorAccount.PrivateKey()).
- Build()
- if err != nil {
- Component.LogWarnf("error creating validation block: %s", err.Error())
-
- return
- }
-
- modelBlock, err := model.BlockFromBlock(validationBlock)
- if err != nil {
- Component.LogWarnf("error creating model block from validation block: %s", err.Error())
-
- return
- }
-
- blockSlot := deps.Protocol.CommittedAPI().TimeProvider().SlotFromTime(blockIssuingTime)
- committee, exists := engineInstance.SybilProtection.SeatManager().CommitteeInSlot(blockSlot)
- if !exists {
- Component.LogWarnf("committee for slot %d not selected: %s", blockSlot, err.Error())
-
- return
- }
-
- if !committee.HasAccount(validatorAccount.ID()) {
- // update nextBroadcast value here, so that this updated value is used in the `defer`
- // callback to schedule issuing of the next block at a different interval than for committee members
- nextBroadcast = blockIssuingTime.Add(ParamsValidator.CandidateBroadcastInterval)
- }
-
- if err = deps.BlockHandler.SubmitBlock(modelBlock); err != nil {
- Component.LogWarnf("error issuing validator block: %s", err.Error())
-
- return
- }
-
- Component.LogDebugf("Issued validator block: %s - commitment %s %d - latest finalized slot %d", modelBlock.ID(), modelBlock.ProtocolBlock().Header.SlotCommitmentID, modelBlock.ProtocolBlock().Header.SlotCommitmentID.Slot(), modelBlock.ProtocolBlock().Header.LatestFinalizedSlot)
-}
-
-func reviveChain(issuingTime time.Time) (*iotago.Commitment, iotago.BlockID, error) {
- lastCommittedSlot := deps.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Slot()
- apiForSlot := deps.Protocol.APIForSlot(lastCommittedSlot)
-
- // Get a rootblock as recent as possible for the parent.
- parentBlockID := iotago.EmptyBlockID
- for rootBlock := range deps.Protocol.MainEngineInstance().EvictionState.ActiveRootBlocks() {
- if rootBlock.Slot() > parentBlockID.Slot() {
- parentBlockID = rootBlock
- }
-
- // Exit the loop if we found a rootblock in the last committed slot (which is the highest we can get).
- if parentBlockID.Slot() == lastCommittedSlot {
- break
- }
- }
-
- issuingSlot := apiForSlot.TimeProvider().SlotFromTime(issuingTime)
-
- // Force commitments until minCommittableAge relative to the block's issuing time. We basically "pretend" that
- // this block was already accepted at the time of issuing so that we have a commitment to reference.
- if issuingSlot < apiForSlot.ProtocolParameters().MinCommittableAge() { // Should never happen as we're beyond maxCommittableAge which is > minCommittableAge.
- return nil, iotago.EmptyBlockID, ierrors.Errorf("issuing slot %d is smaller than min committable age %d", issuingSlot, apiForSlot.ProtocolParameters().MinCommittableAge())
- }
- commitUntilSlot := issuingSlot - apiForSlot.ProtocolParameters().MinCommittableAge()
-
- if err := deps.Protocol.MainEngineInstance().Notarization.ForceCommitUntil(commitUntilSlot); err != nil {
- return nil, iotago.EmptyBlockID, ierrors.Wrapf(err, "failed to force commit until slot %d", commitUntilSlot)
- }
-
- commitment, err := deps.Protocol.MainEngineInstance().Storage.Commitments().Load(commitUntilSlot)
- if err != nil {
- return nil, iotago.EmptyBlockID, ierrors.Wrapf(err, "failed to commit until slot %d to revive chain", commitUntilSlot)
- }
-
- return commitment.Commitment(), parentBlockID, nil
-}
-
-func getAddressableCommitment(blockSlot iotago.SlotIndex) (*iotago.Commitment, error) {
- protoParams := deps.Protocol.CommittedAPI().ProtocolParameters()
- commitment := deps.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment()
-
- if blockSlot > commitment.Slot+protoParams.MaxCommittableAge() {
- return nil, ierrors.Wrapf(ErrBlockTooRecent, "can't issue block: block slot %d is too far in the future, latest commitment is %d", blockSlot, commitment.Slot)
- }
-
- if blockSlot < commitment.Slot+protoParams.MinCommittableAge() {
- if blockSlot < protoParams.MinCommittableAge() || commitment.Slot < protoParams.MinCommittableAge() {
- return commitment, nil
- }
-
- commitmentSlot := commitment.Slot - protoParams.MinCommittableAge()
- loadedCommitment, err := deps.Protocol.MainEngineInstance().Storage.Commitments().Load(commitmentSlot)
- if err != nil {
- return nil, ierrors.Wrapf(err, "error loading valid commitment of slot %d according to minCommittableAge from storage", commitmentSlot)
- }
-
- return loadedCommitment.Commitment(), nil
- }
-
- return commitment, nil
-}
diff --git a/components/validator/params.go b/components/validator/params.go
deleted file mode 100644
index 037498ab2..000000000
--- a/components/validator/params.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package validator
-
-import (
- "time"
-
- "github.com/iotaledger/hive.go/app"
-)
-
-// ParametersValidator contains the definition of the configuration parameters used by the Validator component.
-type ParametersValidator struct {
- // Enabled defines whether the Validator component is enabled.
- Enabled bool `default:"false" usage:"whether the Validator component is enabled"`
- // CommitteeBroadcastInterval the interval at which the node will broadcast its committee validator block.
- CommitteeBroadcastInterval time.Duration `default:"500ms" usage:"the interval at which the node will broadcast its committee validator block"`
- // CandidateBroadcastInterval the interval at which the node will broadcast its candidate validator block.
- CandidateBroadcastInterval time.Duration `default:"30m" usage:"the interval at which the node will broadcast its candidate validator block"`
- // ParentsCount is the number of parents that node will choose for its validator blocks.
- ParentsCount int `default:"8" usage:"the number of parents that node will choose for its validator blocks"`
- // IgnoreBootstrapped sets whether the Validator component should start issuing validator blocks before the main engine is bootstrapped.
- IgnoreBootstrapped bool `default:"false" usage:"whether the Validator component should start issuing validator blocks before the main engine is bootstrapped"`
- // Account the accountID of the account that will issue the blocks.
- Account string `default:"" usage:"the accountID of the validator account that will issue the blocks"`
- // PrivateKey the private key of the account that will issue the blocks.
- PrivateKey string `default:"" usage:"the private key of the validator account that will issue the blocks"`
-}
-
-// ParamsValidator contains the values of the configuration parameters used by the Activity component.
-var ParamsValidator = &ParametersValidator{}
-
-var params = &app.ComponentParams{
- Params: map[string]any{
- "validator": ParamsValidator,
- },
-}
diff --git a/config_defaults.json b/config_defaults.json
index f24471e14..f89cc121a 100644
--- a/config_defaults.json
+++ b/config_defaults.json
@@ -116,15 +116,6 @@
"useMetricPrefix": false
}
},
- "validator": {
- "enabled": false,
- "committeeBroadcastInterval": "500ms",
- "candidateBroadcastInterval": "30m",
- "parentsCount": 8,
- "ignoreBootstrapped": false,
- "account": "",
- "privateKey": ""
- },
"dashboard": {
"enabled": true,
"bindAddress": "0.0.0.0:8081",
diff --git a/deploy/ansible/hosts/feature.yml b/deploy/ansible/hosts/feature.yml
index ac8e44cfc..66e7b10ee 100644
--- a/deploy/ansible/hosts/feature.yml
+++ b/deploy/ansible/hosts/feature.yml
@@ -7,21 +7,19 @@ cores:
internal_nodes:
hosts:
node-01.feature.shimmer.iota.cafe:
- validatorAccount: "{{ NODE_01_ACCOUNTID }}"
+ validatorAccountAddress: "{{ NODE_01_VALIDATOR_ACCOUNTADDRESS }}"
validatorPrvKey: "{{ NODE_01_VALIDATOR_PRIVKEY }}"
- p2pIdentityPrvKey: "{{ NODE_01_P2PIDENTITYPRIVATEKEY }}"
+ p2pIdentityPrvKey: "{{ NODE_01_P2PIDENTITY_PRIVKEY }}"
node-02.feature.shimmer.iota.cafe:
- validatorAccount: "{{ NODE_02_ACCOUNTID }}"
+ validatorAccountAddress: "{{ NODE_02_VALIDATOR_ACCOUNTADDRESS }}"
validatorPrvKey: "{{ NODE_02_VALIDATOR_PRIVKEY }}"
- p2pIdentityPrvKey: "{{ NODE_02_P2PIDENTITYPRIVATEKEY }}"
+ p2pIdentityPrvKey: "{{ NODE_02_P2PIDENTITY_PRIVKEY }}"
node-03.feature.shimmer.iota.cafe:
- validatorAccount: "{{ NODE_03_ACCOUNTID }}"
+ validatorAccountAddress: "{{ NODE_03_VALIDATOR_ACCOUNTADDRESS }}"
validatorPrvKey: "{{ NODE_03_VALIDATOR_PRIVKEY }}"
- p2pIdentityPrvKey: "{{ NODE_03_P2PIDENTITYPRIVATEKEY }}"
+ p2pIdentityPrvKey: "{{ NODE_03_P2PIDENTITY_PRIVKEY }}"
node-04.feature.shimmer.iota.cafe:
- p2pIdentityPrvKey: "{{ NODE_04_P2PIDENTITYPRIVATEKEY }}"
- blockissuerPrvKey: "{{ NODE_04_BLOCKISSUER_PRV_KEY }}"
- faucetPrvKey: "{{ NODE_04_FAUCET_PRV_KEY }}"
+ p2pIdentityPrvKey: "{{ NODE_04_P2PIDENTITY_PRIVKEY }}"
node-05.feature.shimmer.iota.cafe:
- p2pIdentityPrvKey: "{{ NODE_05_P2PIDENTITYPRIVATEKEY }}"
+ p2pIdentityPrvKey: "{{ NODE_05_P2PIDENTITY_PRIVKEY }}"
vars:
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 d3bc9d82b..40beab818 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
@@ -14,7 +14,7 @@ services:
# IOTA-CORE Nodes #
###################
- iota_core:
+ iota-core:
image: {{iota_core_docker_image_repo}}:{{iota_core_docker_image_tag}}
container_name: iota-core
stop_grace_period: 1m
@@ -49,14 +49,6 @@ services:
--restAPI.bindAddress=0.0.0.0:14265
--database.path=/app/data/database
--protocol.snapshot.path=/app/data/snapshot.bin
- {% if 'node-01' in inventory_hostname or 'node-02' in inventory_hostname or 'node-03' in inventory_hostname %}
- --validator.enabled=true
- {% if 'node-01' in inventory_hostname %}
- --validator.ignoreBootstrapped=true
- {% endif %}
- --validator.account={{validatorAccount}}
- --validator.privateKey={{validatorPrvKey}}
- {% endif %}
--dashboard.bindAddress=0.0.0.0:8081
--metrics.bindAddress=iota-core:9311
--inx.enabled=true
@@ -97,11 +89,11 @@ services:
inx-indexer:
condition: service_started
environment:
- - "BLOCKISSUER_PRV_KEY={{blockissuerPrvKey}}"
+ - "BLOCKISSUER_PRV_KEY={{NODE_04_BLOCKISSUER_PRIVKEY}}"
command: >
--inx.address=iota-core:9029
--restAPI.bindAddress=inx-blockissuer:9086
- --blockIssuer.accountAddress=rms1pqas0clgfsf8du9e6dw0yx9nwclqe0dd4f728pvgmcshpscm8r5mkddrrfc
+ --blockIssuer.accountAddress={{NODE_04_BLOCKISSUER_ACCOUNTADDRESS}}
--blockIssuer.proofOfWork.targetTrailingZeros=5
inx-faucet:
@@ -116,13 +108,30 @@ services:
condition: service_started
inx-blockissuer:
condition: service_started
- networks:
- - iota-core
ports:
- "8091:8091/tcp" # Faucet Frontend
environment:
- - "FAUCET_PRV_KEY={{faucetPrvKey}}"
+ - "FAUCET_PRV_KEY={{NODE_04_FAUCET_PRIVKEY}}"
command: >
--inx.address=iota-core:9029
--faucet.bindAddress=0.0.0.0:8091
+{% endif %}
+
+{% if 'node-01' in inventory_hostname or 'node-02' in inventory_hostname or 'node-03' in inventory_hostname %}
+ inx-validator:
+ container_name: inx-validator
+ image: iotaledger/inx-validator:1.0-alpha
+ stop_grace_period: 1m
+ restart: unless-stopped
+ depends_on:
+ iota-core:
+ condition: service_started
+ environment:
+ - "VALIDATOR_PRV_KEY={{validatorPrvKey}}"
+ command: >
+ --inx.address=iota-core:9029
+ {% if 'node-01' in inventory_hostname %}
+ --validator.ignoreBootstrapped=true
+ {% endif %}
+ --validator.accountAddress={{validatorAccountAddress}}
{% endif %}
\ No newline at end of file
diff --git a/deploy/ansible/run.sh b/deploy/ansible/run.sh
index 3d800611d..62ee4840f 100755
--- a/deploy/ansible/run.sh
+++ b/deploy/ansible/run.sh
@@ -17,22 +17,22 @@ elkElasticUser=$ELASTIC_USER
elkElasticPassword=$ELASTIC_PASSWORD
grafanaAdminPassword=$GRAFANA_ADMIN_PASSWORD
-NODE_01_ACCOUNTID=$NODE_01_ACCOUNTID
+NODE_01_VALIDATOR_ACCOUNTADDRESS=$NODE_01_VALIDATOR_ACCOUNTADDRESS
NODE_01_VALIDATOR_PRIVKEY=$NODE_01_VALIDATOR_PRIVKEY
-NODE_01_P2PIDENTITYPRIVATEKEY=$NODE_01_P2PIDENTITYPRIVATEKEY
+NODE_01_P2PIDENTITY_PRIVKEY=$NODE_01_P2PIDENTITY_PRIVKEY
-NODE_02_ACCOUNTID=$NODE_02_ACCOUNTID
+NODE_02_VALIDATOR_ACCOUNTADDRESS=$NODE_02_VALIDATOR_ACCOUNTADDRESS
NODE_02_VALIDATOR_PRIVKEY=$NODE_02_VALIDATOR_PRIVKEY
-NODE_02_P2PIDENTITYPRIVATEKEY=$NODE_02_P2PIDENTITYPRIVATEKEY
+NODE_02_P2PIDENTITY_PRIVKEY=$NODE_02_P2PIDENTITY_PRIVKEY
-NODE_03_ACCOUNTID=$NODE_03_ACCOUNTID
+NODE_03_VALIDATOR_ACCOUNTADDRESS=$NODE_03_VALIDATOR_ACCOUNTADDRESS
NODE_03_VALIDATOR_PRIVKEY=$NODE_03_VALIDATOR_PRIVKEY
-NODE_03_P2PIDENTITYPRIVATEKEY=$NODE_03_P2PIDENTITYPRIVATEKEY
+NODE_03_P2PIDENTITY_PRIVKEY=$NODE_03_P2PIDENTITY_PRIVKEY
-NODE_04_P2PIDENTITYPRIVATEKEY=$NODE_04_P2PIDENTITYPRIVATEKEY
-NODE_04_BLOCKISSUER_PRV_KEY=$NODE_04_BLOCKISSUER_PRIVKEY
-NODE_04_FAUCET_PRV_KEY=$NODE_04_FAUCET_PRIVKEY
-
-NODE_05_P2PIDENTITYPRIVATEKEY=$NODE_05_P2PIDENTITYPRIVATEKEY
+NODE_04_BLOCKISSUER_ACCOUNTADDRESS=$NODE_04_BLOCKISSUER_ACCOUNTADDRESS
+NODE_04_BLOCKISSUER_PRIVKEY=$NODE_04_BLOCKISSUER_PRIVKEY
+NODE_04_FAUCET_PRIVKEY=$NODE_04_FAUCET_PRIVKEY
+NODE_04_P2PIDENTITY_PRIVKEY=$NODE_04_P2PIDENTITY_PRIVKEY
+NODE_05_P2PIDENTITY_PRIVKEY=$NODE_05_P2PIDENTITY_PRIVKEY" \
${ARGS[@]:2} deploy/ansible/"${2:-deploy.yml}"
diff --git a/documentation/docs/references/configuration.md b/documentation/docs/references/configuration.md
index ba034fde1..b6b3d58e2 100644
--- a/documentation/docs/references/configuration.md
+++ b/documentation/docs/references/configuration.md
@@ -375,35 +375,7 @@ Example:
}
```
-## 10. Validator
-
-| Name | Description | Type | Default value |
-| -------------------------- | ------------------------------------------------------------------------------------------------------------ | ------- | ------------- |
-| enabled | Whether the Validator component is enabled | boolean | false |
-| committeeBroadcastInterval | The interval at which the node will broadcast its committee validator block | string | "500ms" |
-| candidateBroadcastInterval | The interval at which the node will broadcast its candidate validator block | string | "30m" |
-| parentsCount | The number of parents that node will choose for its validator blocks | int | 8 |
-| ignoreBootstrapped | Whether the Validator component should start issuing validator blocks before the main engine is bootstrapped | boolean | false |
-| account | The accountID of the validator account that will issue the blocks | string | "" |
-| privateKey | The private key of the validator account that will issue the blocks | string | "" |
-
-Example:
-
-```json
- {
- "validator": {
- "enabled": false,
- "committeeBroadcastInterval": "500ms",
- "candidateBroadcastInterval": "30m",
- "parentsCount": 8,
- "ignoreBootstrapped": false,
- "account": "",
- "privateKey": ""
- }
- }
-```
-
-## 11. Dashboard
+## 10. Dashboard
| Name | Description | Type | Default value |
| --------------------------------- | --------------------------------------- | ------- | -------------- |
@@ -445,7 +417,7 @@ Example:
}
```
-## 12. Metrics
+## 11. Metrics
| Name | Description | Type | Default value |
| --------------- | ---------------------------------------------------- | ------- | -------------- |
@@ -469,7 +441,7 @@ Example:
}
```
-## 13. Inx
+## 12. Inx
| Name | Description | Type | Default value |
| ----------- | ------------------------------------------------------ | ------- | ---------------- |
diff --git a/pkg/blockhandler/account.go b/pkg/blockhandler/account.go
deleted file mode 100644
index 5d71cb86b..000000000
--- a/pkg/blockhandler/account.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package blockhandler
-
-import (
- "crypto/ed25519"
- "fmt"
-
- "github.com/iotaledger/hive.go/crypto"
- iotago "github.com/iotaledger/iota.go/v4"
-)
-
-// Account represents an account.
-type Account interface {
- // ID returns the accountID.
- ID() iotago.AccountID
-
- // Address returns the account address.
- Address() iotago.Address
-
- // PrivateKey returns the account private key for signing.
- PrivateKey() ed25519.PrivateKey
-}
-
-var _ Account = &Ed25519Account{}
-
-// Ed25519Account is an account that uses an Ed25519 key pair.
-type Ed25519Account struct {
- accountID iotago.AccountID
- privateKey ed25519.PrivateKey
-}
-
-// NewEd25519Account creates a new Ed25519Account.
-func NewEd25519Account(accountID iotago.AccountID, privateKey ed25519.PrivateKey) *Ed25519Account {
- return &Ed25519Account{
- accountID: accountID,
- privateKey: privateKey,
- }
-}
-
-// ID returns the accountID.
-func (e *Ed25519Account) ID() iotago.AccountID {
- return e.accountID
-}
-
-// Address returns the account address.
-func (e *Ed25519Account) Address() iotago.Address {
- ed25519PubKey, ok := e.privateKey.Public().(ed25519.PublicKey)
- if !ok {
- panic("invalid public key type")
- }
-
- return iotago.Ed25519AddressFromPubKey(ed25519PubKey)
-}
-
-// PrivateKey returns the account private key for signing.
-func (e *Ed25519Account) PrivateKey() ed25519.PrivateKey {
- return e.privateKey
-}
-
-func AccountFromParams(accountHex, privateKey string) Account {
- accountID, err := iotago.AccountIDFromHexString(accountHex)
- if err != nil {
- panic(fmt.Sprintln("invalid accountID hex string", err))
- }
- privKey, err := crypto.ParseEd25519PrivateKeyFromString(privateKey)
- if err != nil {
- panic(fmt.Sprintln("invalid ed25519 private key string", err))
- }
-
- return NewEd25519Account(accountID, privKey)
-}
diff --git a/pkg/blockhandler/block_params.go b/pkg/blockhandler/block_params.go
deleted file mode 100644
index 951f285c8..000000000
--- a/pkg/blockhandler/block_params.go
+++ /dev/null
@@ -1,122 +0,0 @@
-package blockhandler
-
-import (
- "time"
-
- "github.com/iotaledger/hive.go/runtime/options"
- "github.com/iotaledger/iota-core/pkg/model"
- iotago "github.com/iotaledger/iota.go/v4"
-)
-
-type BlockHeaderParams struct {
- ParentsCount int
- References model.ParentReferences
- SlotCommitment *iotago.Commitment
- LatestFinalizedSlot *iotago.SlotIndex
- IssuingTime *time.Time
- ProtocolVersion *iotago.Version
- Issuer Account
-}
-type BasicBlockParams struct {
- BlockHeader *BlockHeaderParams
- Payload iotago.Payload
-}
-type ValidatorBlockParams struct {
- BlockHeader *BlockHeaderParams
- HighestSupportedVersion *iotago.Version
- ProtocolParametersHash *iotago.Identifier
-}
-
-func WithParentsCount(parentsCount int) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- builder.ParentsCount = parentsCount
- }
-}
-
-func WithStrongParents(blockIDs ...iotago.BlockID) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- if builder.References == nil {
- builder.References = make(model.ParentReferences)
- }
-
- builder.References[iotago.StrongParentType] = blockIDs
- }
-}
-func WithWeakParents(blockIDs ...iotago.BlockID) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- if builder.References == nil {
- builder.References = make(model.ParentReferences)
- }
-
- builder.References[iotago.WeakParentType] = blockIDs
- }
-}
-
-func WithShallowLikeParents(blockIDs ...iotago.BlockID) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- if builder.References == nil {
- builder.References = make(model.ParentReferences)
- }
-
- builder.References[iotago.ShallowLikeParentType] = blockIDs
- }
-}
-
-func WithSlotCommitment(commitment *iotago.Commitment) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- builder.SlotCommitment = commitment
- }
-}
-
-func WithLatestFinalizedSlot(commitmentIndex iotago.SlotIndex) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- builder.LatestFinalizedSlot = &commitmentIndex
- }
-}
-
-func WithIssuingTime(issuingTime time.Time) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- builder.IssuingTime = &issuingTime
- }
-}
-
-func WithProtocolVersion(version iotago.Version) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- builder.ProtocolVersion = &version
- }
-}
-func WithIssuer(issuer Account) func(builder *BlockHeaderParams) {
- return func(builder *BlockHeaderParams) {
- builder.Issuer = issuer
- }
-}
-
-func WithValidationBlockHeaderOptions(opts ...options.Option[BlockHeaderParams]) func(builder *ValidatorBlockParams) {
- return func(builder *ValidatorBlockParams) {
- builder.BlockHeader = options.Apply(&BlockHeaderParams{}, opts)
- }
-}
-
-func WithBasicBlockHeader(opts ...options.Option[BlockHeaderParams]) func(builder *BasicBlockParams) {
- return func(builder *BasicBlockParams) {
- builder.BlockHeader = options.Apply(&BlockHeaderParams{}, opts)
- }
-}
-
-func WithPayload(payload iotago.Payload) func(builder *BasicBlockParams) {
- return func(builder *BasicBlockParams) {
- builder.Payload = payload
- }
-}
-
-func WithHighestSupportedVersion(highestSupportedVersion iotago.Version) func(builder *ValidatorBlockParams) {
- return func(builder *ValidatorBlockParams) {
- builder.HighestSupportedVersion = &highestSupportedVersion
- }
-}
-
-func WithProtocolParametersHash(protocolParametersHash iotago.Identifier) func(builder *ValidatorBlockParams) {
- return func(builder *ValidatorBlockParams) {
- builder.ProtocolParametersHash = &protocolParametersHash
- }
-}
diff --git a/pkg/blockhandler/blockissuer.go b/pkg/blockhandler/blockhandler.go
similarity index 100%
rename from pkg/blockhandler/blockissuer.go
rename to pkg/blockhandler/blockhandler.go
diff --git a/pkg/protocol/engine/syncmanager/syncmanager.go b/pkg/protocol/engine/syncmanager/syncmanager.go
index d251dec88..6f0c0cb53 100644
--- a/pkg/protocol/engine/syncmanager/syncmanager.go
+++ b/pkg/protocol/engine/syncmanager/syncmanager.go
@@ -38,6 +38,7 @@ type SyncManager interface {
}
type SyncStatus struct {
+ NodeBootstrapped bool
NodeSynced bool
LastAcceptedBlockSlot iotago.SlotIndex
LastConfirmedBlockSlot iotago.SlotIndex
diff --git a/pkg/protocol/engine/syncmanager/trivialsyncmanager/syncmanager.go b/pkg/protocol/engine/syncmanager/trivialsyncmanager/syncmanager.go
index 8e93f69bd..38fd0bb00 100644
--- a/pkg/protocol/engine/syncmanager/trivialsyncmanager/syncmanager.go
+++ b/pkg/protocol/engine/syncmanager/trivialsyncmanager/syncmanager.go
@@ -139,6 +139,7 @@ func (s *SyncManager) SyncStatus() *syncmanager.SyncStatus {
return &syncmanager.SyncStatus{
NodeSynced: s.IsNodeSynced(),
+ NodeBootstrapped: s.IsBootstrapped(),
LastAcceptedBlockSlot: s.lastAcceptedBlockSlot,
LastConfirmedBlockSlot: s.lastConfirmedBlockSlot,
LatestCommitment: s.latestCommitment,
diff --git a/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go b/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go
index e167e2ff5..9a58b6680 100644
--- a/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go
+++ b/pkg/protocol/sybilprotection/activitytracker/activitytrackerv1/activitytracker.go
@@ -77,7 +77,9 @@ func (a *ActivityTracker) MarkSeatActive(seat account.SeatIndex, id iotago.Accou
func (a *ActivityTracker) markSeatInactive(seat account.SeatIndex) {
a.lastActivities.Delete(seat)
- a.onlineCommittee.Delete(seat)
- a.Events.OnlineCommitteeSeatRemoved.Trigger(seat)
+ // Only trigger the event if online committee member is removed.
+ if a.onlineCommittee.Delete(seat) {
+ a.Events.OnlineCommitteeSeatRemoved.Trigger(seat)
+ }
}
diff --git a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go
index a798ff647..f5f024a56 100644
--- a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go
+++ b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go
@@ -141,6 +141,13 @@ func (t *Tracker) ValidatorCandidates(epoch iotago.EpochIndex) (ds.Set[iotago.Ac
}
func (t *Tracker) getValidatorCandidates(epoch iotago.EpochIndex) (ds.Set[iotago.AccountID], error) {
+ candidates := ds.NewSet[iotago.AccountID]()
+
+ // Epoch 0 has no candidates as it's the genesis committee.
+ if epoch == 0 {
+ return candidates, nil
+ }
+
// we store candidates in the store for the epoch of their activity, but the passed argument points to the target epoch,
// so it's necessary to subtract one epoch from the passed value
candidateStore, err := t.committeeCandidatesInEpochFunc(epoch - 1)
@@ -148,8 +155,6 @@ func (t *Tracker) getValidatorCandidates(epoch iotago.EpochIndex) (ds.Set[iotago
return nil, ierrors.Wrapf(err, "error while retrieving candidates for epoch %d", epoch)
}
- candidates := ds.NewSet[iotago.AccountID]()
-
var innerErr error
err = candidateStore.IterateKeys(kvstore.EmptyPrefix, func(key kvstore.Key) bool {
accountID, _, err := iotago.AccountIDFromBytes(key)
diff --git a/tools/docker-network/docker-compose.yml b/tools/docker-network/docker-compose.yml
index 22d21b2dc..a16297065 100644
--- a/tools/docker-network/docker-compose.yml
+++ b/tools/docker-network/docker-compose.yml
@@ -20,10 +20,10 @@ services:
networks:
- iota-core
ports:
- - "8080:14265/tcp" # REST-API
- - "8081:8081/tcp" # Dashboard
- - "6081:6061/tcp" # pprof
- - "9089:9029/tcp" # INX
+ - "8050:14265/tcp" # REST-API
+ - "8051:8081/tcp" # Dashboard
+ - "6051:6061/tcp" # pprof
+ - "9059:9029/tcp" # INX
volumes:
- ./docker-network.snapshot:/app/data/snapshot.bin
- ./config.json:/app/config.json:ro
@@ -31,10 +31,6 @@ services:
${COMMON_CONFIG}
${MANUALPEERING_CONFIG}
--p2p.identityPrivateKey=08735375679f3d8031353e94282ed1d65119e5c288fe56d6639d9184a3f978fee8febfedff11cc376daea0f59c395ae2e9a870a25ac4e36093000fbf4d0e8f18
- --validator.enabled=true
- --validator.ignoreBootstrapped=true
- --validator.account=0x907c02e9302e0f0571f10f885594e56d8c54ff0708ab7a39bc1b74d396b93b12
- --validator.privateKey=443a988ea61797651217de1f4662d4d6da11fd78e67f94511453bf6576045a05293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b
--inx.enabled=true
--inx.bindAddress=0.0.0.0:9029
@@ -49,10 +45,10 @@ services:
networks:
- iota-core
ports:
- - "8070:14265/tcp" # REST-API
- - "8071:8081/tcp" # Dashboard
- - "6071:6061/tcp" # pprof
- - "9029:9029/tcp" # INX
+ - "8060:14265/tcp" # REST-API
+ - "8061:8081/tcp" # Dashboard
+ - "6061:6061/tcp" # pprof
+ - "9069:9029/tcp" # INX
volumes:
- ./docker-network.snapshot:/app/data/snapshot.bin
- ./config.json:/app/config.json:ro
@@ -60,9 +56,6 @@ services:
${COMMON_CONFIG}
${MANUALPEERING_CONFIG}
--p2p.identityPrivateKey=ba771419c52132a0dfb2521ed18667813f398da159010a55a0a482af939affb92d3338789ad4a07a7631b91791deb11f82ed5dc612822f24275e9f7a313b691f
- --validator.enabled=true
- --validator.account=0x375358f92cc94750669598b0aaa55a6ff73310b90710e1fad524c0f911be0fea
- --validator.privateKey=3a5d39f8b60367a17fd54dac2a32c172c8e1fd6cf74ce65f1e13edba565f281705c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064
--inx.enabled=true
--inx.bindAddress=0.0.0.0:9029
@@ -77,10 +70,10 @@ services:
networks:
- iota-core
ports:
- - "8090:14265/tcp" # REST-API
- - "8091:8081/tcp" # Dashboard
- - "6091:6061/tcp" # pprof
- - "9099:9029/tcp" # INX
+ - "8070:14265/tcp" # REST-API
+ - "8071:8081/tcp" # Dashboard
+ - "6071:6061/tcp" # pprof
+ - "9079:9029/tcp" # INX
volumes:
- ./docker-network.snapshot:/app/data/snapshot.bin
- ./config.json:/app/config.json:ro
@@ -88,9 +81,6 @@ services:
${COMMON_CONFIG}
${MANUALPEERING_CONFIG}
--p2p.identityPrivateKey=a6261ac049755675ff1437654ca9f83b305055f01ff08c4f039209ef5a4a7d96d06fb61df77a8815209a8f4d204226dee593e50d0ec897ec440a2c1fbde77656
- --validator.enabled=true
- --validator.account=0x6aee704f25558e8aa7630fed0121da53074188abc423b3c5810f80be4936eb6e
- --validator.privateKey=db39d2fde6301d313b108dc9db1ee724d0f405f6fde966bd776365bc5f4a5fb31e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648
--inx.enabled=true
--inx.bindAddress=0.0.0.0:9029
@@ -105,10 +95,10 @@ services:
networks:
- iota-core
ports:
- - "8040:14265/tcp" # REST-API
- - "8041:8081/tcp" # Dashboard
- - "6041:6061/tcp" # pprof
- - "9049:9029/tcp" # INX
+ - "8080:14265/tcp" # REST-API
+ - "8081:8081/tcp" # Dashboard
+ - "6081:6061/tcp" # pprof
+ - "9089:9029/tcp" # INX
volumes:
- ./docker-network.snapshot:/app/data/snapshot.bin
- ./config.json:/app/config.json:ro
@@ -130,10 +120,10 @@ services:
networks:
- iota-core
ports:
- - "8030:14265/tcp" # REST-API
- - "8031:8081/tcp" # Dashboard
- - "6031:6061/tcp" # pprof
- - "9039:9029/tcp" # INX
+ - "8090:14265/tcp" # REST-API
+ - "8091:8081/tcp" # Dashboard
+ - "6091:6061/tcp" # pprof
+ - "9099:9029/tcp" # INX
volumes:
- ./docker-network.snapshot:/app/data/snapshot.bin
- ./config.json:/app/config.json:ro
@@ -201,8 +191,8 @@ services:
networks:
- iota-core
command: >
- --inx.address=node-1-validator:9029
- --restAPI.bindAddress=inx-indexer:9091
+ --inx.address=node-1-validator:9019
+ --restAPI.bindAddress=inx-indexer:9011
inx-blockissuer:
image: iotaledger/inx-blockissuer:1.0-alpha
@@ -245,6 +235,55 @@ services:
--faucet.bindAddress=inx-faucet:8091
--faucet.rateLimit.enabled=false
+ inx-validator-1:
+ image: iotaledger/inx-validator:1.0-alpha
+ stop_grace_period: 1m
+ restart: unless-stopped
+ depends_on:
+ node-1-validator:
+ condition: service_started
+ networks:
+ - iota-core
+ environment:
+ - "VALIDATOR_PRV_KEY=443a988ea61797651217de1f4662d4d6da11fd78e67f94511453bf6576045a05293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b"
+ command: >
+ --logger.level=debug
+ --inx.address=node-1-validator:9029
+ --validator.ignoreBootstrapped=true
+ --validator.accountAddress=rms1pzg8cqhfxqhq7pt37y8cs4v5u4kcc48lquy2k73ehsdhf5ukhya3y5rx2w6
+
+ inx-validator-2:
+ image: iotaledger/inx-validator:1.0-alpha
+ stop_grace_period: 1m
+ restart: unless-stopped
+ depends_on:
+ node-2-validator:
+ condition: service_started
+ networks:
+ - iota-core
+ environment:
+ - "VALIDATOR_PRV_KEY=3a5d39f8b60367a17fd54dac2a32c172c8e1fd6cf74ce65f1e13edba565f281705c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064"
+ command: >
+ --logger.level=debug
+ --inx.address=node-2-validator:9029
+ --validator.accountAddress=rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl
+
+ inx-validator-3:
+ image: iotaledger/inx-validator:1.0-alpha
+ stop_grace_period: 1m
+ restart: unless-stopped
+ depends_on:
+ node-3-validator:
+ condition: service_started
+ networks:
+ - iota-core
+ environment:
+ - "VALIDATOR_PRV_KEY=db39d2fde6301d313b108dc9db1ee724d0f405f6fde966bd776365bc5f4a5fb31e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648"
+ command: >
+ --logger.level=debug
+ --inx.address=node-3-validator:9029
+ --validator.accountAddress=rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt
+
# Create our own network
networks:
iota-core:
diff --git a/tools/docker-network/run.sh b/tools/docker-network/run.sh
index b137a67a4..7ac82d24a 100755
--- a/tools/docker-network/run.sh
+++ b/tools/docker-network/run.sh
@@ -6,8 +6,8 @@ function join { local IFS="$1"; shift; echo "$*"; }
# All parameters can be optional now, just make sure we don't have too many
if [[ $# -gt 4 ]] ; then
- echo 'Call with ./run [replicas=1|2|3|...] [monitoring=0|1] [feature=0|1]'
- exit 0
+ echo 'Call with ./run [replicas=1|2|3|...] [monitoring=0|1] [feature=0|1]'
+ exit 0
fi
REPLICAS=${1:-1}
@@ -15,12 +15,10 @@ MONITORING=${2:-0}
FEATURE=${3:-0}
DOCKER_COMPOSE_FILE=docker-compose.yml
-if [ $FEATURE -ne 0 ]
-then
+if [ $FEATURE -ne 0 ]; then
DOCKER_COMPOSE_FILE=docker-compose-feature.yml
fi
-
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
echo "Build iota-core"
@@ -29,8 +27,7 @@ echo "Build iota-core"
export DOCKER_BUILD_CONTEXT="../../"
export DOCKERFILE_PATH="./Dockerfile.dev"
-if [[ "$WITH_GO_WORK" -eq 1 ]]
-then
+if [[ "$WITH_GO_WORK" -eq 1 ]]; then
export DOCKER_BUILD_CONTEXT="../../../"
export DOCKERFILE_PATH="./iota-core/Dockerfile.dev"
fi
@@ -39,36 +36,34 @@ fi
echo $DOCKER_BUILD_CONTEXT $DOCKERFILE_PATH
docker compose -f $DOCKER_COMPOSE_FILE build --build-arg WITH_GO_WORK=${WITH_GO_WORK:-0} --build-arg DOCKER_BUILD_CONTEXT=${DOCKER_BUILD_CONTEXT} --build-arg DOCKERFILE_PATH=${DOCKERFILE_PATH}
-docker compose pull inx-indexer inx-blockissuer inx-faucet
+docker compose pull inx-indexer inx-blockissuer inx-faucet inx-validator-1
# check exit code of builder
-if [ $? -ne 0 ]
-then
+if [ $? -ne 0 ]; then
echo "Building failed. Please fix and try again!"
exit 1
fi
# create snapshot file
echo "Create snapshot"
-if [ $FEATURE -ne 0 ]
-then
- pushd ../genesis-snapshot; go run -tags=rocksdb . --config feature
+if [ $FEATURE -ne 0 ]; then
+ pushd ../genesis-snapshot
+ go run -tags=rocksdb . --config feature
else
- pushd ../genesis-snapshot; go run -tags=rocksdb . --config docker --seed 7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih
+ pushd ../genesis-snapshot
+ go run -tags=rocksdb . --config docker --seed 7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih
fi
popd
mv ../genesis-snapshot/*.snapshot .
chmod o+r *.snapshot
-
echo "Run iota-core network with ${DOCKER_COMPOSE_FILE}"
# IOTA_CORE_PEER_REPLICAS is used in docker-compose.yml to determine how many replicas to create
export IOTA_CORE_PEER_REPLICAS=$REPLICAS
# Profiles is created to set which docker profiles to run
# https://docs.docker.com/compose/profiles/
PROFILES=()
-if [ $MONITORING -ne 0 ]
-then
+if [ $MONITORING -ne 0 ]; then
PROFILES+=("monitoring")
fi
diff --git a/tools/genesis-snapshot/presets/presets.go b/tools/genesis-snapshot/presets/presets.go
index 8157c81e2..29babde9f 100644
--- a/tools/genesis-snapshot/presets/presets.go
+++ b/tools/genesis-snapshot/presets/presets.go
@@ -37,7 +37,15 @@ var Base = []options.Option[snapshotcreator.Options]{
var Docker = []options.Option[snapshotcreator.Options]{
snapshotcreator.WithFilePath("docker-network.snapshot"),
snapshotcreator.WithAccounts(
- snapshotcreator.AccountDetails{ // node-1-validator
+ snapshotcreator.AccountDetails{
+ /*
+ node-01-validator
+
+ Ed25519 Public Key: 293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b
+ Ed25519 Address: rms1qzg8cqhfxqhq7pt37y8cs4v5u4kcc48lquy2k73ehsdhf5ukhya3ytgk0ny
+ Account Address: rms1pzg8cqhfxqhq7pt37y8cs4v5u4kcc48lquy2k73ehsdhf5ukhya3y5rx2w6
+ Restricted Address: rms1xqqfqlqzayczurc9w8cslzz4jnjkmrz5lurs32m68x7pkaxnj6unkyspqg8mulpm, Capabilities: mana
+ */
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b"))),
Amount: mock.MinValidatorAccountAmount,
@@ -49,7 +57,15 @@ var Docker = []options.Option[snapshotcreator.Options]{
StakedAmount: mock.MinValidatorAccountAmount,
Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
- snapshotcreator.AccountDetails{ // node-2-validator
+ snapshotcreator.AccountDetails{
+ /*
+ node-02-validator
+
+ Ed25519 Public Key: 05c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064
+ Ed25519 Address: rms1qqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875flpz2p
+ Account Address: rms1pqm4xk8e9ny5w5rxjkvtp249tfhlwvcshyr3pc0665jvp7g3hc875k538hl
+ Restricted Address: rms1xqqrw56clykvj36sv62e3v9254dxlaenzzuswy8plt2jfs8ezxlql6spqgkulf7u, Capabilities: mana
+ */
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x05c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x05c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064"))),
Amount: mock.MinValidatorAccountAmount,
@@ -61,7 +77,15 @@ var Docker = []options.Option[snapshotcreator.Options]{
StakedAmount: mock.MinValidatorAccountAmount,
Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
- snapshotcreator.AccountDetails{ // node-3-validator
+ snapshotcreator.AccountDetails{
+ /*
+ node-03-validator
+
+ Ed25519 Public Key: 1e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648
+ Ed25519 Address: rms1qp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kuvz0a44
+ Account Address: rms1pp4wuuz0y42caz48vv876qfpmffswsvg40zz8v79sy8cp0jfxm4kunflcgt
+ Restricted Address: rms1xqqx4mnsfuj4tr525a3slmgpy8d9xp6p3z4ugganckqslq97fymwkmspqgnzrkjq, Capabilities: mana
+ */
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x1e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x1e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648"))),
Amount: mock.MinValidatorAccountAmount,
@@ -77,10 +101,11 @@ var Docker = []options.Option[snapshotcreator.Options]{
/*
inx-blockissuer
- ed25519 private key: 432c624ca3260f910df35008d5c740593b222f1e196e6cdb8cd1ad080f0d4e33997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270
- ed25519 public key: 997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270
- ed25519 address: edc1c3a42a60a04b69c2fbb6e886414c71c464afbc7d19fb63b36a8065334ada
- bech32 address: rms1prkursay9fs2qjmfctamd6yxg9x8r3ry47786x0mvwek4qr9xd9d5c6gkun
+ Ed25519 Private Key: 432c624ca3260f910df35008d5c740593b222f1e196e6cdb8cd1ad080f0d4e33997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270
+ Ed25519 Public Key: 997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270
+ Ed25519 Address: rms1qrkursay9fs2qjmfctamd6yxg9x8r3ry47786x0mvwek4qr9xd9d583cnpd
+ Account Address: rms1prkursay9fs2qjmfctamd6yxg9x8r3ry47786x0mvwek4qr9xd9d5c6gkun
+ Restricted Address: rms1xqqwmswr5s4xpgztd8p0hdhgseq5cuwyvjhmclgeld3mx65qv5e54kspqgda0nrn, Capabilities: mana
*/
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270"))),
@@ -95,12 +120,10 @@ var Docker = []options.Option[snapshotcreator.Options]{
/*
inx-faucet
- ed25519 private key: de52b9964dda96564e9fab362ab16c2669c715c6a2a853bece8a25fc58c599755b938327ea463e0c323c0fd44f6fc1843ed94daecc6909c6043d06b7152e4737
- ed25519 public key: 5b938327ea463e0c323c0fd44f6fc1843ed94daecc6909c6043d06b7152e4737
- ed25519 address: 2f64f9d179991f50542b01e034fa043b195403875b8677efaf196b41c88803d0
- bech32 address: rms1qqhkf7w30xv375z59vq7qd86qsa3j4qrsadcval04uvkkswg3qpaqf4hga2
-
- => restricted address with mana enabled: rms1xqqz7e8e69uej86s2s4srcp5lgzrkx25qwr4hpnha7h3j66pezyq85qpqg55v3ur
+ Ed25519 Private Key: de52b9964dda96564e9fab362ab16c2669c715c6a2a853bece8a25fc58c599755b938327ea463e0c323c0fd44f6fc1843ed94daecc6909c6043d06b7152e4737
+ Ed25519 Public Key: 5b938327ea463e0c323c0fd44f6fc1843ed94daecc6909c6043d06b7152e4737
+ Ed25519 Address: rms1qqhkf7w30xv375z59vq7qd86qsa3j4qrsadcval04uvkkswg3qpaqf4hga2
+ Restricted Address: rms1xqqz7e8e69uej86s2s4srcp5lgzrkx25qwr4hpnha7h3j66pezyq85qpqg55v3ur, Capabilities: mana
*/
snapshotcreator.BasicOutputDetails{
Address: lo.Return2(iotago.ParseBech32("rms1xqqz7e8e69uej86s2s4srcp5lgzrkx25qwr4hpnha7h3j66pezyq85qpqg55v3ur")),
@@ -125,7 +148,15 @@ var Docker = []options.Option[snapshotcreator.Options]{
var Feature = []options.Option[snapshotcreator.Options]{
snapshotcreator.WithFilePath("docker-network.snapshot"),
snapshotcreator.WithAccounts(
- snapshotcreator.AccountDetails{ // node-01
+ snapshotcreator.AccountDetails{
+ /*
+ node-01-validator
+
+ Ed25519 Public Key: 01fb6b9db5d96240aef00bc950d1c67a6494513f6d7cf784e57b4972b96ab2fe
+ Ed25519 Address: rms1qqlhggrg2ml9p0q5c4593r2yd3jwgxn20d65ulyw6z9r7xmm78apq4y2mxh
+ Account Address: rms1pqlhggrg2ml9p0q5c4593r2yd3jwgxn20d65ulyw6z9r7xmm78apq2067mf
+ Restricted Address: rms1xqqr7apqdpt0u59uznzkskydg3kxfeq6dfah2nnu3mgg50cm00cl5yqpqgrpy62q, Capabilities: mana
+ */
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x01fb6b9db5d96240aef00bc950d1c67a6494513f6d7cf784e57b4972b96ab2fe"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x01fb6b9db5d96240aef00bc950d1c67a6494513f6d7cf784e57b4972b96ab2fe"))),
Amount: mock.MinValidatorAccountAmount,
@@ -137,7 +168,15 @@ var Feature = []options.Option[snapshotcreator.Options]{
StakedAmount: mock.MinValidatorAccountAmount,
Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
- snapshotcreator.AccountDetails{ // node-02
+ snapshotcreator.AccountDetails{
+ /*
+ node-02-validator
+
+ Ed25519 Public Key: 83e7f71a440afd48981a8b4684ddae24434b7182ce5c47cfb56ac528525fd4b6
+ Ed25519 Address: rms1qzjwamvhjuqtw3dkfwmmj2fgcetcdyt4uxrnjxel4caxfstzz903ypu8xvn
+ Account Address: rms1pzjwamvhjuqtw3dkfwmmj2fgcetcdyt4uxrnjxel4caxfstzz903y7hhr3d
+ Restricted Address: rms1xqq2fmhdj7tspd69ke9m0wff9rr90p53whscwwgm87hr5expvgg47yspqgm6whkx, Capabilities: mana
+ */
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x83e7f71a440afd48981a8b4684ddae24434b7182ce5c47cfb56ac528525fd4b6"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x83e7f71a440afd48981a8b4684ddae24434b7182ce5c47cfb56ac528525fd4b6"))),
Amount: mock.MinValidatorAccountAmount,
@@ -149,7 +188,15 @@ var Feature = []options.Option[snapshotcreator.Options]{
StakedAmount: mock.MinValidatorAccountAmount,
Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
- snapshotcreator.AccountDetails{ // node-03
+ snapshotcreator.AccountDetails{
+ /*
+ node-03-validator
+
+ Ed25519 Public Key: ac628986b2ef52a1679f2289fcd7b4198476976dea4c30ae34ff04ae52e14805
+ Ed25519 Address: rms1qz6kedkxyw9md2cmp0wcdhvsxrn2e7gzuyly76ffymy4dhvtkm58qlkjupg
+ Account Address: rms1pz6kedkxyw9md2cmp0wcdhvsxrn2e7gzuyly76ffymy4dhvtkm58qqazeuk
+ Restricted Address: rms1xqqt2m9kcc3chd4trv9ampkajqcwdt8eqtsnunmf9ynvj4ka3wmwsuqpqgvp9zxl, Capabilities: mana
+ */
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0xac628986b2ef52a1679f2289fcd7b4198476976dea4c30ae34ff04ae52e14805"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0xac628986b2ef52a1679f2289fcd7b4198476976dea4c30ae34ff04ae52e14805"))),
Amount: mock.MinValidatorAccountAmount,
@@ -165,9 +212,10 @@ var Feature = []options.Option[snapshotcreator.Options]{
/*
inx-blockissuer
- ed25519 public key: 670a1a20ddb02a6cec53ec3196bc7d5bd26df2f5a6ca90b5fffd71364f104b25
- ed25519 address: 3b07e3e84c1276f0b9d35cf218b3763e0cbdadaa7ca38588de2170c31b38e9bb
- bech32 address: rms1pqas0clgfsf8du9e6dw0yx9nwclqe0dd4f728pvgmcshpscm8r5mkddrrfc
+ Ed25519 Public Key: 670a1a20ddb02a6cec53ec3196bc7d5bd26df2f5a6ca90b5fffd71364f104b25
+ Ed25519 Address: rms1qqas0clgfsf8du9e6dw0yx9nwclqe0dd4f728pvgmcshpscm8r5mkjxnx5x
+ Account Address: rms1pqas0clgfsf8du9e6dw0yx9nwclqe0dd4f728pvgmcshpscm8r5mkddrrfc
+ Restricted Address: rms1xqqrkplrapxpyahsh8f4eusckdmrur9a4k48egu93r0zzuxrrvuwnwcpqgj0nu8t, Capabilities: mana
*/
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x670a1a20ddb02a6cec53ec3196bc7d5bd26df2f5a6ca90b5fffd71364f104b25"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x670a1a20ddb02a6cec53ec3196bc7d5bd26df2f5a6ca90b5fffd71364f104b25"))),
@@ -182,11 +230,9 @@ var Feature = []options.Option[snapshotcreator.Options]{
/*
inx-faucet
- ed25519 public key: dcd760a51cfafe901f4ca0745d399af7146028af643e8a339c7bb82fbb1be7f9
- ed25519 address: 48acd764f626523646d5ccf22f807e96d30b7ab0064f370b66fa811985985ec4
- bech32 address: rms1qpy2e4my7cn9ydjx6hx0ytuq06tdxzm6kqry7dctvmagzxv9np0vg9c55n4
-
- => restricted address with mana enabled: rms1xqqy3txhvnmzv53kgm2ueu30splfd5ct02cqvnehpdn04qgeskv9a3qpqgrhlhv3
+ Ed25519 Public Key: dcd760a51cfafe901f4ca0745d399af7146028af643e8a339c7bb82fbb1be7f9
+ Ed25519 Address: rms1qpy2e4my7cn9ydjx6hx0ytuq06tdxzm6kqry7dctvmagzxv9np0vg9c55n4
+ Restricted Address: rms1xqqy3txhvnmzv53kgm2ueu30splfd5ct02cqvnehpdn04qgeskv9a3qpqgrhlhv3, Capabilities: mana
*/
snapshotcreator.BasicOutputDetails{
Address: lo.Return2(iotago.ParseBech32("rms1xqqy3txhvnmzv53kgm2ueu30splfd5ct02cqvnehpdn04qgeskv9a3qpqgrhlhv3")),