diff --git a/Dockerfile b/Dockerfile
index 44a17fda1..ec10c0f75 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -35,6 +35,8 @@ RUN cp ./peering.json /app/peering.json
# using distroless cc "nonroot" image, which includes everything in the base image (glibc, libssl and openssl)
FROM gcr.io/distroless/cc-debian12:nonroot
+HEALTHCHECK --interval=10s --timeout=5s --retries=30 CMD ["/app/iota-core", "tools", "node-info"]
+
# Copy the app dir into distroless image
COPY --chown=nonroot:nonroot --from=build /app /app
diff --git a/Dockerfile.dev b/Dockerfile.dev
index e9073b384..f91006d26 100644
--- a/Dockerfile.dev
+++ b/Dockerfile.dev
@@ -61,6 +61,8 @@ RUN mkdir -p /app/data/peerdb
# using distroless cc "nonroot" image, which includes everything in the base image (glibc, libssl and openssl)
FROM gcr.io/distroless/cc-debian12:nonroot
+HEALTHCHECK --interval=10s --timeout=5s --retries=30 CMD ["/app/iota-core", "tools", "node-info"]
+
# Copy the app dir into distroless image
COPY --chown=nonroot:nonroot --from=build /app /app
diff --git a/components/app/app.go b/components/app/app.go
index 4cb029500..5c4b42957 100644
--- a/components/app/app.go
+++ b/components/app/app.go
@@ -1,6 +1,9 @@
package app
import (
+ "fmt"
+ "os"
+
"github.com/iotaledger/hive.go/app"
"github.com/iotaledger/hive.go/app/components/profiling"
"github.com/iotaledger/hive.go/app/components/shutdown"
@@ -15,6 +18,7 @@ import (
"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"
)
var (
@@ -28,6 +32,12 @@ var (
func App() *app.App {
return app.New(Name, Version,
// app.WithVersionCheck("iotaledger", "iota-core"),
+ app.WithUsageText(fmt.Sprintf(`Usage of %s (%s %s):
+
+Run '%s tools' to list all available tools.
+
+Command line flags:
+`, os.Args[0], Name, Version, os.Args[0])),
app.WithInitComponent(InitComponent),
app.WithComponents(
shutdown.Component,
@@ -63,5 +73,15 @@ func init() {
AdditionalConfigs: []*app.ConfigurationSet{
app.NewConfigurationSet("peering", "peering", "peeringConfigFilePath", "peeringConfig", false, true, false, "peering.json", "n"),
},
+ Init: initialize,
+ }
+}
+
+func initialize(_ *app.App) error {
+ if toolset.ShouldHandleTools() {
+ toolset.HandleTools()
+ // HandleTools will call os.Exit
}
+
+ return nil
}
diff --git a/components/dashboard/explorer_routes.go b/components/dashboard/explorer_routes.go
index ade3c3622..4918fc2f8 100644
--- a/components/dashboard/explorer_routes.go
+++ b/components/dashboard/explorer_routes.go
@@ -105,7 +105,7 @@ func createExplorerBlock(block *model.Block, cachedBlock *blocks.Block, metadata
var payloadJSON []byte
basicBlock, isBasic := block.BasicBlock()
if isBasic {
- payloadJSON, err = lo.PanicOnErr(deps.Protocol.APIForVersion(iotaBlk.ProtocolVersion)).JSONEncode(basicBlock.Payload)
+ payloadJSON, err = lo.PanicOnErr(deps.Protocol.APIForVersion(iotaBlk.Header.ProtocolVersion)).JSONEncode(basicBlock.Payload)
if err != nil {
return nil
}
@@ -113,16 +113,16 @@ func createExplorerBlock(block *model.Block, cachedBlock *blocks.Block, metadata
t := &ExplorerBlock{
ID: block.ID().ToHex(),
- NetworkID: iotaBlk.NetworkID,
- ProtocolVersion: iotaBlk.ProtocolVersion,
+ NetworkID: iotaBlk.Header.NetworkID,
+ ProtocolVersion: iotaBlk.Header.ProtocolVersion,
SolidificationTimestamp: 0,
- IssuanceTimestamp: iotaBlk.IssuingTime.Unix(),
+ IssuanceTimestamp: iotaBlk.Header.IssuingTime.Unix(),
SequenceNumber: 0,
- IssuerID: iotaBlk.IssuerID.ToHex(),
+ IssuerID: iotaBlk.Header.IssuerID.ToHex(),
Signature: hexutil.EncodeHex(sigBytes),
- StrongParents: iotaBlk.Block.StrongParentIDs().ToHex(),
- WeakParents: iotaBlk.Block.WeakParentIDs().ToHex(),
- ShallowLikedParents: iotaBlk.Block.ShallowLikeParentIDs().ToHex(),
+ StrongParents: iotaBlk.Body.StrongParentIDs().ToHex(),
+ WeakParents: iotaBlk.Body.WeakParentIDs().ToHex(),
+ ShallowLikedParents: iotaBlk.Body.ShallowLikeParentIDs().ToHex(),
PayloadType: func() iotago.PayloadType {
if isBasic && basicBlock.Payload != nil {
@@ -152,8 +152,8 @@ func createExplorerBlock(block *model.Block, cachedBlock *blocks.Block, metadata
return ""
}(),
- CommitmentID: iotaBlk.SlotCommitmentID.ToHex(),
- LatestConfirmedSlot: uint64(iotaBlk.LatestFinalizedSlot),
+ CommitmentID: iotaBlk.Header.SlotCommitmentID.ToHex(),
+ LatestConfirmedSlot: uint64(iotaBlk.Header.LatestFinalizedSlot),
}
if cachedBlock != nil {
diff --git a/components/dashboard/visualizer.go b/components/dashboard/visualizer.go
index 305348031..3788bbf76 100644
--- a/components/dashboard/visualizer.go
+++ b/components/dashboard/visualizer.go
@@ -48,9 +48,9 @@ func sendVertex(blk *blocks.Block, confirmed bool) {
broadcastWsBlock(&wsblk{MsgTypeVertex, &vertex{
ID: blk.ID().ToHex(),
- StrongParents: blk.ProtocolBlock().Block.StrongParentIDs().ToHex(),
- WeakParents: blk.ProtocolBlock().Block.WeakParentIDs().ToHex(),
- ShallowLikedParents: blk.ProtocolBlock().Block.ShallowLikeParentIDs().ToHex(),
+ StrongParents: blk.ProtocolBlock().Body.StrongParentIDs().ToHex(),
+ WeakParents: blk.ProtocolBlock().Body.WeakParentIDs().ToHex(),
+ ShallowLikedParents: blk.ProtocolBlock().Body.ShallowLikeParentIDs().ToHex(),
IsConfirmed: confirmed,
IsTx: isTx,
IsTxAccepted: func() bool {
diff --git a/components/debugapi/debug_models.go b/components/debugapi/debug_models.go
index 3ec7eba94..8343b91af 100644
--- a/components/debugapi/debug_models.go
+++ b/components/debugapi/debug_models.go
@@ -72,8 +72,8 @@ func BlockMetadataResponseFromBlock(block *blocks.Block) *BlockMetadataResponse
return &BlockMetadataResponse{
BlockID: block.ID().String(),
StrongParents: lo.Map(block.StrongParents(), func(blockID iotago.BlockID) string { return blockID.String() }),
- WeakParents: lo.Map(block.ProtocolBlock().Block.WeakParentIDs(), func(blockID iotago.BlockID) string { return blockID.String() }),
- ShallowLikeParents: lo.Map(block.ProtocolBlock().Block.ShallowLikeParentIDs(), func(blockID iotago.BlockID) string { return blockID.String() }),
+ WeakParents: lo.Map(block.ProtocolBlock().Body.WeakParentIDs(), func(blockID iotago.BlockID) string { return blockID.String() }),
+ ShallowLikeParents: lo.Map(block.ProtocolBlock().Body.ShallowLikeParentIDs(), func(blockID iotago.BlockID) string { return blockID.String() }),
Solid: block.IsSolid(),
Invalid: block.IsInvalid(),
Booked: block.IsBooked(),
diff --git a/components/inx/server_blocks.go b/components/inx/server_blocks.go
index 77a5e9b77..63b6b076e 100644
--- a/components/inx/server_blocks.go
+++ b/components/inx/server_blocks.go
@@ -126,7 +126,7 @@ func (s *Server) SubmitBlock(ctx context.Context, rawBlock *inx.RawBlock) (*inx.
return s.attachBlock(ctx, block)
}
-func (s *Server) attachBlock(ctx context.Context, block *iotago.ProtocolBlock) (*inx.BlockId, error) {
+func (s *Server) attachBlock(ctx context.Context, block *iotago.Block) (*inx.BlockId, error) {
mergedCtx, mergedCtxCancel := contextutils.MergeContexts(ctx, Component.Daemon().ContextStopped())
defer mergedCtxCancel()
diff --git a/components/metrics/metrics_accounts.go b/components/metrics/metrics_accounts.go
index a6950ba5e..ec7f7e3e5 100644
--- a/components/metrics/metrics_accounts.go
+++ b/components/metrics/metrics_accounts.go
@@ -23,7 +23,7 @@ var AccountMetrics = collector.NewCollection(accountNamespace,
collector.WithPruningDelay(10*time.Minute),
collector.WithInitFunc(func() {
deps.Protocol.Events.Engine.BlockGadget.BlockAccepted.Hook(func(block *blocks.Block) {
- accountData, exists, _ := deps.Protocol.MainEngineInstance().Ledger.Account(block.ProtocolBlock().IssuerID, deps.Protocol.MainEngineInstance().SyncManager.LatestCommitment().Slot())
+ accountData, exists, _ := deps.Protocol.MainEngineInstance().Ledger.Account(block.ProtocolBlock().Header.IssuerID, deps.Protocol.MainEngineInstance().SyncManager.LatestCommitment().Slot())
if exists {
deps.Collector.Update(accountNamespace, credits, float64(accountData.Credits.Value), accountData.ID.String())
}
diff --git a/components/metrics/metrics_scheduler.go b/components/metrics/metrics_scheduler.go
index 2d2896584..f23b17221 100644
--- a/components/metrics/metrics_scheduler.go
+++ b/components/metrics/metrics_scheduler.go
@@ -38,22 +38,22 @@ var SchedulerMetrics = collector.NewCollection(schedulerNamespace,
collector.WithHelp("Current size of each node's queue (in work units)."),
collector.WithInitFunc(func() {
deps.Protocol.Events.Engine.Scheduler.BlockEnqueued.Hook(func(block *blocks.Block) {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockSkipped.Hook(func(block *blocks.Block) {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockDropped.Hook(func(block *blocks.Block, _ error) {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockScheduled.Hook(func(block *blocks.Block) {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeWork, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueWork(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}, event.WithWorkerPool(Component.WorkerPool))
}),
@@ -66,25 +66,25 @@ var SchedulerMetrics = collector.NewCollection(schedulerNamespace,
collector.WithInitFunc(func() {
deps.Protocol.Events.Engine.Scheduler.BlockEnqueued.Hook(func(block *blocks.Block) {
if _, isBasic := block.BasicBlock(); isBasic {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockSkipped.Hook(func(block *blocks.Block) {
if _, isBasic := block.BasicBlock(); isBasic {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockDropped.Hook(func(block *blocks.Block, _ error) {
if _, isBasic := block.BasicBlock(); isBasic {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockScheduled.Hook(func(block *blocks.Block) {
if _, isBasic := block.BasicBlock(); isBasic {
- deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, queueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.IssuerQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
}),
@@ -97,25 +97,25 @@ var SchedulerMetrics = collector.NewCollection(schedulerNamespace,
collector.WithInitFunc(func() {
deps.Protocol.Events.Engine.Scheduler.BlockEnqueued.Hook(func(block *blocks.Block) {
if _, isValidation := block.ValidationBlock(); isValidation {
- deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockSkipped.Hook(func(block *blocks.Block) {
if _, isValidation := block.ValidationBlock(); isValidation {
- deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockDropped.Hook(func(block *blocks.Block, _ error) {
if _, isValidation := block.ValidationBlock(); isValidation {
- deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
deps.Protocol.Events.Engine.Scheduler.BlockScheduled.Hook(func(block *blocks.Block) {
if _, isValidation := block.ValidationBlock(); isValidation {
- deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().IssuerID)), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, validatorQueueSizePerNodeCount, float64(deps.Protocol.MainEngineInstance().Scheduler.ValidatorQueueBlockCount(block.ProtocolBlock().Header.IssuerID)), block.ProtocolBlock().Header.IssuerID.String())
}
}, event.WithWorkerPool(Component.WorkerPool))
}),
@@ -127,14 +127,14 @@ var SchedulerMetrics = collector.NewCollection(schedulerNamespace,
collector.WithHelp("Current amount of mana of each issuer in the queue."),
collector.WithInitFunc(func() {
deps.Protocol.Events.Engine.Scheduler.BlockEnqueued.Hook(func(block *blocks.Block) {
- mana, err := deps.Protocol.MainEngineInstance().Ledger.ManaManager().GetManaOnAccount(block.ProtocolBlock().IssuerID, block.SlotCommitmentID().Slot())
+ mana, err := deps.Protocol.MainEngineInstance().Ledger.ManaManager().GetManaOnAccount(block.ProtocolBlock().Header.IssuerID, block.SlotCommitmentID().Slot())
if err != nil {
- deps.Protocol.MainEngineInstance().ErrorHandler("metrics")(ierrors.Wrapf(err, "failed to retrieve mana on account %s for slot %d", block.ProtocolBlock().IssuerID, block.SlotCommitmentID().Slot()))
+ deps.Protocol.MainEngineInstance().ErrorHandler("metrics")(ierrors.Wrapf(err, "failed to retrieve mana on account %s for slot %d", block.ProtocolBlock().Header.IssuerID, block.SlotCommitmentID().Slot()))
return
}
- deps.Collector.Update(schedulerNamespace, manaAmountPerNode, float64(mana), block.ProtocolBlock().IssuerID.String())
+ deps.Collector.Update(schedulerNamespace, manaAmountPerNode, float64(mana), block.ProtocolBlock().Header.IssuerID.String())
}, event.WithWorkerPool(Component.WorkerPool))
}),
)),
diff --git a/components/p2p/component.go b/components/p2p/component.go
index 9635df585..dff432bb7 100644
--- a/components/p2p/component.go
+++ b/components/p2p/component.go
@@ -230,7 +230,7 @@ func provide(c *dig.Container) error {
if err := c.Provide(func(deps p2pDeps) p2pResult {
res := p2pResult{}
- privKeyFilePath := filepath.Join(deps.P2PDatabasePath, "identity.key")
+ privKeyFilePath := filepath.Join(deps.P2PDatabasePath, IdentityPrivateKeyFileName)
// make sure nobody copies around the peer store since it contains the private key of the node
Component.LogInfof(`WARNING: never share your "%s" folder as it contains your node's private key!`, deps.P2PDatabasePath)
diff --git a/components/p2p/params.go b/components/p2p/params.go
index 37f099d85..7b2cba4e7 100644
--- a/components/p2p/params.go
+++ b/components/p2p/params.go
@@ -6,7 +6,8 @@ import (
const (
// CfgPeers defines the static peers this node should retain a connection to (CLI).
- CfgPeers = "peers"
+ CfgPeers = "peers"
+ IdentityPrivateKeyFileName = "identity.key"
)
// ParametersP2P contains the definition of configuration parameters used by the p2p plugin.
diff --git a/components/restapi/core/accounts.go b/components/restapi/core/accounts.go
index 995e7db33..91c6211c3 100644
--- a/components/restapi/core/accounts.go
+++ b/components/restapi/core/accounts.go
@@ -26,10 +26,10 @@ func congestionForAccountID(c echo.Context) (*apimodels.CongestionResponse, erro
acc, exists, err := deps.Protocol.MainEngineInstance().Ledger.Account(accountID, commitment.Slot())
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get account: %s form the Ledger", accountID.ToHex())
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get account %s from the Ledger: %s", accountID.ToHex(), err)
}
if !exists {
- return nil, ierrors.Errorf("account not found: %s", accountID.ToHex())
+ return nil, ierrors.Wrapf(echo.ErrNotFound, "account not found: %s", accountID.ToHex())
}
return &apimodels.CongestionResponse{
@@ -46,7 +46,7 @@ func validators(c echo.Context) (*apimodels.ValidatorsResponse, error) {
if len(c.QueryParam(restapipkg.QueryParameterPageSize)) > 0 {
pageSize, err = httpserver.ParseUint32QueryParam(c, restapipkg.QueryParameterPageSize)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse the %s parameter", restapipkg.QueryParameterPageSize)
+ return nil, ierrors.Wrapf(err, "failed to parse page size %s", c.Param(restapipkg.QueryParameterPageSize))
}
if pageSize > restapi.ParamsRestAPI.MaxPageSize {
pageSize = restapi.ParamsRestAPI.MaxPageSize
@@ -59,13 +59,13 @@ func validators(c echo.Context) (*apimodels.ValidatorsResponse, error) {
if len(c.QueryParam(restapipkg.QueryParameterCursor)) != 0 {
requestedSlot, cursorIndex, err = httpserver.ParseCursorQueryParam(c, restapipkg.QueryParameterCursor)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse the %s parameter", restapipkg.QueryParameterCursor)
+ return nil, ierrors.Wrapf(err, "failed to parse cursor %s", c.Param(restapipkg.QueryParameterCursor))
}
}
// do not respond to really old requests
if requestedSlot+iotago.SlotIndex(restapi.ParamsRestAPI.MaxRequestedSlotAge) < latestCommittedSlot {
- return nil, ierrors.Errorf("request is too old, request started at %d, latest committed slot index is %d", requestedSlot, latestCommittedSlot)
+ return nil, ierrors.Wrapf(echo.ErrBadRequest, "request is too old, request started at %d, latest committed slot index is %d", requestedSlot, latestCommittedSlot)
}
nextEpoch := deps.Protocol.APIForSlot(latestCommittedSlot).TimeProvider().EpochFromSlot(latestCommittedSlot) + 1
@@ -75,7 +75,7 @@ func validators(c echo.Context) (*apimodels.ValidatorsResponse, error) {
if !exists {
registeredValidators, err = deps.Protocol.MainEngineInstance().SybilProtection.OrderedRegisteredCandidateValidatorsList(nextEpoch)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get ordered registered validators list for epoch %d", nextEpoch)
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get ordered registered validators list for epoch %d : %s", nextEpoch, err)
}
deps.Protocol.MainEngineInstance().Retainer.RetainRegisteredValidatorsCache(slotRange, registeredValidators)
}
@@ -98,16 +98,16 @@ func validators(c echo.Context) (*apimodels.ValidatorsResponse, error) {
func validatorByAccountID(c echo.Context) (*apimodels.ValidatorResponse, error) {
accountID, err := httpserver.ParseAccountIDParam(c, restapipkg.ParameterAccountID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse the %s parameter", restapipkg.ParameterAccountID)
+ return nil, ierrors.Wrapf(err, "failed to parse account ID %s", c.Param(restapipkg.ParameterAccountID))
}
latestCommittedSlot := deps.Protocol.MainEngineInstance().SyncManager.LatestCommitment().Slot()
accountData, exists, err := deps.Protocol.MainEngineInstance().Ledger.Account(accountID, latestCommittedSlot)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get account: %s form the Ledger", accountID.ToHex())
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get account %s from the Ledger: %s", accountID.ToHex(), err)
}
if !exists {
- return nil, ierrors.Errorf("account not found: %s for latest committedSlot %d", accountID.ToHex(), latestCommittedSlot)
+ return nil, ierrors.Wrapf(echo.ErrNotFound, "account %s not found for latest committedSlot %d", accountID.ToHex(), latestCommittedSlot)
}
nextEpoch := deps.Protocol.APIForSlot(latestCommittedSlot).TimeProvider().EpochFromSlot(latestCommittedSlot) + 1
@@ -131,12 +131,12 @@ func validatorByAccountID(c echo.Context) (*apimodels.ValidatorResponse, error)
func rewardsByOutputID(c echo.Context) (*apimodels.ManaRewardsResponse, error) {
outputID, err := httpserver.ParseOutputIDParam(c, restapipkg.ParameterOutputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse the %s parameter", restapipkg.ParameterOutputID)
+ return nil, ierrors.Wrapf(err, "failed to parse output ID %s", c.Param(restapipkg.ParameterOutputID))
}
utxoOutput, err := deps.Protocol.MainEngineInstance().Ledger.Output(outputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get output %s from ledger", outputID.ToHex())
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from ledger: %s", outputID.ToHex(), err)
}
var reward iotago.Mana
@@ -147,7 +147,7 @@ func rewardsByOutputID(c echo.Context) (*apimodels.ManaRewardsResponse, error) {
accountOutput := utxoOutput.Output().(*iotago.AccountOutput)
feature, exists := accountOutput.FeatureSet()[iotago.FeatureStaking]
if !exists {
- return nil, ierrors.Errorf("account %s is not a validator", outputID)
+ return nil, ierrors.Wrapf(echo.ErrBadRequest, "account %s is not a validator", outputID.ToHex())
}
//nolint:forcetypeassert
@@ -178,7 +178,7 @@ func rewardsByOutputID(c echo.Context) (*apimodels.ManaRewardsResponse, error) {
)
}
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to calculate reward for output %s", outputID)
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to calculate reward for output %s: %s", outputID.ToHex(), err)
}
return &apimodels.ManaRewardsResponse{
diff --git a/components/restapi/core/blocks.go b/components/restapi/core/blocks.go
index 03c3598d6..554fdfa08 100644
--- a/components/restapi/core/blocks.go
+++ b/components/restapi/core/blocks.go
@@ -15,12 +15,12 @@ import (
func blockByID(c echo.Context) (*model.Block, error) {
blockID, err := httpserver.ParseBlockIDParam(c, restapi.ParameterBlockID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse block ID: %s", c.Param(restapi.ParameterBlockID))
+ return nil, ierrors.Wrapf(err, "failed to parse block ID %s", c.Param(restapi.ParameterBlockID))
}
block, exists := deps.Protocol.MainEngineInstance().Block(blockID)
if !exists {
- return nil, ierrors.Errorf("block not found: %s", blockID.ToHex())
+ return nil, ierrors.Wrapf(echo.ErrNotFound, "block not found: %s", blockID.ToHex())
}
return block, nil
@@ -29,7 +29,7 @@ func blockByID(c echo.Context) (*model.Block, error) {
func blockMetadataByBlockID(blockID iotago.BlockID) (*apimodels.BlockMetadataResponse, error) {
blockMetadata, err := deps.Protocol.MainEngineInstance().Retainer.BlockMetadata(blockID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get block metadata: %s", blockID.ToHex())
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get block metadata %s: %s", blockID.ToHex(), err)
}
return blockMetadata.BlockMetadataResponse(), nil
@@ -38,7 +38,7 @@ func blockMetadataByBlockID(blockID iotago.BlockID) (*apimodels.BlockMetadataRes
func blockMetadataByID(c echo.Context) (*apimodels.BlockMetadataResponse, error) {
blockID, err := httpserver.ParseBlockIDParam(c, restapi.ParameterBlockID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse block ID: %s", c.Param(restapi.ParameterBlockID))
+ return nil, ierrors.Wrapf(err, "failed to parse block ID %s", c.Param(restapi.ParameterBlockID))
}
return blockMetadataByBlockID(blockID)
@@ -55,7 +55,7 @@ func blockIssuanceBySlot(slotIndex iotago.SlotIndex) (*apimodels.IssuanceBlockHe
} else {
slotCommitment, err = deps.Protocol.MainEngineInstance().Storage.Commitments().Load(slotIndex)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to load commitment for requested slot %d", slotIndex)
+ return nil, ierrors.Wrapf(echo.ErrNotFound, "failed to load commitment for requested slot %d: %s", slotIndex, err)
}
}
@@ -75,9 +75,9 @@ func blockIssuanceBySlot(slotIndex iotago.SlotIndex) (*apimodels.IssuanceBlockHe
}
func sendBlock(c echo.Context) (*apimodels.BlockCreatedResponse, error) {
- iotaBlock, err := httpserver.ParseRequestByHeader(c, deps.Protocol.CommittedAPI(), iotago.ProtocolBlockFromBytes(deps.Protocol))
+ iotaBlock, err := httpserver.ParseRequestByHeader(c, deps.Protocol.CommittedAPI(), iotago.BlockFromBytes(deps.Protocol))
if err != nil {
- return nil, err
+ return nil, ierrors.Wrapf(err, "failed to parse iotablock")
}
blockID, err := deps.BlockHandler.AttachBlock(c.Request().Context(), iotaBlock)
diff --git a/components/restapi/core/commitment.go b/components/restapi/core/commitment.go
index 99059825c..4ff0f581d 100644
--- a/components/restapi/core/commitment.go
+++ b/components/restapi/core/commitment.go
@@ -13,7 +13,7 @@ import (
func indexByCommitmentID(c echo.Context) (iotago.SlotIndex, error) {
commitmentID, err := httpserver.ParseCommitmentIDParam(c, restapipkg.ParameterCommitmentID)
if err != nil {
- return iotago.SlotIndex(0), ierrors.Wrapf(err, "failed to parse commitment ID: %s", c.Param(restapipkg.ParameterCommitmentID))
+ return iotago.SlotIndex(0), ierrors.Wrapf(err, "failed to parse commitment ID %s", c.Param(restapipkg.ParameterCommitmentID))
}
return commitmentID.Slot(), nil
@@ -22,7 +22,7 @@ func indexByCommitmentID(c echo.Context) (iotago.SlotIndex, error) {
func getCommitmentDetails(index iotago.SlotIndex) (*iotago.Commitment, error) {
commitment, err := deps.Protocol.MainEngineInstance().Storage.Commitments().Load(index)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to load commitment: %d", index)
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment %d: %s", index, err)
}
return commitment.Commitment(), nil
@@ -31,7 +31,7 @@ func getCommitmentDetails(index iotago.SlotIndex) (*iotago.Commitment, error) {
func getUTXOChanges(slot iotago.SlotIndex) (*apimodels.UTXOChangesResponse, error) {
diffs, err := deps.Protocol.MainEngineInstance().Ledger.SlotDiffs(slot)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get slot diffs: %d", slot)
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get slot diffs %d: %s", slot, err)
}
createdOutputs := make(iotago.OutputIDs, len(diffs.Outputs))
diff --git a/components/restapi/core/transaction.go b/components/restapi/core/transaction.go
index 44575426a..93f660134 100644
--- a/components/restapi/core/transaction.go
+++ b/components/restapi/core/transaction.go
@@ -14,7 +14,7 @@ import (
func blockIDByTransactionID(c echo.Context) (iotago.BlockID, error) {
txID, err := httpserver.ParseTransactionIDParam(c, restapipkg.ParameterTransactionID)
if err != nil {
- return iotago.EmptyBlockID, ierrors.Wrapf(err, "failed to parse transaction ID: %s", c.Param(restapipkg.ParameterTransactionID))
+ return iotago.EmptyBlockID, ierrors.Wrapf(err, "failed to parse transaction ID %s", c.Param(restapipkg.ParameterTransactionID))
}
return blockIDFromTransactionID(txID)
@@ -26,7 +26,7 @@ func blockIDFromTransactionID(transactionID iotago.TransactionID) (iotago.BlockI
output, spent, err := deps.Protocol.MainEngineInstance().Ledger.OutputOrSpent(outputID)
if err != nil {
- return iotago.EmptyBlockID, ierrors.Wrapf(err, "failed to get output: %s", outputID.ToHex())
+ return iotago.EmptyBlockID, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s: %s", outputID.ToHex(), err)
}
if output != nil {
@@ -39,12 +39,12 @@ func blockIDFromTransactionID(transactionID iotago.TransactionID) (iotago.BlockI
func blockByTransactionID(c echo.Context) (*model.Block, error) {
blockID, err := blockIDByTransactionID(c)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get block ID by transaction ID")
+ return nil, ierrors.Wrapf(echo.ErrBadRequest, "failed to get block ID by transaction ID: %s", err)
}
block, exists := deps.Protocol.MainEngineInstance().Block(blockID)
if !exists {
- return nil, ierrors.Errorf("block not found: %s", blockID.String())
+ return nil, ierrors.Wrapf(echo.ErrNotFound, "block not found: %s", blockID.ToHex())
}
return block, nil
@@ -53,7 +53,7 @@ func blockByTransactionID(c echo.Context) (*model.Block, error) {
func blockMetadataFromTransactionID(c echo.Context) (*apimodels.BlockMetadataResponse, error) {
blockID, err := blockIDByTransactionID(c)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get block ID by transaction ID")
+ return nil, ierrors.Wrapf(echo.ErrBadRequest, "failed to get block ID by transaction ID: %s", err)
}
return blockMetadataByBlockID(blockID)
diff --git a/components/restapi/core/utxo.go b/components/restapi/core/utxo.go
index 196b6c514..bdf62c89c 100644
--- a/components/restapi/core/utxo.go
+++ b/components/restapi/core/utxo.go
@@ -13,12 +13,12 @@ import (
func getOutput(c echo.Context) (*apimodels.OutputResponse, error) {
outputID, err := httpserver.ParseOutputIDParam(c, restapipkg.ParameterOutputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse output ID param: %s", c.Param(restapipkg.ParameterOutputID))
+ return nil, ierrors.Wrapf(err, "failed to parse output ID %s", c.Param(restapipkg.ParameterOutputID))
}
output, err := deps.Protocol.MainEngineInstance().Ledger.Output(outputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get output: %s from the Ledger", outputID.String())
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err)
}
return &apimodels.OutputResponse{
@@ -30,12 +30,12 @@ func getOutput(c echo.Context) (*apimodels.OutputResponse, error) {
func getOutputMetadata(c echo.Context) (*apimodels.OutputMetadata, error) {
outputID, err := httpserver.ParseOutputIDParam(c, restapipkg.ParameterOutputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse output ID param: %s", c.Param(restapipkg.ParameterOutputID))
+ return nil, ierrors.Wrapf(err, "failed to parse output ID %s", c.Param(restapipkg.ParameterOutputID))
}
output, spent, err := deps.Protocol.MainEngineInstance().Ledger.OutputOrSpent(outputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get output: %s from the Ledger", outputID.String())
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err)
}
if spent != nil {
@@ -48,18 +48,18 @@ func getOutputMetadata(c echo.Context) (*apimodels.OutputMetadata, error) {
func getOutputWithMetadata(c echo.Context) (*apimodels.OutputWithMetadataResponse, error) {
outputID, err := httpserver.ParseOutputIDParam(c, restapipkg.ParameterOutputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to parse output ID param: %s", c.Param(restapipkg.ParameterOutputID))
+ return nil, ierrors.Wrapf(err, "failed to parse output ID %s", c.Param(restapipkg.ParameterOutputID))
}
output, spent, err := deps.Protocol.MainEngineInstance().Ledger.OutputOrSpent(outputID)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get output: %s from the Ledger", outputID.String())
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to get output %s from the Ledger: %s", outputID.ToHex(), err)
}
if spent != nil {
metadata, err := newSpentMetadataResponse(spent)
if err != nil {
- return nil, err
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load spent output metadata: %s", err)
}
return &apimodels.OutputWithMetadataResponse{
@@ -96,7 +96,7 @@ func newOutputMetadataResponse(output *utxoledger.Output) (*apimodels.OutputMeta
if includedSlotIndex <= latestCommitment.Slot() {
includedCommitment, err := deps.Protocol.MainEngineInstance().Storage.Commitments().Load(includedSlotIndex)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to load commitment with index: %d", includedSlotIndex)
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment with index %d: %s", includedSlotIndex, err)
}
resp.IncludedCommitmentID = includedCommitment.ID()
}
@@ -120,7 +120,7 @@ func newSpentMetadataResponse(spent *utxoledger.Spent) (*apimodels.OutputMetadat
if includedSlotIndex <= latestCommitment.Slot() {
includedCommitment, err := deps.Protocol.MainEngineInstance().Storage.Commitments().Load(includedSlotIndex)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to load commitment with index: %d", includedSlotIndex)
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment with index %d: %s", includedSlotIndex, err)
}
resp.IncludedCommitmentID = includedCommitment.ID()
}
@@ -129,7 +129,7 @@ func newSpentMetadataResponse(spent *utxoledger.Spent) (*apimodels.OutputMetadat
if spentSlotIndex <= latestCommitment.Slot() {
spentCommitment, err := deps.Protocol.MainEngineInstance().Storage.Commitments().Load(spentSlotIndex)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to load commitment with index: %d", spentSlotIndex)
+ return nil, ierrors.Wrapf(echo.ErrInternalServerError, "failed to load commitment with index %d: %s", spentSlotIndex, err)
}
resp.CommitmentIDSpent = spentCommitment.ID()
}
diff --git a/components/restapi/params.go b/components/restapi/params.go
index 440fdc102..121d07ae8 100644
--- a/components/restapi/params.go
+++ b/components/restapi/params.go
@@ -9,7 +9,7 @@ type ParametersRestAPI struct {
// Enabled defines whether the REST API plugin is enabled.
Enabled bool `default:"true" usage:"whether the REST API plugin is enabled"`
// the bind address on which the REST API listens on
- BindAddress string `default:"0.0.0.0:8080" usage:"the bind address on which the REST API listens on"`
+ BindAddress string `default:"0.0.0.0:14265" usage:"the bind address on which the REST API listens on"`
// the HTTP REST routes which can be called without authorization. Wildcards using * are allowed
PublicRoutes []string `usage:"the HTTP REST routes which can be called without authorization. Wildcards using * are allowed"`
// the HTTP REST routes which need to be called with authorization. Wildcards using * are allowed
diff --git a/components/validator/issuer.go b/components/validator/issuer.go
index 8a748b58f..038fb9e78 100644
--- a/components/validator/issuer.go
+++ b/components/validator/issuer.go
@@ -101,7 +101,7 @@ func issueValidatorBlock(ctx context.Context) {
return
}
- Component.LogDebugf("Issued validator block: %s - commitment %s %d - latest finalized slot %d", modelBlock.ID(), modelBlock.ProtocolBlock().SlotCommitmentID, modelBlock.ProtocolBlock().SlotCommitmentID.Slot(), modelBlock.ProtocolBlock().LatestFinalizedSlot)
+ 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) {
diff --git a/config_defaults.json b/config_defaults.json
index 53114f287..f24471e14 100644
--- a/config_defaults.json
+++ b/config_defaults.json
@@ -44,7 +44,7 @@
},
"restAPI": {
"enabled": true,
- "bindAddress": "0.0.0.0:8080",
+ "bindAddress": "0.0.0.0:14265",
"publicRoutes": [
"/health",
"/api/routes",
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 a5284d45b..d3bc9d82b 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
@@ -26,7 +26,7 @@ services:
ports:
- "14666:14666/tcp" # P2P
- "6061:6061/tcp" # pprof
- - "8080:8080/tcp" # REST-API
+ - "8080:14265/tcp" # REST-API
- "8081:8081/tcp" # Dashboard
- "9311:9311/tcp" # Prometheus
- "9029:9029/tcp" # INX
@@ -46,7 +46,7 @@ services:
--p2p.db.path=/app/data/peerdb
--profiling.enabled=true
--profiling.bindAddress=0.0.0.0:6061
- --restAPI.bindAddress=0.0.0.0:8080
+ --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 %}
@@ -73,7 +73,7 @@ services:
restart: unless-stopped
depends_on:
iota-core:
- condition: service_started
+ condition: service_healthy
ulimits:
nofile:
soft: 16384
@@ -93,7 +93,7 @@ services:
restart: unless-stopped
depends_on:
iota-core:
- condition: service_started
+ condition: service_healthy
inx-indexer:
condition: service_started
environment:
@@ -111,7 +111,7 @@ services:
restart: unless-stopped
depends_on:
iota-core:
- condition: service_started
+ condition: service_healthy
inx-indexer:
condition: service_started
inx-blockissuer:
diff --git a/documentation/docs/references/configuration.md b/documentation/docs/references/configuration.md
index bbcd516e6..ba034fde1 100644
--- a/documentation/docs/references/configuration.md
+++ b/documentation/docs/references/configuration.md
@@ -175,7 +175,7 @@ Example:
| Name | Description | Type | Default value |
| ------------------------------ | ---------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| enabled | Whether the REST API plugin is enabled | boolean | true |
-| bindAddress | The bind address on which the REST API listens on | string | "0.0.0.0:8080" |
+| bindAddress | The bind address on which the REST API listens on | string | "0.0.0.0:14265" |
| 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 |
@@ -204,7 +204,7 @@ Example:
{
"restAPI": {
"enabled": true,
- "bindAddress": "0.0.0.0:8080",
+ "bindAddress": "0.0.0.0:14265",
"publicRoutes": [
"/health",
"/api/routes",
diff --git a/go.mod b/go.mod
index 3895dd8e8..ec5d2d7d5 100644
--- a/go.mod
+++ b/go.mod
@@ -12,29 +12,31 @@ require (
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/iotaledger/hive.go/ads v0.0.0-20231020115340-13da292c580b
github.com/iotaledger/hive.go/app v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b
+ github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b
- github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b
+ github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b
+ github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b
+ github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42
github.com/iotaledger/hive.go/logger v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b
+ github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b
- github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231023191159-38919c4705e0
- github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231023190837-6e7b2cdfd4fd
- github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1
+ github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42
+ github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231028104239-869296c43f26
+ github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231028104044-69b02af0058d
+ github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a
github.com/labstack/echo/v4 v4.11.2
github.com/labstack/gommon v0.4.0
github.com/libp2p/go-libp2p v0.31.0
github.com/libp2p/go-libp2p-kad-dht v0.25.1
+ github.com/mr-tron/base58 v1.2.0
github.com/multiformats/go-multiaddr v0.12.0
github.com/multiformats/go-varint v0.0.7
github.com/orcaman/writerseeker v0.0.0-20200621085525-1d3f536ff85e
github.com/otiai10/copy v1.14.0
github.com/prometheus/client_golang v1.17.0
+ github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
github.com/wollac/iota-crypto-demo v0.0.0-20221117162917-b10619eccb98
github.com/zyedidia/generic v1.2.1
@@ -126,7 +128,6 @@ require (
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
- github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
@@ -157,7 +158,6 @@ require (
github.com/sasha-s/go-deadlock v0.3.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
diff --git a/go.sum b/go.sum
index 40540cd56..4bf13faa4 100644
--- a/go.sum
+++ b/go.sum
@@ -281,36 +281,36 @@ github.com/iotaledger/hive.go/ads v0.0.0-20231020115340-13da292c580b h1:D68khiAF
github.com/iotaledger/hive.go/ads v0.0.0-20231020115340-13da292c580b/go.mod h1:IFh0gDfeMgZtfCo+5afK59IDR4xXh+cTR9YtLnZPcbY=
github.com/iotaledger/hive.go/app v0.0.0-20231020115340-13da292c580b h1:mX3NXaTMLEwZnEs4IlxEvXY0YZo8qbb8M1xM39FS6qY=
github.com/iotaledger/hive.go/app v0.0.0-20231020115340-13da292c580b/go.mod h1:8ZbIKR84oQd/3iQ5eeT7xpudO9/ytzXP7veIYnk7Orc=
-github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b h1:HF4e0wz0JMIT4m3saqdQ//T9nWHV9d5sLMtEwNDuykM=
-github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b/go.mod h1:dOBOM2s4se3HcWefPe8sQLUalGXJ8yVXw58oK8jke3s=
+github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42 h1:drmpgLlJy7kZ09Dt1qKSnbILU+27Qu2jp4VdPDNwbFk=
+github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42/go.mod h1:dOBOM2s4se3HcWefPe8sQLUalGXJ8yVXw58oK8jke3s=
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b h1:ZERXxhQBUBV1AqTE6cUI4vTxSx4JrnsMuLZFgj32xLM=
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b/go.mod h1:Mc+ACqBGPxrPMIPUBOm6/HL0J6m0iVMwjtIEKW3uow8=
-github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b h1:ZUUqRRO6XnQmVcXlXyx07vqySn28+bln6jp9KagYCjY=
-github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b/go.mod h1:h3o6okvMSEK3KOX6pOp3yq1h9ohTkTfo6X8MzEadeb0=
+github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42 h1:r8TkdQJB7/bJd8cF8z5GQ+rX/7JpbPdPoN7wMoV1OCM=
+github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42/go.mod h1:h3o6okvMSEK3KOX6pOp3yq1h9ohTkTfo6X8MzEadeb0=
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b h1:8b2sH+2Vf0y5BDYTMwKa09iQr3JF9JrzTI64DkXb+9U=
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b/go.mod h1:3XkUSKfHaVxGbT0XAvjNlVYqPzhfLTGhDtdNA5UBPco=
-github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b h1:JJPnr231djUTgTnE4oGz847WE9VA7Py6E6fgZwT5TQo=
-github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b/go.mod h1:HcE8B5lP96enc/OALTb2/rIIi+yOLouRoHOKRclKmC8=
+github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42 h1:QMxd32Y/veVhTDPCiOFgetjUbG7sr9MryF29/rSPkMA=
+github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42/go.mod h1:HcE8B5lP96enc/OALTb2/rIIi+yOLouRoHOKRclKmC8=
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b h1:LusmtjpfG/q8lc15Fp9W3kABbN3tArKx/zw2ibdY1DU=
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b/go.mod h1:O/U3jtiUDeqqM0MZQFu2UPqS9fUm0C5hNISxlmg/thE=
-github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b h1:UvFWI8wQJS/XQOeWHpPsaFVeS2nxJ7nIGFr+IFjrnVw=
-github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b/go.mod h1:s4kzx9QY1MVWHJralj+3q5kI0eARtrJhphYD/iBbPfo=
+github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42 h1:AvNLzONVMspwx7nD/NyYUgb5Hi7/zgzIOegr1uRD/M8=
+github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42/go.mod h1:s4kzx9QY1MVWHJralj+3q5kI0eARtrJhphYD/iBbPfo=
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b h1:IwhoeOeRu25mBdrimuOOvbbhHYX0QipibV69ubn8nX0=
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b/go.mod h1:JvokzmpmFZPDskMlUqqjgHtD8usVJU4nAY/TNMGge8M=
github.com/iotaledger/hive.go/logger v0.0.0-20231020115340-13da292c580b h1:EhVgAU/f2J3VYZwP60dRdyfAeDU3c/gBzX9blKtQGKA=
github.com/iotaledger/hive.go/logger v0.0.0-20231020115340-13da292c580b/go.mod h1:aBfAfIB2GO/IblhYt5ipCbyeL9bXSNeAwtYVA3hZaHg=
-github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b h1:O68POYIqBLnoHN+HIszc58QwAI2qocYq0WKGfVrXmMg=
-github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b/go.mod h1:jRw8yFipiPaqmTPHh7hTcxAP9u6pjRGpByS3REJKkbY=
+github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42 h1:1QMJ39qXIx/IZVzus3+97IV7Pa++e+d340TvbMjhiBU=
+github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42/go.mod h1:jRw8yFipiPaqmTPHh7hTcxAP9u6pjRGpByS3REJKkbY=
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b h1:zaXZn9yV/95SRDkgCZQeBbSbmcJTKSZbCB7oBd71Qwg=
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b/go.mod h1:SdK26z8/VhWtxaqCuQrufm80SELgowQPmu9T/8eUQ8g=
-github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b h1:MDZhTZTVDiydXcW5j4TA7HixVCyAdToIMPhHfJee7cE=
-github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b/go.mod h1:FTo/UWzNYgnQ082GI9QVM9HFDERqf9rw9RivNpqrnTs=
-github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231023191159-38919c4705e0 h1:/8pbFXhTSroJvjJMfJqfHjzoT9N8B4LUY3SbKruD5MM=
-github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231023191159-38919c4705e0/go.mod h1:My1SB4vZj42EgTDNJ/dgW8lUpLNmvtzu8f89J5y2kP0=
-github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231023190837-6e7b2cdfd4fd h1:hh5mAnnaZHOYAi4CIqR9K/mv786ex9AQgpisbJ4ZMow=
-github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231023190837-6e7b2cdfd4fd/go.mod h1:MK0SHfNicBmcaZb3qS3tA8NEJIWKNbcNtNNKuSDKqXY=
-github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1 h1:7ChiFHg4KsdS4mKjYpFUUNe9t9nsQzNtJ/XnUV2w5ZM=
-github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1/go.mod h1:jqbLYq4a/FwuiPBqFfkAwwxU8vs3+kReRq2/tyX5qRA=
+github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42 h1:OlDhgvJ48bZxcvTeebJ1b96xtNnJAddejd2Q4rlH1mU=
+github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42/go.mod h1:FTo/UWzNYgnQ082GI9QVM9HFDERqf9rw9RivNpqrnTs=
+github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231028104239-869296c43f26 h1:ZZs7IzdxrogQWGF1HfUUfR3KW8WhfxE4hUbfwZCDXFY=
+github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231028104239-869296c43f26/go.mod h1:aFS0dN6QgKGgZakGgEv57NOLw+pLGdEiGcfDZ3h9GL0=
+github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231028104044-69b02af0058d h1:0SVvkN04C+Ylc2puM/c77HuvRMmHRl0BkNjlZx1YWeA=
+github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231028104044-69b02af0058d/go.mod h1:WFa5hHen6fi3RBX4K6r4fzhGpoh+7KJVIyFztZHdM84=
+github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a h1:WLW4iaJAx4N9Pujv+gzHklnnjCt5MPrtXyVcK3UXdNc=
+github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a/go.mod h1:jqbLYq4a/FwuiPBqFfkAwwxU8vs3+kReRq2/tyX5qRA=
github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI=
github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
diff --git a/pkg/blockhandler/blockissuer.go b/pkg/blockhandler/blockissuer.go
index ed6c99f01..b712bab88 100644
--- a/pkg/blockhandler/blockissuer.go
+++ b/pkg/blockhandler/blockissuer.go
@@ -94,7 +94,7 @@ func (i *BlockHandler) SubmitBlockAndAwaitEvent(ctx context.Context, block *mode
}
}
-func (i *BlockHandler) AttachBlock(ctx context.Context, iotaBlock *iotago.ProtocolBlock) (iotago.BlockID, error) {
+func (i *BlockHandler) AttachBlock(ctx context.Context, iotaBlock *iotago.Block) (iotago.BlockID, error) {
modelBlock, err := model.BlockFromBlock(iotaBlock)
if err != nil {
return iotago.EmptyBlockID, ierrors.Wrap(err, "error serializing block to model block")
diff --git a/pkg/model/block.go b/pkg/model/block.go
index d5c212153..a41c491c0 100644
--- a/pkg/model/block.go
+++ b/pkg/model/block.go
@@ -11,45 +11,45 @@ import (
type Block struct {
blockID iotago.BlockID
- data []byte
- protocolBlock *iotago.ProtocolBlock
+ data []byte
+ block *iotago.Block
}
-func newBlock(blockID iotago.BlockID, iotaBlock *iotago.ProtocolBlock, data []byte) (*Block, error) {
+func newBlock(blockID iotago.BlockID, iotaBlock *iotago.Block, data []byte) (*Block, error) {
block := &Block{
- blockID: blockID,
- data: data,
- protocolBlock: iotaBlock,
+ blockID: blockID,
+ data: data,
+ block: iotaBlock,
}
return block, nil
}
-func BlockFromBlock(protocolBlock *iotago.ProtocolBlock, opts ...serix.Option) (*Block, error) {
- data, err := protocolBlock.API.Encode(protocolBlock, opts...)
+func BlockFromBlock(block *iotago.Block, opts ...serix.Option) (*Block, error) {
+ data, err := block.API.Encode(block, opts...)
if err != nil {
return nil, err
}
- blockID, err := protocolBlock.ID()
+ blockID, err := block.ID()
if err != nil {
return nil, err
}
- return newBlock(blockID, protocolBlock, data)
+ return newBlock(blockID, block, data)
}
func BlockFromIDAndBytes(blockID iotago.BlockID, data []byte, api iotago.API, opts ...serix.Option) (*Block, error) {
- protocolBlock := new(iotago.ProtocolBlock)
- if _, err := api.Decode(data, protocolBlock, opts...); err != nil {
+ block := new(iotago.Block)
+ if _, err := api.Decode(data, block, opts...); err != nil {
return nil, err
}
- return newBlock(blockID, protocolBlock, data)
+ return newBlock(blockID, block, data)
}
func BlockFromBytes(data []byte, apiProvider iotago.APIProvider) (*Block, error) {
- iotaBlock, _, err := iotago.ProtocolBlockFromBytes(apiProvider)(data)
+ iotaBlock, _, err := iotago.BlockFromBytes(apiProvider)(data)
if err != nil {
return nil, err
}
@@ -85,8 +85,8 @@ func (blk *Block) Bytes() ([]byte, error) {
return blk.data, nil
}
-func (blk *Block) ProtocolBlock() *iotago.ProtocolBlock {
- return blk.protocolBlock
+func (blk *Block) ProtocolBlock() *iotago.Block {
+ return blk.block
}
func (blk *Block) Payload() iotago.Payload {
@@ -109,18 +109,18 @@ func (blk *Block) SignedTransaction() (tx *iotago.SignedTransaction, isTransacti
return tx, isTransaction
}
-func (blk *Block) BasicBlock() (basicBlock *iotago.BasicBlock, isBasicBlock bool) {
- basicBlock, isBasicBlock = blk.ProtocolBlock().Block.(*iotago.BasicBlock)
+func (blk *Block) BasicBlock() (basicBlock *iotago.BasicBlockBody, isBasicBlock bool) {
+ basicBlock, isBasicBlock = blk.ProtocolBlock().Body.(*iotago.BasicBlockBody)
return basicBlock, isBasicBlock
}
-func (blk *Block) ValidationBlock() (validationBlock *iotago.ValidationBlock, isValidationBlock bool) {
- validationBlock, isValidationBlock = blk.ProtocolBlock().Block.(*iotago.ValidationBlock)
+func (blk *Block) ValidationBlock() (validationBlock *iotago.ValidationBlockBody, isValidationBlock bool) {
+ validationBlock, isValidationBlock = blk.ProtocolBlock().Body.(*iotago.ValidationBlockBody)
return validationBlock, isValidationBlock
}
func (blk *Block) String() string {
- encode, err := blk.protocolBlock.API.JSONEncode(blk.ProtocolBlock())
+ encode, err := blk.block.API.JSONEncode(blk.ProtocolBlock())
if err != nil {
panic(err)
}
diff --git a/pkg/model/signaled_block.go b/pkg/model/signaled_block.go
index e620b243d..c4bf457d4 100644
--- a/pkg/model/signaled_block.go
+++ b/pkg/model/signaled_block.go
@@ -15,10 +15,10 @@ type SignaledBlock struct {
ProtocolParametersHash iotago.Identifier `serix:"3"`
}
-func NewSignaledBlock(blockID iotago.BlockID, block *iotago.ProtocolBlock, validationBlock *iotago.ValidationBlock) *SignaledBlock {
+func NewSignaledBlock(blockID iotago.BlockID, block *iotago.Block, validationBlock *iotago.ValidationBlockBody) *SignaledBlock {
return &SignaledBlock{
ID: blockID,
- IssuingTime: block.IssuingTime,
+ IssuingTime: block.Header.IssuingTime,
HighestSupportedVersion: validationBlock.HighestSupportedVersion,
ProtocolParametersHash: validationBlock.ProtocolParametersHash,
}
diff --git a/pkg/network/protocols/core/protocol.go b/pkg/network/protocols/core/protocol.go
index d67ab7b06..0ced4c663 100644
--- a/pkg/network/protocols/core/protocol.go
+++ b/pkg/network/protocols/core/protocol.go
@@ -76,7 +76,7 @@ func (p *Protocol) SendAttestations(cm *model.Commitment, attestations []*iotago
encodedAttestations := marshalutil.New()
encodedAttestations.WriteUint32(uint32(len(attestations)))
for _, att := range attestations {
- iotagoAPI := lo.PanicOnErr(p.apiProvider.APIForVersion(att.ProtocolVersion))
+ iotagoAPI := lo.PanicOnErr(p.apiProvider.APIForVersion(att.Header.ProtocolVersion))
encodedAttestations.WriteBytes(lo.PanicOnErr(iotagoAPI.Encode(att)))
}
diff --git a/pkg/protocol/block_dispatcher.go b/pkg/protocol/block_dispatcher.go
index 4737fe5da..15b2fcfa3 100644
--- a/pkg/protocol/block_dispatcher.go
+++ b/pkg/protocol/block_dispatcher.go
@@ -67,7 +67,7 @@ func NewBlockDispatcher(protocol *Protocol, opts ...options.Option[BlockDispatch
// Dispatch dispatches the given block to the correct engine instance.
func (b *BlockDispatcher) Dispatch(block *model.Block, src peer.ID) error {
- slotCommitment := b.protocol.ChainManager.LoadCommitmentOrRequestMissing(block.ProtocolBlock().SlotCommitmentID)
+ slotCommitment := b.protocol.ChainManager.LoadCommitmentOrRequestMissing(block.ProtocolBlock().Header.SlotCommitmentID)
if !slotCommitment.SolidEvent().WasTriggered() {
if !b.unsolidCommitmentBlocks.Add(slotCommitment.ID(), types.NewTuple(block, src)) {
return ierrors.Errorf("failed to add block %s to unsolid commitment buffer", block.ID())
@@ -353,7 +353,7 @@ func (b *BlockDispatcher) inSyncWindow(engine *engine.Engine, block *model.Block
return true
}
- slotCommitmentID := block.ProtocolBlock().SlotCommitmentID
+ slotCommitmentID := block.ProtocolBlock().Header.SlotCommitmentID
latestCommitmentSlot := engine.Storage.Settings().LatestCommitment().Slot()
maxCommittableAge := engine.APIForSlot(slotCommitmentID.Slot()).ProtocolParameters().MaxCommittableAge()
diff --git a/pkg/protocol/commitment_verifier.go b/pkg/protocol/commitment_verifier.go
index 85e715d89..1315071e3 100644
--- a/pkg/protocol/commitment_verifier.go
+++ b/pkg/protocol/commitment_verifier.go
@@ -39,9 +39,9 @@ func (c *CommitmentVerifier) verifyCommitment(commitment *model.Commitment, atte
iotago.AccountID.Bytes,
iotago.AccountIDFromBytes,
func(attestation *iotago.Attestation) ([]byte, error) {
- apiForVersion, err := c.engine.APIForVersion(attestation.ProtocolVersion)
+ apiForVersion, err := c.engine.APIForVersion(attestation.Header.ProtocolVersion)
if err != nil {
- return nil, ierrors.Wrapf(err, "failed to get API for version %d", attestation.ProtocolVersion)
+ return nil, ierrors.Wrapf(err, "failed to get API for version %d", attestation.Header.ProtocolVersion)
}
return apiForVersion.Encode(attestation)
@@ -64,8 +64,8 @@ func (c *CommitmentVerifier) verifyCommitment(commitment *model.Commitment, atte
)
for _, att := range attestations {
- if err := tree.Set(att.IssuerID, att); err != nil {
- return nil, 0, ierrors.Wrapf(err, "failed to set attestation for issuerID %s", att.IssuerID)
+ if err := tree.Set(att.Header.IssuerID, att); err != nil {
+ return nil, 0, ierrors.Wrapf(err, "failed to set attestation for issuerID %s", att.Header.IssuerID)
}
}
if !iotago.VerifyProof(merkleProof, tree.Root(), commitment.RootsID()) {
@@ -119,11 +119,11 @@ func (c *CommitmentVerifier) verifyAttestations(attestations []*iotago.Attestati
// 1. The attestation might be fake.
// 2. The issuer might have added a new public key in the meantime, but we don't know about it yet
// since we only have the ledger state at the forking point.
- accountData, exists := c.validatorAccountsAtFork[att.IssuerID]
+ accountData, exists := c.validatorAccountsAtFork[att.Header.IssuerID]
// We always need to have the accountData for a validator.
if !exists {
- return nil, 0, ierrors.Errorf("accountData for issuerID %s does not exist", att.IssuerID)
+ return nil, 0, ierrors.Errorf("accountData for issuerID %s does not exist", att.Header.IssuerID)
}
switch signature := att.Signature.(type) {
@@ -147,8 +147,8 @@ func (c *CommitmentVerifier) verifyAttestations(attestations []*iotago.Attestati
}
// 3. A valid set of attestations can't contain multiple attestations from the same issuerID.
- if visitedIdentities.Has(att.IssuerID) {
- return nil, 0, ierrors.Errorf("issuerID %s contained in multiple attestations", att.IssuerID)
+ if visitedIdentities.Has(att.Header.IssuerID) {
+ return nil, 0, ierrors.Errorf("issuerID %s contained in multiple attestations", att.Header.IssuerID)
}
// TODO: this might differ if we have a Accounts with changing weights depending on the Slot/epoch
@@ -162,11 +162,11 @@ func (c *CommitmentVerifier) verifyAttestations(attestations []*iotago.Attestati
return nil, 0, ierrors.Errorf("committee for slot %d does not exist", attestationBlockID.Slot())
}
- if _, seatExists := committee.GetSeat(att.IssuerID); seatExists {
+ if _, seatExists := committee.GetSeat(att.Header.IssuerID); seatExists {
seatCount++
}
- visitedIdentities.Add(att.IssuerID)
+ visitedIdentities.Add(att.Header.IssuerID)
blockID, err := att.BlockID()
if err != nil {
diff --git a/pkg/protocol/engine/accounts/accountsledger/manager.go b/pkg/protocol/engine/accounts/accountsledger/manager.go
index 53459cb0c..0d47ec95a 100644
--- a/pkg/protocol/engine/accounts/accountsledger/manager.go
+++ b/pkg/protocol/engine/accounts/accountsledger/manager.go
@@ -98,7 +98,7 @@ func (m *Manager) TrackBlock(block *blocks.Block) {
if validationBlock, isValidationBlock := block.ValidationBlock(); isValidationBlock {
newSignaledBlock := model.NewSignaledBlock(block.ID(), block.ProtocolBlock(), validationBlock)
- m.latestSupportedVersionSignals.Get(block.ID().Slot(), true).Compute(block.ProtocolBlock().IssuerID, func(currentValue *model.SignaledBlock, exists bool) *model.SignaledBlock {
+ m.latestSupportedVersionSignals.Get(block.ID().Slot(), true).Compute(block.ProtocolBlock().Header.IssuerID, func(currentValue *model.SignaledBlock, exists bool) *model.SignaledBlock {
if !exists {
return newSignaledBlock
}
@@ -469,9 +469,9 @@ func (m *Manager) computeBlockBurnsForSlot(slot iotago.SlotIndex, rmc iotago.Man
return nil, ierrors.Errorf("cannot apply the new diff, block %s not found in the block cache", blockID)
}
if _, isBasicBlock := block.BasicBlock(); isBasicBlock {
- burns[block.ProtocolBlock().IssuerID] += iotago.Mana(block.WorkScore()) * rmc
+ burns[block.ProtocolBlock().Header.IssuerID] += iotago.Mana(block.WorkScore()) * rmc
} else if _, isValidationBlock := block.ValidationBlock(); isValidationBlock {
- validationBlockCount[block.ProtocolBlock().IssuerID]++
+ validationBlockCount[block.ProtocolBlock().Header.IssuerID]++
}
}
validationBlocksPerSlot := int(apiForSlot.ProtocolParameters().ValidationBlocksPerSlot())
diff --git a/pkg/protocol/engine/accounts/accountsledger/testsuite_test.go b/pkg/protocol/engine/accounts/accountsledger/testsuite_test.go
index b090c64c5..64d7f8152 100644
--- a/pkg/protocol/engine/accounts/accountsledger/testsuite_test.go
+++ b/pkg/protocol/engine/accounts/accountsledger/testsuite_test.go
@@ -190,7 +190,7 @@ func (t *TestSuite) ApplySlotActions(slot iotago.SlotIndex, rmc iotago.Mana, act
func (t *TestSuite) createBlockWithRMC(accountID iotago.AccountID, slot iotago.SlotIndex, rmc iotago.Mana) *blocks.Block {
innerBlock := tpkg.RandBasicBlockWithIssuerAndRMC(tpkg.TestAPI, accountID, rmc)
- innerBlock.IssuingTime = tpkg.TestAPI.TimeProvider().SlotStartTime(slot)
+ innerBlock.Header.IssuingTime = tpkg.TestAPI.TimeProvider().SlotStartTime(slot)
modelBlock, err := model.BlockFromBlock(innerBlock)
require.NoError(t.T, err)
diff --git a/pkg/protocol/engine/attestation/slotattestation/manager.go b/pkg/protocol/engine/attestation/slotattestation/manager.go
index 6b27b5b2d..437a00631 100644
--- a/pkg/protocol/engine/attestation/slotattestation/manager.go
+++ b/pkg/protocol/engine/attestation/slotattestation/manager.go
@@ -156,7 +156,7 @@ func (m *Manager) AddAttestationFromValidationBlock(block *blocks.Block) error {
return ierrors.Errorf("committee for slot %d does not exist", block.ID().Slot())
}
// Only track attestations of active committee members.
- if _, exists := committee.GetSeat(block.ProtocolBlock().IssuerID); !exists {
+ if _, exists := committee.GetSeat(block.ProtocolBlock().Header.IssuerID); !exists {
return nil
}
@@ -171,7 +171,7 @@ func (m *Manager) AddAttestationFromValidationBlock(block *blocks.Block) error {
newAttestation := iotago.NewAttestation(m.apiProvider.APIForSlot(block.ID().Slot()), block.ProtocolBlock())
// We keep only the latest attestation for each committee member.
- m.futureAttestations.Get(block.ID().Slot(), true).Compute(block.ProtocolBlock().IssuerID, func(currentValue *iotago.Attestation, exists bool) *iotago.Attestation {
+ m.futureAttestations.Get(block.ID().Slot(), true).Compute(block.ProtocolBlock().Header.IssuerID, func(currentValue *iotago.Attestation, exists bool) *iotago.Attestation {
if !exists {
return newAttestation
}
@@ -188,13 +188,13 @@ func (m *Manager) AddAttestationFromValidationBlock(block *blocks.Block) error {
}
func (m *Manager) applyToPendingAttestations(attestation *iotago.Attestation, cutoffSlot iotago.SlotIndex) {
- if attestation.SlotCommitmentID.Slot() < cutoffSlot {
+ if attestation.Header.SlotCommitmentID.Slot() < cutoffSlot {
return
}
updated := true
- updatedAttestation := m.pendingAttestations.Get(cutoffSlot, true).Compute(attestation.IssuerID, func(currentValue *iotago.Attestation, exists bool) *iotago.Attestation {
+ updatedAttestation := m.pendingAttestations.Get(cutoffSlot, true).Compute(attestation.Header.IssuerID, func(currentValue *iotago.Attestation, exists bool) *iotago.Attestation {
if !exists {
return attestation
}
@@ -214,8 +214,8 @@ func (m *Manager) applyToPendingAttestations(attestation *iotago.Attestation, cu
return
}
- for i := cutoffSlot; i <= updatedAttestation.SlotCommitmentID.Slot(); i++ {
- m.pendingAttestations.Get(i, true).Set(attestation.IssuerID, updatedAttestation)
+ for i := cutoffSlot; i <= updatedAttestation.Header.SlotCommitmentID.Slot(); i++ {
+ m.pendingAttestations.Get(i, true).Set(attestation.Header.IssuerID, updatedAttestation)
}
}
@@ -267,9 +267,9 @@ func (m *Manager) Commit(slot iotago.SlotIndex) (newCW uint64, attestationsRoot
for _, a := range attestations {
// TODO: which weight are we using here? The current one? Or the one of the slot of the attestation/commitmentID?
- if _, exists := committee.GetSeat(a.IssuerID); exists {
- if err := tree.Set(a.IssuerID, a); err != nil {
- return 0, iotago.Identifier{}, ierrors.Wrapf(err, "failed to set attestation %s in tree", a.IssuerID)
+ if _, exists := committee.GetSeat(a.Header.IssuerID); exists {
+ if err := tree.Set(a.Header.IssuerID, a); err != nil {
+ return 0, iotago.Identifier{}, ierrors.Wrapf(err, "failed to set attestation %s in tree", a.Header.IssuerID)
}
m.lastCumulativeWeight++
diff --git a/pkg/protocol/engine/attestation/slotattestation/snapshot.go b/pkg/protocol/engine/attestation/slotattestation/snapshot.go
index 12f70bd4a..ec2ae69fd 100644
--- a/pkg/protocol/engine/attestation/slotattestation/snapshot.go
+++ b/pkg/protocol/engine/attestation/slotattestation/snapshot.go
@@ -90,9 +90,9 @@ func (m *Manager) Export(writer io.WriteSeeker, targetSlot iotago.SlotIndex) err
if err = stream.WriteCollection(writer, func() (uint64, error) {
for _, a := range attestations {
- apiForVersion, err := m.apiProvider.APIForVersion(a.ProtocolVersion)
+ apiForVersion, err := m.apiProvider.APIForVersion(a.Header.ProtocolVersion)
if err != nil {
- return 0, ierrors.Wrapf(err, "failed to get API for version %d", a.ProtocolVersion)
+ return 0, ierrors.Wrapf(err, "failed to get API for version %d", a.Header.ProtocolVersion)
}
bytes, err := apiForVersion.Encode(a)
if err != nil {
diff --git a/pkg/protocol/engine/attestation/slotattestation/storage.go b/pkg/protocol/engine/attestation/slotattestation/storage.go
index b5c198e30..6f74e60c0 100644
--- a/pkg/protocol/engine/attestation/slotattestation/storage.go
+++ b/pkg/protocol/engine/attestation/slotattestation/storage.go
@@ -53,7 +53,7 @@ func (m *Manager) writeToDisk() error {
attestations := m.determineAttestationsFromWindow(i)
for _, a := range attestations {
- if err := storage.Set(a.IssuerID, a); err != nil {
+ if err := storage.Set(a.Header.IssuerID, a); err != nil {
return ierrors.Wrapf(err, "failed to set attestation %v", a)
}
}
diff --git a/pkg/protocol/engine/blockdag/inmemoryblockdag/blockdag.go b/pkg/protocol/engine/blockdag/inmemoryblockdag/blockdag.go
index b368f1278..6fe5944b0 100644
--- a/pkg/protocol/engine/blockdag/inmemoryblockdag/blockdag.go
+++ b/pkg/protocol/engine/blockdag/inmemoryblockdag/blockdag.go
@@ -48,7 +48,7 @@ func NewProvider(opts ...options.Option[BlockDAG]) module.Provider[*engine.Engin
e.Events.Filter.BlockPreAllowed.Hook(func(block *model.Block) {
if _, _, err := b.Attach(block); err != nil {
- b.errorHandler(ierrors.Wrapf(err, "failed to attach block with %s (issuerID: %s)", block.ID(), block.ProtocolBlock().IssuerID))
+ b.errorHandler(ierrors.Wrapf(err, "failed to attach block with %s (issuerID: %s)", block.ID(), block.ProtocolBlock().Header.IssuerID))
}
}, event.WithWorkerPool(wp))
@@ -188,7 +188,7 @@ func (b *BlockDAG) attach(data *model.Block) (block *blocks.Block, wasAttached b
func (b *BlockDAG) shouldAttach(data *model.Block) (shouldAttach bool, err error) {
if b.evictionState.InRootBlockSlot(data.ID()) && !b.evictionState.IsRootBlock(data.ID()) {
b.retainBlockFailure(data.ID(), apimodels.BlockFailureIsTooOld)
- return false, ierrors.Errorf("block data with %s is too old (issued at: %s)", data.ID(), data.ProtocolBlock().IssuingTime)
+ return false, ierrors.Errorf("block data with %s is too old (issued at: %s)", data.ID(), data.ProtocolBlock().Header.IssuingTime)
}
storedBlock, storedBlockExists := b.blockCache.Block(data.ID())
diff --git a/pkg/protocol/engine/blocks/block.go b/pkg/protocol/engine/blocks/block.go
index 33de43b2e..10df6cbb5 100644
--- a/pkg/protocol/engine/blocks/block.go
+++ b/pkg/protocol/engine/blocks/block.go
@@ -139,7 +139,7 @@ func NewMissingBlock(blockID iotago.BlockID) *Block {
}
}
-func (b *Block) ProtocolBlock() *iotago.ProtocolBlock {
+func (b *Block) ProtocolBlock() *iotago.Block {
if b.modelBlock == nil {
return nil
}
@@ -152,7 +152,7 @@ func (b *Block) Parents() (parents []iotago.BlockID) {
}
func (b *Block) StrongParents() (parents []iotago.BlockID) {
- return b.modelBlock.ProtocolBlock().Block.StrongParentIDs()
+ return b.modelBlock.ProtocolBlock().Body.StrongParentIDs()
}
// ParentsWithType returns the parents of the block with their type.
@@ -185,7 +185,7 @@ func (b *Block) SignedTransaction() (tx *iotago.SignedTransaction, hasTransactio
return b.modelBlock.SignedTransaction()
}
-func (b *Block) BasicBlock() (basicBlock *iotago.BasicBlock, isBasicBlock bool) {
+func (b *Block) BasicBlock() (basicBlock *iotago.BasicBlockBody, isBasicBlock bool) {
if b.modelBlock == nil {
return nil, false
}
@@ -193,7 +193,7 @@ func (b *Block) BasicBlock() (basicBlock *iotago.BasicBlock, isBasicBlock bool)
return b.modelBlock.BasicBlock()
}
-func (b *Block) ValidationBlock() (validationBlock *iotago.ValidationBlock, isValidationBlock bool) {
+func (b *Block) ValidationBlock() (validationBlock *iotago.ValidationBlockBody, isValidationBlock bool) {
if b.modelBlock == nil {
return nil, false
}
@@ -232,7 +232,7 @@ func (b *Block) IssuingTime() time.Time {
return b.rootBlock.issuingTime
}
- return b.modelBlock.ProtocolBlock().IssuingTime
+ return b.modelBlock.ProtocolBlock().Header.IssuingTime
}
func (b *Block) SlotCommitmentID() iotago.CommitmentID {
@@ -247,7 +247,7 @@ func (b *Block) SlotCommitmentID() iotago.CommitmentID {
return b.rootBlock.commitmentID
}
- return b.modelBlock.ProtocolBlock().SlotCommitmentID
+ return b.modelBlock.ProtocolBlock().Header.SlotCommitmentID
}
// IsMissing returns a flag that indicates if the underlying Block data hasn't been stored, yet.
diff --git a/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter.go b/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter.go
index 2b0f878c9..a088c3d88 100644
--- a/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter.go
+++ b/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter.go
@@ -65,11 +65,11 @@ func (c *CommitmentFilter) ProcessPreFilteredBlock(block *blocks.Block) {
func (c *CommitmentFilter) evaluateBlock(block *blocks.Block) {
// check if the account exists in the specified slot.
- accountData, exists, err := c.accountRetrieveFunc(block.ProtocolBlock().IssuerID, block.SlotCommitmentID().Slot())
+ accountData, exists, err := c.accountRetrieveFunc(block.ProtocolBlock().Header.IssuerID, block.SlotCommitmentID().Slot())
if err != nil {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
- Reason: ierrors.Join(iotago.ErrIssuerAccountNotFound, ierrors.Wrapf(err, "could not retrieve account information for block issuer %s", block.ProtocolBlock().IssuerID)),
+ Reason: ierrors.Join(iotago.ErrIssuerAccountNotFound, ierrors.Wrapf(err, "could not retrieve account information for block issuer %s", block.ProtocolBlock().Header.IssuerID)),
})
return
@@ -77,22 +77,22 @@ func (c *CommitmentFilter) evaluateBlock(block *blocks.Block) {
if !exists {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
- Reason: ierrors.Join(iotago.ErrIssuerAccountNotFound, ierrors.Errorf("block issuer account %s does not exist in slot commitment %s", block.ProtocolBlock().IssuerID, block.ProtocolBlock().SlotCommitmentID.Slot())),
+ Reason: ierrors.Join(iotago.ErrIssuerAccountNotFound, ierrors.Errorf("block issuer account %s does not exist in slot commitment %s", block.ProtocolBlock().Header.IssuerID, block.ProtocolBlock().Header.SlotCommitmentID.Slot())),
})
return
}
// get the api for the block
- blockAPI, err := c.apiProvider.APIForVersion(block.ProtocolBlock().BlockHeader.ProtocolVersion)
+ blockAPI, err := c.apiProvider.APIForVersion(block.ProtocolBlock().Header.ProtocolVersion)
if err != nil {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
- Reason: ierrors.Join(iotago.ErrBlockVersionInvalid, ierrors.Wrapf(err, "could not retrieve API for block version %d", block.ProtocolBlock().BlockHeader.ProtocolVersion)),
+ Reason: ierrors.Join(iotago.ErrBlockVersionInvalid, ierrors.Wrapf(err, "could not retrieve API for block version %d", block.ProtocolBlock().Header.ProtocolVersion)),
})
}
// check that the block burns sufficient Mana, use slot index of the commitment
- rmcSlot := block.ProtocolBlock().SlotCommitmentID.Slot()
+ rmcSlot := block.ProtocolBlock().Header.SlotCommitmentID.Slot()
rmc, err := c.rmcRetrieveFunc(rmcSlot)
if err != nil {
@@ -114,7 +114,7 @@ func (c *CommitmentFilter) evaluateBlock(block *blocks.Block) {
if basicBlock.MaxBurnedMana < manaCost {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
- Reason: ierrors.Join(iotago.ErrBurnedInsufficientMana, ierrors.Errorf("block issuer account %s burned insufficient Mana, required %d, burned %d", block.ProtocolBlock().IssuerID, manaCost, basicBlock.MaxBurnedMana)),
+ Reason: ierrors.Join(iotago.ErrBurnedInsufficientMana, ierrors.Errorf("block issuer account %s burned insufficient Mana, required %d, burned %d", block.ProtocolBlock().Header.IssuerID, manaCost, basicBlock.MaxBurnedMana)),
})
return
@@ -125,17 +125,17 @@ func (c *CommitmentFilter) evaluateBlock(block *blocks.Block) {
if accountData.Credits.Value < 0 {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
- Reason: ierrors.Wrapf(iotago.ErrNegativeBIC, "block issuer account %s is locked due to negative BIC", block.ProtocolBlock().IssuerID),
+ Reason: ierrors.Wrapf(iotago.ErrNegativeBIC, "block issuer account %s is locked due to negative BIC", block.ProtocolBlock().Header.IssuerID),
})
return
}
// Check that the account is not expired
- if accountData.ExpirySlot < block.ProtocolBlock().SlotCommitmentID.Slot() {
+ if accountData.ExpirySlot < block.ProtocolBlock().Header.SlotCommitmentID.Slot() {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
- Reason: ierrors.Wrapf(iotago.ErrAccountExpired, "block issuer account %s is expired, expiry slot %d in commitment %d", block.ProtocolBlock().IssuerID, accountData.ExpirySlot, block.ProtocolBlock().SlotCommitmentID.Slot()),
+ Reason: ierrors.Wrapf(iotago.ErrAccountExpired, "block issuer account %s is expired, expiry slot %d in commitment %d", block.ProtocolBlock().Header.IssuerID, accountData.ExpirySlot, block.ProtocolBlock().Header.SlotCommitmentID.Slot()),
})
return
@@ -155,7 +155,7 @@ func (c *CommitmentFilter) evaluateBlock(block *blocks.Block) {
if !isBikPubKeyHash || bikPubKeyHash.PublicKeyHash != iotago.Ed25519PublicKeyHashBlockIssuerKeyFromPublicKey(signature.PublicKey[:]).PublicKeyHash {
c.events.BlockFiltered.Trigger(&commitmentfilter.BlockFilteredEvent{
Block: block,
- Reason: ierrors.Wrapf(iotago.ErrInvalidSignature, "block issuer account %s does not have block issuer key corresponding to public key %s in slot %d", block.ProtocolBlock().IssuerID, signature.PublicKey, block.ProtocolBlock().SlotCommitmentID.Index()),
+ Reason: ierrors.Wrapf(iotago.ErrInvalidSignature, "block issuer account %s does not have block issuer key corresponding to public key %s in slot %d", block.ProtocolBlock().Header.IssuerID, signature.PublicKey, block.ProtocolBlock().Header.SlotCommitmentID.Index()),
})
return
diff --git a/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter_test.go b/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter_test.go
index dfb7c02a6..127c5fb1c 100644
--- a/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter_test.go
+++ b/pkg/protocol/engine/commitmentfilter/accountsfilter/commitmentfilter_test.go
@@ -85,7 +85,7 @@ func (t *TestFramework) AddRMCData(slot iotago.SlotIndex, rmcData iotago.Mana) {
// q: how to get an engine block.Block from protocol block
-func (t *TestFramework) processBlock(alias string, block *iotago.ProtocolBlock) {
+func (t *TestFramework) processBlock(alias string, block *iotago.Block) {
modelBlock, err := model.BlockFromBlock(block)
require.NoError(t.Test, err)
diff --git a/pkg/protocol/engine/congestioncontrol/scheduler/drr/drrbuffer.go b/pkg/protocol/engine/congestioncontrol/scheduler/drr/drrbuffer.go
index 3ae38379a..86dc0dac6 100644
--- a/pkg/protocol/engine/congestioncontrol/scheduler/drr/drrbuffer.go
+++ b/pkg/protocol/engine/congestioncontrol/scheduler/drr/drrbuffer.go
@@ -156,7 +156,7 @@ func (b *BufferQueue) Submit(blk *blocks.Block, issuerQueue *IssuerQueue, quantu
// Unsubmit removes a block from the submitted blocks.
// If that block is already marked as ready, Unsubmit has no effect.
func (b *BufferQueue) Unsubmit(block *blocks.Block) bool {
- issuerID := block.ProtocolBlock().IssuerID
+ issuerID := block.ProtocolBlock().Header.IssuerID
issuerQueue := b.IssuerQueue(issuerID)
if issuerQueue == nil {
@@ -174,7 +174,7 @@ func (b *BufferQueue) Unsubmit(block *blocks.Block) bool {
// Ready marks a previously submitted block as ready to be scheduled.
func (b *BufferQueue) Ready(block *blocks.Block) bool {
- issuerQueue := b.IssuerQueue(block.ProtocolBlock().IssuerID)
+ issuerQueue := b.IssuerQueue(block.ProtocolBlock().Header.IssuerID)
if issuerQueue == nil {
return false
}
diff --git a/pkg/protocol/engine/congestioncontrol/scheduler/drr/issuerqueue.go b/pkg/protocol/engine/congestioncontrol/scheduler/drr/issuerqueue.go
index 6b26acbc5..80fc750b9 100644
--- a/pkg/protocol/engine/congestioncontrol/scheduler/drr/issuerqueue.go
+++ b/pkg/protocol/engine/congestioncontrol/scheduler/drr/issuerqueue.go
@@ -61,7 +61,7 @@ func (q *IssuerQueue) IssuerID() iotago.AccountID {
// Submit submits a block for the queue.
func (q *IssuerQueue) Submit(element *blocks.Block) bool {
// this is just a debugging check, it will never happen in practice
- if blkIssuerID := element.ProtocolBlock().IssuerID; q.issuerID != blkIssuerID {
+ if blkIssuerID := element.ProtocolBlock().Header.IssuerID; q.issuerID != blkIssuerID {
panic(fmt.Sprintf("issuerqueue: queue issuer ID(%x) and issuer ID(%x) does not match.", q.issuerID, blkIssuerID))
}
diff --git a/pkg/protocol/engine/congestioncontrol/scheduler/drr/scheduler.go b/pkg/protocol/engine/congestioncontrol/scheduler/drr/scheduler.go
index 37ba9de2a..917787009 100644
--- a/pkg/protocol/engine/congestioncontrol/scheduler/drr/scheduler.go
+++ b/pkg/protocol/engine/congestioncontrol/scheduler/drr/scheduler.go
@@ -250,7 +250,7 @@ func (s *Scheduler) enqueueBasicBlock(block *blocks.Block) {
slot := s.latestCommittedSlot()
- issuerID := block.ProtocolBlock().IssuerID
+ issuerID := block.ProtocolBlock().Header.IssuerID
issuerQueue := s.getOrCreateIssuer(issuerID)
droppedBlocks, submitted := s.basicBuffer.Submit(
@@ -286,9 +286,9 @@ func (s *Scheduler) enqueueValidationBlock(block *blocks.Block) {
s.bufferMutex.Lock()
defer s.bufferMutex.Unlock()
- _, exists := s.validatorBuffer.Get(block.ProtocolBlock().IssuerID)
+ _, exists := s.validatorBuffer.Get(block.ProtocolBlock().Header.IssuerID)
if !exists {
- s.addValidator(block.ProtocolBlock().IssuerID)
+ s.addValidator(block.ProtocolBlock().Header.IssuerID)
}
droppedBlock, submitted := s.validatorBuffer.Submit(block, int(s.apiProvider.CommittedAPI().ProtocolParameters().CongestionControlParameters().MaxValidationBufferSize))
if !submitted {
@@ -468,7 +468,7 @@ func (s *Scheduler) selectBasicBlockWithoutLocking() {
// remove the block from the buffer and adjust issuer's deficit
block := s.basicBuffer.PopFront()
- issuerID := block.ProtocolBlock().IssuerID
+ issuerID := block.ProtocolBlock().Header.IssuerID
if _, err := s.updateDeficit(issuerID, -s.deficitFromWork(block.WorkScore())); err != nil {
// if something goes wrong with deficit update, drop the block instead of scheduling it.
block.SetDropped()
@@ -502,7 +502,7 @@ func (s *Scheduler) selectIssuer(start *IssuerQueue, slot iotago.SlotIndex) (Def
continue
}
- issuerID := block.ProtocolBlock().IssuerID
+ issuerID := block.ProtocolBlock().Header.IssuerID
// compute how often the deficit needs to be incremented until the block can be scheduled
deficit, exists := s.deficits.Get(issuerID)
@@ -672,7 +672,7 @@ func (s *Scheduler) ready(block *blocks.Block) {
}
func (s *Scheduler) readyValidationBlock(block *blocks.Block) {
- if validatorQueue, exists := s.validatorBuffer.Get(block.ProtocolBlock().IssuerID); exists {
+ if validatorQueue, exists := s.validatorBuffer.Get(block.ProtocolBlock().Header.IssuerID); exists {
validatorQueue.Ready(block)
}
}
diff --git a/pkg/protocol/engine/congestioncontrol/scheduler/drr/validatorqueue.go b/pkg/protocol/engine/congestioncontrol/scheduler/drr/validatorqueue.go
index 8d2fd0aaf..900262b82 100644
--- a/pkg/protocol/engine/congestioncontrol/scheduler/drr/validatorqueue.go
+++ b/pkg/protocol/engine/congestioncontrol/scheduler/drr/validatorqueue.go
@@ -53,7 +53,7 @@ func (q *ValidatorQueue) AccountID() iotago.AccountID {
}
func (q *ValidatorQueue) Submit(block *blocks.Block, maxBuffer int) (*blocks.Block, bool) {
- if blkAccountID := block.ProtocolBlock().IssuerID; q.accountID != blkAccountID {
+ if blkAccountID := block.ProtocolBlock().Header.IssuerID; q.accountID != blkAccountID {
panic(fmt.Sprintf("issuerqueue: queue issuer ID(%x) and issuer ID(%x) does not match.", q.accountID, blkAccountID))
}
@@ -202,7 +202,7 @@ func (b *ValidatorBuffer) Set(accountID iotago.AccountID, validatorQueue *Valida
}
func (b *ValidatorBuffer) Submit(block *blocks.Block, maxBuffer int) (*blocks.Block, bool) {
- validatorQueue, exists := b.buffer.Get(block.ProtocolBlock().IssuerID)
+ validatorQueue, exists := b.buffer.Get(block.ProtocolBlock().Header.IssuerID)
if !exists {
return nil, false
}
diff --git a/pkg/protocol/engine/consensus/blockgadget/thresholdblockgadget/gadget.go b/pkg/protocol/engine/consensus/blockgadget/thresholdblockgadget/gadget.go
index 9ee2becde..3e973f7c6 100644
--- a/pkg/protocol/engine/consensus/blockgadget/thresholdblockgadget/gadget.go
+++ b/pkg/protocol/engine/consensus/blockgadget/thresholdblockgadget/gadget.go
@@ -109,7 +109,7 @@ func (g *Gadget) isCommitteeValidationBlock(block *blocks.Block) (seat account.S
}
// Only accept blocks for issuers that are part of the committee.
- return committee.GetSeat(block.ProtocolBlock().IssuerID)
+ return committee.GetSeat(block.ProtocolBlock().Header.IssuerID)
}
func anyChildInSet(block *blocks.Block, set ds.Set[iotago.BlockID]) bool {
diff --git a/pkg/protocol/engine/consensus/slotgadget/totalweightslotgadget/gadget.go b/pkg/protocol/engine/consensus/slotgadget/totalweightslotgadget/gadget.go
index ed1e4fae8..9dd33e104 100644
--- a/pkg/protocol/engine/consensus/slotgadget/totalweightslotgadget/gadget.go
+++ b/pkg/protocol/engine/consensus/slotgadget/totalweightslotgadget/gadget.go
@@ -99,7 +99,7 @@ func (g *Gadget) trackVotes(block *blocks.Block) {
return slottracker.NewSlotTracker()
})
- prevLatestSlot, latestSlot, updated := tracker.TrackVotes(block.SlotCommitmentID().Slot(), block.ProtocolBlock().IssuerID, g.lastFinalizedSlot)
+ prevLatestSlot, latestSlot, updated := tracker.TrackVotes(block.SlotCommitmentID().Slot(), block.ProtocolBlock().Header.IssuerID, g.lastFinalizedSlot)
if !updated {
return nil
}
diff --git a/pkg/protocol/engine/engine.go b/pkg/protocol/engine/engine.go
index 1bb299aa8..1cee3527b 100644
--- a/pkg/protocol/engine/engine.go
+++ b/pkg/protocol/engine/engine.go
@@ -443,7 +443,7 @@ func (e *Engine) setupEvictionState() {
e.errorHandler(ierrors.Errorf("cannot store root block (%s) because it is missing", parent.ID))
return
}
- e.EvictionState.AddRootBlock(parentBlock.ID(), parentBlock.ProtocolBlock().SlotCommitmentID)
+ e.EvictionState.AddRootBlock(parentBlock.ID(), parentBlock.ProtocolBlock().Header.SlotCommitmentID)
}
})
}, event.WithWorkerPool(wp))
diff --git a/pkg/protocol/engine/filter/blockfilter/filter.go b/pkg/protocol/engine/filter/blockfilter/filter.go
index 0ed6900ec..77950c5c3 100644
--- a/pkg/protocol/engine/filter/blockfilter/filter.go
+++ b/pkg/protocol/engine/filter/blockfilter/filter.go
@@ -68,10 +68,10 @@ func New(apiProvider iotago.APIProvider, opts ...options.Option[Filter]) *Filter
func (f *Filter) ProcessReceivedBlock(block *model.Block, source peer.ID) {
// Verify the block's version corresponds to the protocol version for the slot.
apiForSlot := f.apiProvider.APIForSlot(block.ID().Slot())
- if apiForSlot.Version() != block.ProtocolBlock().ProtocolVersion {
+ if apiForSlot.Version() != block.ProtocolBlock().Header.ProtocolVersion {
f.events.BlockPreFiltered.Trigger(&filter.BlockPreFilteredEvent{
Block: block,
- Reason: ierrors.Wrapf(ErrInvalidBlockVersion, "invalid protocol version %d (expected %d) for epoch %d", block.ProtocolBlock().ProtocolVersion, apiForSlot.Version(), apiForSlot.TimeProvider().EpochFromSlot(block.ID().Slot())),
+ Reason: ierrors.Wrapf(ErrInvalidBlockVersion, "invalid protocol version %d (expected %d) for epoch %d", block.ProtocolBlock().Header.ProtocolVersion, apiForSlot.Version(), apiForSlot.TimeProvider().EpochFromSlot(block.ID().Slot())),
Source: source,
})
@@ -79,7 +79,7 @@ func (f *Filter) ProcessReceivedBlock(block *model.Block, source peer.ID) {
}
// Verify the timestamp is not too far in the future.
- timeDelta := time.Since(block.ProtocolBlock().IssuingTime)
+ timeDelta := time.Since(block.ProtocolBlock().Header.IssuingTime)
if timeDelta < -f.optsMaxAllowedWallClockDrift {
f.events.BlockPreFiltered.Trigger(&filter.BlockPreFilteredEvent{
Block: block,
@@ -91,7 +91,7 @@ func (f *Filter) ProcessReceivedBlock(block *model.Block, source peer.ID) {
}
if _, isValidation := block.ValidationBlock(); isValidation {
- blockSlot := block.ProtocolBlock().API.TimeProvider().SlotFromTime(block.ProtocolBlock().IssuingTime)
+ blockSlot := block.ProtocolBlock().API.TimeProvider().SlotFromTime(block.ProtocolBlock().Header.IssuingTime)
committee, exists := f.committeeFunc(blockSlot)
if !exists {
f.events.BlockPreFiltered.Trigger(&filter.BlockPreFilteredEvent{
@@ -103,10 +103,10 @@ func (f *Filter) ProcessReceivedBlock(block *model.Block, source peer.ID) {
return
}
- if !committee.HasAccount(block.ProtocolBlock().IssuerID) {
+ if !committee.HasAccount(block.ProtocolBlock().Header.IssuerID) {
f.events.BlockPreFiltered.Trigger(&filter.BlockPreFilteredEvent{
Block: block,
- Reason: ierrors.Wrapf(ErrValidatorNotInCommittee, "validation block issuer %s is not part of the committee for slot %d", block.ProtocolBlock().IssuerID, blockSlot),
+ Reason: ierrors.Wrapf(ErrValidatorNotInCommittee, "validation block issuer %s is not part of the committee for slot %d", block.ProtocolBlock().Header.IssuerID, blockSlot),
Source: source,
})
diff --git a/pkg/protocol/engine/filter/blockfilter/filter_test.go b/pkg/protocol/engine/filter/blockfilter/filter_test.go
index 02646bb56..6f1b4bdc4 100644
--- a/pkg/protocol/engine/filter/blockfilter/filter_test.go
+++ b/pkg/protocol/engine/filter/blockfilter/filter_test.go
@@ -44,7 +44,7 @@ func NewTestFramework(t *testing.T, apiProvider iotago.APIProvider, optsFilter .
return tf
}
-func (t *TestFramework) processBlock(alias string, block *iotago.ProtocolBlock) error {
+func (t *TestFramework) processBlock(alias string, block *iotago.Block) error {
modelBlock, err := model.BlockFromBlock(block, serix.WithValidation())
if err != nil {
return err
diff --git a/pkg/protocol/engine/ledger/ledger/ledger.go b/pkg/protocol/engine/ledger/ledger/ledger.go
index a6c177204..31632f082 100644
--- a/pkg/protocol/engine/ledger/ledger/ledger.go
+++ b/pkg/protocol/engine/ledger/ledger/ledger.go
@@ -746,14 +746,14 @@ func (l *Ledger) resolveState(stateRef mempool.StateReference) *promise.Promise[
}
func (l *Ledger) blockPreAccepted(block *blocks.Block) {
- voteRank := ledger.NewBlockVoteRank(block.ID(), block.ProtocolBlock().IssuingTime)
+ voteRank := ledger.NewBlockVoteRank(block.ID(), block.ProtocolBlock().Header.IssuingTime)
committee, exists := l.sybilProtection.SeatManager().CommitteeInSlot(block.ID().Slot())
if !exists {
panic("committee should exist because we pre-accepted the block")
}
- seat, exists := committee.GetSeat(block.ProtocolBlock().IssuerID)
+ seat, exists := committee.GetSeat(block.ProtocolBlock().Header.IssuerID)
if !exists {
return
}
diff --git a/pkg/protocol/engine/upgrade/signalingupgradeorchestrator/orchestrator.go b/pkg/protocol/engine/upgrade/signalingupgradeorchestrator/orchestrator.go
index 4e5ee6026..bca67f268 100644
--- a/pkg/protocol/engine/upgrade/signalingupgradeorchestrator/orchestrator.go
+++ b/pkg/protocol/engine/upgrade/signalingupgradeorchestrator/orchestrator.go
@@ -151,7 +151,7 @@ func (o *Orchestrator) TrackValidationBlock(block *blocks.Block) {
return
}
- seat, exists := committee.GetSeat(block.ProtocolBlock().IssuerID)
+ seat, exists := committee.GetSeat(block.ProtocolBlock().Header.IssuerID)
if !exists {
return
}
diff --git a/pkg/protocol/sybilprotection/seatmanager/poa/poa.go b/pkg/protocol/sybilprotection/seatmanager/poa/poa.go
index 8a0256e61..d73ce7191 100644
--- a/pkg/protocol/sybilprotection/seatmanager/poa/poa.go
+++ b/pkg/protocol/sybilprotection/seatmanager/poa/poa.go
@@ -66,9 +66,9 @@ func NewProvider(opts ...options.Option[SeatManager]) module.Provider[*engine.En
panic(ierrors.Errorf("committee not selected for slot %d, but received block in that slot", block.ID().Slot()))
}
- seat, exists := committee.GetSeat(block.ProtocolBlock().IssuerID)
+ seat, exists := committee.GetSeat(block.ProtocolBlock().Header.IssuerID)
if exists {
- s.activityTracker.MarkSeatActive(seat, block.ProtocolBlock().IssuerID, block.IssuingTime())
+ s.activityTracker.MarkSeatActive(seat, block.ProtocolBlock().Header.IssuerID, block.IssuingTime())
}
s.events.BlockProcessed.Trigger(block)
diff --git a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go
index 5d85f85bf..4d572c888 100644
--- a/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go
+++ b/pkg/protocol/sybilprotection/seatmanager/topstakers/topstakers.go
@@ -67,9 +67,9 @@ func NewProvider(opts ...options.Option[SeatManager]) module.Provider[*engine.En
panic(ierrors.Errorf("committee not selected for slot %d, but received block in that slot", block.ID().Slot()))
}
- seat, exists := committee.GetSeat(block.ProtocolBlock().IssuerID)
+ seat, exists := committee.GetSeat(block.ProtocolBlock().Header.IssuerID)
if exists {
- s.activityTracker.MarkSeatActive(seat, block.ProtocolBlock().IssuerID, block.IssuingTime())
+ s.activityTracker.MarkSeatActive(seat, block.ProtocolBlock().Header.IssuerID, block.IssuingTime())
}
s.events.BlockProcessed.Trigger(block)
diff --git a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go
index 37f061d5d..a798ff647 100644
--- a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go
+++ b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/performance.go
@@ -64,9 +64,9 @@ func (t *Tracker) TrackValidationBlock(block *blocks.Block) {
t.performanceFactorsMutex.Lock()
defer t.performanceFactorsMutex.Unlock()
- isCommitteeMember, err := t.isCommitteeMember(block.ID().Slot(), block.ProtocolBlock().IssuerID)
+ isCommitteeMember, err := t.isCommitteeMember(block.ID().Slot(), block.ProtocolBlock().Header.IssuerID)
if err != nil {
- t.errHandler(ierrors.Wrapf(err, "error while checking if account %s is a committee member in slot %d", block.ProtocolBlock().IssuerID, block.ID().Slot()))
+ t.errHandler(ierrors.Wrapf(err, "error while checking if account %s is a committee member in slot %d", block.ProtocolBlock().Header.IssuerID, block.ID().Slot()))
return
}
@@ -87,7 +87,7 @@ func (t *Tracker) TrackCandidateBlock(block *blocks.Block) {
}
var rollback bool
- t.nextEpochCommitteeCandidates.Compute(block.ProtocolBlock().IssuerID, func(currentValue iotago.SlotIndex, exists bool) iotago.SlotIndex {
+ t.nextEpochCommitteeCandidates.Compute(block.ProtocolBlock().Header.IssuerID, func(currentValue iotago.SlotIndex, exists bool) iotago.SlotIndex {
if !exists || currentValue > block.ID().Slot() {
committeeCandidatesStore, err := t.committeeCandidatesInEpochFunc(blockEpoch)
if err != nil {
@@ -100,7 +100,7 @@ func (t *Tracker) TrackCandidateBlock(block *blocks.Block) {
return currentValue
}
- err = committeeCandidatesStore.Set(block.ProtocolBlock().IssuerID[:], block.ID().Slot().MustBytes())
+ err = committeeCandidatesStore.Set(block.ProtocolBlock().Header.IssuerID[:], block.ID().Slot().MustBytes())
if err != nil {
// if there is an error, and we don't register a candidate, then we might eventually create a different commitment
t.errHandler(ierrors.Wrapf(err, "error while updating candidate activity for epoch %d", blockEpoch))
@@ -120,7 +120,7 @@ func (t *Tracker) TrackCandidateBlock(block *blocks.Block) {
// if there was an error when computing the value,
// and it was the first entry for the given issuer, then remove the entry
if rollback {
- t.nextEpochCommitteeCandidates.Delete(block.ProtocolBlock().IssuerID)
+ t.nextEpochCommitteeCandidates.Delete(block.ProtocolBlock().Header.IssuerID)
}
}
@@ -313,7 +313,7 @@ func (t *Tracker) isCommitteeMember(slot iotago.SlotIndex, accountID iotago.Acco
return committee.Has(accountID), nil
}
-func (t *Tracker) trackCommitteeMemberPerformance(validationBlock *iotago.ValidationBlock, block *blocks.Block) {
+func (t *Tracker) trackCommitteeMemberPerformance(validationBlock *iotago.ValidationBlockBody, block *blocks.Block) {
validatorPerformances, err := t.validatorPerformancesFunc(block.ID().Slot())
if err != nil {
t.errHandler(ierrors.Errorf("failed to load performance factor for slot %s", block.ID().Slot()))
@@ -321,9 +321,9 @@ func (t *Tracker) trackCommitteeMemberPerformance(validationBlock *iotago.Valida
return
}
- validatorPerformance, err := validatorPerformances.Load(block.ProtocolBlock().IssuerID)
+ validatorPerformance, err := validatorPerformances.Load(block.ProtocolBlock().Header.IssuerID)
if err != nil {
- t.errHandler(ierrors.Errorf("failed to load performance factor for account %s", block.ProtocolBlock().IssuerID))
+ t.errHandler(ierrors.Errorf("failed to load performance factor for account %s", block.ProtocolBlock().Header.IssuerID))
return
}
@@ -334,7 +334,7 @@ func (t *Tracker) trackCommitteeMemberPerformance(validationBlock *iotago.Valida
}
// set a bit at subslotIndex to 1 to indicate activity in that subslot
- validatorPerformance.SlotActivityVector = validatorPerformance.SlotActivityVector | (1 << t.subslotIndex(block.ID().Slot(), block.ProtocolBlock().IssuingTime))
+ validatorPerformance.SlotActivityVector = validatorPerformance.SlotActivityVector | (1 << t.subslotIndex(block.ID().Slot(), block.ProtocolBlock().Header.IssuingTime))
apiForSlot := t.apiProvider.APIForSlot(block.ID().Slot())
@@ -349,8 +349,8 @@ func (t *Tracker) trackCommitteeMemberPerformance(validationBlock *iotago.Valida
Hash: validationBlock.ProtocolParametersHash,
}
- if err = validatorPerformances.Store(block.ProtocolBlock().IssuerID, validatorPerformance); err != nil {
- t.errHandler(ierrors.Errorf("failed to store performance factor for account %s", block.ProtocolBlock().IssuerID))
+ if err = validatorPerformances.Store(block.ProtocolBlock().Header.IssuerID, validatorPerformance); err != nil {
+ t.errHandler(ierrors.Errorf("failed to store performance factor for account %s", block.ProtocolBlock().Header.IssuerID))
}
}
diff --git a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/testsuite_test.go b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/testsuite_test.go
index 6615023d4..684e21916 100644
--- a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/testsuite_test.go
+++ b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/testsuite_test.go
@@ -289,14 +289,14 @@ func (t *TestSuite) applyPerformanceFactor(accountID iotago.AccountID, epoch iot
for i := uint64(0); i < validationBlocksSentPerSlot; i++ {
valBlock := tpkg.RandValidationBlock(t.api)
- block := tpkg.RandProtocolBlock(valBlock, t.api, 10)
- block.IssuerID = accountID
+ block := tpkg.RandBlock(valBlock, t.api, 10)
+ block.Header.IssuerID = accountID
subslotIndex := i
// issued more than one block in the same slot to reduce performance factor
if i >= slotPerformanceFactor {
subslotIndex = 0
}
- block.IssuingTime = t.api.TimeProvider().SlotStartTime(slot).Add(time.Duration(subslotIndex)*subslotDur + 1*time.Nanosecond)
+ block.Header.IssuingTime = t.api.TimeProvider().SlotStartTime(slot).Add(time.Duration(subslotIndex)*subslotDur + 1*time.Nanosecond)
modelBlock, err := model.BlockFromBlock(block)
t.Instance.TrackValidationBlock(blocks.NewBlock(modelBlock))
require.NoError(t.T, err)
diff --git a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/tracker_test.go b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/tracker_test.go
index 49a1a95bf..1eddb125d 100644
--- a/pkg/protocol/sybilprotection/sybilprotectionv1/performance/tracker_test.go
+++ b/pkg/protocol/sybilprotection/sybilprotectionv1/performance/tracker_test.go
@@ -96,20 +96,20 @@ func TestManager_Candidates(t *testing.T) {
issuer2 := tpkg.RandAccountID()
issuer3 := tpkg.RandAccountID()
{
- block1 := tpkg.RandProtocolBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
+ block1 := tpkg.RandBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
- block1.IssuingTime = ts.api.TimeProvider().SlotStartTime(1)
- block1.IssuerID = issuer1
+ block1.Header.IssuingTime = ts.api.TimeProvider().SlotStartTime(1)
+ block1.Header.IssuerID = issuer1
- block2 := tpkg.RandProtocolBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
+ block2 := tpkg.RandBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
- block2.IssuingTime = ts.api.TimeProvider().SlotStartTime(2)
- block2.IssuerID = issuer2
+ block2.Header.IssuingTime = ts.api.TimeProvider().SlotStartTime(2)
+ block2.Header.IssuerID = issuer2
- block3 := tpkg.RandProtocolBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
+ block3 := tpkg.RandBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
- block3.IssuingTime = ts.api.TimeProvider().SlotStartTime(3)
- block3.IssuerID = issuer3
+ block3.Header.IssuingTime = ts.api.TimeProvider().SlotStartTime(3)
+ block3.Header.IssuerID = issuer3
ts.Instance.TrackCandidateBlock(blocks.NewBlock(lo.PanicOnErr(model.BlockFromBlock(block1))))
ts.Instance.TrackCandidateBlock(blocks.NewBlock(lo.PanicOnErr(model.BlockFromBlock(block2))))
@@ -117,19 +117,19 @@ func TestManager_Candidates(t *testing.T) {
}
{
- block4 := tpkg.RandProtocolBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
- block4.IssuingTime = ts.api.TimeProvider().SlotStartTime(4)
- block4.IssuerID = issuer1
+ block4 := tpkg.RandBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
+ block4.Header.IssuingTime = ts.api.TimeProvider().SlotStartTime(4)
+ block4.Header.IssuerID = issuer1
- block5 := tpkg.RandProtocolBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
+ block5 := tpkg.RandBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
- block5.IssuingTime = ts.api.TimeProvider().SlotStartTime(5)
- block5.IssuerID = issuer2
+ block5.Header.IssuingTime = ts.api.TimeProvider().SlotStartTime(5)
+ block5.Header.IssuerID = issuer2
- block6 := tpkg.RandProtocolBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
+ block6 := tpkg.RandBlock(tpkg.RandBasicBlock(ts.api, iotago.PayloadCandidacyAnnouncement), ts.api, 0)
- block6.IssuingTime = ts.api.TimeProvider().SlotStartTime(6)
- block6.IssuerID = issuer3
+ block6.Header.IssuingTime = ts.api.TimeProvider().SlotStartTime(6)
+ block6.Header.IssuerID = issuer3
ts.Instance.TrackCandidateBlock(blocks.NewBlock(lo.PanicOnErr(model.BlockFromBlock(block4))))
ts.Instance.TrackCandidateBlock(blocks.NewBlock(lo.PanicOnErr(model.BlockFromBlock(block5))))
diff --git a/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go b/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go
index 1e15ec4e2..2ebd75b0c 100644
--- a/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go
+++ b/pkg/protocol/sybilprotection/sybilprotectionv1/sybilprotection.go
@@ -106,9 +106,9 @@ func (o *SybilProtection) TrackBlock(block *blocks.Block) {
return
}
- accountData, exists, err := o.ledger.Account(block.ProtocolBlock().IssuerID, block.SlotCommitmentID().Slot())
+ accountData, exists, err := o.ledger.Account(block.ProtocolBlock().Header.IssuerID, block.SlotCommitmentID().Slot())
if err != nil {
- o.errHandler(ierrors.Wrapf(err, "error while retrieving account from account %s in slot %d from accounts ledger", block.ProtocolBlock().IssuerID, block.SlotCommitmentID().Slot()))
+ o.errHandler(ierrors.Wrapf(err, "error while retrieving account from account %s in slot %d from accounts ledger", block.ProtocolBlock().Header.IssuerID, block.SlotCommitmentID().Slot()))
return
}
diff --git a/pkg/retainer/retainer/errors.go b/pkg/retainer/retainer/errors.go
index 9ef4908a0..88d9594f6 100644
--- a/pkg/retainer/retainer/errors.go
+++ b/pkg/retainer/retainer/errors.go
@@ -62,6 +62,14 @@ var txErrorsFailureReasonMap = map[error]apimodels.TransactionFailureReason{
iotago.ErrInputOutputManaMismatch: apimodels.TxFailureManaAmountInvalid,
iotago.ErrManaAmountInvalid: apimodels.TxFailureManaAmountInvalid,
iotago.ErrInputCreationAfterTxCreation: apimodels.TxFailureInputCreationAfterTxCreation,
+
+ // tx capabilities errors
+ iotago.ErrTxCapabilitiesNativeTokenBurningNotAllowed: apimodels.TxFailureCapabilitiesNativeTokenBurningNotAllowed,
+ iotago.ErrTxCapabilitiesManaBurningNotAllowed: apimodels.TxFailureCapabilitiesManaBurningNotAllowed,
+ iotago.ErrTxCapabilitiesAccountDestructionNotAllowed: apimodels.TxFailureCapabilitiesAccountDestructionNotAllowed,
+ iotago.ErrTxCapabilitiesAnchorDestructionNotAllowed: apimodels.TxFailureCapabilitiesAnchorDestructionNotAllowed,
+ iotago.ErrTxCapabilitiesFoundryDestructionNotAllowed: apimodels.TxFailureCapabilitiesFoundryDestructionNotAllowed,
+ iotago.ErrTxCapabilitiesNFTDestructionNotAllowed: apimodels.TxFailureCapabilitiesNFTDestructionNotAllowed,
}
func determineTxFailureReason(err error) apimodels.TransactionFailureReason {
diff --git a/pkg/storage/testframework_test.go b/pkg/storage/testframework_test.go
index c88a32ff2..290f180dd 100644
--- a/pkg/storage/testframework_test.go
+++ b/pkg/storage/testframework_test.go
@@ -90,7 +90,7 @@ func (t *TestFramework) GeneratePrunableData(epoch iotago.EpochIndex, size int64
endSlot := apiForEpoch.TimeProvider().EpochEnd(epoch)
var createdBytes int64
for createdBytes < size {
- block := tpkg.RandProtocolBlock(&iotago.BasicBlock{
+ block := tpkg.RandBlock(&iotago.BasicBlockBody{
StrongParents: tpkg.SortedRandBlockIDs(1 + rand.Intn(iotago.BlockMaxParents)),
Payload: &iotago.TaggedData{Data: make([]byte, 8192)},
MaxBurnedMana: 1000,
diff --git a/pkg/tests/accounts_test.go b/pkg/tests/accounts_test.go
index 1195eba30..99886583d 100644
--- a/pkg/tests/accounts_test.go
+++ b/pkg/tests/accounts_test.go
@@ -3,40 +3,34 @@ package tests
import (
"testing"
- "github.com/iotaledger/hive.go/lo"
- "github.com/iotaledger/hive.go/runtime/options"
"github.com/iotaledger/iota-core/pkg/model"
- "github.com/iotaledger/iota-core/pkg/protocol"
"github.com/iotaledger/iota-core/pkg/protocol/engine/accounts"
- "github.com/iotaledger/iota-core/pkg/protocol/snapshotcreator"
"github.com/iotaledger/iota-core/pkg/testsuite"
"github.com/iotaledger/iota-core/pkg/testsuite/mock"
+ "github.com/iotaledger/iota-core/pkg/testsuite/snapshotcreator"
"github.com/iotaledger/iota-core/pkg/utils"
iotago "github.com/iotaledger/iota.go/v4"
)
-// TODO: implement tests for staking and delegation transitions that cover edge cases - part of hardening phase.
-func Test_TransitionAccount(t *testing.T) {
+func Test_TransitionAndDestroyAccount(t *testing.T) {
oldGenesisOutputKey := utils.RandBlockIssuerKey()
+
ts := testsuite.NewTestSuite(t, testsuite.WithAccounts(snapshotcreator.AccountDetails{
// Nil address will be replaced with the address generated from genesis seed.
- // A single key may unlock multiple accounts; that's why it can't be used as a source for AccountID derivation.
Address: nil,
- // Set an amount enough to cover the rent and to cover an additional key that is added in the test.
- // If it's too little, then the test will fail.
- Amount: testsuite.MinIssuerAccountAmount * 10,
+ // Set an amount enough to cover storage deposit and more issuer keys.
+ Amount: mock.MinIssuerAccountAmount * 10,
Mana: 0,
// AccountID is derived from this field, so this must be set uniquely for each account.
IssuerKey: oldGenesisOutputKey,
// Expiry Slot is the slot index at which the account expires.
- ExpirySlot: 1,
+ ExpirySlot: iotago.MaxSlotIndex,
// BlockIssuanceCredits on this account is custom because it never needs to issue.
- // On Validator nodes it's unlimited (MaxInt64).
BlockIssuanceCredits: iotago.BlockIssuanceCredits(123),
}),
testsuite.WithProtocolParametersOptions(
iotago.WithTimeProviderOptions(
- testsuite.GenesisTimeWithOffsetBySlots(100, testsuite.DefaultSlotDurationInSeconds),
+ testsuite.GenesisTimeWithOffsetBySlots(200, testsuite.DefaultSlotDurationInSeconds),
testsuite.DefaultSlotDurationInSeconds,
8,
),
@@ -51,68 +45,73 @@ func Test_TransitionAccount(t *testing.T) {
)
defer ts.Shutdown()
+ // add a validator node to the network. This will add a validator account to the snapshot.
node1 := ts.AddValidatorNode("node1")
+ // add a non-validator node to the network. This will not add any accounts to the snapshot.
_ = ts.AddNode("node2")
- blockIssuer := ts.AddBasicBlockIssuer("default", iotago.MaxBlockIssuanceCredits/2)
+ // add a default block issuer to the network. This will add another block issuer account to the snapshot.
+ wallet := ts.AddGenesisWallet("default", node1, iotago.MaxBlockIssuanceCredits/2)
- ts.Run(true, map[string][]options.Option[protocol.Protocol]{})
+ ts.Run(true)
+ // check that the accounts added in the genesis snapshot were added to account manager correctly.
+ // genesis account.
genesisAccount := ts.AccountOutput("Genesis:1")
genesisAccountOutput := genesisAccount.Output().(*iotago.AccountOutput)
-
ts.AssertAccountData(&accounts.AccountData{
ID: genesisAccountOutput.AccountID,
Credits: accounts.NewBlockIssuanceCredits(iotago.BlockIssuanceCredits(123), 0),
OutputID: genesisAccount.OutputID(),
- ExpirySlot: 1,
+ ExpirySlot: iotago.MaxSlotIndex,
BlockIssuerKeys: iotago.NewBlockIssuerKeys(oldGenesisOutputKey),
}, ts.Nodes()...)
+ // validator node account.
+ validatorAccountOutput := ts.AccountOutput("Genesis:2")
+ ts.AssertAccountData(&accounts.AccountData{
+ ID: node1.Validator.AccountID,
+ Credits: accounts.NewBlockIssuanceCredits(iotago.MaxBlockIssuanceCredits/2, 0),
+ OutputID: validatorAccountOutput.OutputID(),
+ ExpirySlot: iotago.MaxSlotIndex,
+ BlockIssuerKeys: node1.Validator.BlockIssuerKeys(),
+ StakeEndEpoch: iotago.MaxEpochIndex,
+ ValidatorStake: mock.MinValidatorAccountAmount,
+ }, ts.Nodes()...)
+ // default wallet block issuer account.
+ blockIssuerAccountOutput := ts.AccountOutput("Genesis:3")
+ ts.AssertAccountData(&accounts.AccountData{
+ ID: wallet.BlockIssuer.AccountID,
+ Credits: accounts.NewBlockIssuanceCredits(iotago.MaxBlockIssuanceCredits/2, 0),
+ OutputID: blockIssuerAccountOutput.OutputID(),
+ ExpirySlot: iotago.MaxSlotIndex,
+ BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(),
+ }, ts.Nodes()...)
- // MODIFY EXISTING GENESIS ACCOUNT AND PREPARE SOME BASIC OUTPUTS
-
+ // MODIFY EXISTING GENESIS ACCOUNT
newGenesisOutputKey := utils.RandBlockIssuerKey()
- newAccountBlockIssuerKey := utils.RandBlockIssuerKey()
- latestCommitmentID := node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID()
+ var block1Slot iotago.SlotIndex = 1
+ // set the expiry of the genesis account to be the block slot + max committable age.
+ newExpirySlot := block1Slot + ts.API.ProtocolParameters().MaxCommittableAge()
- accountInput, accountOutputs, accountWallets := ts.TransactionFramework.TransitionAccount(
+ tx1 := ts.DefaultWallet().TransitionAccount(
+ "TX1",
"Genesis:1",
- testsuite.WithAddBlockIssuerKey(newGenesisOutputKey),
- testsuite.WithBlockIssuerExpirySlot(1),
+ mock.WithAddBlockIssuerKey(newGenesisOutputKey),
+ mock.WithBlockIssuerExpirySlot(newExpirySlot),
)
- consumedInputs, equalOutputs, equalWallets := ts.TransactionFramework.CreateBasicOutputsEqually(4, "Genesis:0")
-
- tx1 := lo.PanicOnErr(ts.TransactionFramework.CreateSignedTransactionWithOptions("TX1", append(accountWallets, equalWallets...),
- testsuite.WithAccountInput(accountInput, true),
- testsuite.WithInputs(consumedInputs),
- testsuite.WithContextInputs(iotago.TxEssenceContextInputs{
- &iotago.BlockIssuanceCreditInput{
- AccountID: genesisAccountOutput.AccountID,
- },
- &iotago.CommitmentInput{
- CommitmentID: latestCommitmentID,
- },
- }),
- testsuite.WithOutputs(append(accountOutputs, equalOutputs...)),
- testsuite.WithAllotments(iotago.Allotments{&iotago.Allotment{
- AccountID: genesisAccountOutput.AccountID,
- Mana: 0,
- }}),
- ))
- var block1Slot iotago.SlotIndex = 1
+ // default block issuer issues a block containing the transaction in slot 1.
genesisCommitment := iotago.NewEmptyCommitment(ts.API.ProtocolParameters().Version())
genesisCommitment.ReferenceManaCost = ts.API.ProtocolParameters().CongestionControlParameters().MinReferenceManaCost
-
- block1 := ts.IssueBasicBlockAtSlotWithOptions("block1", block1Slot, genesisCommitment, blockIssuer, node1, tx1)
-
+ block1 := ts.IssueBasicBlockAtSlotWithOptions("block1", block1Slot, ts.DefaultWallet(), tx1, mock.WithSlotCommitment(genesisCommitment))
latestParent := ts.CommitUntilSlot(ts.BlockID("block1").Slot(), block1)
+ // assert diff of the genesis account, it should have a new output ID, new expiry slot and a new block issuer key.
ts.AssertAccountDiff(genesisAccountOutput.AccountID, block1Slot, &model.AccountDiff{
BICChange: 0,
PreviousUpdatedTime: 0,
- PreviousExpirySlot: 1,
- NewExpirySlot: 1,
- NewOutputID: iotago.OutputIDFromTransactionIDAndIndex(ts.TransactionFramework.TransactionID("TX1"), 0),
+ PreviousExpirySlot: iotago.MaxSlotIndex,
+ NewExpirySlot: newExpirySlot,
+ NewOutputID: ts.DefaultWallet().Output("TX1:0").OutputID(),
PreviousOutputID: genesisAccount.OutputID(),
BlockIssuerKeysRemoved: iotago.NewBlockIssuerKeys(),
BlockIssuerKeysAdded: iotago.NewBlockIssuerKeys(newGenesisOutputKey),
@@ -121,57 +120,30 @@ func Test_TransitionAccount(t *testing.T) {
ts.AssertAccountData(&accounts.AccountData{
ID: genesisAccountOutput.AccountID,
Credits: accounts.NewBlockIssuanceCredits(iotago.BlockIssuanceCredits(123), 0),
- OutputID: iotago.OutputIDFromTransactionIDAndIndex(ts.TransactionFramework.TransactionID("TX1"), 0),
+ OutputID: ts.DefaultWallet().Output("TX1:0").OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(oldGenesisOutputKey, newGenesisOutputKey),
- ExpirySlot: 1,
+ ExpirySlot: newExpirySlot,
}, ts.Nodes()...)
- // DESTROY GENESIS ACCOUNT, CREATE NEW ACCOUNT WITH BLOCK ISSUER AND STAKING FEATURES FROM BASIC UTXO
-
- // commit until the expiry slot of the transitioned genesis account plus one
- latestParent = ts.CommitUntilSlot(accountOutputs[0].FeatureSet().BlockIssuer().ExpirySlot+1, latestParent)
- // set the expiry slof of the transitioned genesis account to the latest committed + MaxCommittableAge
- newAccountExpirySlot := node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Slot() + ts.API.ProtocolParameters().MaxCommittableAge()
- inputForNewAccount, newAccountOutputs, newAccountWallets := ts.TransactionFramework.CreateAccountFromInput("TX1:1",
- testsuite.WithAccountConditions(iotago.AccountOutputUnlockConditions{
- &iotago.StateControllerAddressUnlockCondition{Address: ts.TransactionFramework.DefaultAddress()},
- &iotago.GovernorAddressUnlockCondition{Address: ts.TransactionFramework.DefaultAddress()},
- }),
- testsuite.WithBlockIssuerFeature(iotago.BlockIssuerKeys{newAccountBlockIssuerKey}, newAccountExpirySlot),
- testsuite.WithStakingFeature(10000, 421, 0, 10),
- )
-
- destroyedAccountInput, destructionOutputs, destroyWallets := ts.TransactionFramework.DestroyAccount("TX1:0")
+ // DESTROY GENESIS ACCOUNT
+ // commit until the expiry slot of the transitioned genesis account plus one.
+ latestParent = ts.CommitUntilSlot(newExpirySlot+1, latestParent)
+ // issue the block containing the transaction in the same slot as the latest parent block.
block2Slot := latestParent.ID().Slot()
-
- tx2 := lo.PanicOnErr(ts.TransactionFramework.CreateSignedTransactionWithOptions("TX2", append(newAccountWallets, destroyWallets...),
- testsuite.WithContextInputs(iotago.TxEssenceContextInputs{
- &iotago.BlockIssuanceCreditInput{
- AccountID: genesisAccountOutput.AccountID,
- },
- &iotago.CommitmentInput{
- CommitmentID: node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
- },
- }),
- testsuite.WithInputs(inputForNewAccount),
- testsuite.WithAccountInput(destroyedAccountInput, true),
- testsuite.WithOutputs(append(newAccountOutputs, destructionOutputs...)),
- testsuite.WithSlotCreated(block2Slot),
- ))
-
- block2 := ts.IssueBasicBlockAtSlotWithOptions("block2", block2Slot, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), blockIssuer, node1, tx2, mock.WithStrongParents(latestParent.ID()))
-
+ // create a transaction which destroys the genesis account.
+ tx2 := ts.DefaultWallet().DestroyAccount("TX2", "TX1:0", block2Slot)
+ block2 := ts.IssueBasicBlockAtSlotWithOptions("block2", block2Slot, ts.DefaultWallet(), tx2, mock.WithStrongParents(latestParent.ID()))
latestParent = ts.CommitUntilSlot(block2Slot, block2)
- // assert diff of a destroyed account, to make sure we can correctly restore it
+ // assert diff of the destroyed account.
ts.AssertAccountDiff(genesisAccountOutput.AccountID, block2Slot, &model.AccountDiff{
BICChange: -iotago.BlockIssuanceCredits(123),
PreviousUpdatedTime: 0,
NewExpirySlot: 0,
- PreviousExpirySlot: 1,
+ PreviousExpirySlot: newExpirySlot,
NewOutputID: iotago.EmptyOutputID,
- PreviousOutputID: iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(ts.TransactionFramework.Transaction("TX1").ID()), 0),
+ PreviousOutputID: ts.DefaultWallet().Output("TX1:0").OutputID(),
BlockIssuerKeysAdded: iotago.NewBlockIssuerKeys(),
BlockIssuerKeysRemoved: iotago.NewBlockIssuerKeys(oldGenesisOutputKey, newGenesisOutputKey),
ValidatorStakeChange: 0,
@@ -179,11 +151,83 @@ func Test_TransitionAccount(t *testing.T) {
FixedCostChange: 0,
DelegationStakeChange: 0,
}, true, ts.Nodes()...)
+}
+
+func Test_StakeDelegateAndDelayedClaim(t *testing.T) {
+ ts := testsuite.NewTestSuite(t,
+ testsuite.WithProtocolParametersOptions(
+ iotago.WithTimeProviderOptions(
+ testsuite.GenesisTimeWithOffsetBySlots(100, testsuite.DefaultSlotDurationInSeconds),
+ testsuite.DefaultSlotDurationInSeconds,
+ 8,
+ ),
+ iotago.WithLivenessOptions(
+ testsuite.DefaultLivenessThresholdLowerBoundInSeconds,
+ testsuite.DefaultLivenessThresholdUpperBoundInSeconds,
+ testsuite.DefaultMinCommittableAge,
+ 100,
+ testsuite.DefaultEpochNearingThreshold,
+ ),
+ ),
+ )
+ defer ts.Shutdown()
+
+ // add a validator node to the network. This will add a validator account to the snapshot.
+ node1 := ts.AddValidatorNode("node1")
+ // add a non-validator node to the network. This will not add any accounts to the snapshot.
+ _ = ts.AddNode("node2")
+ // add a default block issuer to the network. This will add another block issuer account to the snapshot.
+ wallet := ts.AddGenesisWallet("default", node1, iotago.MaxBlockIssuanceCredits/2)
+
+ ts.Run(true)
+
+ // assert validator and block issuer accounts in genesis snapshot.
+ // validator node account.
+ validatorAccountOutput := ts.AccountOutput("Genesis:1")
+ ts.AssertAccountData(&accounts.AccountData{
+ ID: node1.Validator.AccountID,
+ Credits: accounts.NewBlockIssuanceCredits(iotago.MaxBlockIssuanceCredits/2, 0),
+ OutputID: validatorAccountOutput.OutputID(),
+ ExpirySlot: iotago.MaxSlotIndex,
+ BlockIssuerKeys: node1.Validator.BlockIssuerKeys(),
+ StakeEndEpoch: iotago.MaxEpochIndex,
+ ValidatorStake: mock.MinValidatorAccountAmount,
+ }, ts.Nodes()...)
+ // default wallet block issuer account.
+ blockIssuerAccountOutput := ts.AccountOutput("Genesis:2")
+ ts.AssertAccountData(&accounts.AccountData{
+ ID: wallet.BlockIssuer.AccountID,
+ Credits: accounts.NewBlockIssuanceCredits(iotago.MaxBlockIssuanceCredits/2, 0),
+ OutputID: blockIssuerAccountOutput.OutputID(),
+ ExpirySlot: iotago.MaxSlotIndex,
+ BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(),
+ }, ts.Nodes()...)
+
+ //CREATE NEW ACCOUNT WITH BLOCK ISSUER AND STAKING FEATURES FROM BASIC UTXO
+ newAccountBlockIssuerKey := utils.RandBlockIssuerKey()
+ // set the expiry slot of the transitioned genesis account to the latest committed + MaxCommittableAge
+ newAccountExpirySlot := node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Slot() + ts.API.ProtocolParameters().MaxCommittableAge()
+
+ var block1Slot iotago.SlotIndex = 1
+ tx1 := ts.DefaultWallet().CreateAccountFromInput(
+ "TX1",
+ "Genesis:0",
+ ts.DefaultWallet(),
+ block1Slot,
+ mock.WithBlockIssuerFeature(iotago.BlockIssuerKeys{newAccountBlockIssuerKey}, newAccountExpirySlot),
+ mock.WithStakingFeature(10000, 421, 0, 10),
+ mock.WithAccountAmount(mock.MinIssuerAccountAmount),
+ )
+
+ genesisCommitment := iotago.NewEmptyCommitment(ts.API.ProtocolParameters().Version())
+ genesisCommitment.ReferenceManaCost = ts.API.ProtocolParameters().CongestionControlParameters().MinReferenceManaCost
+ block1 := ts.IssueBasicBlockAtSlotWithOptions("block1", block1Slot, ts.DefaultWallet(), tx1)
+ latestParent := ts.CommitUntilSlot(block1Slot, block1)
- newAccount := ts.AccountOutput("TX2:0")
+ newAccount := ts.DefaultWallet().AccountOutput("TX1:0")
newAccountOutput := newAccount.Output().(*iotago.AccountOutput)
- ts.AssertAccountDiff(newAccountOutput.AccountID, block2Slot, &model.AccountDiff{
+ ts.AssertAccountDiff(newAccountOutput.AccountID, block1Slot, &model.AccountDiff{
BICChange: 0,
PreviousUpdatedTime: 0,
NewExpirySlot: newAccountExpirySlot,
@@ -200,7 +244,7 @@ func Test_TransitionAccount(t *testing.T) {
ts.AssertAccountData(&accounts.AccountData{
ID: newAccountOutput.AccountID,
- Credits: accounts.NewBlockIssuanceCredits(0, block2Slot),
+ Credits: accounts.NewBlockIssuanceCredits(0, block1Slot),
ExpirySlot: newAccountExpirySlot,
OutputID: newAccount.OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(newAccountBlockIssuerKey),
@@ -210,32 +254,22 @@ func Test_TransitionAccount(t *testing.T) {
ValidatorStake: 10000,
}, ts.Nodes()...)
+ // CREATE DELEGATION TO NEW ACCOUNT FROM BASIC UTXO
accountAddress := iotago.AccountAddress(newAccountOutput.AccountID)
- // create a delegation output delegating to the newly created account
- inputForNewDelegation, newDelegationOutputs, newDelegationWallets := ts.TransactionFramework.CreateDelegationFromInput("TX1:2",
- testsuite.WithDelegatedValidatorAddress(&accountAddress),
- testsuite.WithDelegationStartEpoch(1),
+ block2Slot := latestParent.ID().Slot()
+ tx2 := ts.DefaultWallet().CreateDelegationFromInput(
+ "TX2",
+ "TX1:1",
+ block2Slot,
+ mock.WithDelegatedValidatorAddress(&accountAddress),
+ mock.WithDelegationStartEpoch(1),
)
+ block2 := ts.IssueBasicBlockAtSlotWithOptions("block2", block2Slot, ts.DefaultWallet(), tx2, mock.WithStrongParents(latestParent.ID()))
- block3Slot := latestParent.ID().Slot()
-
- tx3 := lo.PanicOnErr(ts.TransactionFramework.CreateSignedTransactionWithOptions("TX3", newDelegationWallets,
- testsuite.WithContextInputs(iotago.TxEssenceContextInputs{
- &iotago.CommitmentInput{
- CommitmentID: node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
- },
- }),
- testsuite.WithInputs(inputForNewDelegation),
- testsuite.WithOutputs(newDelegationOutputs),
- testsuite.WithSlotCreated(block3Slot),
- ))
-
- block3 := ts.IssueBasicBlockAtSlotWithOptions("block3", block3Slot, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), blockIssuer, node1, tx3, mock.WithStrongParents(latestParent.ID()))
-
- latestParent = ts.CommitUntilSlot(block3Slot, block3)
- delegatedAmount := inputForNewDelegation[0].BaseTokenAmount()
+ latestParent = ts.CommitUntilSlot(block2Slot, block2)
+ delegatedAmount := ts.DefaultWallet().Output("TX1:1").BaseTokenAmount()
- ts.AssertAccountDiff(newAccountOutput.AccountID, block3Slot, &model.AccountDiff{
+ ts.AssertAccountDiff(newAccountOutput.AccountID, block2Slot, &model.AccountDiff{
BICChange: 0,
PreviousUpdatedTime: 0,
NewOutputID: iotago.EmptyOutputID,
@@ -250,7 +284,7 @@ func Test_TransitionAccount(t *testing.T) {
ts.AssertAccountData(&accounts.AccountData{
ID: newAccountOutput.AccountID,
- Credits: accounts.NewBlockIssuanceCredits(0, block2Slot),
+ Credits: accounts.NewBlockIssuanceCredits(0, block1Slot),
ExpirySlot: newAccountExpirySlot,
OutputID: newAccount.OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(newAccountBlockIssuerKey),
@@ -261,27 +295,14 @@ func Test_TransitionAccount(t *testing.T) {
}, ts.Nodes()...)
// transition a delegation output to a delayed claiming state
- inputForDelegationTransition, delegationTransitionOutputs, delegationTransitionWallets := ts.TransactionFramework.DelayedClaimingTransition("TX3:0", 0)
-
- tx4 := lo.PanicOnErr(ts.TransactionFramework.CreateSignedTransactionWithOptions("TX4", delegationTransitionWallets,
- testsuite.WithContextInputs(iotago.TxEssenceContextInputs{
- &iotago.CommitmentInput{
- CommitmentID: node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
- },
- }),
- testsuite.WithInputs(inputForDelegationTransition),
- testsuite.WithOutputs(delegationTransitionOutputs),
- testsuite.WithSlotCreated(block3Slot),
- ))
-
- block4Slot := latestParent.ID().Slot()
-
- block4 := ts.IssueBasicBlockAtSlotWithOptions("block4", block4Slot, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), blockIssuer, node1, tx4, mock.WithStrongParents(latestParent.ID()))
+ block3Slot := latestParent.ID().Slot()
+ tx3 := ts.DefaultWallet().DelayedClaimingTransition("TX3", "TX2:0", block3Slot, 0)
+ block3 := ts.IssueBasicBlockAtSlotWithOptions("block3", block3Slot, ts.DefaultWallet(), tx3, mock.WithStrongParents(latestParent.ID()))
- latestParent = ts.CommitUntilSlot(block4Slot, block4)
+ latestParent = ts.CommitUntilSlot(block3Slot, block3)
// Transitioning to delayed claiming effectively removes the delegation, so we expect a negative delegation stake change.
- ts.AssertAccountDiff(newAccountOutput.AccountID, block4Slot, &model.AccountDiff{
+ ts.AssertAccountDiff(newAccountOutput.AccountID, block3Slot, &model.AccountDiff{
BICChange: 0,
PreviousUpdatedTime: 0,
NewOutputID: iotago.EmptyOutputID,
@@ -296,7 +317,7 @@ func Test_TransitionAccount(t *testing.T) {
ts.AssertAccountData(&accounts.AccountData{
ID: newAccountOutput.AccountID,
- Credits: accounts.NewBlockIssuanceCredits(0, block2Slot),
+ Credits: accounts.NewBlockIssuanceCredits(0, block1Slot),
ExpirySlot: newAccountExpirySlot,
OutputID: newAccount.OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(newAccountBlockIssuerKey),
@@ -305,72 +326,110 @@ func Test_TransitionAccount(t *testing.T) {
DelegationStake: iotago.BaseToken(0),
ValidatorStake: 10000,
}, ts.Nodes()...)
+}
- // CREATE IMPLICIT ACCOUNT FROM BASIC UTXO
- inputForImplicitAccount, outputsForImplicitAccount, implicitAccountAddress, implicitWallet := ts.TransactionFramework.CreateImplicitAccountFromInput("TX1:3")
-
- tx5 := lo.PanicOnErr(ts.TransactionFramework.CreateSignedTransactionWithOptions("TX5", implicitWallet,
- testsuite.WithInputs(inputForImplicitAccount),
- testsuite.WithOutputs(outputsForImplicitAccount),
- ))
-
- implicitAccountOutput := ts.TransactionFramework.Output("TX5:0")
- implicitAccountOutputID := implicitAccountOutput.OutputID()
- implicitAccountID := iotago.AccountIDFromOutputID(implicitAccountOutputID)
+func Test_ImplicitAccounts(t *testing.T) {
+ ts := testsuite.NewTestSuite(t,
+ testsuite.WithProtocolParametersOptions(
+ iotago.WithTimeProviderOptions(
+ testsuite.GenesisTimeWithOffsetBySlots(100, testsuite.DefaultSlotDurationInSeconds),
+ testsuite.DefaultSlotDurationInSeconds,
+ 8,
+ ),
+ iotago.WithLivenessOptions(
+ testsuite.DefaultLivenessThresholdLowerBoundInSeconds,
+ testsuite.DefaultLivenessThresholdUpperBoundInSeconds,
+ testsuite.DefaultMinCommittableAge,
+ 100,
+ testsuite.DefaultEpochNearingThreshold,
+ ),
+ ),
+ )
+ defer ts.Shutdown()
- slotIndexBlock5 := latestParent.ID().Index()
+ // add a validator node to the network. This will add a validator account to the snapshot.
+ node1 := ts.AddValidatorNode("node1")
+ // add a non-validator node to the network. This will not add any accounts to the snapshot.
+ _ = ts.AddNode("node2")
+ // add a default block issuer to the network. This will add another block issuer account to the snapshot.
+ wallet := ts.AddGenesisWallet("default", node1, iotago.MaxBlockIssuanceCredits/2)
- block5 := ts.IssueBasicBlockAtSlotWithOptions("block5", slotIndexBlock5, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), blockIssuer, node1, tx5, mock.WithStrongParents(latestParent.ID()))
+ ts.Run(true)
- latestParent = ts.CommitUntilSlot(slotIndexBlock5, block5)
+ // assert validator and block issuer accounts in genesis snapshot.
+ // validator node account.
+ validatorAccountOutput := ts.AccountOutput("Genesis:1")
+ ts.AssertAccountData(&accounts.AccountData{
+ ID: node1.Validator.AccountID,
+ Credits: accounts.NewBlockIssuanceCredits(iotago.MaxBlockIssuanceCredits/2, 0),
+ OutputID: validatorAccountOutput.OutputID(),
+ ExpirySlot: iotago.MaxSlotIndex,
+ BlockIssuerKeys: node1.Validator.BlockIssuerKeys(),
+ StakeEndEpoch: iotago.MaxEpochIndex,
+ ValidatorStake: mock.MinValidatorAccountAmount,
+ }, ts.Nodes()...)
+ // default wallet block issuer account.
+ blockIssuerAccountOutput := ts.AccountOutput("Genesis:2")
+ ts.AssertAccountData(&accounts.AccountData{
+ ID: wallet.BlockIssuer.AccountID,
+ Credits: accounts.NewBlockIssuanceCredits(iotago.MaxBlockIssuanceCredits/2, 0),
+ OutputID: blockIssuerAccountOutput.OutputID(),
+ ExpirySlot: iotago.MaxSlotIndex,
+ BlockIssuerKeys: wallet.BlockIssuer.BlockIssuerKeys(),
+ }, ts.Nodes()...)
- var implicitBlockIssuerKey iotago.BlockIssuerKey = iotago.Ed25519PublicKeyHashBlockIssuerKeyFromImplicitAccountCreationAddress(implicitAccountAddress)
+ // CREATE IMPLICIT ACCOUNT FROM GENESIS BASIC UTXO, SENT TO A NEW USER WALLET.
+ // this wallet is not registered in the ledger yet.
+ newUserWallet := mock.NewWallet(ts.Testing, "newUser", node1)
+ // a default wallet, already registered in the ledger, will issue the transaction and block.
+ tx1 := ts.DefaultWallet().CreateImplicitAccountFromInput(
+ "TX1",
+ "Genesis:0",
+ newUserWallet,
+ )
+ var block1Slot iotago.SlotIndex = 1
+ block1 := ts.IssueBasicBlockAtSlotWithOptions("block1", block1Slot, ts.DefaultWallet(), tx1)
+ latestParent := ts.CommitUntilSlot(block1Slot, block1)
+ implicitAccountOutput := newUserWallet.Output("TX1:0")
+ implicitAccountOutputID := implicitAccountOutput.OutputID()
+ implicitAccountID := iotago.AccountIDFromOutputID(implicitAccountOutputID)
+ var implicitBlockIssuerKey iotago.BlockIssuerKey = iotago.Ed25519PublicKeyHashBlockIssuerKeyFromImplicitAccountCreationAddress(newUserWallet.ImplicitAccountCreationAddress())
+ // the new implicit account should now be registered in the accounts ledger.
ts.AssertAccountData(&accounts.AccountData{
ID: implicitAccountID,
- Credits: accounts.NewBlockIssuanceCredits(0, slotIndexBlock5),
+ Credits: accounts.NewBlockIssuanceCredits(0, block1Slot),
ExpirySlot: iotago.MaxSlotIndex,
OutputID: implicitAccountOutputID,
BlockIssuerKeys: iotago.NewBlockIssuerKeys(implicitBlockIssuerKey),
}, ts.Nodes()...)
- // TRANSITION IMPLICIT ACCOUNT TO ACCOUNT OUTPUT
-
+ // TRANSITION IMPLICIT ACCOUNT TO ACCOUNT OUTPUT.
+ // USE IMPLICIT ACCOUNT AS BLOCK ISSUER.
fullAccountBlockIssuerKey := utils.RandBlockIssuerKey()
- inputForImplicitAccountTransition, outputsForImplicitAccountTransition, fullAccountWallet := ts.TransactionFramework.TransitionImplicitAccountToAccountOutput(
- "TX5:0",
- testsuite.WithBlockIssuerFeature(
+ block2Slot := latestParent.ID().Index()
+ tx2 := newUserWallet.TransitionImplicitAccountToAccountOutput(
+ "TX2",
+ "TX1:0",
+ block2Slot,
+ mock.WithBlockIssuerFeature(
iotago.BlockIssuerKeys{fullAccountBlockIssuerKey},
iotago.MaxSlotIndex,
),
+ mock.WithAccountAmount(mock.MinIssuerAccountAmount),
)
+ block2Commitment := node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment()
+ block2 := ts.IssueBasicBlockAtSlotWithOptions("block2", block2Slot, newUserWallet, tx2, mock.WithStrongParents(latestParent.ID()))
+ latestParent = ts.CommitUntilSlot(block2Slot, block2)
- tx6 := lo.PanicOnErr(ts.TransactionFramework.CreateSignedTransactionWithOptions("TX6", fullAccountWallet,
- testsuite.WithContextInputs(iotago.TxEssenceContextInputs{
- &iotago.BlockIssuanceCreditInput{
- AccountID: implicitAccountID,
- },
- &iotago.CommitmentInput{
- CommitmentID: node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
- },
- }),
- testsuite.WithInputs(inputForImplicitAccountTransition),
- testsuite.WithOutputs(outputsForImplicitAccountTransition),
- testsuite.WithSlotCreated(slotIndexBlock5),
- ))
-
- slotIndexBlock6 := latestParent.ID().Index()
-
- block6 := ts.IssueBasicBlockAtSlotWithOptions("block6", slotIndexBlock6, node1.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), blockIssuer, node1, tx6, mock.WithStrongParents(latestParent.ID()))
-
- latestParent = ts.CommitUntilSlot(slotIndexBlock6, block6)
-
- fullAccountOutputID := ts.TransactionFramework.Output("TX6:0").OutputID()
-
- ts.AssertAccountDiff(implicitAccountID, slotIndexBlock6, &model.AccountDiff{
- BICChange: 0,
- PreviousUpdatedTime: 0,
+ fullAccountOutputID := newUserWallet.Output("TX2:0").OutputID()
+ allotted := iotago.BlockIssuanceCredits(tx2.Transaction.Allotments.Get(implicitAccountID))
+ burned := iotago.BlockIssuanceCredits(block2.WorkScore()) * iotago.BlockIssuanceCredits(block2Commitment.ReferenceManaCost)
+ // the implicit account should now have been transitioned to a full account in the accounts ledger.
+ ts.AssertAccountDiff(implicitAccountID, block2Slot, &model.AccountDiff{
+ BICChange: allotted - burned,
+ PreviousUpdatedTime: block1Slot,
NewOutputID: fullAccountOutputID,
PreviousOutputID: implicitAccountOutputID,
PreviousExpirySlot: iotago.MaxSlotIndex,
@@ -382,10 +441,9 @@ func Test_TransitionAccount(t *testing.T) {
FixedCostChange: 0,
DelegationStakeChange: 0,
}, false, ts.Nodes()...)
-
ts.AssertAccountData(&accounts.AccountData{
ID: implicitAccountID,
- Credits: accounts.NewBlockIssuanceCredits(0, slotIndexBlock5),
+ Credits: accounts.NewBlockIssuanceCredits(allotted-burned, block2Slot),
ExpirySlot: iotago.MaxSlotIndex,
OutputID: fullAccountOutputID,
BlockIssuerKeys: iotago.NewBlockIssuerKeys(fullAccountBlockIssuerKey),
diff --git a/pkg/tests/booker_test.go b/pkg/tests/booker_test.go
index e667664e3..8a9e2e576 100644
--- a/pkg/tests/booker_test.go
+++ b/pkg/tests/booker_test.go
@@ -18,33 +18,33 @@ func Test_IssuingTransactionsOutOfOrder(t *testing.T) {
defer ts.Shutdown()
node1 := ts.AddValidatorNode("node1")
- blockIssuer := ts.AddBasicBlockIssuer("default")
+ wallet := ts.AddGenesisWallet("default", node1)
ts.Run(true, map[string][]options.Option[protocol.Protocol]{})
- tx1 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx1", 1, "Genesis:0"))
+ tx1 := wallet.CreateBasicOutputsEquallyFromInputs("tx1", 1, "Genesis:0")
- tx2 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx2", 1, "tx1:0"))
+ tx2 := wallet.CreateBasicOutputsEquallyFromInputs("tx2", 1, "tx1:0")
- ts.IssuePayloadWithOptions("block1", blockIssuer, node1, tx2)
+ ts.IssuePayloadWithOptions("block1", wallet, tx2)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx2"), true, node1)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1"), false, node1)
+ ts.AssertTransactionsExist(wallet.Transactions("tx2"), true, node1)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1"), false, node1)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx2"), false, node1)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx2"), false, node1)
// make sure that the block is not booked
- ts.IssuePayloadWithOptions("block2", blockIssuer, node1, tx1)
+ ts.IssuePayloadWithOptions("block2", wallet, tx1)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2"), true, node1)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx1", "tx2"), true, node1)
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("block1"): {"tx2"},
ts.Block("block2"): {"tx1"},
}, node1)
ts.AssertTransactionInCacheConflicts(map[*iotago.Transaction][]string{
- ts.TransactionFramework.Transaction("tx2"): {"tx2"},
- ts.TransactionFramework.Transaction("tx1"): {"tx1"},
+ wallet.Transaction("tx2"): {"tx2"},
+ wallet.Transaction("tx1"): {"tx1"},
}, node1)
}
@@ -54,7 +54,7 @@ func Test_DoubleSpend(t *testing.T) {
node1 := ts.AddValidatorNode("node1")
node2 := ts.AddValidatorNode("node2")
- blockIssuer := ts.AddBasicBlockIssuer("default")
+ wallet := ts.AddGenesisWallet("default", node1)
ts.Run(true, map[string][]options.Option[protocol.Protocol]{})
@@ -65,23 +65,23 @@ func Test_DoubleSpend(t *testing.T) {
// Create and issue double spends
{
- tx1 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx1", 1, "Genesis:0"))
- tx2 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx2", 1, "Genesis:0"))
+ tx1 := wallet.CreateBasicOutputsEquallyFromInputs("tx1", 1, "Genesis:0")
+ tx2 := wallet.CreateBasicOutputsEquallyFromInputs("tx2", 1, "Genesis:0")
- ts.IssuePayloadWithOptions("block1", blockIssuer, node1, tx1, mock.WithStrongParents(ts.BlockID("Genesis")))
- ts.IssuePayloadWithOptions("block2", blockIssuer, node1, tx2, mock.WithStrongParents(ts.BlockID("Genesis")))
+ ts.IssuePayloadWithOptions("block1", wallet, tx1, mock.WithStrongParents(ts.BlockID("Genesis")))
+ ts.IssuePayloadWithOptions("block2", wallet, tx2, mock.WithStrongParents(ts.BlockID("Genesis")))
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("block1"): {"tx1"},
ts.Block("block2"): {"tx2"},
}, node1, node2)
ts.AssertTransactionInCacheConflicts(map[*iotago.Transaction][]string{
- ts.TransactionFramework.Transaction("tx2"): {"tx2"},
- ts.TransactionFramework.Transaction("tx1"): {"tx1"},
+ wallet.Transaction("tx2"): {"tx2"},
+ wallet.Transaction("tx1"): {"tx1"},
}, node1, node2)
}
@@ -94,14 +94,14 @@ func Test_DoubleSpend(t *testing.T) {
ts.Block("block3"): {"tx1"},
ts.Block("block4"): {"tx2"},
}, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
}
// Issue an invalid block and assert that its vote is not cast.
{
ts.IssueValidationBlock("block5", node2, mock.WithStrongParents(ts.BlockIDs("block3", "block4")...))
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
}
// Issue valid blocks that resolve the conflict.
@@ -112,8 +112,8 @@ func Test_DoubleSpend(t *testing.T) {
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("block6"): {"tx2"},
}, node1, node2)
- ts.AssertTransactionsInCacheAccepted(ts.TransactionFramework.Transactions("tx2"), true, node1, node2)
- ts.AssertTransactionsInCacheRejected(ts.TransactionFramework.Transactions("tx1"), true, node1, node2)
+ ts.AssertTransactionsInCacheAccepted(wallet.Transactions("tx2"), true, node1, node2)
+ ts.AssertTransactionsInCacheRejected(wallet.Transactions("tx1"), true, node1, node2)
}
}
@@ -124,8 +124,7 @@ func Test_MultipleAttachments(t *testing.T) {
nodeA := ts.AddValidatorNode("nodeA")
nodeB := ts.AddValidatorNode("nodeB")
- blockIssuerA := ts.AddBasicBlockIssuer("blockIssuerA")
- blockIssuerB := ts.AddBasicBlockIssuer("blockIssuerB")
+ wallet := ts.AddGenesisWallet("default", nodeA)
ts.Run(true, map[string][]options.Option[protocol.Protocol]{})
@@ -133,11 +132,12 @@ func Test_MultipleAttachments(t *testing.T) {
// Create a transaction and issue it from both nodes, so that the conflict is accepted, but no attachment is included yet.
{
- tx1 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx1", 2, "Genesis:0"))
+ tx1 := wallet.CreateBasicOutputsEquallyFromInputs("tx1", 2, "Genesis:0")
- ts.IssuePayloadWithOptions("A.1", blockIssuerA, nodeA, tx1, mock.WithStrongParents(ts.BlockID("Genesis")))
+ ts.IssuePayloadWithOptions("A.1", wallet, tx1, mock.WithStrongParents(ts.BlockID("Genesis")))
ts.IssueValidationBlock("A.1.1", nodeA, mock.WithStrongParents(ts.BlockID("A.1")))
- ts.IssuePayloadWithOptions("B.1", blockIssuerB, nodeB, tx1, mock.WithStrongParents(ts.BlockID("Genesis")))
+ wallet.SetDefaultNode(nodeB)
+ ts.IssuePayloadWithOptions("B.1", wallet, tx1, mock.WithStrongParents(ts.BlockID("Genesis")))
ts.IssueValidationBlock("B.1.1", nodeB, mock.WithStrongParents(ts.BlockID("B.1")))
ts.IssueValidationBlock("A.2", nodeA, mock.WithStrongParents(ts.BlockID("B.1.1")))
@@ -153,17 +153,19 @@ func Test_MultipleAttachments(t *testing.T) {
ts.Block("B.2"): {"tx1"},
}), ts.Nodes()...)
ts.AssertTransactionInCacheConflicts(map[*iotago.Transaction][]string{
- ts.TransactionFramework.Transaction("tx1"): {"tx1"},
+ wallet.Transaction("tx1"): {"tx1"},
}, ts.Nodes()...)
ts.AssertConflictsInCacheAcceptanceState([]string{"tx1"}, acceptance.Accepted, ts.Nodes()...)
}
// Create a transaction that is included and whose conflict is accepted, but whose inputs are not accepted.
{
- tx2 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx2", 1, "tx1:1"))
+ tx2 := wallet.CreateBasicOutputsEquallyFromInputs("tx2", 1, "tx1:1")
- ts.IssuePayloadWithOptions("A.3", nodeA.Validator, nodeA, tx2, mock.WithStrongParents(ts.BlockID("Genesis")))
- ts.IssueValidationBlock("B.3", nodeB, mock.WithStrongParents(ts.BlockID("A.3")))
+ wallet.SetDefaultNode(nodeA)
+ ts.IssuePayloadWithOptions("A.3", wallet, tx2, mock.WithStrongParents(ts.BlockID("Genesis")))
+ ts.IssueValidationBlock("A.3.1", nodeA, mock.WithStrongParents(ts.BlockID("A.3")))
+ ts.IssueValidationBlock("B.3", nodeB, mock.WithStrongParents(ts.BlockID("A.3.1")))
ts.IssueValidationBlock("A.4", nodeA, mock.WithStrongParents(ts.BlockID("B.3")))
ts.AssertBlocksInCachePreAccepted(ts.Blocks("A.3"), true, ts.Nodes()...)
@@ -175,8 +177,8 @@ func Test_MultipleAttachments(t *testing.T) {
ts.AssertBlocksInCachePreAccepted(ts.Blocks("B.4", "A.5"), false, ts.Nodes()...)
ts.AssertBlocksInCacheAccepted(ts.Blocks("A.3"), true, ts.Nodes()...)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx1", "tx2"), true, ts.Nodes()...)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, ts.Nodes()...)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx1", "tx2"), true, ts.Nodes()...)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, ts.Nodes()...)
ts.AssertBlocksInCacheConflicts(lo.MergeMaps(blocksConflicts, map[*blocks.Block][]string{
ts.Block("A.3"): {"tx2"},
@@ -186,8 +188,8 @@ func Test_MultipleAttachments(t *testing.T) {
ts.Block("B.4"): {},
}), ts.Nodes()...)
ts.AssertTransactionInCacheConflicts(map[*iotago.Transaction][]string{
- ts.TransactionFramework.Transaction("tx1"): {"tx1"},
- ts.TransactionFramework.Transaction("tx2"): {"tx2"},
+ wallet.Transaction("tx1"): {"tx1"},
+ wallet.Transaction("tx2"): {"tx2"},
}, nodeA, nodeB)
ts.AssertConflictsInCacheAcceptanceState([]string{"tx1", "tx2"}, acceptance.Accepted, ts.Nodes()...)
}
@@ -204,9 +206,9 @@ func Test_MultipleAttachments(t *testing.T) {
ts.AssertBlocksInCacheAccepted(ts.Blocks("A.1", "B.1"), true, ts.Nodes()...)
ts.AssertBlocksInCachePreAccepted(ts.Blocks("A.7", "B.6"), false, ts.Nodes()...)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2"), true, ts.Nodes()...)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx1", "tx2"), true, ts.Nodes()...)
- ts.AssertTransactionsInCacheAccepted(ts.TransactionFramework.Transactions("tx1", "tx2"), true, ts.Nodes()...)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2"), true, ts.Nodes()...)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx1", "tx2"), true, ts.Nodes()...)
+ ts.AssertTransactionsInCacheAccepted(wallet.Transactions("tx1", "tx2"), true, ts.Nodes()...)
ts.AssertBlocksInCacheConflicts(lo.MergeMaps(blocksConflicts, map[*blocks.Block][]string{
ts.Block("A.6"): {},
@@ -216,8 +218,8 @@ func Test_MultipleAttachments(t *testing.T) {
}), ts.Nodes()...)
ts.AssertTransactionInCacheConflicts(map[*iotago.Transaction][]string{
- ts.TransactionFramework.Transaction("tx1"): {"tx1"},
- ts.TransactionFramework.Transaction("tx2"): {"tx2"},
+ wallet.Transaction("tx1"): {"tx1"},
+ wallet.Transaction("tx2"): {"tx2"},
}, nodeA, nodeB)
ts.AssertConflictsInCacheAcceptanceState([]string{"tx1", "tx2"}, acceptance.Accepted, nodeA, nodeB)
}
@@ -244,7 +246,7 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
node1 := ts.AddValidatorNode("node1")
node2 := ts.AddValidatorNode("node2")
- ts.AddBasicBlockIssuer("default")
+ wallet := ts.AddGenesisWallet("default", node1)
ts.Run(true, map[string][]options.Option[protocol.Protocol]{})
@@ -257,16 +259,17 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
// Create and issue double spends
{
- tx1 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx1", 1, "Genesis:0"))
- tx2 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx2", 1, "Genesis:0"))
+ tx1 := wallet.CreateBasicOutputsEquallyFromInputs("tx1", 1, "Genesis:0")
+ tx2 := wallet.CreateBasicOutputsEquallyFromInputs("tx2", 1, "Genesis:0")
- ts.IssueBasicBlockAtSlotWithOptions("block1.1", 1, genesisCommitment, ts.DefaultBasicBlockIssuer(), node1, tx1)
- ts.IssueBasicBlockAtSlotWithOptions("block1.2", 1, genesisCommitment, ts.DefaultBasicBlockIssuer(), node1, tx2)
+ wallet.SetDefaultNode(node1)
+ ts.IssueBasicBlockAtSlotWithOptions("block1.1", 1, wallet, tx1, mock.WithSlotCommitment(genesisCommitment))
+ ts.IssueBasicBlockAtSlotWithOptions("block1.2", 1, wallet, tx2, mock.WithSlotCommitment(genesisCommitment))
ts.IssueValidationBlockAtSlot("block2.tx1", 2, genesisCommitment, node1, ts.BlockIDs("block1.1")...)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("block1.1"): {"tx1"},
ts.Block("block1.2"): {"tx2"},
@@ -274,8 +277,8 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
}, node1, node2)
ts.AssertTransactionInCacheConflicts(map[*iotago.Transaction][]string{
- ts.TransactionFramework.Transaction("tx2"): {"tx2"},
- ts.TransactionFramework.Transaction("tx1"): {"tx1"},
+ wallet.Transaction("tx2"): {"tx2"},
+ wallet.Transaction("tx1"): {"tx1"},
}, node1, node2)
}
@@ -289,7 +292,7 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
ts.Block("block2.2"): {"tx2"},
ts.Block("block2.tx1"): {"tx1"},
}, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
}
// Issue valid blocks that resolve the conflict.
@@ -301,8 +304,8 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
ts.Block("block2.3"): {"tx2"},
ts.Block("block2.tx1"): {"tx1"},
}, node1, node2)
- ts.AssertTransactionsInCacheAccepted(ts.TransactionFramework.Transactions("tx2"), true, node1, node2)
- ts.AssertTransactionsInCacheRejected(ts.TransactionFramework.Transactions("tx1"), true, node1, node2)
+ ts.AssertTransactionsInCacheAccepted(wallet.Transactions("tx2"), true, node1, node2)
+ ts.AssertTransactionsInCacheRejected(wallet.Transactions("tx1"), true, node1, node2)
}
// Advance both nodes at the edge of slot 1 committability
@@ -361,20 +364,21 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
commitment1 := lo.PanicOnErr(node2.Protocol.MainEngineInstance().Storage.Commitments().Load(1)).Commitment()
// This should be booked on the rejected tx1 conflict
- tx4 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx4", 1, "tx1:0"))
+ tx4 := wallet.CreateBasicOutputsEquallyFromInputs("tx4", 1, "tx1:0")
// Issue TX3 on top of rejected TX1 and 1 commitment on node2 (committed to slot 1)
{
- ts.IssueBasicBlockAtSlotWithOptions("n2-commit1", 5, commitment1, ts.DefaultBasicBlockIssuer(), node2, tx4)
+ wallet.SetDefaultNode(node2)
+ ts.IssueBasicBlockAtSlotWithOptions("n2-commit1", 5, wallet, tx4, mock.WithSlotCommitment(commitment1))
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("n2-commit1"): {}, // no conflits inherited as the block is invalid and doesn't get booked.
ts.Block("block2.tx1"): {"tx1"},
}, node2)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1"), true, node2)
- ts.AssertTransactionsInCacheRejected(ts.TransactionFramework.Transactions("tx4"), true, node2)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx4"), true, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1"), true, node2)
+ ts.AssertTransactionsInCacheRejected(wallet.Transactions("tx4"), true, node2)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx4"), true, node2)
// As the block commits to 1 but spending something orphaned in 1 it should be invalid
ts.AssertBlocksInCacheBooked(ts.Blocks("n2-commit1"), false, node2)
@@ -388,7 +392,7 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
ts.AssertBlocksInCacheBooked(ts.Blocks("n1-rejected-genesis"), true, node1)
ts.AssertBlocksInCacheInvalid(ts.Blocks("n1-rejected-genesis"), false, node1)
- ts.AssertTransactionsInCacheRejected(ts.TransactionFramework.Transactions("tx1"), true, node2)
+ ts.AssertTransactionsInCacheRejected(wallet.Transactions("tx1"), true, node2)
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("block2.tx1"): {"tx1"},
@@ -398,7 +402,8 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
// Issue TX4 on top of rejected TX1 but Genesis commitment on node2 (committed to slot 1)
{
- ts.IssueBasicBlockAtSlotWithOptions("n2-genesis", 5, genesisCommitment, ts.DefaultBasicBlockIssuer(), node2, tx4, mock.WithStrongParents(ts.BlockID("Genesis")))
+ wallet.SetDefaultNode(node2)
+ ts.IssueBasicBlockAtSlotWithOptions("n2-genesis", 5, wallet, tx4, mock.WithStrongParents(ts.BlockID("Genesis")), mock.WithSlotCommitment(genesisCommitment))
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("n2-genesis"): {"tx4"}, // on rejected conflict
@@ -410,11 +415,12 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
// Issue TX4 on top of rejected TX1 but Genesis commitment on node1 (committed to slot 0)
{
- ts.IssueBasicBlockAtSlotWithOptions("n1-genesis", 5, genesisCommitment, ts.DefaultBasicBlockIssuer(), node1, tx4, mock.WithStrongParents(ts.BlockID("Genesis")))
+ wallet.SetDefaultNode(node1)
+ ts.IssueBasicBlockAtSlotWithOptions("n1-genesis", 5, wallet, tx4, mock.WithStrongParents(ts.BlockID("Genesis")), mock.WithSlotCommitment(genesisCommitment))
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1"), true, node2)
- ts.AssertTransactionsInCacheRejected(ts.TransactionFramework.Transactions("tx4"), true, node2)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx4"), true, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1"), true, node2)
+ ts.AssertTransactionsInCacheRejected(wallet.Transactions("tx4"), true, node2)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx4"), true, node2)
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("n1-genesis"): {"tx4"}, // on rejected conflict
@@ -439,14 +445,16 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
)
// Exchange each-other blocks, ignoring invalidity
- ts.IssueExistingBlock("n2-genesis", ts.DefaultBasicBlockIssuer(), node1)
- ts.IssueExistingBlock("n2-commit1", ts.DefaultBasicBlockIssuer(), node1)
- ts.IssueExistingBlock("n1-genesis", ts.DefaultBasicBlockIssuer(), node2)
- ts.IssueExistingBlock("n1-rejected-genesis", ts.DefaultBasicBlockIssuer(), node2)
+ wallet.SetDefaultNode(node1)
+ ts.IssueExistingBlock("n2-genesis", wallet)
+ ts.IssueExistingBlock("n2-commit1", wallet)
+ wallet.SetDefaultNode(node2)
+ ts.IssueExistingBlock("n1-genesis", wallet)
+ ts.IssueExistingBlock("n1-rejected-genesis", wallet)
ts.IssueValidationBlockAtSlot("n1-rejected-commit1", 5, commitment1, node1, ts.BlockIDs("n1-rejected-genesis")...)
// Needs reissuing on node2 because it is invalid
- ts.IssueExistingBlock("n1-rejected-commit1", ts.DefaultBasicBlockIssuer(), node2)
+ ts.IssueExistingBlock("n1-rejected-commit1", wallet)
// The nodes agree on the results of the invalid blocks
ts.AssertBlocksInCacheBooked(ts.Blocks("n2-genesis", "n1-genesis", "n1-rejected-genesis"), true, node1, node2)
@@ -471,7 +479,7 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
// Commit further and test eviction of transactions
{
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2", "tx4"), true, node1, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2", "tx4"), true, node1, node2)
ts.IssueBlocksAtSlots("", []iotago.SlotIndex{6, 7, 8, 9, 10}, 5, "5.1", ts.Nodes("node1", "node2"), false, nil)
@@ -482,7 +490,7 @@ func Test_SpendRejectedCommittedRace(t *testing.T) {
testsuite.WithEvictedSlot(8),
)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2", "tx4"), false, node1, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2", "tx4"), false, node1, node2)
}
}
@@ -507,7 +515,7 @@ func Test_SpendPendingCommittedRace(t *testing.T) {
node1 := ts.AddValidatorNode("node1")
node2 := ts.AddValidatorNode("node2")
- ts.AddBasicBlockIssuer("default")
+ wallet := ts.AddGenesisWallet("default", node1)
ts.Run(true, map[string][]options.Option[protocol.Protocol]{})
@@ -520,23 +528,24 @@ func Test_SpendPendingCommittedRace(t *testing.T) {
// Create and issue double spends
{
- tx1 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx1", 1, "Genesis:0"))
- tx2 := lo.PanicOnErr(ts.TransactionFramework.CreateSimpleTransaction("tx2", 1, "Genesis:0"))
+ tx1 := wallet.CreateBasicOutputsEquallyFromInputs("tx1", 1, "Genesis:0")
+ tx2 := wallet.CreateBasicOutputsEquallyFromInputs("tx2", 1, "Genesis:0")
- ts.IssueBasicBlockAtSlotWithOptions("block1.1", 1, genesisCommitment, ts.DefaultBasicBlockIssuer(), node2, tx1)
- ts.IssueBasicBlockAtSlotWithOptions("block1.2", 1, genesisCommitment, ts.DefaultBasicBlockIssuer(), node2, tx2)
+ wallet.SetDefaultNode(node2)
+ ts.IssueBasicBlockAtSlotWithOptions("block1.1", 1, wallet, tx1)
+ ts.IssueBasicBlockAtSlotWithOptions("block1.2", 1, wallet, tx2)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
- ts.AssertTransactionsInCacheBooked(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCacheBooked(wallet.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
ts.AssertBlocksInCacheConflicts(map[*blocks.Block][]string{
ts.Block("block1.1"): {"tx1"},
ts.Block("block1.2"): {"tx2"},
}, node1, node2)
ts.AssertTransactionInCacheConflicts(map[*iotago.Transaction][]string{
- ts.TransactionFramework.Transaction("tx2"): {"tx2"},
- ts.TransactionFramework.Transaction("tx1"): {"tx1"},
+ wallet.Transaction("tx2"): {"tx2"},
+ wallet.Transaction("tx1"): {"tx1"},
}, node1, node2)
}
@@ -549,7 +558,7 @@ func Test_SpendPendingCommittedRace(t *testing.T) {
ts.Block("block2.1"): {"tx1"},
ts.Block("block2.2"): {"tx2"},
}, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
}
// Advance both nodes at the edge of slot 1 committability
@@ -604,8 +613,8 @@ func Test_SpendPendingCommittedRace(t *testing.T) {
ts.IssueValidationBlockAtSlot("n2-pending-genesis", 5, genesisCommitment, node2, ts.BlockIDs("block2.1")...)
ts.IssueValidationBlockAtSlot("n2-pending-commit1", 5, commitment1, node2, ts.BlockIDs("block2.1")...)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1"), true, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1"), true, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1"), true, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1"), true, node2)
ts.AssertBlocksInCacheBooked(ts.Blocks("n2-pending-genesis", "n2-pending-commit1"), true, node2)
ts.AssertBlocksInCacheInvalid(ts.Blocks("n2-pending-genesis", "n2-pending-commit1"), false, node2)
@@ -632,8 +641,9 @@ func Test_SpendPendingCommittedRace(t *testing.T) {
)
// Exchange each-other blocks, ignoring invalidity
- ts.IssueExistingBlock("n2-pending-genesis", ts.DefaultBasicBlockIssuer(), node1)
- ts.IssueExistingBlock("n2-pending-commit1", ts.DefaultBasicBlockIssuer(), node1)
+ wallet.SetDefaultNode(node1)
+ ts.IssueExistingBlock("n2-pending-genesis", wallet)
+ ts.IssueExistingBlock("n2-pending-commit1", wallet)
// The nodes agree on the results of the invalid blocks
ts.AssertBlocksInCacheBooked(ts.Blocks("n2-pending-genesis", "n2-pending-commit1"), true, node1, node2)
@@ -645,13 +655,13 @@ func Test_SpendPendingCommittedRace(t *testing.T) {
ts.Block("n2-pending-commit1"): {}, // no conflits inherited as the block merges orphaned conflicts.
}, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
}
// Commit further and test eviction of transactions
{
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
- ts.AssertTransactionsInCachePending(ts.TransactionFramework.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2"), true, node1, node2)
+ ts.AssertTransactionsInCachePending(wallet.Transactions("tx1", "tx2"), true, node1, node2)
ts.IssueBlocksAtSlots("", []iotago.SlotIndex{6, 7, 8, 9, 10}, 5, "5.1", ts.Nodes("node1", "node2"), false, nil)
@@ -662,6 +672,6 @@ func Test_SpendPendingCommittedRace(t *testing.T) {
testsuite.WithEvictedSlot(8),
)
- ts.AssertTransactionsExist(ts.TransactionFramework.Transactions("tx1", "tx2"), false, node1, node2)
+ ts.AssertTransactionsExist(wallet.Transactions("tx1", "tx2"), false, node1, node2)
}
}
diff --git a/pkg/tests/committee_rotation_test.go b/pkg/tests/committee_rotation_test.go
index 56b4f397d..375a3c98f 100644
--- a/pkg/tests/committee_rotation_test.go
+++ b/pkg/tests/committee_rotation_test.go
@@ -5,10 +5,10 @@ import (
"github.com/iotaledger/hive.go/runtime/options"
"github.com/iotaledger/iota-core/pkg/protocol"
- "github.com/iotaledger/iota-core/pkg/protocol/snapshotcreator"
"github.com/iotaledger/iota-core/pkg/protocol/sybilprotection/seatmanager/topstakers"
"github.com/iotaledger/iota-core/pkg/protocol/sybilprotection/sybilprotectionv1"
"github.com/iotaledger/iota-core/pkg/testsuite"
+ "github.com/iotaledger/iota-core/pkg/testsuite/snapshotcreator"
iotago "github.com/iotaledger/iota.go/v4"
)
@@ -38,12 +38,13 @@ func Test_TopStakersRotation(t *testing.T) {
)
defer ts.Shutdown()
- ts.AddValidatorNode("node1", 1_000_006)
+ node1 := ts.AddValidatorNode("node1", 1_000_006)
ts.AddValidatorNode("node2", 1_000_005)
ts.AddValidatorNode("node3", 1_000_004)
ts.AddValidatorNode("node4", 1_000_003)
ts.AddValidatorNode("node5", 1_000_002)
ts.AddValidatorNode("node6", 1_000_001)
+ ts.AddGenesisWallet("default", node1)
nodeOptions := make(map[string][]options.Option[protocol.Protocol])
@@ -77,24 +78,24 @@ func Test_TopStakersRotation(t *testing.T) {
ts.IssueBlocksAtSlots("wave-1:", []iotago.SlotIndex{1, 2, 3, 4}, 4, "Genesis", ts.Nodes(), true, nil)
- ts.IssueCandidacyAnnouncementInSlot("node1-candidacy:1", 4, "wave-1:4.3", ts.Node("node1"))
- ts.IssueCandidacyAnnouncementInSlot("node4-candidacy:1", 5, "node1-candidacy:1", ts.Node("node4"))
+ ts.IssueCandidacyAnnouncementInSlot("node1-candidacy:1", 4, "wave-1:4.3", ts.Wallet("node1"))
+ ts.IssueCandidacyAnnouncementInSlot("node4-candidacy:1", 5, "node1-candidacy:1", ts.Wallet("node4"))
ts.IssueBlocksAtSlots("wave-2:", []iotago.SlotIndex{5, 6, 7, 8, 9}, 4, "node4-candidacy:1", ts.Nodes(), true, nil)
- ts.IssueCandidacyAnnouncementInSlot("node4-candidacy:2", 9, "wave-2:9.3", ts.Node("node4"))
- ts.IssueCandidacyAnnouncementInSlot("node5-candidacy:1", 9, "node4-candidacy:2", ts.Node("node5"))
+ ts.IssueCandidacyAnnouncementInSlot("node4-candidacy:2", 9, "wave-2:9.3", ts.Wallet("node4"))
+ ts.IssueCandidacyAnnouncementInSlot("node5-candidacy:1", 9, "node4-candidacy:2", ts.Wallet("node5"))
// This candidacy should be considered as it's announced at the last possible slot.
- ts.IssueCandidacyAnnouncementInSlot("node6-candidacy:1", 10, "node5-candidacy:1", ts.Node("node6"))
+ ts.IssueCandidacyAnnouncementInSlot("node6-candidacy:1", 10, "node5-candidacy:1", ts.Wallet("node6"))
ts.IssueBlocksAtSlots("wave-3:", []iotago.SlotIndex{10}, 4, "node6-candidacy:1", ts.Nodes(), true, nil)
// Those candidacies should not be considered as they're issued after EpochNearingThreshold (slot 10).
- ts.IssueCandidacyAnnouncementInSlot("node2-candidacy:1", 11, "wave-3:10.3", ts.Node("node2"))
- ts.IssueCandidacyAnnouncementInSlot("node3-candidacy:1", 11, "node2-candidacy:1", ts.Node("node3"))
- ts.IssueCandidacyAnnouncementInSlot("node4-candidacy:3", 11, "node3-candidacy:1", ts.Node("node3"))
- ts.IssueCandidacyAnnouncementInSlot("node5-candidacy:2", 11, "node4-candidacy:3", ts.Node("node3"))
+ ts.IssueCandidacyAnnouncementInSlot("node2-candidacy:1", 11, "wave-3:10.3", ts.Wallet("node2"))
+ ts.IssueCandidacyAnnouncementInSlot("node3-candidacy:1", 11, "node2-candidacy:1", ts.Wallet("node3"))
+ ts.IssueCandidacyAnnouncementInSlot("node4-candidacy:3", 11, "node3-candidacy:1", ts.Wallet("node3"))
+ ts.IssueCandidacyAnnouncementInSlot("node5-candidacy:2", 11, "node4-candidacy:3", ts.Wallet("node3"))
// Assert that only candidates that issued before slot 11 are considered.
ts.AssertSybilProtectionCandidates(1, []iotago.AccountID{
diff --git a/pkg/tests/loss_of_acceptance_test.go b/pkg/tests/loss_of_acceptance_test.go
index ed26be402..a8bb02537 100644
--- a/pkg/tests/loss_of_acceptance_test.go
+++ b/pkg/tests/loss_of_acceptance_test.go
@@ -32,8 +32,8 @@ func TestLossOfAcceptanceFromGenesis(t *testing.T) {
)
defer ts.Shutdown()
- ts.AddBasicBlockIssuer("default")
node0 := ts.AddValidatorNode("node0")
+ ts.AddGenesisWallet("default", node0)
ts.AddValidatorNode("node1")
ts.AddNode("node2")
@@ -117,8 +117,8 @@ func TestLossOfAcceptanceFromSnapshot(t *testing.T) {
)
defer ts.Shutdown()
- ts.AddBasicBlockIssuer("default")
node0 := ts.AddValidatorNode("node0")
+ ts.AddGenesisWallet("default", node0)
ts.AddValidatorNode("node1")
node2 := ts.AddNode("node2")
@@ -211,8 +211,8 @@ func TestLossOfAcceptanceWithRestartFromDisk(t *testing.T) {
)
defer ts.Shutdown()
- ts.AddBasicBlockIssuer("default")
node0 := ts.AddValidatorNode("node0")
+ ts.AddGenesisWallet("default", node0)
ts.AddValidatorNode("node1")
node2 := ts.AddNode("node2")
diff --git a/pkg/tests/protocol_engine_switching_test.go b/pkg/tests/protocol_engine_switching_test.go
index b0c262f19..aa6bf7834 100644
--- a/pkg/tests/protocol_engine_switching_test.go
+++ b/pkg/tests/protocol_engine_switching_test.go
@@ -56,7 +56,7 @@ func TestProtocol_EngineSwitching(t *testing.T) {
node6 := ts.AddValidatorNode("node6")
node7 := ts.AddValidatorNode("node7")
node8 := ts.AddNode("node8")
- ts.AddBasicBlockIssuer("default", iotago.MaxBlockIssuanceCredits/2)
+ ts.AddGenesisWallet("default", node0, iotago.MaxBlockIssuanceCredits/2)
const expectedCommittedSlotAfterPartitionMerge = 19
nodesP1 := []*mock.Node{node0, node1, node2, node3, node4, node5}
diff --git a/pkg/tests/protocol_startup_test.go b/pkg/tests/protocol_startup_test.go
index 20e957be5..11b6672d1 100644
--- a/pkg/tests/protocol_startup_test.go
+++ b/pkg/tests/protocol_startup_test.go
@@ -141,7 +141,7 @@ func Test_StartNodeFromSnapshotAndDisk(t *testing.T) {
nodeA := ts.AddValidatorNode("nodeA")
nodeB := ts.AddValidatorNode("nodeB")
ts.AddNode("nodeC")
- ts.AddBasicBlockIssuer("default", iotago.MaxBlockIssuanceCredits/2)
+ ts.AddGenesisWallet("default", nodeA, iotago.MaxBlockIssuanceCredits/2)
nodeOptions := []options.Option[protocol.Protocol]{
protocol.WithStorageOptions(
diff --git a/pkg/tests/upgrade_signaling_test.go b/pkg/tests/upgrade_signaling_test.go
index b5ce6336b..8f5ed29f3 100644
--- a/pkg/tests/upgrade_signaling_test.go
+++ b/pkg/tests/upgrade_signaling_test.go
@@ -22,6 +22,7 @@ import (
"github.com/iotaledger/iota-core/pkg/storage"
"github.com/iotaledger/iota-core/pkg/storage/permanent"
"github.com/iotaledger/iota-core/pkg/testsuite"
+ "github.com/iotaledger/iota-core/pkg/testsuite/mock"
iotago "github.com/iotaledger/iota.go/v4"
"github.com/iotaledger/iota.go/v4/api"
)
@@ -107,13 +108,13 @@ func Test_Upgrade_Signaling(t *testing.T) {
),
)
- ts.AddValidatorNode("nodeA")
+ nodeA := ts.AddValidatorNode("nodeA")
ts.AddValidatorNode("nodeB")
ts.AddValidatorNode("nodeC")
ts.AddValidatorNode("nodeD")
ts.AddNode("nodeE")
ts.AddNode("nodeF")
- ts.AddBasicBlockIssuer("default", iotago.MaxBlockIssuanceCredits/2)
+ wallet := ts.AddGenesisWallet("default", nodeA, iotago.MaxBlockIssuanceCredits/2)
ts.Run(true, map[string][]options.Option[protocol.Protocol]{
"nodeA": nodeOptionsWithoutV5,
@@ -135,7 +136,7 @@ func Test_Upgrade_Signaling(t *testing.T) {
ExpirySlot: iotago.MaxSlotIndex,
OutputID: ts.AccountOutput("Genesis:1").OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(ts.Node("nodeA").Validator.PublicKey))),
- ValidatorStake: testsuite.MinValidatorAccountAmount,
+ ValidatorStake: mock.MinValidatorAccountAmount,
DelegationStake: 0,
FixedCost: 0,
StakeEndEpoch: iotago.MaxEpochIndex,
@@ -143,11 +144,11 @@ func Test_Upgrade_Signaling(t *testing.T) {
}, ts.Nodes()...)
ts.AssertAccountData(&accounts.AccountData{
- ID: ts.DefaultBasicBlockIssuer().AccountID,
+ ID: wallet.BlockIssuer.AccountID,
Credits: &accounts.BlockIssuanceCredits{Value: iotago.MaxBlockIssuanceCredits / 2, UpdateTime: 0},
ExpirySlot: iotago.MaxSlotIndex,
OutputID: ts.AccountOutput("Genesis:5").OutputID(),
- BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(ts.DefaultBasicBlockIssuer().PublicKey))),
+ BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(wallet.BlockIssuer.PublicKey))),
ValidatorStake: 0,
DelegationStake: 0,
FixedCost: 0,
@@ -169,7 +170,7 @@ func Test_Upgrade_Signaling(t *testing.T) {
ExpirySlot: iotago.MaxSlotIndex,
OutputID: ts.AccountOutput("Genesis:1").OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(ts.Node("nodeA").Validator.PublicKey))),
- ValidatorStake: testsuite.MinValidatorAccountAmount,
+ ValidatorStake: mock.MinValidatorAccountAmount,
DelegationStake: 0,
FixedCost: 0,
StakeEndEpoch: iotago.MaxEpochIndex,
@@ -182,7 +183,7 @@ func Test_Upgrade_Signaling(t *testing.T) {
ExpirySlot: iotago.MaxSlotIndex,
OutputID: ts.AccountOutput("Genesis:4").OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(ts.Node("nodeD").Validator.PublicKey))),
- ValidatorStake: testsuite.MinValidatorAccountAmount,
+ ValidatorStake: mock.MinValidatorAccountAmount,
DelegationStake: 0,
FixedCost: 0,
StakeEndEpoch: iotago.MaxEpochIndex,
@@ -203,7 +204,7 @@ func Test_Upgrade_Signaling(t *testing.T) {
ExpirySlot: iotago.MaxSlotIndex,
OutputID: ts.AccountOutput("Genesis:1").OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(ts.Node("nodeA").Validator.PublicKey))),
- ValidatorStake: testsuite.MinValidatorAccountAmount,
+ ValidatorStake: mock.MinValidatorAccountAmount,
DelegationStake: 0,
FixedCost: 0,
StakeEndEpoch: iotago.MaxEpochIndex,
@@ -368,7 +369,7 @@ func Test_Upgrade_Signaling(t *testing.T) {
ExpirySlot: iotago.MaxSlotIndex,
OutputID: ts.AccountOutput("Genesis:1").OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(ts.Node("nodeA").Validator.PublicKey))),
- ValidatorStake: testsuite.MinValidatorAccountAmount,
+ ValidatorStake: mock.MinValidatorAccountAmount,
DelegationStake: 0,
FixedCost: 0,
StakeEndEpoch: iotago.MaxEpochIndex,
@@ -381,7 +382,7 @@ func Test_Upgrade_Signaling(t *testing.T) {
ExpirySlot: iotago.MaxSlotIndex,
OutputID: ts.AccountOutput("Genesis:4").OutputID(),
BlockIssuerKeys: iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(ts.Node("nodeD").Validator.PublicKey))),
- ValidatorStake: testsuite.MinValidatorAccountAmount,
+ ValidatorStake: mock.MinValidatorAccountAmount,
DelegationStake: 0,
FixedCost: 0,
StakeEndEpoch: iotago.MaxEpochIndex,
diff --git a/pkg/testsuite/blocks.go b/pkg/testsuite/blocks.go
index cf6c89cc5..90e5c70ac 100644
--- a/pkg/testsuite/blocks.go
+++ b/pkg/testsuite/blocks.go
@@ -130,7 +130,7 @@ func (t *TestSuite) AssertBlocksInCacheConflicts(blockConflicts map[*blocks.Bloc
return ierrors.Errorf("AssertBlocksInCacheConflicts: %s: block %s is root block", node.Name, blockFromCache.ID())
}
- expectedConflictIDs := ds.NewSet(lo.Map(conflictAliases, t.TransactionFramework.TransactionID)...)
+ expectedConflictIDs := ds.NewSet(lo.Map(conflictAliases, t.DefaultWallet().TransactionID)...)
actualConflictIDs := blockFromCache.ConflictIDs()
if expectedConflictIDs.Size() != actualConflictIDs.Size() {
diff --git a/pkg/testsuite/conflicts.go b/pkg/testsuite/conflicts.go
index 7c7047da0..b1fa92989 100644
--- a/pkg/testsuite/conflicts.go
+++ b/pkg/testsuite/conflicts.go
@@ -13,7 +13,7 @@ func (t *TestSuite) AssertConflictsInCacheAcceptanceState(expectedConflictAliase
for _, node := range nodes {
for _, conflictAlias := range expectedConflictAliases {
t.Eventually(func() error {
- acceptanceState := node.Protocol.MainEngineInstance().Ledger.ConflictDAG().AcceptanceState(ds.NewSet(t.TransactionFramework.TransactionID(conflictAlias)))
+ acceptanceState := node.Protocol.MainEngineInstance().Ledger.ConflictDAG().AcceptanceState(ds.NewSet(t.DefaultWallet().TransactionID(conflictAlias)))
if acceptanceState != expectedState {
return ierrors.Errorf("assertTransactionsInCacheWithFunc: %s: conflict %s is %s, but expected %s", node.Name, conflictAlias, acceptanceState, expectedState)
diff --git a/pkg/testsuite/mock/blockissuer.go b/pkg/testsuite/mock/blockissuer.go
index 527bcff19..1e6fad7fa 100644
--- a/pkg/testsuite/mock/blockissuer.go
+++ b/pkg/testsuite/mock/blockissuer.go
@@ -12,6 +12,7 @@ import (
"golang.org/x/crypto/blake2b"
"github.com/iotaledger/hive.go/core/safemath"
+ hiveEd25519 "github.com/iotaledger/hive.go/crypto/ed25519"
"github.com/iotaledger/hive.go/ierrors"
"github.com/iotaledger/hive.go/lo"
"github.com/iotaledger/hive.go/runtime/event"
@@ -45,14 +46,15 @@ type BlockIssuer struct {
Name string
Validator bool
+ AccountID iotago.AccountID
+ OutputID iotago.OutputID
+ PublicKey ed25519.PublicKey
+ privateKey ed25519.PrivateKey
+
events *Events
workerPool *workerpool.WorkerPool
- privateKey ed25519.PrivateKey
- PublicKey ed25519.PublicKey
- AccountID iotago.AccountID
-
optsTipSelectionTimeout time.Duration
optsTipSelectionRetryInterval time.Duration
// optsIncompleteBlockAccepted defines whether the node allows filling in incomplete block and issuing it for user.
@@ -60,13 +62,12 @@ type BlockIssuer struct {
optsRateSetterEnabled bool
}
-func NewBlockIssuer(t *testing.T, name string, validator bool, opts ...options.Option[BlockIssuer]) *BlockIssuer {
- pub, priv, err := ed25519.GenerateKey(nil)
- if err != nil {
- panic(err)
- }
+func NewBlockIssuer(t *testing.T, name string, keyManager *KeyManager, accountID iotago.AccountID, validator bool, opts ...options.Option[BlockIssuer]) *BlockIssuer {
+ priv, pub := keyManager.KeyPair()
- accountID := iotago.AccountID(blake2b.Sum256(pub))
+ if accountID == iotago.EmptyAccountID {
+ accountID = iotago.AccountID(blake2b.Sum256(pub))
+ }
accountID.RegisterAlias(name)
return options.Apply(&BlockIssuer{
@@ -85,6 +86,10 @@ func NewBlockIssuer(t *testing.T, name string, validator bool, opts ...options.O
}, opts)
}
+func (i *BlockIssuer) BlockIssuerKeys() iotago.BlockIssuerKeys {
+ return iotago.NewBlockIssuerKeys(iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(hiveEd25519.PublicKey(i.PublicKey)))
+}
+
// Shutdown shuts down the block issuer.
func (i *BlockIssuer) Shutdown() {
i.workerPool.Shutdown()
@@ -188,7 +193,7 @@ func (i *BlockIssuer) IssueValidationBlock(ctx context.Context, alias string, no
validationBlock, _ := block.ValidationBlock()
- fmt.Printf("Issued ValidationBlock: %s - slot %d - commitment %s %d - latest finalized slot %d - version: %d - highestSupportedVersion: %d, hash: %s\n", block.ID(), block.ID().Slot(), block.SlotCommitmentID(), block.SlotCommitmentID().Slot(), block.ProtocolBlock().LatestFinalizedSlot, block.ProtocolBlock().ProtocolVersion, validationBlock.HighestSupportedVersion, validationBlock.ProtocolParametersHash)
+ fmt.Printf("Issued ValidationBlock: %s - slot %d - commitment %s %d - latest finalized slot %d - version: %d - highestSupportedVersion: %d, hash: %s\n", block.ID(), block.ID().Slot(), block.SlotCommitmentID(), block.SlotCommitmentID().Slot(), block.ProtocolBlock().Header.LatestFinalizedSlot, block.ProtocolBlock().Header.ProtocolVersion, validationBlock.HighestSupportedVersion, validationBlock.ProtocolParametersHash)
return block
}
@@ -283,7 +288,7 @@ func (i *BlockIssuer) IssueBasicBlock(ctx context.Context, alias string, node *N
require.NoErrorf(i.Testing, i.IssueBlock(block.ModelBlock(), node), "%s > failed to issue block with alias %s", i.Name, alias)
- fmt.Printf("%s > Issued block: %s - slot %d - commitment %s %d - latest finalized slot %d\n", i.Name, block.ID(), block.ID().Slot(), block.SlotCommitmentID(), block.SlotCommitmentID().Slot(), block.ProtocolBlock().LatestFinalizedSlot)
+ fmt.Printf("%s > Issued block: %s - slot %d - commitment %s %d - latest finalized slot %d\n", i.Name, block.ID(), block.ID().Slot(), block.SlotCommitmentID(), block.SlotCommitmentID().Slot(), block.ProtocolBlock().Header.LatestFinalizedSlot)
return block
}
@@ -361,30 +366,30 @@ func (i *BlockIssuer) IssueBlockAndAwaitEvent(ctx context.Context, block *model.
}
}
-func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.ProtocolBlock, node *Node, optIssuerAccount ...Account) (iotago.BlockID, error) {
+func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Block, node *Node, optIssuerAccount ...Account) (iotago.BlockID, error) {
// if anything changes, need to make a new signature
var resign bool
- apiForVersion, err := node.Protocol.APIForVersion(iotaBlock.ProtocolVersion)
+ apiForVersion, err := node.Protocol.APIForVersion(iotaBlock.Header.ProtocolVersion)
if err != nil {
- return iotago.EmptyBlockID, ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "protocolVersion invalid: %d", iotaBlock.ProtocolVersion)
+ return iotago.EmptyBlockID, ierrors.Wrapf(ErrBlockAttacherInvalidBlock, "protocolVersion invalid: %d", iotaBlock.Header.ProtocolVersion)
}
protoParams := apiForVersion.ProtocolParameters()
- if iotaBlock.NetworkID == 0 {
- iotaBlock.NetworkID = protoParams.NetworkID()
+ if iotaBlock.Header.NetworkID == 0 {
+ iotaBlock.Header.NetworkID = protoParams.NetworkID()
resign = true
}
- if iotaBlock.SlotCommitmentID == iotago.EmptyCommitmentID {
- iotaBlock.SlotCommitmentID = node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID()
- iotaBlock.LatestFinalizedSlot = node.Protocol.MainEngineInstance().Storage.Settings().LatestFinalizedSlot()
+ if iotaBlock.Header.SlotCommitmentID == iotago.EmptyCommitmentID {
+ iotaBlock.Header.SlotCommitmentID = node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID()
+ iotaBlock.Header.LatestFinalizedSlot = node.Protocol.MainEngineInstance().Storage.Settings().LatestFinalizedSlot()
resign = true
}
- switch innerBlock := iotaBlock.Block.(type) {
- case *iotago.BasicBlock:
+ switch innerBlock := iotaBlock.Body.(type) {
+ case *iotago.BasicBlockBody:
switch payload := innerBlock.Payload.(type) {
case *iotago.SignedTransaction:
if payload.Transaction.NetworkID != protoParams.NetworkID() {
@@ -404,7 +409,7 @@ func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Protoco
resign = true
}
- case *iotago.ValidationBlock:
+ case *iotago.ValidationBlockBody:
//nolint:revive,staticcheck //temporarily disable
if len(iotaBlock.Parents()) == 0 {
// TODO: implement tipselection for validator blocks
@@ -412,20 +417,20 @@ func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Protoco
}
references := make(model.ParentReferences)
- 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()
+ references[iotago.StrongParentType] = iotaBlock.Body.StrongParentIDs().RemoveDupsAndSort()
+ references[iotago.WeakParentType] = iotaBlock.Body.WeakParentIDs().RemoveDupsAndSort()
+ references[iotago.ShallowLikeParentType] = iotaBlock.Body.ShallowLikeParentIDs().RemoveDupsAndSort()
+ if iotaBlock.Header.IssuingTime.Equal(time.Unix(0, 0)) {
+ iotaBlock.Header.IssuingTime = time.Now().UTC()
resign = true
}
- if err = i.validateReferences(iotaBlock.IssuingTime, iotaBlock.SlotCommitmentID.Slot(), references, node); err != nil {
+ if err = i.validateReferences(iotaBlock.Header.IssuingTime, iotaBlock.Header.SlotCommitmentID.Slot(), references, node); 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(apiForVersion.TimeProvider().SlotFromTime(iotaBlock.IssuingTime), apiForVersion.ProtocolParameters().MaxCommittableAge())
+ if basicBlock, isBasicBlock := iotaBlock.Body.(*iotago.BasicBlockBody); isBasicBlock && basicBlock.MaxBurnedMana == 0 {
+ rmcSlot, err := safemath.SafeSub(apiForVersion.TimeProvider().SlotFromTime(iotaBlock.Header.IssuingTime), apiForVersion.ProtocolParameters().MaxCommittableAge())
if err != nil {
rmcSlot = 0
}
@@ -442,10 +447,10 @@ func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Protoco
resign = true
}
- if iotaBlock.IssuerID.Empty() || resign {
+ if iotaBlock.Header.IssuerID.Empty() || resign {
if i.optsIncompleteBlockAccepted && len(optIssuerAccount) > 0 {
issuerAccount := optIssuerAccount[0]
- iotaBlock.IssuerID = issuerAccount.ID()
+ iotaBlock.Header.IssuerID = issuerAccount.ID()
signature, signatureErr := iotaBlock.Sign(iotago.NewAddressKeysForEd25519Address(issuerAccount.Address().(*iotago.Ed25519Address), issuerAccount.PrivateKey()))
if signatureErr != nil {
@@ -468,7 +473,7 @@ func (i *BlockIssuer) AttachBlock(ctx context.Context, iotaBlock *iotago.Protoco
return iotago.EmptyBlockID, ierrors.Wrap(err, "error serializing block to model block")
}
- if !i.optsRateSetterEnabled || node.Protocol.MainEngineInstance().Scheduler.IsBlockIssuerReady(modelBlock.ProtocolBlock().IssuerID) {
+ if !i.optsRateSetterEnabled || node.Protocol.MainEngineInstance().Scheduler.IsBlockIssuerReady(modelBlock.ProtocolBlock().Header.IssuerID) {
i.events.BlockConstructed.Trigger(modelBlock)
if err = i.IssueBlockAndAwaitEvent(ctx, modelBlock, node, node.Protocol.Events.Engine.BlockDAG.BlockAttached); err != nil {
diff --git a/pkg/testsuite/mock/hdwallet.go b/pkg/testsuite/mock/hdwallet.go
deleted file mode 100644
index a4e1ceb4e..000000000
--- a/pkg/testsuite/mock/hdwallet.go
+++ /dev/null
@@ -1,138 +0,0 @@
-package mock
-
-import (
- "crypto/ed25519"
- "fmt"
-
- "github.com/wollac/iota-crypto-demo/pkg/bip32path"
- "github.com/wollac/iota-crypto-demo/pkg/slip10"
- "github.com/wollac/iota-crypto-demo/pkg/slip10/eddsa"
-
- "github.com/iotaledger/hive.go/ierrors"
- "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
- iotago "github.com/iotaledger/iota.go/v4"
-)
-
-const (
- pathString = "44'/4218'/0'/%d'"
-)
-
-type HDWallet struct {
- name string
- seed []byte
- index uint64
- utxo []*utxoledger.Output
-}
-
-func NewHDWallet(name string, seed []byte, index uint64) *HDWallet {
- return &HDWallet{
- name: name,
- seed: seed,
- index: index,
- utxo: make([]*utxoledger.Output, 0),
- }
-}
-
-func (hd *HDWallet) BookSpents(spentOutputs []*utxoledger.Output) {
- for _, spent := range spentOutputs {
- hd.BookSpent(spent)
- }
-}
-
-func (hd *HDWallet) BookSpent(spentOutput *utxoledger.Output) {
- newUtxo := make([]*utxoledger.Output, 0)
- for _, u := range hd.utxo {
- if u.OutputID() == spentOutput.OutputID() {
- fmt.Printf("%s spent %s\n", hd.name, u.OutputID().ToHex())
-
- continue
- }
- newUtxo = append(newUtxo, u)
- }
- hd.utxo = newUtxo
-}
-
-func (hd *HDWallet) Name() string {
- return hd.name
-}
-
-func (hd *HDWallet) Balance() iotago.BaseToken {
- var balance iotago.BaseToken
- for _, u := range hd.utxo {
- balance += u.BaseTokenAmount()
- }
-
- return balance
-}
-
-func (hd *HDWallet) BookOutput(output *utxoledger.Output) {
- if output != nil {
- fmt.Printf("%s book %s\n", hd.name, output.OutputID().ToHex())
- hd.utxo = append(hd.utxo, output)
- }
-}
-
-// KeyPair calculates an ed25519 key pair by using slip10.
-func (hd *HDWallet) KeyPair() (ed25519.PrivateKey, ed25519.PublicKey) {
- path, err := bip32path.ParsePath(fmt.Sprintf(pathString, hd.index))
- if err != nil {
- panic(err)
- }
-
- curve := eddsa.Ed25519()
- key, err := slip10.DeriveKeyFromPath(hd.seed, curve, path)
- if err != nil {
- panic(err)
- }
-
- pubKey, privKey := key.Key.(eddsa.Seed).Ed25519Key()
-
- return ed25519.PrivateKey(privKey), ed25519.PublicKey(pubKey)
-}
-
-func (hd *HDWallet) AddressSigner() iotago.AddressSigner {
- privKey, pubKey := hd.KeyPair()
- address := iotago.Ed25519AddressFromPubKey(pubKey)
-
- return iotago.NewInMemoryAddressSigner(iotago.NewAddressKeysForEd25519Address(address, privKey))
-}
-
-func (hd *HDWallet) Outputs() []*utxoledger.Output {
- return hd.utxo
-}
-
-// Address calculates an ed25519 address by using slip10.
-func (hd *HDWallet) Address(addressType ...iotago.AddressType) iotago.DirectUnlockableAddress {
- _, pubKey := hd.KeyPair()
-
- addrType := iotago.AddressEd25519
- if len(addressType) > 0 {
- addrType = addressType[0]
- }
-
- switch addrType {
- case iotago.AddressEd25519:
- return iotago.Ed25519AddressFromPubKey(pubKey)
- case iotago.AddressImplicitAccountCreation:
- return iotago.ImplicitAccountCreationAddressFromPubKey(pubKey)
- default:
- panic(ierrors.Wrapf(iotago.ErrUnknownAddrType, "type %d", addressType))
- }
-}
-
-func (hd *HDWallet) PrintStatus() {
- var status string
- status += fmt.Sprintf("Name: %s\n", hd.name)
- status += fmt.Sprintf("Address: %s\n", hd.Address().Bech32(iotago.PrefixTestnet))
- status += fmt.Sprintf("Balance: %d\n", hd.Balance())
- status += "Outputs: \n"
- for _, u := range hd.utxo {
- nativeTokenDescription := ""
- nativeTokenFeature := u.Output().FeatureSet().NativeToken()
- if nativeTokenFeature != nil {
- nativeTokenDescription += fmt.Sprintf("%s: %s, ", nativeTokenFeature.ID.ToHex(), nativeTokenFeature.Amount)
- }
- status += fmt.Sprintf("\t%s [%s] = %d %v\n", u.OutputID().ToHex(), u.OutputType(), u.BaseTokenAmount(), nativeTokenDescription)
- }
- fmt.Printf("%s\n", status)
-}
diff --git a/pkg/testsuite/mock/keymanager.go b/pkg/testsuite/mock/keymanager.go
new file mode 100644
index 000000000..236a50551
--- /dev/null
+++ b/pkg/testsuite/mock/keymanager.go
@@ -0,0 +1,75 @@
+package mock
+
+import (
+ "crypto/ed25519"
+ "fmt"
+
+ "github.com/wollac/iota-crypto-demo/pkg/bip32path"
+ "github.com/wollac/iota-crypto-demo/pkg/slip10"
+ "github.com/wollac/iota-crypto-demo/pkg/slip10/eddsa"
+
+ "github.com/iotaledger/hive.go/ierrors"
+ iotago "github.com/iotaledger/iota.go/v4"
+)
+
+const (
+ pathString = "44'/4218'/0'/%d'"
+)
+
+// KeyManager is a hierarchical deterministic key manager.
+type KeyManager struct {
+ seed []byte
+ index uint64
+}
+
+func NewKeyManager(seed []byte, index uint64) *KeyManager {
+ return &KeyManager{
+ seed: seed,
+ index: index,
+ }
+}
+
+// KeyPair calculates an ed25519 key pair by using slip10.
+func (k *KeyManager) KeyPair() (ed25519.PrivateKey, ed25519.PublicKey) {
+ path, err := bip32path.ParsePath(fmt.Sprintf(pathString, k.index))
+ if err != nil {
+ panic(err)
+ }
+
+ curve := eddsa.Ed25519()
+ key, err := slip10.DeriveKeyFromPath(k.seed, curve, path)
+ if err != nil {
+ panic(err)
+ }
+
+ pubKey, privKey := key.Key.(eddsa.Seed).Ed25519Key()
+
+ return ed25519.PrivateKey(privKey), ed25519.PublicKey(pubKey)
+}
+
+// AddressSigner returns an address signer.
+func (k *KeyManager) AddressSigner() iotago.AddressSigner {
+ privKey, pubKey := k.KeyPair()
+
+ // add both address types for simplicity in tests
+ ed25519Address := iotago.Ed25519AddressFromPubKey(pubKey)
+ ed25519AddressKey := iotago.NewAddressKeysForEd25519Address(ed25519Address, privKey)
+ implicitAccountCreationAddress := iotago.ImplicitAccountCreationAddressFromPubKey(pubKey)
+ implicitAccountCreationAddressKey := iotago.NewAddressKeysForImplicitAccountCreationAddress(implicitAccountCreationAddress, privKey)
+
+ return iotago.NewInMemoryAddressSigner(ed25519AddressKey, implicitAccountCreationAddressKey)
+}
+
+// Address calculates an address of the specified type.
+func (k *KeyManager) Address(addressType iotago.AddressType) iotago.DirectUnlockableAddress {
+ _, pubKey := k.KeyPair()
+
+ switch addressType {
+ case iotago.AddressEd25519:
+ return iotago.Ed25519AddressFromPubKey(pubKey)
+ case iotago.AddressImplicitAccountCreation:
+ return iotago.ImplicitAccountCreationAddressFromPubKey(pubKey)
+ default:
+ panic(ierrors.Wrapf(iotago.ErrUnknownAddrType, "type %d", addressType))
+ }
+}
diff --git a/pkg/testsuite/mock/node.go b/pkg/testsuite/mock/node.go
index afca4da93..b9bde387f 100644
--- a/pkg/testsuite/mock/node.go
+++ b/pkg/testsuite/mock/node.go
@@ -2,7 +2,6 @@ package mock
import (
"context"
- "crypto/ed25519"
"fmt"
"sync/atomic"
"testing"
@@ -29,6 +28,7 @@ import (
"github.com/iotaledger/iota-core/pkg/protocol/engine/notarization"
iotago "github.com/iotaledger/iota.go/v4"
"github.com/iotaledger/iota.go/v4/merklehasher"
+ "github.com/iotaledger/iota.go/v4/tpkg"
)
// idAliases contains a list of aliases registered for a set of IDs.
@@ -48,8 +48,9 @@ func UnregisterIDAliases() {
type Node struct {
Testing *testing.T
- Name string
- Validator *BlockIssuer
+ Name string
+ Validator *BlockIssuer
+ KeyManager *KeyManager
ctx context.Context
ctxCancel context.CancelFunc
@@ -73,10 +74,9 @@ type Node struct {
}
func NewNode(t *testing.T, net *Network, partition string, name string, validator bool) *Node {
- pub, priv, err := ed25519.GenerateKey(nil)
- if err != nil {
- panic(err)
- }
+ seed := tpkg.RandEd25519Seed()
+ keyManager := NewKeyManager(seed[:], 0)
+ priv, pub := keyManager.KeyPair()
accountID := iotago.AccountID(blake2b.Sum256(pub))
accountID.RegisterAlias(name)
@@ -86,7 +86,7 @@ func NewNode(t *testing.T, net *Network, partition string, name string, validato
var validatorBlockIssuer *BlockIssuer
if validator {
- validatorBlockIssuer = NewBlockIssuer(t, name, validator)
+ validatorBlockIssuer = NewBlockIssuer(t, name, keyManager, accountID, validator)
} else {
validatorBlockIssuer = nil
}
@@ -96,7 +96,8 @@ func NewNode(t *testing.T, net *Network, partition string, name string, validato
Name: name,
- Validator: validatorBlockIssuer,
+ Validator: validatorBlockIssuer,
+ KeyManager: keyManager,
PeerID: peerID,
@@ -354,19 +355,19 @@ func (n *Node) attachEngineLogsWithName(failOnBlockFiltered bool, instance *engi
})
events.BlockGadget.BlockPreAccepted.Hook(func(block *blocks.Block) {
- fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockPreAccepted: %s %s\n", n.Name, engineName, block.ID(), block.ProtocolBlock().SlotCommitmentID)
+ fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockPreAccepted: %s %s\n", n.Name, engineName, block.ID(), block.ProtocolBlock().Header.SlotCommitmentID)
})
events.BlockGadget.BlockAccepted.Hook(func(block *blocks.Block) {
- fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockAccepted: %s @ slot %s committing to %s\n", n.Name, engineName, block.ID(), block.ID().Slot(), block.ProtocolBlock().SlotCommitmentID)
+ fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockAccepted: %s @ slot %s committing to %s\n", n.Name, engineName, block.ID(), block.ID().Slot(), block.ProtocolBlock().Header.SlotCommitmentID)
})
events.BlockGadget.BlockPreConfirmed.Hook(func(block *blocks.Block) {
- fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockPreConfirmed: %s %s\n", n.Name, engineName, block.ID(), block.ProtocolBlock().SlotCommitmentID)
+ fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockPreConfirmed: %s %s\n", n.Name, engineName, block.ID(), block.ProtocolBlock().Header.SlotCommitmentID)
})
events.BlockGadget.BlockConfirmed.Hook(func(block *blocks.Block) {
- fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockConfirmed: %s %s\n", n.Name, engineName, block.ID(), block.ProtocolBlock().SlotCommitmentID)
+ fmt.Printf("%s > [%s] Consensus.BlockGadget.BlockConfirmed: %s %s\n", n.Name, engineName, block.ID(), block.ProtocolBlock().Header.SlotCommitmentID)
})
events.SlotGadget.SlotFinalized.Hook(func(slot iotago.SlotIndex) {
@@ -515,3 +516,11 @@ func (n *Node) AttachedBlocks() []*blocks.Block {
return n.attachedBlocks
}
+
+func (n *Node) IssueValidationBlock(ctx context.Context, alias string, opts ...options.Option[ValidatorBlockParams]) *blocks.Block {
+ if n.Validator == nil {
+ panic("node is not a validator")
+ }
+
+ return n.Validator.IssueValidationBlock(ctx, alias, n, opts...)
+}
diff --git a/pkg/testsuite/mock/utils.go b/pkg/testsuite/mock/utils.go
new file mode 100644
index 000000000..f7cc8adcd
--- /dev/null
+++ b/pkg/testsuite/mock/utils.go
@@ -0,0 +1,221 @@
+package mock
+
+import (
+ "github.com/iotaledger/hive.go/runtime/options"
+ "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
+ iotago "github.com/iotaledger/iota.go/v4"
+ "github.com/iotaledger/iota.go/v4/builder"
+)
+
+const MinIssuerAccountAmount = iotago.BaseToken(372900)
+const MinValidatorAccountAmount = iotago.BaseToken(722800)
+const AccountConversionManaCost = iotago.Mana(1000000)
+
+// TransactionBuilder options
+
+func WithInputs(inputs utxoledger.Outputs) options.Option[builder.TransactionBuilder] {
+ return func(txBuilder *builder.TransactionBuilder) {
+ for _, input := range inputs {
+ switch input.OutputType() {
+ case iotago.OutputFoundry:
+ // For foundries we need to unlock the account output
+ txBuilder.AddInput(&builder.TxInput{
+ UnlockTarget: input.Output().UnlockConditionSet().ImmutableAccount().Address,
+ InputID: input.OutputID(),
+ Input: input.Output(),
+ })
+ case iotago.OutputAccount:
+ // For alias we need to unlock the state controller
+ txBuilder.AddInput(&builder.TxInput{
+ UnlockTarget: input.Output().UnlockConditionSet().StateControllerAddress().Address,
+ InputID: input.OutputID(),
+ Input: input.Output(),
+ })
+ default:
+ txBuilder.AddInput(&builder.TxInput{
+ UnlockTarget: input.Output().UnlockConditionSet().Address().Address,
+ InputID: input.OutputID(),
+ Input: input.Output(),
+ })
+ }
+ }
+ }
+}
+
+func WithAccountInput(input *utxoledger.Output, governorTransition bool) options.Option[builder.TransactionBuilder] {
+ return func(txBuilder *builder.TransactionBuilder) {
+ switch input.OutputType() {
+ case iotago.OutputAccount:
+ address := input.Output().UnlockConditionSet().StateControllerAddress().Address
+ if governorTransition {
+ address = input.Output().UnlockConditionSet().GovernorAddress().Address
+ }
+ txBuilder.AddInput(&builder.TxInput{
+ UnlockTarget: address,
+ InputID: input.OutputID(),
+ Input: input.Output(),
+ })
+ default:
+ panic("only OutputAccount can be added as account input")
+ }
+ }
+}
+
+func WithAllotments(allotments iotago.Allotments) options.Option[builder.TransactionBuilder] {
+ return func(txBuilder *builder.TransactionBuilder) {
+ for _, allotment := range allotments {
+ txBuilder.IncreaseAllotment(allotment.AccountID, allotment.Mana)
+ }
+ }
+}
+
+func WithSlotCreated(creationSlot iotago.SlotIndex) options.Option[builder.TransactionBuilder] {
+ return func(txBuilder *builder.TransactionBuilder) {
+ txBuilder.SetCreationSlot(creationSlot)
+ }
+}
+
+func WithContextInputs(contextInputs iotago.TxEssenceContextInputs) options.Option[builder.TransactionBuilder] {
+ return func(txBuilder *builder.TransactionBuilder) {
+ for _, input := range contextInputs {
+ txBuilder.AddContextInput(input)
+ }
+ }
+}
+
+func WithOutputs(outputs iotago.Outputs[iotago.Output]) options.Option[builder.TransactionBuilder] {
+ return func(txBuilder *builder.TransactionBuilder) {
+ for _, output := range outputs {
+ txBuilder.AddOutput(output)
+ }
+ }
+}
+
+func WithTaggedDataPayload(payload *iotago.TaggedData) options.Option[builder.TransactionBuilder] {
+ return func(txBuilder *builder.TransactionBuilder) {
+ txBuilder.AddTaggedDataPayload(payload)
+ }
+}
+
+// DelegationOutput options
+
+func WithDelegatedAmount(delegatedAmount iotago.BaseToken) options.Option[builder.DelegationOutputBuilder] {
+ return func(delegationBuilder *builder.DelegationOutputBuilder) {
+ delegationBuilder.DelegatedAmount(delegatedAmount)
+ }
+}
+
+func WithDelegatedValidatorAddress(validatorAddress *iotago.AccountAddress) options.Option[builder.DelegationOutputBuilder] {
+ return func(delegationBuilder *builder.DelegationOutputBuilder) {
+ delegationBuilder.ValidatorAddress(validatorAddress)
+ }
+}
+
+func WithDelegationStartEpoch(startEpoch iotago.EpochIndex) options.Option[builder.DelegationOutputBuilder] {
+ return func(delegationBuilder *builder.DelegationOutputBuilder) {
+ delegationBuilder.StartEpoch(startEpoch)
+ }
+}
+
+func WithDelegationEndEpoch(endEpoch iotago.EpochIndex) options.Option[builder.DelegationOutputBuilder] {
+ return func(delegationBuilder *builder.DelegationOutputBuilder) {
+ delegationBuilder.EndEpoch(endEpoch)
+ }
+}
+
+func WithDelegationConditions(delegationConditions iotago.DelegationOutputUnlockConditions) options.Option[builder.DelegationOutputBuilder] {
+ return func(delegationBuilder *builder.DelegationOutputBuilder) {
+ delegationBuilder.Address(delegationConditions.MustSet().Address().Address)
+ }
+}
+
+func WithDelegationAmount(amount iotago.BaseToken) options.Option[builder.DelegationOutputBuilder] {
+ return func(delegationBuilder *builder.DelegationOutputBuilder) {
+ delegationBuilder.Amount(amount)
+ }
+}
+
+// BlockIssuer options
+
+func WithBlockIssuerFeature(keys iotago.BlockIssuerKeys, expirySlot iotago.SlotIndex) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ accountBuilder.BlockIssuer(keys, expirySlot)
+ }
+}
+
+func WithAddBlockIssuerKey(key iotago.BlockIssuerKey) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ transition := accountBuilder.GovernanceTransition()
+ transition.BlockIssuerTransition().AddKeys(key)
+ }
+}
+
+func WithBlockIssuerKeys(keys iotago.BlockIssuerKeys) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ transition := accountBuilder.GovernanceTransition()
+ transition.BlockIssuerTransition().Keys(keys)
+ }
+}
+
+func WithBlockIssuerExpirySlot(expirySlot iotago.SlotIndex) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ transition := accountBuilder.GovernanceTransition()
+ transition.BlockIssuerTransition().ExpirySlot(expirySlot)
+ }
+}
+
+func WithStakingFeature(amount iotago.BaseToken, fixedCost iotago.Mana, startEpoch iotago.EpochIndex, optEndEpoch ...iotago.EpochIndex) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ accountBuilder.Staking(amount, fixedCost, startEpoch, optEndEpoch...)
+ }
+}
+
+// Account options
+
+func WithAccountMana(mana iotago.Mana) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ accountBuilder.Mana(mana)
+ }
+}
+
+func WithAccountAmount(amount iotago.BaseToken) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ accountBuilder.Amount(amount)
+ }
+}
+
+func WithAccountIncreasedFoundryCounter(diff uint32) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ accountBuilder.FoundriesToGenerate(diff)
+ }
+}
+
+func WithAccountImmutableFeatures(features iotago.AccountOutputImmFeatures) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ for _, feature := range features.MustSet() {
+ switch feature.Type() {
+ case iotago.FeatureMetadata:
+ //nolint:forcetypeassert
+ accountBuilder.ImmutableMetadata(feature.(*iotago.MetadataFeature).Data)
+ case iotago.FeatureSender:
+ //nolint:forcetypeassert
+ accountBuilder.ImmutableSender(feature.(*iotago.SenderFeature).Address)
+ }
+ }
+ }
+}
+
+func WithAccountConditions(conditions iotago.AccountOutputUnlockConditions) options.Option[builder.AccountOutputBuilder] {
+ return func(accountBuilder *builder.AccountOutputBuilder) {
+ for _, condition := range conditions.MustSet() {
+ switch condition.Type() {
+ case iotago.UnlockConditionStateControllerAddress:
+ //nolint:forcetypeassert
+ accountBuilder.StateController(condition.(*iotago.StateControllerAddressUnlockCondition).Address)
+ case iotago.UnlockConditionGovernorAddress:
+ //nolint:forcetypeassert
+ accountBuilder.Governor(condition.(*iotago.GovernorAddressUnlockCondition).Address)
+ }
+ }
+ }
+}
diff --git a/pkg/testsuite/mock/wallet.go b/pkg/testsuite/mock/wallet.go
new file mode 100644
index 000000000..b161ed1af
--- /dev/null
+++ b/pkg/testsuite/mock/wallet.go
@@ -0,0 +1,131 @@
+package mock
+
+import (
+ "crypto/ed25519"
+ "testing"
+
+ "github.com/iotaledger/hive.go/ierrors"
+ "github.com/iotaledger/hive.go/lo"
+ "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
+ iotago "github.com/iotaledger/iota.go/v4"
+ "github.com/iotaledger/iota.go/v4/tpkg"
+)
+
+// Wallet is an object representing a wallet (similar to a FireFly wallet) capable of the following:
+// - hierarchical deterministic key management
+// - signing transactions
+// - signing blocks
+// - keeping track of unspent outputs.
+type Wallet struct {
+ Testing *testing.T
+
+ Name string
+
+ Node *Node
+
+ keyManager *KeyManager
+
+ BlockIssuer *BlockIssuer
+
+ outputs map[string]*utxoledger.Output
+ transactions map[string]*iotago.Transaction
+}
+
+func NewWallet(t *testing.T, name string, node *Node, keyManager ...*KeyManager) *Wallet {
+ var km *KeyManager
+ if len(keyManager) == 0 {
+ randomSeed := tpkg.RandEd25519Seed()
+ km = NewKeyManager(randomSeed[:], 0)
+ } else {
+ km = keyManager[0]
+ }
+
+ return &Wallet{
+ Testing: t,
+ Name: name,
+ Node: node,
+ outputs: make(map[string]*utxoledger.Output),
+ transactions: make(map[string]*iotago.Transaction),
+ keyManager: km,
+ }
+}
+
+func (w *Wallet) SetBlockIssuer(accountID iotago.AccountID) {
+ w.BlockIssuer = NewBlockIssuer(w.Testing, w.Name, w.keyManager, accountID, false)
+}
+
+func (w *Wallet) SetDefaultNode(node *Node) {
+ w.Node = node
+}
+
+func (w *Wallet) AddOutput(outputName string, output *utxoledger.Output) {
+ w.outputs[outputName] = output
+}
+
+func (w *Wallet) Balance() iotago.BaseToken {
+ var balance iotago.BaseToken
+ for _, output := range w.outputs {
+ balance += output.BaseTokenAmount()
+ }
+
+ return balance
+}
+
+func (w *Wallet) Output(outputName string) *utxoledger.Output {
+ output, exists := w.outputs[outputName]
+ if !exists {
+ panic(ierrors.Errorf("output %s not registered in wallet %s", outputName, w.Name))
+ }
+
+ return output
+}
+
+func (w *Wallet) AccountOutput(outputName string) *utxoledger.Output {
+ output := w.Output(outputName)
+ if _, ok := output.Output().(*iotago.AccountOutput); !ok {
+ panic(ierrors.Errorf("output %s is not an account output", outputName))
+ }
+
+ return output
+}
+
+func (w *Wallet) Transaction(alias string) *iotago.Transaction {
+ transaction, exists := w.transactions[alias]
+ if !exists {
+ panic(ierrors.Errorf("transaction with given alias does not exist %s", alias))
+ }
+
+ return transaction
+}
+
+func (w *Wallet) Transactions(transactionNames ...string) []*iotago.Transaction {
+ return lo.Map(transactionNames, w.Transaction)
+}
+
+func (w *Wallet) TransactionID(alias string) iotago.TransactionID {
+ return lo.PanicOnErr(w.Transaction(alias).ID())
+}
+
+func (w *Wallet) Address() iotago.DirectUnlockableAddress {
+ address := w.keyManager.Address(iotago.AddressEd25519)
+ //nolint:forcetypeassert
+ return address.(*iotago.Ed25519Address)
+}
+
+func (w *Wallet) ImplicitAccountCreationAddress() *iotago.ImplicitAccountCreationAddress {
+ address := w.keyManager.Address(iotago.AddressImplicitAccountCreation)
+ //nolint:forcetypeassert
+ return address.(*iotago.ImplicitAccountCreationAddress)
+}
+
+func (w *Wallet) HasAddress(address iotago.Address) bool {
+ return address.Equal(w.Address()) || address.Equal(w.ImplicitAccountCreationAddress())
+}
+
+func (w *Wallet) KeyPair() (ed25519.PrivateKey, ed25519.PublicKey) {
+ return w.keyManager.KeyPair()
+}
+
+func (w *Wallet) AddressSigner() iotago.AddressSigner {
+ return w.keyManager.AddressSigner()
+}
diff --git a/pkg/testsuite/mock/wallet_blocks.go b/pkg/testsuite/mock/wallet_blocks.go
new file mode 100644
index 000000000..22fe8bea4
--- /dev/null
+++ b/pkg/testsuite/mock/wallet_blocks.go
@@ -0,0 +1,12 @@
+package mock
+
+import (
+ "context"
+
+ "github.com/iotaledger/hive.go/runtime/options"
+ "github.com/iotaledger/iota-core/pkg/protocol/engine/blocks"
+)
+
+func (w *Wallet) IssueBasicBlock(ctx context.Context, blockName string, opts ...options.Option[BasicBlockParams]) *blocks.Block {
+ return w.BlockIssuer.IssueBasicBlock(ctx, blockName, w.Node, opts...)
+}
diff --git a/pkg/testsuite/mock/wallet_transactions.go b/pkg/testsuite/mock/wallet_transactions.go
new file mode 100644
index 000000000..6b3481046
--- /dev/null
+++ b/pkg/testsuite/mock/wallet_transactions.go
@@ -0,0 +1,362 @@
+package mock
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/iotaledger/hive.go/ierrors"
+ "github.com/iotaledger/hive.go/lo"
+ "github.com/iotaledger/hive.go/runtime/options"
+ "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
+ iotago "github.com/iotaledger/iota.go/v4"
+ "github.com/iotaledger/iota.go/v4/builder"
+ "github.com/iotaledger/iota.go/v4/tpkg"
+)
+
+// Functionality for creating transactions in the mock wallet.
+
+func (w *Wallet) CreateAccountFromInput(transactionName string, inputName string, recipientWallet *Wallet, creationSlot iotago.SlotIndex, opts ...options.Option[builder.AccountOutputBuilder]) *iotago.SignedTransaction {
+ input := w.Output(inputName)
+
+ accountOutput := options.Apply(builder.NewAccountOutputBuilder(recipientWallet.Address(), recipientWallet.Address(), input.BaseTokenAmount()).
+ Mana(input.StoredMana()),
+ opts).MustBuild()
+
+ outputStates := iotago.Outputs[iotago.Output]{accountOutput}
+
+ // if amount was set by options, a remainder output needs to be created
+ if accountOutput.Amount != input.BaseTokenAmount() {
+ remainderOutput := &iotago.BasicOutput{
+ Amount: input.BaseTokenAmount() - accountOutput.Amount,
+ Mana: input.StoredMana() - accountOutput.Mana,
+ Conditions: iotago.BasicOutputUnlockConditions{
+ &iotago.AddressUnlockCondition{Address: recipientWallet.Address()},
+ },
+ Features: iotago.BasicOutputFeatures{},
+ }
+ outputStates = append(outputStates, remainderOutput)
+ }
+
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithContextInputs(iotago.TxEssenceContextInputs{
+ &iotago.CommitmentInput{
+ CommitmentID: w.Node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
+ },
+ }),
+ WithInputs(utxoledger.Outputs{input}),
+ WithOutputs(outputStates),
+ WithSlotCreated(creationSlot),
+ ))
+
+ // register the outputs in the recipient wallet (so wallet doesn't have to scan for outputs on its addresses)
+ recipientWallet.registerOutputs(transactionName, signedTransaction.Transaction)
+
+ return signedTransaction
+}
+
+// CreateDelegationFromInput creates a new DelegationOutput with given options from an input. If the remainder Output
+// is not created, then StoredMana from the input is not passed and can potentially be burned.
+// In order not to burn it, it needs to be assigned manually in another output in the transaction.
+func (w *Wallet) CreateDelegationFromInput(transactionName string, inputName string, creationSlot iotago.SlotIndex, opts ...options.Option[builder.DelegationOutputBuilder]) *iotago.SignedTransaction {
+ input := w.Output(inputName)
+
+ delegationOutput := options.Apply(builder.NewDelegationOutputBuilder(&iotago.AccountAddress{}, w.Address(), input.BaseTokenAmount()).
+ DelegatedAmount(input.BaseTokenAmount()),
+ opts).MustBuild()
+
+ if delegationOutput.ValidatorAddress.AccountID() == iotago.EmptyAccountID ||
+ delegationOutput.DelegatedAmount == 0 ||
+ delegationOutput.StartEpoch == 0 {
+ panic(fmt.Sprintf("delegation output created incorrectly %+v", delegationOutput))
+ }
+
+ outputStates := iotago.Outputs[iotago.Output]{delegationOutput}
+
+ // if options set an Amount, a remainder output needs to be created
+ if delegationOutput.Amount != input.BaseTokenAmount() {
+ outputStates = append(outputStates, &iotago.BasicOutput{
+ Amount: input.BaseTokenAmount() - delegationOutput.Amount,
+ Mana: input.StoredMana(),
+ Conditions: iotago.BasicOutputUnlockConditions{
+ &iotago.AddressUnlockCondition{Address: w.Address()},
+ },
+ Features: iotago.BasicOutputFeatures{},
+ })
+ }
+
+ // create the signed transaction
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithContextInputs(iotago.TxEssenceContextInputs{
+ &iotago.CommitmentInput{
+ CommitmentID: w.Node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
+ },
+ }),
+ WithInputs(utxoledger.Outputs{input}),
+ WithOutputs(outputStates),
+ WithSlotCreated(creationSlot),
+ ))
+
+ return signedTransaction
+}
+
+// DelayedClaimingTransition transitions DelegationOutput into delayed claiming state by setting DelegationID and EndEpoch.
+func (w *Wallet) DelayedClaimingTransition(transactionName string, inputName string, creationSlot iotago.SlotIndex, delegationEndEpoch iotago.EpochIndex) *iotago.SignedTransaction {
+ input := w.Output(inputName)
+ if input.OutputType() != iotago.OutputDelegation {
+ panic(ierrors.Errorf("%s is not a delegation output, cannot transition to delayed claiming state", inputName))
+ }
+
+ prevOutput, ok := input.Output().Clone().(*iotago.DelegationOutput)
+ if !ok {
+ panic(ierrors.Errorf("cloned output %s is not a delegation output, cannot transition to delayed claiming state", inputName))
+ }
+
+ delegationBuilder := builder.NewDelegationOutputBuilderFromPrevious(prevOutput).EndEpoch(delegationEndEpoch)
+ if prevOutput.DelegationID == iotago.EmptyDelegationID() {
+ delegationBuilder.DelegationID(iotago.DelegationIDFromOutputID(input.OutputID()))
+ }
+
+ delegationOutput := delegationBuilder.MustBuild()
+
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithContextInputs(iotago.TxEssenceContextInputs{
+ &iotago.CommitmentInput{
+ CommitmentID: w.Node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
+ },
+ }),
+ WithInputs(utxoledger.Outputs{input}),
+ WithOutputs(iotago.Outputs[iotago.Output]{delegationOutput}),
+ WithSlotCreated(creationSlot),
+ ))
+
+ return signedTransaction
+}
+
+func (w *Wallet) TransitionAccount(transactionName string, inputName string, opts ...options.Option[builder.AccountOutputBuilder]) *iotago.SignedTransaction {
+ input, exists := w.outputs[inputName]
+ if !exists {
+ panic(fmt.Sprintf("account with alias %s does not exist", inputName))
+ }
+
+ accountOutput, ok := input.Output().Clone().(*iotago.AccountOutput)
+ if !ok {
+ panic(fmt.Sprintf("output with alias %s is not *iotago.AccountOutput", inputName))
+ }
+
+ accountBuilder := builder.NewAccountOutputBuilderFromPrevious(accountOutput)
+ accountOutput = options.Apply(accountBuilder, opts).MustBuild()
+
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithAccountInput(input, true),
+ WithContextInputs(iotago.TxEssenceContextInputs{
+ &iotago.BlockIssuanceCreditInput{
+ AccountID: accountOutput.AccountID,
+ },
+ &iotago.CommitmentInput{
+ CommitmentID: w.Node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
+ },
+ }),
+ WithOutputs(iotago.Outputs[iotago.Output]{accountOutput}),
+ ))
+
+ return signedTransaction
+}
+
+func (w *Wallet) DestroyAccount(transactionName string, inputName string, creationSlot iotago.SlotIndex) *iotago.SignedTransaction {
+ input := w.Output(inputName)
+ inputAccount, ok := input.Output().(*iotago.AccountOutput)
+ if !ok {
+ panic(fmt.Sprintf("output with alias %s is not *iotago.AccountOutput", inputName))
+ }
+
+ destructionOutputs := iotago.Outputs[iotago.Output]{&iotago.BasicOutput{
+ Amount: input.BaseTokenAmount(),
+ Mana: input.StoredMana(),
+ Conditions: iotago.BasicOutputUnlockConditions{
+ &iotago.AddressUnlockCondition{Address: w.Address()},
+ },
+ Features: iotago.BasicOutputFeatures{},
+ }}
+
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithContextInputs(iotago.TxEssenceContextInputs{
+ &iotago.BlockIssuanceCreditInput{
+ AccountID: inputAccount.AccountID,
+ },
+ &iotago.CommitmentInput{
+ CommitmentID: w.Node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
+ },
+ }),
+ WithAccountInput(input, true),
+ WithOutputs(destructionOutputs),
+ WithSlotCreated(creationSlot),
+ ))
+
+ return signedTransaction
+}
+
+// CreateImplicitAccountFromInput creates an implicit account output.
+func (w *Wallet) CreateImplicitAccountFromInput(transactionName string, inputName string, recipientWallet *Wallet) *iotago.SignedTransaction {
+ input := w.Output(inputName)
+
+ implicitAccountOutput := &iotago.BasicOutput{
+ Amount: MinIssuerAccountAmount,
+ Mana: AccountConversionManaCost,
+ Conditions: iotago.BasicOutputUnlockConditions{
+ &iotago.AddressUnlockCondition{Address: recipientWallet.ImplicitAccountCreationAddress()},
+ },
+ Features: iotago.BasicOutputFeatures{},
+ }
+
+ remainderBasicOutput := &iotago.BasicOutput{
+ Amount: input.BaseTokenAmount() - MinIssuerAccountAmount,
+ Mana: input.StoredMana() - AccountConversionManaCost,
+ Conditions: iotago.BasicOutputUnlockConditions{
+ &iotago.AddressUnlockCondition{Address: input.Output().UnlockConditionSet().Address().Address},
+ },
+ Features: iotago.BasicOutputFeatures{},
+ }
+
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithInputs(utxoledger.Outputs{input}),
+ WithOutputs(iotago.Outputs[iotago.Output]{implicitAccountOutput, remainderBasicOutput}),
+ ))
+
+ // register the outputs in the recipient wallet (so wallet doesn't have to scan for outputs on its addresses)
+ recipientWallet.registerOutputs(transactionName, signedTransaction.Transaction)
+
+ // register the implicit account as a block issuer in the wallet
+ implicitAccountID := iotago.AccountIDFromOutputID(recipientWallet.Output(fmt.Sprintf("%s:0", transactionName)).OutputID())
+ recipientWallet.SetBlockIssuer(implicitAccountID)
+
+ return signedTransaction
+}
+
+func (w *Wallet) TransitionImplicitAccountToAccountOutput(transactionName string, inputName string, creationSlot iotago.SlotIndex, opts ...options.Option[builder.AccountOutputBuilder]) *iotago.SignedTransaction {
+ input := w.Output(inputName)
+ implicitAccountID := iotago.AccountIDFromOutputID(input.OutputID())
+
+ basicOutput, isBasic := input.Output().(*iotago.BasicOutput)
+ if !isBasic {
+ panic(fmt.Sprintf("output with alias %s is not *iotago.BasicOutput", inputName))
+ }
+ if basicOutput.UnlockConditionSet().Address().Address.Type() != iotago.AddressImplicitAccountCreation {
+ panic(fmt.Sprintf("output with alias %s is not an implicit account", inputName))
+ }
+
+ accountOutput := options.Apply(builder.NewAccountOutputBuilder(w.Address(), w.Address(), MinIssuerAccountAmount).
+ AccountID(iotago.AccountIDFromOutputID(input.OutputID())),
+ opts).MustBuild()
+
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithContextInputs(iotago.TxEssenceContextInputs{
+ &iotago.BlockIssuanceCreditInput{
+ AccountID: implicitAccountID,
+ },
+ &iotago.CommitmentInput{
+ CommitmentID: w.Node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment().MustID(),
+ },
+ }),
+ WithInputs(utxoledger.Outputs{input}),
+ WithOutputs(iotago.Outputs[iotago.Output]{accountOutput}),
+ WithSlotCreated(creationSlot),
+ func(txBuilder *builder.TransactionBuilder) {
+ txBuilder.AllotAllMana(creationSlot, implicitAccountID)
+ },
+ ))
+
+ return signedTransaction
+}
+
+func (w *Wallet) CreateBasicOutputsEquallyFromInputs(transactionName string, outputCount int, inputNames ...string) *iotago.SignedTransaction {
+ inputStates := make([]*utxoledger.Output, 0, len(inputNames))
+ totalInputAmounts := iotago.BaseToken(0)
+ totalInputStoredMana := iotago.Mana(0)
+
+ for _, inputName := range inputNames {
+ output := w.Output(inputName)
+ inputStates = append(inputStates, output)
+ totalInputAmounts += output.BaseTokenAmount()
+ totalInputStoredMana += output.StoredMana()
+ }
+
+ manaAmount := totalInputStoredMana / iotago.Mana(outputCount)
+ remainderMana := totalInputStoredMana
+
+ tokenAmount := totalInputAmounts / iotago.BaseToken(outputCount)
+ remainderFunds := totalInputAmounts
+
+ outputStates := make(iotago.Outputs[iotago.Output], 0, outputCount)
+ for i := 0; i < outputCount; i++ {
+ if i+1 == outputCount {
+ tokenAmount = remainderFunds
+ manaAmount = remainderMana
+ }
+ remainderFunds -= tokenAmount
+ remainderMana -= manaAmount
+
+ outputStates = append(outputStates, &iotago.BasicOutput{
+ Amount: tokenAmount,
+ Mana: manaAmount,
+ Conditions: iotago.BasicOutputUnlockConditions{
+ &iotago.AddressUnlockCondition{Address: w.Address()},
+ },
+ Features: iotago.BasicOutputFeatures{},
+ })
+ }
+
+ signedTransaction := lo.PanicOnErr(w.createSignedTransactionWithOptions(
+ transactionName,
+ WithInputs(inputStates),
+ WithOutputs(outputStates),
+ ))
+
+ return signedTransaction
+}
+
+func (w *Wallet) createSignedTransactionWithOptions(transactionName string, opts ...options.Option[builder.TransactionBuilder]) (*iotago.SignedTransaction, error) {
+ currentAPI := w.Node.Protocol.CommittedAPI()
+
+ txBuilder := builder.NewTransactionBuilder(currentAPI)
+ txBuilder.WithTransactionCapabilities(iotago.TransactionCapabilitiesBitMaskWithCapabilities(iotago.WithTransactionCanDoAnything()))
+ // Always add a random payload to randomize transaction ID.
+ randomPayload := tpkg.Rand12ByteArray()
+ txBuilder.AddTaggedDataPayload(&iotago.TaggedData{Tag: randomPayload[:], Data: randomPayload[:]})
+
+ addrSigner := w.AddressSigner()
+ signedTransaction, err := options.Apply(txBuilder, opts).Build(addrSigner)
+
+ // register the outputs in the wallet
+ w.registerOutputs(transactionName, signedTransaction.Transaction)
+
+ return signedTransaction, err
+}
+
+func (w *Wallet) registerOutputs(transactionName string, transaction *iotago.Transaction) {
+ currentAPI := w.Node.Protocol.CommittedAPI()
+ (lo.PanicOnErr(transaction.ID())).RegisterAlias(transactionName)
+ w.transactions[transactionName] = transaction
+
+ for outputID, output := range lo.PanicOnErr(transaction.OutputsSet()) {
+ // register the output if it belongs to this wallet
+ addressUC := output.UnlockConditionSet().Address()
+ stateControllerUC := output.UnlockConditionSet().StateControllerAddress()
+ if addressUC != nil && w.HasAddress(addressUC.Address) || stateControllerUC != nil && w.HasAddress(stateControllerUC.Address) {
+ clonedOutput := output.Clone()
+ actualOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(transaction.ID()), outputID.Index())
+ if clonedOutput.Type() == iotago.OutputAccount {
+ if accountOutput, ok := clonedOutput.(*iotago.AccountOutput); ok && accountOutput.AccountID == iotago.EmptyAccountID {
+ accountOutput.AccountID = iotago.AccountIDFromOutputID(actualOutputID)
+ }
+ }
+ w.outputs[fmt.Sprintf("%s:%d", transactionName, outputID.Index())] = utxoledger.CreateOutput(w.Node.Protocol, actualOutputID, iotago.EmptyBlockID, currentAPI.TimeProvider().SlotFromTime(time.Now()), clonedOutput, lo.PanicOnErr(iotago.OutputIDProofFromTransaction(transaction, outputID.Index())))
+ }
+ }
+}
diff --git a/pkg/protocol/snapshotcreator/options.go b/pkg/testsuite/snapshotcreator/options.go
similarity index 90%
rename from pkg/protocol/snapshotcreator/options.go
rename to pkg/testsuite/snapshotcreator/options.go
index 74d986fe4..85aa1f439 100644
--- a/pkg/protocol/snapshotcreator/options.go
+++ b/pkg/testsuite/snapshotcreator/options.go
@@ -8,6 +8,7 @@ import (
ledger1 "github.com/iotaledger/iota-core/pkg/protocol/engine/ledger/ledger"
"github.com/iotaledger/iota-core/pkg/protocol/sybilprotection/seatmanager"
"github.com/iotaledger/iota-core/pkg/protocol/sybilprotection/seatmanager/poa"
+ "github.com/iotaledger/iota-core/pkg/testsuite/mock"
iotago "github.com/iotaledger/iota.go/v4"
)
@@ -22,8 +23,8 @@ type Options struct {
// RootBlocks define the initial blocks to which new blocks can attach to.
RootBlocks map[iotago.BlockID]iotago.CommitmentID
- // GenesisSeed defines the seed used to generate keypair that can spend Genesis outputs.
- GenesisSeed []byte
+ // GenesisKeyManager defines the key manager used to generate keypair that can spend Genesis outputs.
+ GenesisKeyManager *mock.KeyManager
// Accounts defines the accounts that are created in the ledger as part of the Genesis.
Accounts []AccountDetails
@@ -83,10 +84,10 @@ func WithRootBlocks(rootBlocks map[iotago.BlockID]iotago.CommitmentID) options.O
}
}
-// WithGenesisSeed defines the seed used to generate keypair that can spend Genesis outputs.
-func WithGenesisSeed(genesisSeed []byte) options.Option[Options] {
+// WithGenesisKeyManager defines the seed used to generate keypair that can spend Genesis outputs.
+func WithGenesisKeyManager(keyManager *mock.KeyManager) options.Option[Options] {
return func(m *Options) {
- m.GenesisSeed = genesisSeed
+ m.GenesisKeyManager = keyManager
}
}
diff --git a/pkg/protocol/snapshotcreator/snapshotcreator.go b/pkg/testsuite/snapshotcreator/snapshotcreator.go
similarity index 98%
rename from pkg/protocol/snapshotcreator/snapshotcreator.go
rename to pkg/testsuite/snapshotcreator/snapshotcreator.go
index 5223e0083..f0d3ee8a0 100644
--- a/pkg/protocol/snapshotcreator/snapshotcreator.go
+++ b/pkg/testsuite/snapshotcreator/snapshotcreator.go
@@ -133,7 +133,7 @@ func CreateSnapshot(opts ...options.Option[Options]) error {
}, iotago.BaseToken(0))
var genesisTransactionOutputs iotago.TxEssenceOutputs
- genesisOutput, err := createGenesisOutput(api, opt.ProtocolParameters.TokenSupply()-totalAccountAmount-totalBasicOutputAmount, opt.GenesisSeed)
+ genesisOutput, err := createGenesisOutput(api, opt.ProtocolParameters.TokenSupply()-totalAccountAmount-totalBasicOutputAmount, opt.GenesisKeyManager)
if err != nil {
return ierrors.Wrap(err, "failed to create genesis outputs")
}
@@ -187,10 +187,9 @@ func CreateSnapshot(opts ...options.Option[Options]) error {
return engineInstance.WriteSnapshot(opt.FilePath)
}
-func createGenesisOutput(api iotago.API, genesisTokenAmount iotago.BaseToken, genesisSeed []byte) (iotago.Output, error) {
+func createGenesisOutput(api iotago.API, genesisTokenAmount iotago.BaseToken, genesisKeyManager *mock.KeyManager) (iotago.Output, error) {
if genesisTokenAmount > 0 {
- genesisWallet := mock.NewHDWallet("genesis", genesisSeed, 0)
- output := createOutput(genesisWallet.Address(), genesisTokenAmount, 0)
+ output := createOutput(genesisKeyManager.Address(iotago.AddressEd25519), genesisTokenAmount, iotago.Mana(genesisTokenAmount))
if _, err := api.StorageScoreStructure().CoversMinDeposit(output, genesisTokenAmount); err != nil {
return nil, ierrors.Wrap(err, "min rent not covered by Genesis output with index 0")
diff --git a/pkg/testsuite/testsuite.go b/pkg/testsuite/testsuite.go
index 52d99db5c..794702d79 100644
--- a/pkg/testsuite/testsuite.go
+++ b/pkg/testsuite/testsuite.go
@@ -19,26 +19,23 @@ import (
"github.com/iotaledger/iota-core/pkg/protocol"
"github.com/iotaledger/iota-core/pkg/protocol/engine/blocks"
"github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
- "github.com/iotaledger/iota-core/pkg/protocol/snapshotcreator"
"github.com/iotaledger/iota-core/pkg/protocol/sybilprotection/sybilprotectionv1"
"github.com/iotaledger/iota-core/pkg/storage/utils"
"github.com/iotaledger/iota-core/pkg/testsuite/mock"
+ "github.com/iotaledger/iota-core/pkg/testsuite/snapshotcreator"
iotago "github.com/iotaledger/iota.go/v4"
"github.com/iotaledger/iota.go/v4/tpkg"
)
-const MinIssuerAccountAmount = iotago.BaseToken(372900)
-const MinValidatorAccountAmount = iotago.BaseToken(722800)
-
type TestSuite struct {
Testing *testing.T
fakeTesting *testing.T
network *mock.Network
- Directory *utils.Directory
- nodes *orderedmap.OrderedMap[string, *mock.Node]
- blockIssuers *orderedmap.OrderedMap[string, *mock.BlockIssuer]
- running bool
+ Directory *utils.Directory
+ nodes *orderedmap.OrderedMap[string, *mock.Node]
+ wallets *orderedmap.OrderedMap[string, *mock.Wallet]
+ running bool
snapshotPath string
blocks *shrinkingmap.ShrinkingMap[string, *blocks.Block]
@@ -54,19 +51,19 @@ type TestSuite struct {
uniqueBlockTimeCounter atomic.Int64
automaticTransactionIssuingCounters shrinkingmap.ShrinkingMap[string, int]
mutex syncutils.RWMutex
- TransactionFramework *TransactionFramework
- genesisSeed [32]byte
+ genesisKeyManager *mock.KeyManager
}
func NewTestSuite(testingT *testing.T, opts ...options.Option[TestSuite]) *TestSuite {
+ genesisSeed := tpkg.RandEd25519Seed()
return options.Apply(&TestSuite{
Testing: testingT,
fakeTesting: &testing.T{},
- genesisSeed: tpkg.RandEd25519Seed(),
+ genesisKeyManager: mock.NewKeyManager(genesisSeed[:], 0),
network: mock.NewNetwork(),
Directory: utils.NewDirectory(testingT.TempDir()),
nodes: orderedmap.New[string, *mock.Node](),
- blockIssuers: orderedmap.New[string, *mock.BlockIssuer](),
+ wallets: orderedmap.New[string, *mock.Wallet](),
blocks: shrinkingmap.New[string, *blocks.Block](),
automaticTransactionIssuingCounters: *shrinkingmap.New[string, int](),
@@ -153,10 +150,7 @@ func (t *TestSuite) AccountOutput(alias string) *utxoledger.Output {
t.mutex.RLock()
defer t.mutex.RUnlock()
- output, exist := t.TransactionFramework.states[alias]
- if !exist {
- panic(fmt.Sprintf("account %s not registered", alias))
- }
+ output := t.DefaultWallet().Output(alias)
if _, ok := output.Output().(*iotago.AccountOutput); !ok {
panic(fmt.Sprintf("output %s is not an account", alias))
@@ -255,6 +249,18 @@ func (t *TestSuite) Node(name string) *mock.Node {
return node
}
+func (t *TestSuite) Wallet(name string) *mock.Wallet {
+ t.mutex.RLock()
+ defer t.mutex.RUnlock()
+
+ wallet, exist := t.wallets.Get(name)
+ if !exist {
+ panic(fmt.Sprintf("wallet %s does not exist", name))
+ }
+
+ return wallet
+}
+
func (t *TestSuite) Nodes(names ...string) []*mock.Node {
if len(names) == 0 {
t.mutex.RLock()
@@ -320,7 +326,7 @@ func (t *TestSuite) addNodeToPartition(name string, partition string, validator
node := mock.NewNode(t.Testing, t.network, partition, name, validator)
t.nodes.Set(name, node)
- amount := MinValidatorAccountAmount
+ amount := mock.MinValidatorAccountAmount
if len(optAmount) > 0 {
amount = optAmount[0]
}
@@ -349,7 +355,11 @@ func (t *TestSuite) AddValidatorNodeToPartition(name string, partition string, o
}
func (t *TestSuite) AddValidatorNode(name string, optAmount ...iotago.BaseToken) *mock.Node {
- return t.addNodeToPartition(name, mock.NetworkMainPartition, true, optAmount...)
+ node := t.addNodeToPartition(name, mock.NetworkMainPartition, true, optAmount...)
+ // create a wallet for each validator node which uses the validator account as a block issuer
+ t.addWallet(name, node, node.Validator.AccountID, node.KeyManager)
+
+ return node
}
func (t *TestSuite) AddNodeToPartition(name string, partition string, optAmount ...iotago.BaseToken) *mock.Node {
@@ -364,9 +374,10 @@ func (t *TestSuite) RemoveNode(name string) {
t.nodes.Delete(name)
}
-func (t *TestSuite) AddBasicBlockIssuer(name string, blockIssuanceCredits ...iotago.BlockIssuanceCredits) *mock.BlockIssuer {
- newBlockIssuer := mock.NewBlockIssuer(t.Testing, name, false)
- t.blockIssuers.Set(name, newBlockIssuer)
+// AddGenesisWallet adds a wallet to the test suite with a block issuer in the genesis snapshot and access to the genesis seed.
+// If no block issuance credits are provided, the wallet will be assigned half of the maximum block issuance credits.
+func (t *TestSuite) AddGenesisWallet(name string, node *mock.Node, blockIssuanceCredits ...iotago.BlockIssuanceCredits) *mock.Wallet {
+ newWallet := t.addWallet(name, node, iotago.EmptyAccountID, t.genesisKeyManager)
var bic iotago.BlockIssuanceCredits
if len(blockIssuanceCredits) == 0 {
bic = iotago.MaxBlockIssuanceCredits / 2
@@ -375,24 +386,34 @@ func (t *TestSuite) AddBasicBlockIssuer(name string, blockIssuanceCredits ...iot
}
accountDetails := snapshotcreator.AccountDetails{
- Address: iotago.Ed25519AddressFromPubKey(newBlockIssuer.PublicKey),
- Amount: MinIssuerAccountAmount,
- Mana: iotago.Mana(MinIssuerAccountAmount),
- IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(newBlockIssuer.PublicKey)),
+ Address: iotago.Ed25519AddressFromPubKey(newWallet.BlockIssuer.PublicKey),
+ Amount: mock.MinIssuerAccountAmount,
+ Mana: iotago.Mana(mock.MinIssuerAccountAmount),
+ IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(newWallet.BlockIssuer.PublicKey)),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: bic,
}
t.optsAccounts = append(t.optsAccounts, accountDetails)
- return newBlockIssuer
+ return newWallet
}
-func (t *TestSuite) DefaultBasicBlockIssuer() *mock.BlockIssuer {
- defaultBasicBlockIssuer, exists := t.blockIssuers.Get("default")
- require.True(t.Testing, exists, "default block issuer not found")
+func (t *TestSuite) addWallet(name string, node *mock.Node, accountID iotago.AccountID, keyManager *mock.KeyManager) *mock.Wallet {
+ newWallet := mock.NewWallet(t.Testing, name, node, keyManager)
+ newWallet.SetBlockIssuer(accountID)
+ t.wallets.Set(name, newWallet)
- return defaultBasicBlockIssuer
+ return newWallet
+}
+
+func (t *TestSuite) DefaultWallet() *mock.Wallet {
+ defaultWallet, exists := t.wallets.Get("default")
+ if !exists {
+ return nil
+ }
+
+ return defaultWallet
}
func (t *TestSuite) Run(failOnBlockFiltered bool, nodesOptions ...map[string][]options.Option[protocol.Protocol]) {
@@ -401,11 +422,10 @@ func (t *TestSuite) Run(failOnBlockFiltered bool, nodesOptions ...map[string][]o
// Create accounts for any block issuer nodes added before starting the network.
if t.optsAccounts != nil {
- wallet := mock.NewHDWallet("genesis", t.genesisSeed[:], 0)
t.optsSnapshotOptions = append(t.optsSnapshotOptions, snapshotcreator.WithAccounts(lo.Map(t.optsAccounts, func(accountDetails snapshotcreator.AccountDetails) snapshotcreator.AccountDetails {
- // if no custom address is assigned to the account, assign an address generated from GenesisSeed
+ // if no custom address is assigned to the account, assign an address generated from GenesisKeyManager
if accountDetails.Address == nil {
- accountDetails.Address = wallet.Address()
+ accountDetails.Address = t.genesisKeyManager.Address(iotago.AddressEd25519)
}
if accountDetails.AccountID.Empty() {
@@ -422,7 +442,7 @@ func (t *TestSuite) Run(failOnBlockFiltered bool, nodesOptions ...map[string][]o
})...))
}
- err := snapshotcreator.CreateSnapshot(append([]options.Option[snapshotcreator.Options]{snapshotcreator.WithGenesisSeed(t.genesisSeed[:])}, t.optsSnapshotOptions...)...)
+ err := snapshotcreator.CreateSnapshot(append([]options.Option[snapshotcreator.Options]{snapshotcreator.WithGenesisKeyManager(t.genesisKeyManager)}, t.optsSnapshotOptions...)...)
if err != nil {
panic(fmt.Sprintf("failed to create snapshot: %s", err))
}
@@ -443,8 +463,13 @@ func (t *TestSuite) Run(failOnBlockFiltered bool, nodesOptions ...map[string][]o
node.Initialize(failOnBlockFiltered, baseOpts...)
- if t.TransactionFramework == nil {
- t.TransactionFramework = NewTransactionFramework(node.Protocol, t.genesisSeed[:])
+ if defaultWallet := t.DefaultWallet(); defaultWallet != nil {
+ if err := node.Protocol.MainEngineInstance().Ledger.ForEachUnspentOutput(func(output *utxoledger.Output) bool {
+ defaultWallet.AddOutput(fmt.Sprintf("Genesis:%d", output.OutputID().Index()), output)
+ return true
+ }); err != nil {
+ panic(err)
+ }
}
return true
@@ -473,7 +498,7 @@ func (t *TestSuite) BlockIssuersForNodes(nodes []*mock.Node) []*mock.BlockIssuer
if node.IsValidator() {
blockIssuers = append(blockIssuers, node.Validator)
} else {
- blockIssuers = append(blockIssuers, t.DefaultBasicBlockIssuer())
+ blockIssuers = append(blockIssuers, t.DefaultWallet().BlockIssuer)
}
}
diff --git a/pkg/testsuite/testsuite_issue_blocks.go b/pkg/testsuite/testsuite_issue_blocks.go
index 8b07356ac..982f4a714 100644
--- a/pkg/testsuite/testsuite_issue_blocks.go
+++ b/pkg/testsuite/testsuite_issue_blocks.go
@@ -49,29 +49,19 @@ func (t *TestSuite) limitParentsCountInBlockOptions(blockOpts []options.Option[m
return blockOpts
}
-func (t *TestSuite) RegisterBlock(alias string, block *blocks.Block) {
+func (t *TestSuite) RegisterBlock(blockName string, block *blocks.Block) {
t.mutex.Lock()
defer t.mutex.Unlock()
- t.registerBlock(alias, block)
+ t.registerBlock(blockName, block)
}
-func (t *TestSuite) registerBlock(alias string, block *blocks.Block) {
- t.blocks.Set(alias, block)
- block.ID().RegisterAlias(alias)
+func (t *TestSuite) registerBlock(blockName string, block *blocks.Block) {
+ t.blocks.Set(blockName, block)
+ block.ID().RegisterAlias(blockName)
}
-func (t *TestSuite) CreateBasicBlock(alias string, blockIssuer *mock.BlockIssuer, node *mock.Node, blockOpts ...options.Option[mock.BasicBlockParams]) {
- t.mutex.Lock()
- defer t.mutex.Unlock()
-
- block, err := blockIssuer.CreateBasicBlock(context.Background(), alias, node, blockOpts...)
- require.NoError(t.Testing, err)
-
- t.registerBlock(alias, block)
-}
-
-func (t *TestSuite) IssueValidationBlockAtSlot(alias string, slot iotago.SlotIndex, slotCommitment *iotago.Commitment, node *mock.Node, parents ...iotago.BlockID) *blocks.Block {
+func (t *TestSuite) IssueValidationBlockAtSlot(blockName string, slot iotago.SlotIndex, slotCommitment *iotago.Commitment, node *mock.Node, parents ...iotago.BlockID) *blocks.Block {
t.AssertBlocksExist(t.Blocks(lo.Map(parents, func(id iotago.BlockID) string { return id.Alias() })...), true, node)
t.mutex.Lock()
@@ -83,48 +73,48 @@ func (t *TestSuite) IssueValidationBlockAtSlot(alias string, slot iotago.SlotInd
require.Truef(t.Testing, issuingTime.Before(time.Now()), "node: %s: issued block (%s, slot: %d) is in the current (%s, slot: %d) or future slot", node.Name, issuingTime, slot, time.Now(), timeProvider.SlotFromTime(time.Now()))
require.True(t.Testing, node.IsValidator(), "node: %s: is not a validator node", node.Name)
- block := node.Validator.IssueValidationBlock(context.Background(), alias, node, mock.WithValidationBlockHeaderOptions(mock.WithIssuingTime(issuingTime), mock.WithSlotCommitment(slotCommitment), mock.WithStrongParents(parents...)))
+ block := node.Validator.IssueValidationBlock(context.Background(), blockName, node, mock.WithValidationBlockHeaderOptions(mock.WithIssuingTime(issuingTime), mock.WithSlotCommitment(slotCommitment), mock.WithStrongParents(parents...)))
- t.registerBlock(alias, block)
+ t.registerBlock(blockName, block)
return block
}
-func (t *TestSuite) IssueExistingBlock(alias string, blockIssuer *mock.BlockIssuer, node *mock.Node) {
+func (t *TestSuite) IssueExistingBlock(blockName string, wallet *mock.Wallet) {
t.mutex.Lock()
defer t.mutex.Unlock()
- block, exists := t.blocks.Get(alias)
+ block, exists := t.blocks.Get(blockName)
require.True(t.Testing, exists)
require.NotNil(t.Testing, block)
- require.NoError(t.Testing, blockIssuer.IssueBlock(block.ModelBlock(), node))
+ require.NoError(t.Testing, wallet.BlockIssuer.IssueBlock(block.ModelBlock(), wallet.Node))
}
-func (t *TestSuite) IssueValidationBlockWithOptions(alias string, blockIssuer *mock.BlockIssuer, node *mock.Node, blockOpts ...options.Option[mock.ValidatorBlockParams]) *blocks.Block {
+func (t *TestSuite) IssueValidationBlockWithOptions(blockName string, node *mock.Node, blockOpts ...options.Option[mock.ValidatorBlockParams]) *blocks.Block {
t.mutex.Lock()
defer t.mutex.Unlock()
- block := blockIssuer.IssueValidationBlock(context.Background(), alias, node, blockOpts...)
+ block := node.IssueValidationBlock(context.Background(), blockName, blockOpts...)
- t.registerBlock(alias, block)
+ t.registerBlock(blockName, block)
return block
}
-func (t *TestSuite) IssueBasicBlockWithOptions(alias string, blockIssuer *mock.BlockIssuer, node *mock.Node, blockOpts ...options.Option[mock.BasicBlockParams]) *blocks.Block {
+func (t *TestSuite) IssueBasicBlockWithOptions(blockName string, wallet *mock.Wallet, blockOpts ...options.Option[mock.BasicBlockParams]) *blocks.Block {
t.mutex.Lock()
defer t.mutex.Unlock()
- block := blockIssuer.IssueBasicBlock(context.Background(), alias, node, blockOpts...)
+ block := wallet.IssueBasicBlock(context.Background(), blockName, blockOpts...)
- t.registerBlock(alias, block)
+ t.registerBlock(blockName, block)
return block
}
-func (t *TestSuite) IssueBasicBlockAtSlotWithOptions(alias string, slot iotago.SlotIndex, slotCommitment *iotago.Commitment, blockIssuer *mock.BlockIssuer, node *mock.Node, payload iotago.Payload, blockOpts ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
- t.assertParentsExistFromBlockOptions(blockOpts, node)
+func (t *TestSuite) IssueBasicBlockAtSlotWithOptions(blockName string, slot iotago.SlotIndex, wallet *mock.Wallet, payload iotago.Payload, blockOpts ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
+ t.assertParentsExistFromBlockOptions(blockOpts, wallet.Node)
t.mutex.Lock()
defer t.mutex.Unlock()
@@ -132,29 +122,29 @@ func (t *TestSuite) IssueBasicBlockAtSlotWithOptions(alias string, slot iotago.S
timeProvider := t.API.TimeProvider()
issuingTime := timeProvider.SlotStartTime(slot).Add(time.Duration(t.uniqueBlockTimeCounter.Add(1)))
- require.Truef(t.Testing, issuingTime.Before(time.Now()), "node: %s: issued block (%s, slot: %d) is in the current (%s, slot: %d) or future slot", node.Name, issuingTime, slot, time.Now(), timeProvider.SlotFromTime(time.Now()))
+ require.Truef(t.Testing, issuingTime.Before(time.Now()), "wallet: %s: issued block (%s, slot: %d) is in the current (%s, slot: %d) or future slot", wallet.Name, issuingTime, slot, time.Now(), timeProvider.SlotFromTime(time.Now()))
- block := blockIssuer.IssueBasicBlock(context.Background(), alias, node, mock.WithBasicBlockHeader(append(blockOpts, mock.WithIssuingTime(issuingTime), mock.WithSlotCommitment(slotCommitment))...), mock.WithPayload(payload))
+ block := wallet.IssueBasicBlock(context.Background(), blockName, mock.WithBasicBlockHeader(append(blockOpts, mock.WithIssuingTime(issuingTime))...), mock.WithPayload(payload))
- t.registerBlock(alias, block)
+ t.registerBlock(blockName, block)
return block
}
-func (t *TestSuite) IssuePayloadWithOptions(alias string, blockIssuer *mock.BlockIssuer, node *mock.Node, payload iotago.Payload, blockHeaderOpts ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
- t.assertParentsExistFromBlockOptions(blockHeaderOpts, node)
+func (t *TestSuite) IssuePayloadWithOptions(blockName string, wallet *mock.Wallet, payload iotago.Payload, blockHeaderOpts ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
+ t.assertParentsExistFromBlockOptions(blockHeaderOpts, wallet.Node)
t.mutex.Lock()
defer t.mutex.Unlock()
- block := blockIssuer.IssueBasicBlock(context.Background(), alias, node, mock.WithPayload(payload), mock.WithBasicBlockHeader(blockHeaderOpts...))
+ block := wallet.IssueBasicBlock(context.Background(), blockName, mock.WithPayload(payload), mock.WithBasicBlockHeader(blockHeaderOpts...))
- t.registerBlock(alias, block)
+ t.registerBlock(blockName, block)
return block
}
-func (t *TestSuite) IssueValidationBlock(alias string, node *mock.Node, blockHeaderOpts ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
+func (t *TestSuite) IssueValidationBlock(blockName string, node *mock.Node, blockHeaderOpts ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
t.assertParentsExistFromBlockOptions(blockHeaderOpts, node)
require.Truef(t.Testing, node.IsValidator(), "node: %s: is not a validator node", node.Name)
@@ -162,21 +152,20 @@ func (t *TestSuite) IssueValidationBlock(alias string, node *mock.Node, blockHea
t.mutex.Lock()
defer t.mutex.Unlock()
- block := node.Validator.IssueValidationBlock(context.Background(), alias, node, mock.WithValidationBlockHeaderOptions(blockHeaderOpts...))
+ block := node.Validator.IssueValidationBlock(context.Background(), blockName, node, mock.WithValidationBlockHeaderOptions(blockHeaderOpts...))
- t.registerBlock(alias, block)
+ t.registerBlock(blockName, block)
return block
}
-func (t *TestSuite) IssueCandidacyAnnouncementInSlot(alias string, slot iotago.SlotIndex, parentsPrefixAlias string, node *mock.Node, issuingOptions ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
+func (t *TestSuite) IssueCandidacyAnnouncementInSlot(alias string, slot iotago.SlotIndex, parentsPrefixAlias string, wallet *mock.Wallet, issuingOptions ...options.Option[mock.BlockHeaderParams]) *blocks.Block {
timeProvider := t.API.TimeProvider()
issuingTime := timeProvider.SlotStartTime(slot).Add(time.Duration(t.uniqueBlockTimeCounter.Add(1)))
- require.Truef(t.Testing, issuingTime.Before(time.Now()), "node: %s: issued block (%s, slot: %d) is in the current (%s, slot: %d) or future slot", node.Name, issuingTime, slot, time.Now(), timeProvider.SlotFromTime(time.Now()))
+ require.Truef(t.Testing, issuingTime.Before(time.Now()), "wallet: %s: issued block (%s, slot: %d) is in the current (%s, slot: %d) or future slot", wallet.Name, issuingTime, slot, time.Now(), timeProvider.SlotFromTime(time.Now()))
return t.IssuePayloadWithOptions(
alias,
- node.Validator,
- node,
+ wallet,
&iotago.CandidacyAnnouncement{},
append(issuingOptions,
mock.WithStrongParents(t.BlockIDsWithPrefix(parentsPrefixAlias)...),
@@ -185,15 +174,14 @@ func (t *TestSuite) IssueCandidacyAnnouncementInSlot(alias string, slot iotago.S
)
}
-func (t *TestSuite) IssueBlockRowInSlot(prefix string, slot iotago.SlotIndex, row int, parentsPrefixAlias string, nodes []*mock.Node, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) []*blocks.Block {
- blockIssuers := t.BlockIssuersForNodes(nodes)
+func (t *TestSuite) IssueBlockRowInSlot(prefix string, slot iotago.SlotIndex, row int, parentsPrefix string, nodes []*mock.Node, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) []*blocks.Block {
blocksIssued := make([]*blocks.Block, 0, len(nodes))
- strongParents := t.BlockIDsWithPrefix(parentsPrefixAlias)
+ strongParents := t.BlockIDsWithPrefix(parentsPrefix)
issuingOptionsCopy := lo.MergeMaps(make(map[string][]options.Option[mock.BlockHeaderParams]), issuingOptions)
- for index, node := range nodes {
- blockAlias := fmt.Sprintf("%s%d.%d-%s", prefix, slot, row, node.Name)
+ for _, node := range nodes {
+ blockName := fmt.Sprintf("%s%d.%d-%s", prefix, slot, row, node.Name)
issuingOptionsCopy[node.Name] = append(issuingOptionsCopy[node.Name], mock.WithStrongParents(strongParents...))
timeProvider := t.API.TimeProvider()
@@ -202,23 +190,22 @@ func (t *TestSuite) IssueBlockRowInSlot(prefix string, slot iotago.SlotIndex, ro
var b *blocks.Block
// Only issue validator blocks if account has staking feature and is part of committee.
- if blockIssuers[index].Validator && lo.Return1(node.Protocol.MainEngineInstance().SybilProtection.SeatManager().CommitteeInSlot(slot)).HasAccount(node.Validator.AccountID) {
+ if node.Validator != nil && lo.Return1(node.Protocol.MainEngineInstance().SybilProtection.SeatManager().CommitteeInSlot(slot)).HasAccount(node.Validator.AccountID) {
blockHeaderOptions := append(issuingOptionsCopy[node.Name], mock.WithIssuingTime(issuingTime))
t.assertParentsCommitmentExistFromBlockOptions(blockHeaderOptions, node)
t.assertParentsExistFromBlockOptions(blockHeaderOptions, node)
- b = t.IssueValidationBlockWithOptions(blockAlias, blockIssuers[index], node, mock.WithValidationBlockHeaderOptions(blockHeaderOptions...), mock.WithHighestSupportedVersion(node.HighestSupportedVersion()), mock.WithProtocolParametersHash(node.ProtocolParametersHash()))
+ b = t.IssueValidationBlockWithOptions(blockName, node, mock.WithValidationBlockHeaderOptions(blockHeaderOptions...), mock.WithHighestSupportedVersion(node.HighestSupportedVersion()), mock.WithProtocolParametersHash(node.ProtocolParametersHash()))
} else {
txCount := t.automaticTransactionIssuingCounters.Compute(node.Partition, func(currentValue int, exists bool) int {
return currentValue + 1
})
- inputAlias := fmt.Sprintf("automaticSpent-%d:0", txCount-1)
- txAlias := fmt.Sprintf("automaticSpent-%d", txCount)
+ inputName := fmt.Sprintf("automaticSpent-%d:0", txCount-1)
+ txName := fmt.Sprintf("automaticSpent-%d", txCount)
if txCount == 1 {
- inputAlias = "Genesis:0"
+ inputName = "Genesis:0"
}
- tx, err := t.TransactionFramework.CreateSimpleTransaction(txAlias, 1, inputAlias)
- require.NoError(t.Testing, err)
+ tx := t.DefaultWallet().CreateBasicOutputsEquallyFromInputs(txName, 1, inputName)
issuingOptionsCopy[node.Name] = t.limitParentsCountInBlockOptions(issuingOptionsCopy[node.Name], iotago.BlockMaxParents)
@@ -226,7 +213,8 @@ func (t *TestSuite) IssueBlockRowInSlot(prefix string, slot iotago.SlotIndex, ro
t.assertParentsCommitmentExistFromBlockOptions(blockHeaderOptions, node)
t.assertParentsExistFromBlockOptions(blockHeaderOptions, node)
- b = t.IssueBasicBlockWithOptions(blockAlias, blockIssuers[index], node, mock.WithPayload(tx), mock.WithBasicBlockHeader(blockHeaderOptions...))
+ t.DefaultWallet().SetDefaultNode(node)
+ b = t.IssueBasicBlockWithOptions(blockName, t.DefaultWallet(), mock.WithPayload(tx), mock.WithBasicBlockHeader(blockHeaderOptions...))
}
blocksIssued = append(blocksIssued, b)
}
@@ -234,32 +222,32 @@ func (t *TestSuite) IssueBlockRowInSlot(prefix string, slot iotago.SlotIndex, ro
return blocksIssued
}
-func (t *TestSuite) IssueBlockRowsInSlot(prefix string, slot iotago.SlotIndex, rows int, initialParentsPrefixAlias string, nodes []*mock.Node, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) (allBlocksIssued []*blocks.Block, lastBlockRow []*blocks.Block) {
+func (t *TestSuite) IssueBlockRowsInSlot(prefix string, slot iotago.SlotIndex, rows int, initialParentsPrefix string, nodes []*mock.Node, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) (allBlocksIssued []*blocks.Block, lastBlockRow []*blocks.Block) {
var blocksIssued, lastBlockRowIssued []*blocks.Block
- parentsPrefixAlias := initialParentsPrefixAlias
+ parentsPrefix := initialParentsPrefix
for row := 0; row < rows; row++ {
if row > 0 {
- parentsPrefixAlias = fmt.Sprintf("%s%d.%d", prefix, slot, row-1)
+ parentsPrefix = fmt.Sprintf("%s%d.%d", prefix, slot, row-1)
}
- lastBlockRowIssued = t.IssueBlockRowInSlot(prefix, slot, row, parentsPrefixAlias, nodes, issuingOptions)
+ lastBlockRowIssued = t.IssueBlockRowInSlot(prefix, slot, row, parentsPrefix, nodes, issuingOptions)
blocksIssued = append(blocksIssued, lastBlockRowIssued...)
}
return blocksIssued, lastBlockRowIssued
}
-func (t *TestSuite) IssueBlocksAtSlots(prefix string, slots []iotago.SlotIndex, rowsPerSlot int, initialParentsPrefixAlias string, nodes []*mock.Node, waitForSlotsCommitted bool, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) (allBlocksIssued []*blocks.Block, lastBlockRow []*blocks.Block) {
+func (t *TestSuite) IssueBlocksAtSlots(prefix string, slots []iotago.SlotIndex, rowsPerSlot int, initialParentsPrefix string, nodes []*mock.Node, waitForSlotsCommitted bool, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) (allBlocksIssued []*blocks.Block, lastBlockRow []*blocks.Block) {
var blocksIssued, lastBlockRowIssued []*blocks.Block
- parentsPrefixAlias := initialParentsPrefixAlias
+ parentsPrefix := initialParentsPrefix
for i, slot := range slots {
if i > 0 {
- parentsPrefixAlias = fmt.Sprintf("%s%d.%d", prefix, slots[i-1], rowsPerSlot-1)
+ parentsPrefix = fmt.Sprintf("%s%d.%d", prefix, slots[i-1], rowsPerSlot-1)
}
- blocksInSlot, lastRowInSlot := t.IssueBlockRowsInSlot(prefix, slot, rowsPerSlot, parentsPrefixAlias, nodes, issuingOptions)
+ blocksInSlot, lastRowInSlot := t.IssueBlockRowsInSlot(prefix, slot, rowsPerSlot, parentsPrefix, nodes, issuingOptions)
blocksIssued = append(blocksIssued, blocksInSlot...)
lastBlockRowIssued = lastRowInSlot
@@ -275,8 +263,8 @@ func (t *TestSuite) IssueBlocksAtSlots(prefix string, slots []iotago.SlotIndex,
return blocksIssued, lastBlockRowIssued
}
-func (t *TestSuite) IssueBlocksAtEpoch(prefix string, epoch iotago.EpochIndex, rowsPerSlot int, initialParentsPrefixAlias string, nodes []*mock.Node, waitForSlotsCommitted bool, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) (allBlocksIssued []*blocks.Block, lastBlockRow []*blocks.Block) {
- return t.IssueBlocksAtSlots(prefix, t.SlotsForEpoch(epoch), rowsPerSlot, initialParentsPrefixAlias, nodes, waitForSlotsCommitted, issuingOptions)
+func (t *TestSuite) IssueBlocksAtEpoch(prefix string, epoch iotago.EpochIndex, rowsPerSlot int, initialParentsPrefix string, nodes []*mock.Node, waitForSlotsCommitted bool, issuingOptions map[string][]options.Option[mock.BlockHeaderParams]) (allBlocksIssued []*blocks.Block, lastBlockRow []*blocks.Block) {
+ return t.IssueBlocksAtSlots(prefix, t.SlotsForEpoch(epoch), rowsPerSlot, initialParentsPrefix, nodes, waitForSlotsCommitted, issuingOptions)
}
func (t *TestSuite) SlotsForEpoch(epoch iotago.EpochIndex) []iotago.SlotIndex {
@@ -315,8 +303,8 @@ func (t *TestSuite) CommitUntilSlot(slot iotago.SlotIndex, parent *blocks.Block)
committeeAtBlockSlot, exists := node.Protocol.MainEngineInstance().SybilProtection.SeatManager().CommitteeInSlot(nextBlockSlot)
require.True(t.Testing, exists, "node: %s: does not have committee selected for slot %d", node.Name, nextBlockSlot)
if committeeAtBlockSlot.HasAccount(node.Validator.AccountID) {
- blockAlias := fmt.Sprintf("chain-%s-%d-%s", parent.ID().Alias(), chainIndex, node.Name)
- tip = t.IssueValidationBlockAtSlot(blockAlias, nextBlockSlot, node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), node, tip.ID())
+ blockName := fmt.Sprintf("chain-%s-%d-%s", parent.ID().Alias(), chainIndex, node.Name)
+ tip = t.IssueValidationBlockAtSlot(blockName, nextBlockSlot, node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), node, tip.ID())
}
}
// acceptance of nextBlockSlot
@@ -324,8 +312,8 @@ func (t *TestSuite) CommitUntilSlot(slot iotago.SlotIndex, parent *blocks.Block)
committeeAtBlockSlot, exists := node.Protocol.MainEngineInstance().SybilProtection.SeatManager().CommitteeInSlot(nextBlockSlot)
require.True(t.Testing, exists, "node: %s: does not have committee selected for slot %d", node.Name, nextBlockSlot)
if committeeAtBlockSlot.HasAccount(node.Validator.AccountID) {
- blockAlias := fmt.Sprintf("chain-%s-%d-%s", parent.ID().Alias(), chainIndex+1, node.Name)
- tip = t.IssueValidationBlockAtSlot(blockAlias, nextBlockSlot, node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), node, tip.ID())
+ blockName := fmt.Sprintf("chain-%s-%d-%s", parent.ID().Alias(), chainIndex+1, node.Name)
+ tip = t.IssueValidationBlockAtSlot(blockName, nextBlockSlot, node.Protocol.MainEngineInstance().Storage.Settings().LatestCommitment().Commitment(), node, tip.ID())
}
}
diff --git a/pkg/testsuite/testsuite_options.go b/pkg/testsuite/testsuite_options.go
index eec758168..6f467834e 100644
--- a/pkg/testsuite/testsuite_options.go
+++ b/pkg/testsuite/testsuite_options.go
@@ -5,7 +5,7 @@ import (
"time"
"github.com/iotaledger/hive.go/runtime/options"
- "github.com/iotaledger/iota-core/pkg/protocol/snapshotcreator"
+ "github.com/iotaledger/iota-core/pkg/testsuite/snapshotcreator"
iotago "github.com/iotaledger/iota.go/v4"
)
diff --git a/pkg/testsuite/transactions.go b/pkg/testsuite/transactions.go
index f87e92e3a..23d2eb885 100644
--- a/pkg/testsuite/transactions.go
+++ b/pkg/testsuite/transactions.go
@@ -141,7 +141,7 @@ func (t *TestSuite) AssertTransactionInCacheConflicts(transactionConflicts map[*
return ierrors.Errorf("AssertTransactionInCacheConflicts: %s: block %s does not exist", node.Name, transactionID)
}
- expectedConflictIDs := ds.NewSet(lo.Map(conflictAliases, t.TransactionFramework.TransactionID)...)
+ expectedConflictIDs := ds.NewSet(lo.Map(conflictAliases, t.DefaultWallet().TransactionID)...)
actualConflictIDs := transactionFromCache.ConflictIDs()
if expectedConflictIDs.Size() != actualConflictIDs.Size() {
diff --git a/pkg/testsuite/transactions_framework.go b/pkg/testsuite/transactions_framework.go
deleted file mode 100644
index 0419fda55..000000000
--- a/pkg/testsuite/transactions_framework.go
+++ /dev/null
@@ -1,603 +0,0 @@
-package testsuite
-
-import (
- "fmt"
- "time"
-
- "github.com/iotaledger/hive.go/ierrors"
- "github.com/iotaledger/hive.go/lo"
- "github.com/iotaledger/hive.go/runtime/options"
- "github.com/iotaledger/iota-core/pkg/protocol"
- "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
- "github.com/iotaledger/iota-core/pkg/testsuite/mock"
- iotago "github.com/iotaledger/iota.go/v4"
- "github.com/iotaledger/iota.go/v4/builder"
- "github.com/iotaledger/iota.go/v4/tpkg"
-)
-
-type TransactionFramework struct {
- apiProvider iotago.APIProvider
-
- wallet *mock.HDWallet
- states map[string]*utxoledger.Output
- signedTransactions map[string]*iotago.SignedTransaction
- transactions map[string]*iotago.Transaction
-}
-
-func NewTransactionFramework(protocol *protocol.Protocol, genesisSeed []byte) *TransactionFramework {
- tf := &TransactionFramework{
- apiProvider: protocol,
- states: make(map[string]*utxoledger.Output),
- signedTransactions: make(map[string]*iotago.SignedTransaction),
- transactions: make(map[string]*iotago.Transaction),
-
- wallet: mock.NewHDWallet("genesis", genesisSeed, 0),
- }
-
- if err := protocol.MainEngineInstance().Ledger.ForEachUnspentOutput(func(output *utxoledger.Output) bool {
- tf.states[fmt.Sprintf("Genesis:%d", output.OutputID().Index())] = output
- return true
- }); err != nil {
- panic(err)
- }
-
- if len(tf.states) == 0 {
- panic("no genesis outputs found")
- }
-
- return tf
-}
-
-func (t *TransactionFramework) RegisterTransaction(alias string, transaction *iotago.Transaction) {
- currentAPI := t.apiProvider.CommittedAPI()
- (lo.PanicOnErr(transaction.ID())).RegisterAlias(alias)
-
- t.transactions[alias] = transaction
-
- for outputID, output := range lo.PanicOnErr(transaction.OutputsSet()) {
- clonedOutput := output.Clone()
- actualOutputID := iotago.OutputIDFromTransactionIDAndIndex(lo.PanicOnErr(transaction.ID()), outputID.Index())
- if clonedOutput.Type() == iotago.OutputAccount {
- if accountOutput, ok := clonedOutput.(*iotago.AccountOutput); ok && accountOutput.AccountID == iotago.EmptyAccountID {
- accountOutput.AccountID = iotago.AccountIDFromOutputID(actualOutputID)
- }
- }
-
- t.states[fmt.Sprintf("%s:%d", alias, outputID.Index())] = utxoledger.CreateOutput(t.apiProvider, actualOutputID, iotago.EmptyBlockID, currentAPI.TimeProvider().SlotFromTime(time.Now()), clonedOutput, lo.PanicOnErr(iotago.OutputIDProofFromTransaction(transaction, outputID.Index())))
- }
-}
-
-func (t *TransactionFramework) RegisterSignedTransaction(alias string, signedTransaction *iotago.SignedTransaction) {
- (lo.PanicOnErr(signedTransaction.ID())).RegisterAlias(alias)
-
- t.signedTransactions[alias] = signedTransaction
-}
-
-func (t *TransactionFramework) CreateSignedTransactionWithOptions(alias string, signingWallets []*mock.HDWallet, opts ...options.Option[builder.TransactionBuilder]) (*iotago.SignedTransaction, error) {
- currentAPI := t.apiProvider.CommittedAPI()
-
- walletKeys := make([]iotago.AddressKeys, 0, len(signingWallets)*2)
- for _, wallet := range signingWallets {
- inputPrivateKey, _ := wallet.KeyPair()
- // add address keys for both types of directly unlockable addresses to simplify the TransactionFramework
- //nolint:forcetypeassert
- walletKeys = append(walletKeys, iotago.NewAddressKeysForEd25519Address(wallet.Address(iotago.AddressEd25519).(*iotago.Ed25519Address), inputPrivateKey))
- //nolint:forcetypeassert
- walletKeys = append(walletKeys, iotago.NewAddressKeysForImplicitAccountCreationAddress(wallet.Address(iotago.AddressImplicitAccountCreation).(*iotago.ImplicitAccountCreationAddress), inputPrivateKey))
- }
-
- txBuilder := builder.NewTransactionBuilder(currentAPI)
- txBuilder.WithTransactionCapabilities(iotago.TransactionCapabilitiesBitMaskWithCapabilities(iotago.WithTransactionCanDoAnything()))
- // Always add a random payload to randomize transaction ID.
- randomPayload := tpkg.Rand12ByteArray()
- txBuilder.AddTaggedDataPayload(&iotago.TaggedData{Tag: randomPayload[:], Data: randomPayload[:]})
-
- signedTransaction, err := options.Apply(txBuilder, opts).Build(iotago.NewInMemoryAddressSigner(walletKeys...))
- if err == nil {
- t.RegisterSignedTransaction(alias, signedTransaction)
- t.RegisterTransaction(alias, signedTransaction.Transaction)
- }
-
- return signedTransaction, err
-}
-
-func (t *TransactionFramework) CreateSimpleTransaction(alias string, outputCount int, inputAliases ...string) (*iotago.SignedTransaction, error) {
- inputStates, outputStates, signingWallets := t.CreateBasicOutputsEqually(outputCount, inputAliases...)
-
- return t.CreateSignedTransactionWithOptions(alias, signingWallets, WithInputs(inputStates), WithOutputs(outputStates))
-}
-
-func (t *TransactionFramework) CreateBasicOutputsEqually(outputCount int, inputAliases ...string) (consumedInputs utxoledger.Outputs, outputs iotago.Outputs[iotago.Output], signingWallets []*mock.HDWallet) {
- inputStates := make([]*utxoledger.Output, 0, len(inputAliases))
- totalInputAmounts := iotago.BaseToken(0)
- totalInputStoredMana := iotago.Mana(0)
-
- for _, inputAlias := range inputAliases {
- output := t.Output(inputAlias)
- inputStates = append(inputStates, output)
- totalInputAmounts += output.BaseTokenAmount()
- totalInputStoredMana += output.StoredMana()
- }
-
- manaAmount := totalInputStoredMana / iotago.Mana(outputCount)
- remainderMana := totalInputStoredMana
-
- tokenAmount := totalInputAmounts / iotago.BaseToken(outputCount)
- remainderFunds := totalInputAmounts
-
- outputStates := make(iotago.Outputs[iotago.Output], 0, outputCount)
- for i := 0; i < outputCount; i++ {
- if i+1 == outputCount {
- tokenAmount = remainderFunds
- manaAmount = remainderMana
- }
- remainderFunds -= tokenAmount
- remainderMana -= manaAmount
-
- outputStates = append(outputStates, &iotago.BasicOutput{
- Amount: tokenAmount,
- Mana: manaAmount,
- Conditions: iotago.BasicOutputUnlockConditions{
- &iotago.AddressUnlockCondition{Address: t.DefaultAddress()},
- },
- Features: iotago.BasicOutputFeatures{},
- })
- }
-
- return inputStates, outputStates, []*mock.HDWallet{t.wallet}
-}
-
-func (t *TransactionFramework) CreateBasicOutputs(amountDistribution []iotago.BaseToken, manaDistribution []iotago.Mana, inputAliases ...string) (consumedInputs utxoledger.Outputs, outputs iotago.Outputs[iotago.Output], signingWallets []*mock.HDWallet) {
- if len(amountDistribution) != len(manaDistribution) {
- panic("amount and mana distributions should have the same length")
- }
-
- inputStates := make([]*utxoledger.Output, 0, len(inputAliases))
- totalInputAmounts := iotago.BaseToken(0)
- totalInputStoredMana := iotago.Mana(0)
-
- for _, inputAlias := range inputAliases {
- output := t.Output(inputAlias)
- inputStates = append(inputStates, output)
- totalInputAmounts += output.BaseTokenAmount()
- totalInputStoredMana += output.StoredMana()
- }
-
- if lo.Sum(amountDistribution...) != totalInputAmounts {
- panic("amount on input and output side must be equal")
- }
-
- outputStates := make(iotago.Outputs[iotago.Output], 0, len(amountDistribution))
- for idx, outputAmount := range amountDistribution {
- outputStates = append(outputStates, &iotago.BasicOutput{
- Amount: outputAmount,
- Mana: manaDistribution[idx],
- Conditions: iotago.BasicOutputUnlockConditions{
- &iotago.AddressUnlockCondition{Address: t.DefaultAddress()},
- },
- Features: iotago.BasicOutputFeatures{},
- })
- }
-
- return inputStates, outputStates, []*mock.HDWallet{t.wallet}
-}
-
-func (t *TransactionFramework) CreateAccountFromInput(inputAlias string, opts ...options.Option[builder.AccountOutputBuilder]) (utxoledger.Outputs, iotago.Outputs[iotago.Output], []*mock.HDWallet) {
- input := t.Output(inputAlias)
-
- accountOutput := options.Apply(builder.NewAccountOutputBuilder(t.DefaultAddress(), t.DefaultAddress(), input.BaseTokenAmount()).
- Mana(input.StoredMana()).
- StateController(t.DefaultAddress()).
- Governor(t.DefaultAddress()),
- opts).MustBuild()
-
- outputStates := iotago.Outputs[iotago.Output]{accountOutput}
-
- // if amount was set by options, a remainder output needs to be created
- if accountOutput.Amount != input.BaseTokenAmount() {
- outputStates = append(outputStates, &iotago.BasicOutput{
- Amount: input.BaseTokenAmount() - accountOutput.Amount,
- Mana: input.StoredMana() - accountOutput.Mana,
- Conditions: iotago.BasicOutputUnlockConditions{
- &iotago.AddressUnlockCondition{Address: t.DefaultAddress()},
- },
- Features: iotago.BasicOutputFeatures{},
- })
- }
-
- return utxoledger.Outputs{input}, outputStates, []*mock.HDWallet{t.wallet}
-}
-
-// CreateImplicitAccountFromInput creates an implicit account output.
-func (t *TransactionFramework) CreateImplicitAccountFromInput(inputAlias string) (utxoledger.Outputs, iotago.Outputs[iotago.Output], *iotago.ImplicitAccountCreationAddress, []*mock.HDWallet) {
- input := t.Output(inputAlias)
-
- //nolint:forcetypeassert
- implicitAccountAddress := t.DefaultAddress(iotago.AddressImplicitAccountCreation).(*iotago.ImplicitAccountCreationAddress)
-
- basicOutput := &iotago.BasicOutput{
- Amount: input.BaseTokenAmount(),
- Mana: input.StoredMana(),
- Conditions: iotago.BasicOutputUnlockConditions{
- &iotago.AddressUnlockCondition{Address: implicitAccountAddress},
- },
- Features: iotago.BasicOutputFeatures{},
- }
-
- return utxoledger.Outputs{input}, iotago.Outputs[iotago.Output]{basicOutput}, implicitAccountAddress, []*mock.HDWallet{t.wallet}
-}
-
-// CreateDelegationFromInput creates a new DelegationOutput with given options from an input. If the remainder Output
-// is not created, then StoredMana from the input is not passed and can potentially be burned.
-// In order not to burn it, it needs to be assigned manually in another output in the transaction.
-func (t *TransactionFramework) CreateDelegationFromInput(inputAlias string, opts ...options.Option[builder.DelegationOutputBuilder]) (utxoledger.Outputs, iotago.Outputs[iotago.Output], []*mock.HDWallet) {
- input := t.Output(inputAlias)
-
- delegationOutput := options.Apply(builder.NewDelegationOutputBuilder(&iotago.AccountAddress{}, t.DefaultAddress(), input.BaseTokenAmount()).
- DelegatedAmount(input.BaseTokenAmount()),
- opts).MustBuild()
-
- if delegationOutput.ValidatorAddress.AccountID() == iotago.EmptyAccountID ||
- delegationOutput.DelegatedAmount == 0 ||
- delegationOutput.StartEpoch == 0 {
- panic(fmt.Sprintf("delegation output created incorrectly %+v", delegationOutput))
- }
-
- outputStates := iotago.Outputs[iotago.Output]{delegationOutput}
-
- // if options set an Amount, a remainder output needs to be created
- if delegationOutput.Amount != input.BaseTokenAmount() {
- outputStates = append(outputStates, &iotago.BasicOutput{
- Amount: input.BaseTokenAmount() - delegationOutput.Amount,
- Mana: input.StoredMana(),
- Conditions: iotago.BasicOutputUnlockConditions{
- &iotago.AddressUnlockCondition{Address: t.DefaultAddress()},
- },
- Features: iotago.BasicOutputFeatures{},
- })
- }
-
- return utxoledger.Outputs{input}, outputStates, []*mock.HDWallet{t.wallet}
-}
-
-// DelayedClaimingTransition transitions DelegationOutput into delayed claiming state by setting DelegationID and EndEpoch.
-func (t *TransactionFramework) DelayedClaimingTransition(inputAlias string, delegationEndEpoch iotago.EpochIndex) (utxoledger.Outputs, iotago.Outputs[iotago.Output], []*mock.HDWallet) {
- input := t.Output(inputAlias)
- if input.OutputType() != iotago.OutputDelegation {
- panic(ierrors.Errorf("%s is not a delegation output, cannot transition to delayed claiming state", inputAlias))
- }
-
- prevOutput, ok := input.Output().Clone().(*iotago.DelegationOutput)
- if !ok {
- panic(ierrors.Errorf("cloned output %s is not a delegation output, cannot transition to delayed claiming state", inputAlias))
- }
-
- delegationBuilder := builder.NewDelegationOutputBuilderFromPrevious(prevOutput).EndEpoch(delegationEndEpoch)
- if prevOutput.DelegationID == iotago.EmptyDelegationID() {
- delegationBuilder.DelegationID(iotago.DelegationIDFromOutputID(input.OutputID()))
- }
-
- return utxoledger.Outputs{input}, iotago.Outputs[iotago.Output]{delegationBuilder.MustBuild()}, []*mock.HDWallet{t.wallet}
-}
-
-func (t *TransactionFramework) DestroyAccount(alias string) (consumedInputs *utxoledger.Output, outputs iotago.Outputs[iotago.Output], signingWallets []*mock.HDWallet) {
- output := t.Output(alias)
-
- outputStates := iotago.Outputs[iotago.Output]{&iotago.BasicOutput{
- Amount: output.BaseTokenAmount(),
- Mana: output.StoredMana(),
- Conditions: iotago.BasicOutputUnlockConditions{
- &iotago.AddressUnlockCondition{Address: t.DefaultAddress()},
- },
- Features: iotago.BasicOutputFeatures{},
- }}
-
- return output, outputStates, []*mock.HDWallet{t.wallet}
-}
-
-func (t *TransactionFramework) TransitionAccount(alias string, opts ...options.Option[builder.AccountOutputBuilder]) (consumedInput *utxoledger.Output, outputs iotago.Outputs[iotago.Output], signingWallets []*mock.HDWallet) {
- output, exists := t.states[alias]
- if !exists {
- panic(fmt.Sprintf("account with alias %s does not exist", alias))
- }
-
- accountOutput, ok := output.Output().Clone().(*iotago.AccountOutput)
- if !ok {
- panic(fmt.Sprintf("output with alias %s is not *iotago.AccountOutput", alias))
- }
-
- accountBuilder := builder.NewAccountOutputBuilderFromPrevious(accountOutput)
- accountOutput = options.Apply(accountBuilder, opts).MustBuild()
-
- return output, iotago.Outputs[iotago.Output]{accountOutput}, []*mock.HDWallet{t.wallet}
-}
-
-func (t *TransactionFramework) TransitionImplicitAccountToAccountOutput(alias string, opts ...options.Option[builder.AccountOutputBuilder]) (consumedInput utxoledger.Outputs, outputs iotago.Outputs[iotago.Output], signingWallets []*mock.HDWallet) {
- input, exists := t.states[alias]
- if !exists {
- panic(fmt.Sprintf("output with alias %s does not exist", alias))
- }
-
- basicOutput, isBasic := input.Output().(*iotago.BasicOutput)
- if !isBasic {
- panic(fmt.Sprintf("output with alias %s is not *iotago.BasicOutput", alias))
- }
- if basicOutput.UnlockConditionSet().Address().Address.Type() != iotago.AddressImplicitAccountCreation {
- panic(fmt.Sprintf("output with alias %s is not an implicit account", alias))
- }
-
- accountOutput := options.Apply(builder.NewAccountOutputBuilder(t.DefaultAddress(), t.DefaultAddress(), input.BaseTokenAmount()).
- Mana(input.StoredMana()).
- AccountID(iotago.AccountIDFromOutputID(input.OutputID())),
- opts).MustBuild()
-
- return utxoledger.Outputs{input}, iotago.Outputs[iotago.Output]{accountOutput}, []*mock.HDWallet{t.wallet}
-}
-
-func (t *TransactionFramework) Output(alias string) *utxoledger.Output {
- output, exists := t.states[alias]
- if !exists {
- panic(ierrors.Errorf("output with given alias does not exist %s", alias))
- }
-
- return output
-}
-
-func (t *TransactionFramework) OutputID(alias string) iotago.OutputID {
- return t.Output(alias).OutputID()
-}
-
-func (t *TransactionFramework) SignedTransaction(alias string) *iotago.SignedTransaction {
- transaction, exists := t.signedTransactions[alias]
- if !exists {
- panic(ierrors.Errorf("transaction with given alias does not exist %s", alias))
- }
-
- return transaction
-}
-
-func (t *TransactionFramework) SignedTransactionID(alias string) iotago.SignedTransactionID {
- return lo.PanicOnErr(t.SignedTransaction(alias).ID())
-}
-
-func (t *TransactionFramework) SignedTransactions(aliases ...string) []*iotago.SignedTransaction {
- return lo.Map(aliases, t.SignedTransaction)
-}
-
-func (t *TransactionFramework) SignedTransactionIDs(aliases ...string) []iotago.SignedTransactionID {
- return lo.Map(aliases, t.SignedTransactionID)
-}
-
-func (t *TransactionFramework) Transaction(alias string) *iotago.Transaction {
- transaction, exists := t.transactions[alias]
- if !exists {
- panic(ierrors.Errorf("transaction with given alias does not exist %s", alias))
- }
-
- return transaction
-}
-
-func (t *TransactionFramework) TransactionID(alias string) iotago.TransactionID {
- return lo.PanicOnErr(t.Transaction(alias).ID())
-}
-
-func (t *TransactionFramework) Transactions(aliases ...string) []*iotago.Transaction {
- return lo.Map(aliases, t.Transaction)
-}
-
-func (t *TransactionFramework) TransactionIDs(aliases ...string) []iotago.TransactionID {
- return lo.Map(aliases, t.TransactionID)
-}
-
-func (t *TransactionFramework) DefaultAddress(addressType ...iotago.AddressType) iotago.Address {
- return t.wallet.Address(addressType...)
-}
-
-// DelegationOutput options
-
-func WithDelegatedAmount(delegatedAmount iotago.BaseToken) options.Option[builder.DelegationOutputBuilder] {
- return func(delegationBuilder *builder.DelegationOutputBuilder) {
- delegationBuilder.DelegatedAmount(delegatedAmount)
- }
-}
-
-func WithDelegatedValidatorAddress(validatorAddress *iotago.AccountAddress) options.Option[builder.DelegationOutputBuilder] {
- return func(delegationBuilder *builder.DelegationOutputBuilder) {
- delegationBuilder.ValidatorAddress(validatorAddress)
- }
-}
-
-func WithDelegationStartEpoch(startEpoch iotago.EpochIndex) options.Option[builder.DelegationOutputBuilder] {
- return func(delegationBuilder *builder.DelegationOutputBuilder) {
- delegationBuilder.StartEpoch(startEpoch)
- }
-}
-
-func WithDelegationEndEpoch(endEpoch iotago.EpochIndex) options.Option[builder.DelegationOutputBuilder] {
- return func(delegationBuilder *builder.DelegationOutputBuilder) {
- delegationBuilder.EndEpoch(endEpoch)
- }
-}
-
-func WithDelegationConditions(delegationConditions iotago.DelegationOutputUnlockConditions) options.Option[builder.DelegationOutputBuilder] {
- return func(delegationBuilder *builder.DelegationOutputBuilder) {
- delegationBuilder.Address(delegationConditions.MustSet().Address().Address)
- }
-}
-
-func WithDelegationAmount(amount iotago.BaseToken) options.Option[builder.DelegationOutputBuilder] {
- return func(delegationBuilder *builder.DelegationOutputBuilder) {
- delegationBuilder.Amount(amount)
- }
-}
-
-// BlockIssuer options
-
-func WithBlockIssuerFeature(keys iotago.BlockIssuerKeys, expirySlot iotago.SlotIndex) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- accountBuilder.BlockIssuer(keys, expirySlot)
- }
-}
-
-func WithAddBlockIssuerKey(key iotago.BlockIssuerKey) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- transition := accountBuilder.GovernanceTransition()
- transition.BlockIssuerTransition().AddKeys(key)
- }
-}
-
-func WithBlockIssuerKeys(keys iotago.BlockIssuerKeys) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- transition := accountBuilder.GovernanceTransition()
- transition.BlockIssuerTransition().Keys(keys)
- }
-}
-
-func WithBlockIssuerExpirySlot(expirySlot iotago.SlotIndex) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- transition := accountBuilder.GovernanceTransition()
- transition.BlockIssuerTransition().ExpirySlot(expirySlot)
- }
-}
-
-func WithStakingFeature(amount iotago.BaseToken, fixedCost iotago.Mana, startEpoch iotago.EpochIndex, optEndEpoch ...iotago.EpochIndex) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- accountBuilder.Staking(amount, fixedCost, startEpoch, optEndEpoch...)
- }
-}
-
-// Account options
-
-func WithAccountMana(mana iotago.Mana) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- accountBuilder.Mana(mana)
- }
-}
-
-func WithAccountAmount(amount iotago.BaseToken) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- accountBuilder.Amount(amount)
- }
-}
-
-func WithAccountIncreasedFoundryCounter(diff uint32) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- accountBuilder.FoundriesToGenerate(diff)
- }
-}
-
-func WithAccountImmutableFeatures(features iotago.AccountOutputImmFeatures) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- for _, feature := range features.MustSet() {
- switch feature.Type() {
- case iotago.FeatureMetadata:
- //nolint:forcetypeassert
- accountBuilder.ImmutableMetadata(feature.(*iotago.MetadataFeature).Data)
- case iotago.FeatureSender:
- //nolint:forcetypeassert
- accountBuilder.ImmutableSender(feature.(*iotago.SenderFeature).Address)
- }
- }
- }
-}
-
-func WithAccountConditions(conditions iotago.AccountOutputUnlockConditions) options.Option[builder.AccountOutputBuilder] {
- return func(accountBuilder *builder.AccountOutputBuilder) {
- for _, condition := range conditions.MustSet() {
- switch condition.Type() {
- case iotago.UnlockConditionStateControllerAddress:
- //nolint:forcetypeassert
- accountBuilder.StateController(condition.(*iotago.StateControllerAddressUnlockCondition).Address)
- case iotago.UnlockConditionGovernorAddress:
- //nolint:forcetypeassert
- accountBuilder.Governor(condition.(*iotago.GovernorAddressUnlockCondition).Address)
- }
- }
- }
-}
-
-// TransactionBuilder options
-
-func WithInputs(inputs utxoledger.Outputs) options.Option[builder.TransactionBuilder] {
- return func(txBuilder *builder.TransactionBuilder) {
- for _, input := range inputs {
- switch input.OutputType() {
- case iotago.OutputFoundry:
- // For foundries we need to unlock the alias
- txBuilder.AddInput(&builder.TxInput{
- UnlockTarget: input.Output().UnlockConditionSet().ImmutableAccount().Address,
- InputID: input.OutputID(),
- Input: input.Output(),
- })
- case iotago.OutputAccount:
- // For alias we need to unlock the state controller
- txBuilder.AddInput(&builder.TxInput{
- UnlockTarget: input.Output().UnlockConditionSet().StateControllerAddress().Address,
- InputID: input.OutputID(),
- Input: input.Output(),
- })
- default:
- txBuilder.AddInput(&builder.TxInput{
- UnlockTarget: input.Output().UnlockConditionSet().Address().Address,
- InputID: input.OutputID(),
- Input: input.Output(),
- })
- }
- }
- }
-}
-
-func WithAccountInput(input *utxoledger.Output, governorTransition bool) options.Option[builder.TransactionBuilder] {
- return func(txBuilder *builder.TransactionBuilder) {
- switch input.OutputType() {
- case iotago.OutputAccount:
- address := input.Output().UnlockConditionSet().StateControllerAddress().Address
- if governorTransition {
- address = input.Output().UnlockConditionSet().GovernorAddress().Address
- }
- txBuilder.AddInput(&builder.TxInput{
- UnlockTarget: address,
- InputID: input.OutputID(),
- Input: input.Output(),
- })
- default:
- panic("only OutputAccount can be added as account input")
- }
- }
-}
-
-func WithAllotments(allotments iotago.Allotments) options.Option[builder.TransactionBuilder] {
- return func(txBuilder *builder.TransactionBuilder) {
- for _, allotment := range allotments {
- txBuilder.IncreaseAllotment(allotment.AccountID, allotment.Mana)
- }
- }
-}
-
-func WithSlotCreated(creationSlot iotago.SlotIndex) options.Option[builder.TransactionBuilder] {
- return func(txBuilder *builder.TransactionBuilder) {
- txBuilder.SetCreationSlot(creationSlot)
- }
-}
-
-func WithContextInputs(contextInputs iotago.TxEssenceContextInputs) options.Option[builder.TransactionBuilder] {
- return func(txBuilder *builder.TransactionBuilder) {
- for _, input := range contextInputs {
- txBuilder.AddContextInput(input)
- }
- }
-}
-
-func WithOutputs(outputs iotago.Outputs[iotago.Output]) options.Option[builder.TransactionBuilder] {
- return func(txBuilder *builder.TransactionBuilder) {
- for _, output := range outputs {
- txBuilder.AddOutput(output)
- }
- }
-}
-
-func WithTaggedDataPayload(payload *iotago.TaggedData) options.Option[builder.TransactionBuilder] {
- return func(txBuilder *builder.TransactionBuilder) {
- txBuilder.AddTaggedDataPayload(payload)
- }
-}
diff --git a/pkg/toolset/ed25519.go b/pkg/toolset/ed25519.go
new file mode 100644
index 000000000..bae379fbf
--- /dev/null
+++ b/pkg/toolset/ed25519.go
@@ -0,0 +1,172 @@
+package toolset
+
+import (
+ "crypto/ed25519"
+ "encoding/hex"
+ "fmt"
+ "os"
+
+ flag "github.com/spf13/pflag"
+ "github.com/wollac/iota-crypto-demo/pkg/bip32path"
+ "github.com/wollac/iota-crypto-demo/pkg/bip39"
+ "github.com/wollac/iota-crypto-demo/pkg/slip10"
+ "github.com/wollac/iota-crypto-demo/pkg/slip10/eddsa"
+
+ "github.com/iotaledger/hive.go/app/configuration"
+ "github.com/iotaledger/hive.go/crypto"
+ iotago "github.com/iotaledger/iota.go/v4"
+)
+
+func printEd25519Info(mnemonic bip39.Mnemonic, path bip32path.Path, prvKey ed25519.PrivateKey, pubKey ed25519.PublicKey, hrp iotago.NetworkPrefix, outputJSON bool) error {
+ addr := iotago.Ed25519AddressFromPubKey(pubKey)
+
+ type keys struct {
+ BIP39 string `json:"mnemonic,omitempty"`
+ BIP32 string `json:"path,omitempty"`
+ PrivateKey string `json:"privateKey,omitempty"`
+ PublicKey string `json:"publicKey"`
+ Ed25519Address string `json:"ed25519"`
+ Bech32Address string `json:"bech32"`
+ }
+
+ k := keys{
+ PublicKey: hex.EncodeToString(pubKey),
+ Ed25519Address: hex.EncodeToString(addr[:]),
+ Bech32Address: addr.Bech32(hrp),
+ }
+
+ if prvKey != nil {
+ k.PrivateKey = hex.EncodeToString(prvKey)
+ }
+
+ if mnemonic != nil {
+ k.BIP39 = mnemonic.String()
+ k.BIP32 = path.String()
+ }
+
+ if outputJSON {
+ return printJSON(k)
+ }
+
+ if len(k.BIP39) > 0 {
+ fmt.Println("Your seed BIP39 mnemonic: ", k.BIP39)
+ fmt.Println()
+ fmt.Println("Your BIP32 path: ", k.BIP32)
+ }
+
+ if k.PrivateKey != "" {
+ fmt.Println("Your ed25519 private key: ", k.PrivateKey)
+ }
+
+ fmt.Println("Your ed25519 public key: ", k.PublicKey)
+ fmt.Println("Your ed25519 address: ", k.Ed25519Address)
+ fmt.Println("Your bech32 address: ", k.Bech32Address)
+
+ return nil
+}
+
+func generateEd25519Key(args []string) error {
+ fs := configuration.NewUnsortedFlagSet("", flag.ContinueOnError)
+ hrpFlag := fs.String(FlagToolHRP, string(iotago.PrefixTestnet), "the HRP which should be used for the Bech32 address")
+ bip32Path := fs.String(FlagToolBIP32Path, "m/44'/4218'/0'/0'/0'", "the BIP32 path that should be used to derive keys from seed")
+ mnemonicFlag := fs.String(FlagToolMnemonic, "", "the BIP-39 mnemonic sentence that should be used to derive the seed from (optional)")
+ outputJSONFlag := fs.Bool(FlagToolOutputJSON, false, FlagToolDescriptionOutputJSON)
+
+ fs.Usage = func() {
+ _, _ = fmt.Fprintf(os.Stderr, "Usage of %s:\n", ToolEd25519Key)
+ fs.PrintDefaults()
+ println(fmt.Sprintf("\nexample: %s --%s %s",
+ ToolEd25519Key,
+ FlagToolHRP,
+ string(iotago.PrefixTestnet)))
+ }
+
+ if err := parseFlagSet(fs, args); err != nil {
+ return err
+ }
+
+ if len(*hrpFlag) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolHRP)
+ }
+
+ if len(*bip32Path) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolBIP32Path)
+ }
+
+ var mnemonicSentence bip39.Mnemonic
+ if len(*mnemonicFlag) == 0 {
+ // Generate random entropy by using ed25519 key generation and using the private key seed (32 bytes)
+ _, random, err := ed25519.GenerateKey(nil)
+ if err != nil {
+ return err
+ }
+ entropy := random.Seed()
+
+ mnemonicSentence, err = bip39.EntropyToMnemonic(entropy)
+ if err != nil {
+ return err
+ }
+ } else {
+ mnemonicSentence = bip39.ParseMnemonic(*mnemonicFlag)
+ if len(mnemonicSentence) != 24 {
+ return fmt.Errorf("'%s' contains an invalid sentence length. Mnemonic should be 24 words", FlagToolMnemonic)
+ }
+ }
+
+ path, err := bip32path.ParsePath(*bip32Path)
+ if err != nil {
+ return err
+ }
+
+ seed, err := bip39.MnemonicToSeed(mnemonicSentence, "")
+ if err != nil {
+ return err
+ }
+
+ key, err := slip10.DeriveKeyFromPath(seed, eddsa.Ed25519(), path)
+ if err != nil {
+ return err
+ }
+ pubKey, prvKey := key.Key.(eddsa.Seed).Ed25519Key()
+
+ return printEd25519Info(mnemonicSentence, path, ed25519.PrivateKey(prvKey), ed25519.PublicKey(pubKey), iotago.NetworkPrefix(*hrpFlag), *outputJSONFlag)
+}
+
+func generateEd25519Address(args []string) error {
+ fs := configuration.NewUnsortedFlagSet("", flag.ContinueOnError)
+ hrpFlag := fs.String(FlagToolHRP, string(iotago.PrefixTestnet), "the HRP which should be used for the Bech32 address")
+ publicKeyFlag := fs.String(FlagToolPublicKey, "", "an ed25519 public key")
+ outputJSONFlag := fs.Bool(FlagToolOutputJSON, false, FlagToolDescriptionOutputJSON)
+
+ fs.Usage = func() {
+ _, _ = fmt.Fprintf(os.Stderr, "Usage of %s:\n", ToolEd25519Addr)
+ fs.PrintDefaults()
+ println(fmt.Sprintf("\nexample: %s --%s %s --%s %s",
+ ToolEd25519Addr,
+ FlagToolHRP,
+ string(iotago.PrefixTestnet),
+ FlagToolPublicKey,
+ "[PUB_KEY]",
+ ))
+ }
+
+ if err := parseFlagSet(fs, args); err != nil {
+ return err
+ }
+
+ if len(*hrpFlag) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolHRP)
+ }
+
+ if len(*publicKeyFlag) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolPublicKey)
+ }
+
+ // parse pubkey
+ pubKey, err := crypto.ParseEd25519PublicKeyFromString(*publicKeyFlag)
+ if err != nil {
+ return fmt.Errorf("can't decode '%s': %w", FlagToolPublicKey, err)
+ }
+
+ return printEd25519Info(nil, nil, nil, pubKey, iotago.NetworkPrefix(*hrpFlag), *outputJSONFlag)
+}
diff --git a/pkg/toolset/jwt.go b/pkg/toolset/jwt.go
new file mode 100644
index 000000000..9585eee8c
--- /dev/null
+++ b/pkg/toolset/jwt.go
@@ -0,0 +1,109 @@
+package toolset
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/libp2p/go-libp2p/core/peer"
+ flag "github.com/spf13/pflag"
+
+ "github.com/iotaledger/hive.go/app/configuration"
+ hivep2p "github.com/iotaledger/hive.go/crypto/p2p"
+ "github.com/iotaledger/hive.go/crypto/pem"
+ "github.com/iotaledger/iota-core/components/p2p"
+ "github.com/iotaledger/iota-core/pkg/jwt"
+)
+
+func generateJWTApiToken(args []string) error {
+
+ fs := configuration.NewUnsortedFlagSet("", flag.ContinueOnError)
+ databasePathFlag := fs.String(FlagToolDatabasePath, DefaultValueP2PDatabasePath, "the path to the p2p database folder")
+ apiJWTSaltFlag := fs.String(FlagToolSalt, DefaultValueAPIJWTTokenSalt, "salt used inside the JWT tokens for the REST API")
+ outputJSONFlag := fs.Bool(FlagToolOutputJSON, false, FlagToolDescriptionOutputJSON)
+
+ fs.Usage = func() {
+ _, _ = fmt.Fprintf(os.Stderr, "Usage of %s:\n", ToolJWTApi)
+ fs.PrintDefaults()
+ println(fmt.Sprintf("\nexample: %s --%s %s --%s %s",
+ ToolJWTApi,
+ FlagToolDatabasePath,
+ DefaultValueP2PDatabasePath,
+ FlagToolSalt,
+ DefaultValueAPIJWTTokenSalt))
+ }
+
+ if err := parseFlagSet(fs, args); err != nil {
+ return err
+ }
+
+ if len(*databasePathFlag) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolDatabasePath)
+ }
+ if len(*apiJWTSaltFlag) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolSalt)
+ }
+
+ databasePath := *databasePathFlag
+ privKeyFilePath := filepath.Join(databasePath, p2p.IdentityPrivateKeyFileName)
+
+ salt := *apiJWTSaltFlag
+
+ _, err := os.Stat(privKeyFilePath)
+ switch {
+ case os.IsNotExist(err):
+ // private key does not exist
+ return fmt.Errorf("private key file (%s) does not exist", privKeyFilePath)
+
+ case err == nil || os.IsExist(err):
+ // private key file exists
+
+ default:
+ return fmt.Errorf("unable to check private key file (%s): %w", privKeyFilePath, err)
+ }
+
+ privKey, err := pem.ReadEd25519PrivateKeyFromPEMFile(privKeyFilePath)
+ if err != nil {
+ return fmt.Errorf("reading private key file for peer identity failed: %w", err)
+ }
+
+ libp2pPrivKey, err := hivep2p.Ed25519PrivateKeyToLibp2pPrivateKey(privKey)
+ if err != nil {
+ return fmt.Errorf("reading private key file for peer identity failed: %w", err)
+ }
+
+ peerID, err := peer.IDFromPublicKey(libp2pPrivKey.GetPublic())
+ if err != nil {
+ return fmt.Errorf("unable to get peer identity from public key: %w", err)
+ }
+
+ // API tokens do not expire.
+ jwtAuth, err := jwt.NewAuth(salt,
+ 0,
+ peerID.String(),
+ libp2pPrivKey,
+ )
+ if err != nil {
+ return fmt.Errorf("JWT auth initialization failed: %w", err)
+ }
+
+ jwtToken, err := jwtAuth.IssueJWT()
+ if err != nil {
+ return fmt.Errorf("issuing JWT token failed: %w", err)
+ }
+
+ if *outputJSONFlag {
+
+ result := struct {
+ JWT string `json:"jwt"`
+ }{
+ JWT: jwtToken,
+ }
+
+ return printJSON(result)
+ }
+
+ fmt.Println("Your API JWT token: ", jwtToken)
+
+ return nil
+}
diff --git a/pkg/toolset/node_info.go b/pkg/toolset/node_info.go
new file mode 100644
index 000000000..058a3e6d6
--- /dev/null
+++ b/pkg/toolset/node_info.go
@@ -0,0 +1,50 @@
+package toolset
+
+import (
+ "context"
+ "fmt"
+ "os"
+
+ flag "github.com/spf13/pflag"
+
+ "github.com/iotaledger/hive.go/app/configuration"
+ "github.com/iotaledger/iota.go/v4/nodeclient"
+)
+
+func nodeInfo(args []string) error {
+ fs := configuration.NewUnsortedFlagSet("", flag.ContinueOnError)
+ nodeURLFlag := fs.String(FlagToolNodeURL, "http://localhost:14265", "URL of the node (optional)")
+ outputJSONFlag := fs.Bool(FlagToolOutputJSON, false, FlagToolDescriptionOutputJSON)
+
+ fs.Usage = func() {
+ _, _ = fmt.Fprintf(os.Stderr, "Usage of %s:\n", ToolNodeInfo)
+ fs.PrintDefaults()
+ println(fmt.Sprintf("\nexample: %s --%s %s",
+ ToolNodeInfo,
+ FlagToolNodeURL,
+ "http://192.168.1.221:14265",
+ ))
+ }
+
+ if err := parseFlagSet(fs, args); err != nil {
+ return err
+ }
+
+ client, err := nodeclient.New(*nodeURLFlag)
+ if err != nil {
+ return err
+ }
+
+ info, err := client.Info(context.Background())
+ if err != nil {
+ return err
+ }
+
+ if *outputJSONFlag {
+ return printJSON(info)
+ }
+
+ fmt.Printf("Name: %s\nVersion: %s\nLatestAcceptedBlockSlot: %d\nLatestConfirmedBlockSlot: %d\nIsHealthy: %s\n", info.Name, info.Version, info.Status.LatestAcceptedBlockSlot, info.Status.LatestConfirmedBlockSlot, yesOrNo(info.Status.IsHealthy))
+
+ return nil
+}
diff --git a/pkg/toolset/p2p_identity_extract.go b/pkg/toolset/p2p_identity_extract.go
new file mode 100644
index 000000000..45a364d10
--- /dev/null
+++ b/pkg/toolset/p2p_identity_extract.go
@@ -0,0 +1,66 @@
+package toolset
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+
+ flag "github.com/spf13/pflag"
+
+ "github.com/iotaledger/hive.go/app/configuration"
+ hivep2p "github.com/iotaledger/hive.go/crypto/p2p"
+ "github.com/iotaledger/hive.go/crypto/pem"
+ "github.com/iotaledger/iota-core/components/p2p"
+)
+
+func extractP2PIdentity(args []string) error {
+
+ fs := configuration.NewUnsortedFlagSet("", flag.ContinueOnError)
+ databasePathFlag := fs.String(FlagToolDatabasePath, DefaultValueP2PDatabasePath, "the path to the p2p database folder")
+ outputJSONFlag := fs.Bool(FlagToolOutputJSON, false, FlagToolDescriptionOutputJSON)
+
+ fs.Usage = func() {
+ _, _ = fmt.Fprintf(os.Stderr, "Usage of %s:\n", ToolP2PExtractIdentity)
+ fs.PrintDefaults()
+ println(fmt.Sprintf("\nexample: %s --%s %s",
+ ToolP2PExtractIdentity,
+ FlagToolDatabasePath,
+ DefaultValueP2PDatabasePath))
+ }
+
+ if err := parseFlagSet(fs, args); err != nil {
+ return err
+ }
+
+ if len(*databasePathFlag) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolDatabasePath)
+ }
+
+ databasePath := *databasePathFlag
+ privKeyFilePath := filepath.Join(databasePath, p2p.IdentityPrivateKeyFileName)
+
+ _, err := os.Stat(privKeyFilePath)
+ switch {
+ case os.IsNotExist(err):
+ // private key does not exist
+ return fmt.Errorf("private key file (%s) does not exist", privKeyFilePath)
+
+ case err == nil || os.IsExist(err):
+ // private key file exists
+
+ default:
+ return fmt.Errorf("unable to check private key file (%s): %w", privKeyFilePath, err)
+ }
+
+ privKey, err := pem.ReadEd25519PrivateKeyFromPEMFile(privKeyFilePath)
+ if err != nil {
+ return fmt.Errorf("reading private key file for peer identity failed: %w", err)
+ }
+
+ libp2pPrivKey, err := hivep2p.Ed25519PrivateKeyToLibp2pPrivateKey(privKey)
+ if err != nil {
+ return err
+ }
+
+ return printP2PIdentity(libp2pPrivKey, libp2pPrivKey.GetPublic(), *outputJSONFlag)
+}
diff --git a/pkg/toolset/p2p_identity_gen.go b/pkg/toolset/p2p_identity_gen.go
new file mode 100644
index 000000000..b376fd5e8
--- /dev/null
+++ b/pkg/toolset/p2p_identity_gen.go
@@ -0,0 +1,136 @@
+package toolset
+
+import (
+ "crypto/ed25519"
+ "encoding/hex"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "github.com/libp2p/go-libp2p/core/crypto"
+ "github.com/libp2p/go-libp2p/core/peer"
+ "github.com/mr-tron/base58"
+ flag "github.com/spf13/pflag"
+
+ "github.com/iotaledger/hive.go/app/configuration"
+ hivecrypto "github.com/iotaledger/hive.go/crypto"
+ "github.com/iotaledger/hive.go/crypto/pem"
+ "github.com/iotaledger/iota-core/components/p2p"
+ "github.com/iotaledger/iota.go/v4/hexutil"
+)
+
+func generateP2PIdentity(args []string) error {
+
+ fs := configuration.NewUnsortedFlagSet("", flag.ContinueOnError)
+ databasePathFlag := fs.String(FlagToolOutputPath, DefaultValueP2PDatabasePath, "the path to the output folder")
+ privateKeyFlag := fs.String(FlagToolPrivateKey, "", "the p2p private key")
+ outputJSONFlag := fs.Bool(FlagToolOutputJSON, false, FlagToolDescriptionOutputJSON)
+
+ fs.Usage = func() {
+ fmt.Fprintf(os.Stderr, "Usage of %s:\n", ToolP2PIdentityGen)
+ fs.PrintDefaults()
+ println(fmt.Sprintf("\nexample: %s --%s %s --%s %s",
+ ToolP2PIdentityGen,
+ FlagToolDatabasePath,
+ DefaultValueP2PDatabasePath,
+ FlagToolPrivateKey,
+ "[PRIVATE_KEY]",
+ ))
+ }
+
+ if err := parseFlagSet(fs, args); err != nil {
+ return err
+ }
+
+ if len(*databasePathFlag) == 0 {
+ return fmt.Errorf("'%s' not specified", FlagToolDatabasePath)
+ }
+
+ databasePath := *databasePathFlag
+ privKeyFilePath := filepath.Join(databasePath, p2p.IdentityPrivateKeyFileName)
+
+ if err := os.MkdirAll(databasePath, 0700); err != nil {
+ return fmt.Errorf("could not create peer store database dir '%s': %w", databasePath, err)
+ }
+
+ _, err := os.Stat(privKeyFilePath)
+ switch {
+ case err == nil || os.IsExist(err):
+ // private key file already exists
+ return fmt.Errorf("private key file (%s) already exists", privKeyFilePath)
+
+ case os.IsNotExist(err):
+ // private key file does not exist, create a new one
+
+ default:
+ return fmt.Errorf("unable to check private key file (%s): %w", privKeyFilePath, err)
+ }
+
+ var privKey ed25519.PrivateKey
+ if privateKeyFlag != nil && len(*privateKeyFlag) > 0 {
+ privKey, err = hivecrypto.ParseEd25519PrivateKeyFromString(*privateKeyFlag)
+ if err != nil {
+ return fmt.Errorf("invalid private key given '%s': %w", *privateKeyFlag, err)
+ }
+ } else {
+ // create identity
+ _, privKey, err = ed25519.GenerateKey(nil)
+ if err != nil {
+ return fmt.Errorf("unable to generate Ed25519 private key for peer identity: %w", err)
+ }
+ }
+
+ libp2pPrivKey, libp2pPubKey, err := crypto.KeyPairFromStdKey(&privKey)
+ if err != nil {
+ return fmt.Errorf("unable to convert given private key '%s': %w", hexutil.EncodeHex(privKey), err)
+ }
+
+ if err := pem.WriteEd25519PrivateKeyToPEMFile(privKeyFilePath, privKey); err != nil {
+ return fmt.Errorf("writing private key file for peer identity failed: %w", err)
+ }
+
+ return printP2PIdentity(libp2pPrivKey, libp2pPubKey, *outputJSONFlag)
+}
+
+func printP2PIdentity(libp2pPrivKey crypto.PrivKey, libp2pPubKey crypto.PubKey, outputJSON bool) error {
+
+ type P2PIdentity struct {
+ PrivateKey string `json:"privateKey"`
+ PublicKey string `json:"publicKey"`
+ PublicKeyBase58 string `json:"publicKeyBase58"`
+ PeerID string `json:"peerId"`
+ }
+
+ privKeyBytes, err := libp2pPrivKey.Raw()
+ if err != nil {
+ return fmt.Errorf("unable to get raw private key bytes: %w", err)
+ }
+
+ pubKeyBytes, err := libp2pPubKey.Raw()
+ if err != nil {
+ return fmt.Errorf("unable to get raw public key bytes: %w", err)
+ }
+
+ peerID, err := peer.IDFromPublicKey(libp2pPubKey)
+ if err != nil {
+ return fmt.Errorf("unable to get peer identity from public key: %w", err)
+ }
+
+ identity := P2PIdentity{
+ PrivateKey: hex.EncodeToString(privKeyBytes),
+ PublicKey: hex.EncodeToString(pubKeyBytes),
+ PublicKeyBase58: base58.Encode(pubKeyBytes),
+ PeerID: peerID.String(),
+ }
+
+ if outputJSON {
+ return printJSON(identity)
+ }
+
+ fmt.Println("Your p2p private key (hex): ", identity.PrivateKey)
+ fmt.Println("Your p2p public key (hex): ", identity.PublicKey)
+ fmt.Println("Your p2p public key (base58): ", identity.PublicKeyBase58)
+ fmt.Println("Your p2p PeerID: ", identity.PeerID)
+
+ return nil
+}
diff --git a/pkg/toolset/toolset.go b/pkg/toolset/toolset.go
new file mode 100644
index 000000000..cad18b14e
--- /dev/null
+++ b/pkg/toolset/toolset.go
@@ -0,0 +1,157 @@
+package toolset
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "strings"
+
+ flag "github.com/spf13/pflag"
+
+ "github.com/iotaledger/hive.go/app/configuration"
+ "github.com/iotaledger/hive.go/ierrors"
+)
+
+const (
+ FlagToolDatabasePath = "databasePath"
+
+ FlagToolOutputPath = "outputPath"
+
+ FlagToolPrivateKey = "privateKey"
+ FlagToolPublicKey = "publicKey"
+
+ FlagToolHRP = "hrp"
+ FlagToolBIP32Path = "bip32Path"
+ FlagToolMnemonic = "mnemonic"
+ FlagToolSalt = "salt"
+
+ FlagToolNodeURL = "nodeURL"
+
+ FlagToolOutputJSON = "json"
+ FlagToolDescriptionOutputJSON = "format output as JSON"
+)
+
+const (
+ ToolP2PIdentityGen = "p2pidentity-gen"
+ ToolP2PExtractIdentity = "p2pidentity-extract"
+ ToolEd25519Key = "ed25519-key"
+ ToolEd25519Addr = "ed25519-addr"
+ ToolJWTApi = "jwt-api"
+ ToolNodeInfo = "node-info"
+)
+
+const (
+ DefaultValueAPIJWTTokenSalt = "IOTA"
+ DefaultValueP2PDatabasePath = "testnet/p2pstore"
+)
+
+// ShouldHandleTools checks if tools were requested.
+func ShouldHandleTools() bool {
+ args := os.Args[1:]
+
+ for _, arg := range args {
+ if strings.ToLower(arg) == "tool" || strings.ToLower(arg) == "tools" {
+ return true
+ }
+ }
+
+ return false
+}
+
+// HandleTools handles available tools.
+func HandleTools() {
+
+ args := os.Args[1:]
+ if len(args) == 1 {
+ listTools()
+ os.Exit(1)
+ }
+
+ tools := map[string]func([]string) error{
+ ToolP2PIdentityGen: generateP2PIdentity,
+ ToolP2PExtractIdentity: extractP2PIdentity,
+ ToolEd25519Key: generateEd25519Key,
+ ToolEd25519Addr: generateEd25519Address,
+ ToolJWTApi: generateJWTApiToken,
+ ToolNodeInfo: nodeInfo,
+ }
+
+ tool, exists := tools[strings.ToLower(args[1])]
+ if !exists {
+ fmt.Print("tool not found.\n\n")
+ listTools()
+ os.Exit(1)
+ }
+
+ if err := tool(args[2:]); err != nil {
+ if ierrors.Is(err, flag.ErrHelp) {
+ // help text was requested
+ os.Exit(0)
+ }
+
+ fmt.Printf("\nerror: %s\n", err)
+ os.Exit(1)
+ }
+
+ os.Exit(0)
+}
+
+func listTools() {
+ fmt.Printf("%-20s generates a p2p identity private key file\n", fmt.Sprintf("%s:", ToolP2PIdentityGen))
+ fmt.Printf("%-20s extracts the p2p identity from the private key file\n", fmt.Sprintf("%s:", ToolP2PExtractIdentity))
+ fmt.Printf("%-20s generates an ed25519 key pair\n", fmt.Sprintf("%s:", ToolEd25519Key))
+ fmt.Printf("%-20s generates an ed25519 address from a public key\n", fmt.Sprintf("%s:", ToolEd25519Addr))
+ fmt.Printf("%-20s generates a JWT token for REST-API access\n", fmt.Sprintf("%s:", ToolJWTApi))
+ fmt.Printf("%-20s queries the info endpoint of a node\n", fmt.Sprintf("%s:", ToolNodeInfo))
+}
+
+func yesOrNo(value bool) string {
+ if value {
+ return "YES"
+ }
+
+ return "NO"
+}
+
+func parseFlagSet(fs *flag.FlagSet, args []string) error {
+
+ if err := fs.Parse(args); err != nil {
+ return err
+ }
+
+ // Check if all parameters were parsed
+ if fs.NArg() != 0 {
+ return ierrors.New("too much arguments")
+ }
+
+ return nil
+}
+
+func printJSON(obj interface{}) error {
+ output, err := json.MarshalIndent(obj, "", " ")
+ if err != nil {
+ return err
+ }
+
+ fmt.Println(string(output))
+
+ return nil
+}
+
+//nolint:unused // we will need it at a later point in time
+func loadConfigFile(filePath string, parameters map[string]any) error {
+ config := configuration.New()
+ flagset := configuration.NewUnsortedFlagSet("", flag.ContinueOnError)
+
+ for namespace, pointerToStruct := range parameters {
+ config.BindParameters(flagset, namespace, pointerToStruct)
+ }
+
+ if err := config.LoadFile(filePath); err != nil {
+ return fmt.Errorf("loading config file failed: %w", err)
+ }
+
+ config.UpdateBoundParameters()
+
+ return nil
+}
diff --git a/tools/docker-network/docker-compose.yml b/tools/docker-network/docker-compose.yml
index bd63e2eab..22d21b2dc 100644
--- a/tools/docker-network/docker-compose.yml
+++ b/tools/docker-network/docker-compose.yml
@@ -20,7 +20,7 @@ services:
networks:
- iota-core
ports:
- - "8080:8080/tcp" # REST-API
+ - "8080:14265/tcp" # REST-API
- "8081:8081/tcp" # Dashboard
- "6081:6061/tcp" # pprof
- "9089:9029/tcp" # INX
@@ -49,7 +49,7 @@ services:
networks:
- iota-core
ports:
- - "8070:8080/tcp" # REST-API
+ - "8070:14265/tcp" # REST-API
- "8071:8081/tcp" # Dashboard
- "6071:6061/tcp" # pprof
- "9029:9029/tcp" # INX
@@ -77,7 +77,7 @@ services:
networks:
- iota-core
ports:
- - "8090:8080/tcp" # REST-API
+ - "8090:14265/tcp" # REST-API
- "8091:8081/tcp" # Dashboard
- "6091:6061/tcp" # pprof
- "9099:9029/tcp" # INX
@@ -105,7 +105,7 @@ services:
networks:
- iota-core
ports:
- - "8040:8080/tcp" # REST-API
+ - "8040:14265/tcp" # REST-API
- "8041:8081/tcp" # Dashboard
- "6041:6061/tcp" # pprof
- "9049:9029/tcp" # INX
@@ -130,7 +130,7 @@ services:
networks:
- iota-core
ports:
- - "8030:8080/tcp" # REST-API
+ - "8030:14265/tcp" # REST-API
- "8031:8081/tcp" # Dashboard
- "6031:6061/tcp" # pprof
- "9039:9029/tcp" # INX
@@ -193,7 +193,7 @@ services:
restart: unless-stopped
depends_on:
node-1-validator:
- condition: service_started
+ condition: service_healthy
ulimits:
nofile:
soft: 16384
@@ -210,7 +210,7 @@ services:
restart: unless-stopped
depends_on:
node-1-validator:
- condition: service_started
+ condition: service_healthy
inx-indexer:
condition: service_started
networks:
@@ -229,7 +229,7 @@ services:
restart: unless-stopped
depends_on:
node-1-validator:
- condition: service_started
+ condition: service_healthy
inx-indexer:
condition: service_started
inx-blockissuer:
diff --git a/tools/gendoc/go.mod b/tools/gendoc/go.mod
index f024b6b9d..0fa7e6386 100644
--- a/tools/gendoc/go.mod
+++ b/tools/gendoc/go.mod
@@ -59,21 +59,21 @@ require (
github.com/iancoleman/orderedmap v0.3.0 // indirect
github.com/iotaledger/grocksdb v1.7.5-0.20230220105546-5162e18885c7 // indirect
github.com/iotaledger/hive.go/ads v0.0.0-20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b // indirect
+ github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42 // indirect
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b // indirect
+ github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42 // indirect
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b // indirect
+ github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42 // indirect
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b // indirect
+ github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42 // indirect
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b // indirect
github.com/iotaledger/hive.go/logger v0.0.0-20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b // indirect
+ github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42 // indirect
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b // indirect
- github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231023191159-38919c4705e0 // indirect
- github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231023190837-6e7b2cdfd4fd // indirect
- github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1 // indirect
+ github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42 // indirect
+ github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231028104239-869296c43f26 // indirect
+ github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231028104044-69b02af0058d // indirect
+ github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a // indirect
github.com/ipfs/boxo v0.13.1 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
@@ -156,6 +156,7 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
+ github.com/wollac/iota-crypto-demo v0.0.0-20221117162917-b10619eccb98 // indirect
github.com/zyedidia/generic v1.2.1 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
diff --git a/tools/gendoc/go.sum b/tools/gendoc/go.sum
index 2a2b0dd6e..955217c98 100644
--- a/tools/gendoc/go.sum
+++ b/tools/gendoc/go.sum
@@ -285,36 +285,36 @@ github.com/iotaledger/hive.go/app v0.0.0-20231020115340-13da292c580b h1:mX3NXaTM
github.com/iotaledger/hive.go/app v0.0.0-20231020115340-13da292c580b/go.mod h1:8ZbIKR84oQd/3iQ5eeT7xpudO9/ytzXP7veIYnk7Orc=
github.com/iotaledger/hive.go/apputils v0.0.0-20230829152614-7afc7a4d89b3 h1:4aVJTc0KS77uEw0Tny4r0n1ORwcbAQDECaCclgf/6lE=
github.com/iotaledger/hive.go/apputils v0.0.0-20230829152614-7afc7a4d89b3/go.mod h1:TZeAqieDu+xDOZp2e9+S+8pZp1PrfgcwLUnxmd8IgLU=
-github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b h1:HF4e0wz0JMIT4m3saqdQ//T9nWHV9d5sLMtEwNDuykM=
-github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b/go.mod h1:dOBOM2s4se3HcWefPe8sQLUalGXJ8yVXw58oK8jke3s=
+github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42 h1:drmpgLlJy7kZ09Dt1qKSnbILU+27Qu2jp4VdPDNwbFk=
+github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42/go.mod h1:dOBOM2s4se3HcWefPe8sQLUalGXJ8yVXw58oK8jke3s=
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b h1:ZERXxhQBUBV1AqTE6cUI4vTxSx4JrnsMuLZFgj32xLM=
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b/go.mod h1:Mc+ACqBGPxrPMIPUBOm6/HL0J6m0iVMwjtIEKW3uow8=
-github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b h1:ZUUqRRO6XnQmVcXlXyx07vqySn28+bln6jp9KagYCjY=
-github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b/go.mod h1:h3o6okvMSEK3KOX6pOp3yq1h9ohTkTfo6X8MzEadeb0=
+github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42 h1:r8TkdQJB7/bJd8cF8z5GQ+rX/7JpbPdPoN7wMoV1OCM=
+github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42/go.mod h1:h3o6okvMSEK3KOX6pOp3yq1h9ohTkTfo6X8MzEadeb0=
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b h1:8b2sH+2Vf0y5BDYTMwKa09iQr3JF9JrzTI64DkXb+9U=
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b/go.mod h1:3XkUSKfHaVxGbT0XAvjNlVYqPzhfLTGhDtdNA5UBPco=
-github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b h1:JJPnr231djUTgTnE4oGz847WE9VA7Py6E6fgZwT5TQo=
-github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b/go.mod h1:HcE8B5lP96enc/OALTb2/rIIi+yOLouRoHOKRclKmC8=
+github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42 h1:QMxd32Y/veVhTDPCiOFgetjUbG7sr9MryF29/rSPkMA=
+github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42/go.mod h1:HcE8B5lP96enc/OALTb2/rIIi+yOLouRoHOKRclKmC8=
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b h1:LusmtjpfG/q8lc15Fp9W3kABbN3tArKx/zw2ibdY1DU=
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b/go.mod h1:O/U3jtiUDeqqM0MZQFu2UPqS9fUm0C5hNISxlmg/thE=
-github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b h1:UvFWI8wQJS/XQOeWHpPsaFVeS2nxJ7nIGFr+IFjrnVw=
-github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b/go.mod h1:s4kzx9QY1MVWHJralj+3q5kI0eARtrJhphYD/iBbPfo=
+github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42 h1:AvNLzONVMspwx7nD/NyYUgb5Hi7/zgzIOegr1uRD/M8=
+github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42/go.mod h1:s4kzx9QY1MVWHJralj+3q5kI0eARtrJhphYD/iBbPfo=
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b h1:IwhoeOeRu25mBdrimuOOvbbhHYX0QipibV69ubn8nX0=
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b/go.mod h1:JvokzmpmFZPDskMlUqqjgHtD8usVJU4nAY/TNMGge8M=
github.com/iotaledger/hive.go/logger v0.0.0-20231020115340-13da292c580b h1:EhVgAU/f2J3VYZwP60dRdyfAeDU3c/gBzX9blKtQGKA=
github.com/iotaledger/hive.go/logger v0.0.0-20231020115340-13da292c580b/go.mod h1:aBfAfIB2GO/IblhYt5ipCbyeL9bXSNeAwtYVA3hZaHg=
-github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b h1:O68POYIqBLnoHN+HIszc58QwAI2qocYq0WKGfVrXmMg=
-github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b/go.mod h1:jRw8yFipiPaqmTPHh7hTcxAP9u6pjRGpByS3REJKkbY=
+github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42 h1:1QMJ39qXIx/IZVzus3+97IV7Pa++e+d340TvbMjhiBU=
+github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42/go.mod h1:jRw8yFipiPaqmTPHh7hTcxAP9u6pjRGpByS3REJKkbY=
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b h1:zaXZn9yV/95SRDkgCZQeBbSbmcJTKSZbCB7oBd71Qwg=
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b/go.mod h1:SdK26z8/VhWtxaqCuQrufm80SELgowQPmu9T/8eUQ8g=
-github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b h1:MDZhTZTVDiydXcW5j4TA7HixVCyAdToIMPhHfJee7cE=
-github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b/go.mod h1:FTo/UWzNYgnQ082GI9QVM9HFDERqf9rw9RivNpqrnTs=
-github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231023191159-38919c4705e0 h1:/8pbFXhTSroJvjJMfJqfHjzoT9N8B4LUY3SbKruD5MM=
-github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231023191159-38919c4705e0/go.mod h1:My1SB4vZj42EgTDNJ/dgW8lUpLNmvtzu8f89J5y2kP0=
-github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231023190837-6e7b2cdfd4fd h1:hh5mAnnaZHOYAi4CIqR9K/mv786ex9AQgpisbJ4ZMow=
-github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231023190837-6e7b2cdfd4fd/go.mod h1:MK0SHfNicBmcaZb3qS3tA8NEJIWKNbcNtNNKuSDKqXY=
-github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1 h1:7ChiFHg4KsdS4mKjYpFUUNe9t9nsQzNtJ/XnUV2w5ZM=
-github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1/go.mod h1:jqbLYq4a/FwuiPBqFfkAwwxU8vs3+kReRq2/tyX5qRA=
+github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42 h1:OlDhgvJ48bZxcvTeebJ1b96xtNnJAddejd2Q4rlH1mU=
+github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42/go.mod h1:FTo/UWzNYgnQ082GI9QVM9HFDERqf9rw9RivNpqrnTs=
+github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231028104239-869296c43f26 h1:ZZs7IzdxrogQWGF1HfUUfR3KW8WhfxE4hUbfwZCDXFY=
+github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231028104239-869296c43f26/go.mod h1:aFS0dN6QgKGgZakGgEv57NOLw+pLGdEiGcfDZ3h9GL0=
+github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231028104044-69b02af0058d h1:0SVvkN04C+Ylc2puM/c77HuvRMmHRl0BkNjlZx1YWeA=
+github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231028104044-69b02af0058d/go.mod h1:WFa5hHen6fi3RBX4K6r4fzhGpoh+7KJVIyFztZHdM84=
+github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a h1:WLW4iaJAx4N9Pujv+gzHklnnjCt5MPrtXyVcK3UXdNc=
+github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a/go.mod h1:jqbLYq4a/FwuiPBqFfkAwwxU8vs3+kReRq2/tyX5qRA=
github.com/ipfs/boxo v0.13.1 h1:nQ5oQzcMZR3oL41REJDcTbrvDvuZh3J9ckc9+ILeRQI=
github.com/ipfs/boxo v0.13.1/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
@@ -668,6 +668,8 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSD
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
+github.com/wollac/iota-crypto-demo v0.0.0-20221117162917-b10619eccb98 h1:i7k63xHOX2ntuHrhHewfKro67c834jug2DIk599fqAA=
+github.com/wollac/iota-crypto-demo v0.0.0-20221117162917-b10619eccb98/go.mod h1:Knu2XMRWe8SkwTlHc/+ghP+O9DEaZRQQEyTjvLJ5Cck=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
diff --git a/tools/genesis-snapshot/go.mod b/tools/genesis-snapshot/go.mod
index 080b961b4..aaab649cb 100644
--- a/tools/genesis-snapshot/go.mod
+++ b/tools/genesis-snapshot/go.mod
@@ -5,12 +5,12 @@ go 1.21
replace github.com/iotaledger/iota-core => ../../
require (
- github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b
- github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b
+ github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42
+ github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42
+ github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42
+ github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42
github.com/iotaledger/iota-core v0.0.0-00010101000000-000000000000
- github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1
+ github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a
github.com/mr-tron/base58 v1.2.0
github.com/spf13/pflag v1.0.5
golang.org/x/crypto v0.14.0
@@ -27,13 +27,13 @@ require (
github.com/iancoleman/orderedmap v0.3.0 // indirect
github.com/iotaledger/grocksdb v1.7.5-0.20230220105546-5162e18885c7 // indirect
github.com/iotaledger/hive.go/ads v0.0.0-20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b // indirect
+ github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42 // indirect
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b // indirect
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b // indirect
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b // indirect
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b // indirect
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b // indirect
- github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b // indirect
+ github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/kr/text v0.2.0 // indirect
diff --git a/tools/genesis-snapshot/go.sum b/tools/genesis-snapshot/go.sum
index fd8d7e3ec..3dbf42773 100644
--- a/tools/genesis-snapshot/go.sum
+++ b/tools/genesis-snapshot/go.sum
@@ -30,30 +30,30 @@ github.com/iotaledger/grocksdb v1.7.5-0.20230220105546-5162e18885c7 h1:dTrD7X2PT
github.com/iotaledger/grocksdb v1.7.5-0.20230220105546-5162e18885c7/go.mod h1:ZRdPu684P0fQ1z8sXz4dj9H5LWHhz4a9oCtvjunkSrw=
github.com/iotaledger/hive.go/ads v0.0.0-20231020115340-13da292c580b h1:D68khiAFb9DwTvjZc2nc4R0E6wUdKyYCUXkmdaMzuoQ=
github.com/iotaledger/hive.go/ads v0.0.0-20231020115340-13da292c580b/go.mod h1:IFh0gDfeMgZtfCo+5afK59IDR4xXh+cTR9YtLnZPcbY=
-github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b h1:HF4e0wz0JMIT4m3saqdQ//T9nWHV9d5sLMtEwNDuykM=
-github.com/iotaledger/hive.go/constraints v0.0.0-20231020115340-13da292c580b/go.mod h1:dOBOM2s4se3HcWefPe8sQLUalGXJ8yVXw58oK8jke3s=
+github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42 h1:drmpgLlJy7kZ09Dt1qKSnbILU+27Qu2jp4VdPDNwbFk=
+github.com/iotaledger/hive.go/constraints v0.0.0-20231027195901-620bd7470e42/go.mod h1:dOBOM2s4se3HcWefPe8sQLUalGXJ8yVXw58oK8jke3s=
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b h1:ZERXxhQBUBV1AqTE6cUI4vTxSx4JrnsMuLZFgj32xLM=
github.com/iotaledger/hive.go/core v1.0.0-rc.3.0.20231020115340-13da292c580b/go.mod h1:Mc+ACqBGPxrPMIPUBOm6/HL0J6m0iVMwjtIEKW3uow8=
-github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b h1:ZUUqRRO6XnQmVcXlXyx07vqySn28+bln6jp9KagYCjY=
-github.com/iotaledger/hive.go/crypto v0.0.0-20231020115340-13da292c580b/go.mod h1:h3o6okvMSEK3KOX6pOp3yq1h9ohTkTfo6X8MzEadeb0=
+github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42 h1:r8TkdQJB7/bJd8cF8z5GQ+rX/7JpbPdPoN7wMoV1OCM=
+github.com/iotaledger/hive.go/crypto v0.0.0-20231027195901-620bd7470e42/go.mod h1:h3o6okvMSEK3KOX6pOp3yq1h9ohTkTfo6X8MzEadeb0=
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b h1:8b2sH+2Vf0y5BDYTMwKa09iQr3JF9JrzTI64DkXb+9U=
github.com/iotaledger/hive.go/ds v0.0.0-20231020115340-13da292c580b/go.mod h1:3XkUSKfHaVxGbT0XAvjNlVYqPzhfLTGhDtdNA5UBPco=
-github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b h1:JJPnr231djUTgTnE4oGz847WE9VA7Py6E6fgZwT5TQo=
-github.com/iotaledger/hive.go/ierrors v0.0.0-20231020115340-13da292c580b/go.mod h1:HcE8B5lP96enc/OALTb2/rIIi+yOLouRoHOKRclKmC8=
+github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42 h1:QMxd32Y/veVhTDPCiOFgetjUbG7sr9MryF29/rSPkMA=
+github.com/iotaledger/hive.go/ierrors v0.0.0-20231027195901-620bd7470e42/go.mod h1:HcE8B5lP96enc/OALTb2/rIIi+yOLouRoHOKRclKmC8=
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b h1:LusmtjpfG/q8lc15Fp9W3kABbN3tArKx/zw2ibdY1DU=
github.com/iotaledger/hive.go/kvstore v0.0.0-20231020115340-13da292c580b/go.mod h1:O/U3jtiUDeqqM0MZQFu2UPqS9fUm0C5hNISxlmg/thE=
-github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b h1:UvFWI8wQJS/XQOeWHpPsaFVeS2nxJ7nIGFr+IFjrnVw=
-github.com/iotaledger/hive.go/lo v0.0.0-20231020115340-13da292c580b/go.mod h1:s4kzx9QY1MVWHJralj+3q5kI0eARtrJhphYD/iBbPfo=
+github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42 h1:AvNLzONVMspwx7nD/NyYUgb5Hi7/zgzIOegr1uRD/M8=
+github.com/iotaledger/hive.go/lo v0.0.0-20231027195901-620bd7470e42/go.mod h1:s4kzx9QY1MVWHJralj+3q5kI0eARtrJhphYD/iBbPfo=
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b h1:IwhoeOeRu25mBdrimuOOvbbhHYX0QipibV69ubn8nX0=
github.com/iotaledger/hive.go/log v0.0.0-20231020115340-13da292c580b/go.mod h1:JvokzmpmFZPDskMlUqqjgHtD8usVJU4nAY/TNMGge8M=
-github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b h1:O68POYIqBLnoHN+HIszc58QwAI2qocYq0WKGfVrXmMg=
-github.com/iotaledger/hive.go/runtime v0.0.0-20231020115340-13da292c580b/go.mod h1:jRw8yFipiPaqmTPHh7hTcxAP9u6pjRGpByS3REJKkbY=
+github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42 h1:1QMJ39qXIx/IZVzus3+97IV7Pa++e+d340TvbMjhiBU=
+github.com/iotaledger/hive.go/runtime v0.0.0-20231027195901-620bd7470e42/go.mod h1:jRw8yFipiPaqmTPHh7hTcxAP9u6pjRGpByS3REJKkbY=
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b h1:zaXZn9yV/95SRDkgCZQeBbSbmcJTKSZbCB7oBd71Qwg=
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20231020115340-13da292c580b/go.mod h1:SdK26z8/VhWtxaqCuQrufm80SELgowQPmu9T/8eUQ8g=
-github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b h1:MDZhTZTVDiydXcW5j4TA7HixVCyAdToIMPhHfJee7cE=
-github.com/iotaledger/hive.go/stringify v0.0.0-20231020115340-13da292c580b/go.mod h1:FTo/UWzNYgnQ082GI9QVM9HFDERqf9rw9RivNpqrnTs=
-github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1 h1:7ChiFHg4KsdS4mKjYpFUUNe9t9nsQzNtJ/XnUV2w5ZM=
-github.com/iotaledger/iota.go/v4 v4.0.0-20231025071930-7cc5b35d50b1/go.mod h1:jqbLYq4a/FwuiPBqFfkAwwxU8vs3+kReRq2/tyX5qRA=
+github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42 h1:OlDhgvJ48bZxcvTeebJ1b96xtNnJAddejd2Q4rlH1mU=
+github.com/iotaledger/hive.go/stringify v0.0.0-20231027195901-620bd7470e42/go.mod h1:FTo/UWzNYgnQ082GI9QVM9HFDERqf9rw9RivNpqrnTs=
+github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a h1:WLW4iaJAx4N9Pujv+gzHklnnjCt5MPrtXyVcK3UXdNc=
+github.com/iotaledger/iota.go/v4 v4.0.0-20231028103644-b834fd54b02a/go.mod h1:jqbLYq4a/FwuiPBqFfkAwwxU8vs3+kReRq2/tyX5qRA=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
diff --git a/tools/genesis-snapshot/main.go b/tools/genesis-snapshot/main.go
index a8d292a87..63d303a83 100644
--- a/tools/genesis-snapshot/main.go
+++ b/tools/genesis-snapshot/main.go
@@ -8,7 +8,8 @@ import (
"github.com/iotaledger/hive.go/ierrors"
"github.com/iotaledger/hive.go/runtime/options"
- "github.com/iotaledger/iota-core/pkg/protocol/snapshotcreator"
+ "github.com/iotaledger/iota-core/pkg/testsuite/mock"
+ "github.com/iotaledger/iota-core/pkg/testsuite/snapshotcreator"
"github.com/iotaledger/iota-core/tools/genesis-snapshot/presets"
)
@@ -49,7 +50,8 @@ func parseFlags() (opt []options.Option[snapshotcreator.Options], conf string) {
if err != nil {
log.Fatal(ierrors.Errorf("failed to decode base58 seed, using the default one: %w", err))
}
- opt = append(opt, snapshotcreator.WithGenesisSeed(genesisSeed))
+ keyManager := mock.NewKeyManager(genesisSeed[:], 0)
+ opt = append(opt, snapshotcreator.WithGenesisKeyManager(keyManager))
}
return opt, *config
diff --git a/tools/genesis-snapshot/presets/presets.go b/tools/genesis-snapshot/presets/presets.go
index 96d3ce284..8157c81e2 100644
--- a/tools/genesis-snapshot/presets/presets.go
+++ b/tools/genesis-snapshot/presets/presets.go
@@ -9,8 +9,8 @@ import (
"github.com/iotaledger/hive.go/lo"
"github.com/iotaledger/hive.go/runtime/options"
"github.com/iotaledger/iota-core/pkg/protocol"
- "github.com/iotaledger/iota-core/pkg/protocol/snapshotcreator"
- "github.com/iotaledger/iota-core/pkg/testsuite"
+ "github.com/iotaledger/iota-core/pkg/testsuite/mock"
+ "github.com/iotaledger/iota-core/pkg/testsuite/snapshotcreator"
iotago "github.com/iotaledger/iota.go/v4"
"github.com/iotaledger/iota.go/v4/hexutil"
)
@@ -40,38 +40,38 @@ var Docker = []options.Option[snapshotcreator.Options]{
snapshotcreator.AccountDetails{ // node-1-validator
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b"))),
- Amount: testsuite.MinValidatorAccountAmount,
+ Amount: mock.MinValidatorAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0x293dc170d9a59474e6d81cfba7f7d924c09b25d7166bcfba606e53114d0a758b")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
StakingEpochEnd: iotago.MaxEpochIndex,
FixedCost: 1,
- StakedAmount: testsuite.MinValidatorAccountAmount,
- Mana: iotago.Mana(testsuite.MinValidatorAccountAmount),
+ StakedAmount: mock.MinValidatorAccountAmount,
+ Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
snapshotcreator.AccountDetails{ // node-2-validator
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x05c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x05c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064"))),
- Amount: testsuite.MinValidatorAccountAmount,
+ Amount: mock.MinValidatorAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0x05c1de274451db8de8182d64c6ee0dca3ae0c9077e0b4330c976976171d79064")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
StakingEpochEnd: iotago.MaxEpochIndex,
FixedCost: 1,
- StakedAmount: testsuite.MinValidatorAccountAmount,
- Mana: iotago.Mana(testsuite.MinValidatorAccountAmount),
+ StakedAmount: mock.MinValidatorAccountAmount,
+ Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
snapshotcreator.AccountDetails{ // node-3-validator
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x1e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x1e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648"))),
- Amount: testsuite.MinValidatorAccountAmount,
+ Amount: mock.MinValidatorAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0x1e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
StakingEpochEnd: iotago.MaxEpochIndex,
FixedCost: 1,
- StakedAmount: testsuite.MinValidatorAccountAmount,
- Mana: iotago.Mana(testsuite.MinValidatorAccountAmount),
+ StakedAmount: mock.MinValidatorAccountAmount,
+ Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
snapshotcreator.AccountDetails{
/*
@@ -84,11 +84,11 @@ var Docker = []options.Option[snapshotcreator.Options]{
*/
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270"))),
- Amount: testsuite.MinIssuerAccountAmount,
+ Amount: mock.MinIssuerAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0x997be92a22b1933f36e26fba5f721756f95811d6b4ae21564197c2bfa4f28270")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
- Mana: iotago.Mana(testsuite.MinIssuerAccountAmount),
+ Mana: iotago.Mana(mock.MinIssuerAccountAmount),
},
),
snapshotcreator.WithBasicOutputs(
@@ -100,10 +100,10 @@ var Docker = []options.Option[snapshotcreator.Options]{
ed25519 address: 2f64f9d179991f50542b01e034fa043b195403875b8677efaf196b41c88803d0
bech32 address: rms1qqhkf7w30xv375z59vq7qd86qsa3j4qrsadcval04uvkkswg3qpaqf4hga2
- => restricted address with mana enabled: rms19qqz7e8e69uej86s2s4srcp5lgzrkx25qwr4hpnha7h3j66pezyq85qpqgqjjc5k
+ => restricted address with mana enabled: rms1xqqz7e8e69uej86s2s4srcp5lgzrkx25qwr4hpnha7h3j66pezyq85qpqg55v3ur
*/
snapshotcreator.BasicOutputDetails{
- Address: lo.Return2(iotago.ParseBech32("rms19qqz7e8e69uej86s2s4srcp5lgzrkx25qwr4hpnha7h3j66pezyq85qpqgqjjc5k")),
+ Address: lo.Return2(iotago.ParseBech32("rms1xqqz7e8e69uej86s2s4srcp5lgzrkx25qwr4hpnha7h3j66pezyq85qpqg55v3ur")),
Amount: 1_000_000_000_000_000,
Mana: 10_000_000,
},
@@ -128,38 +128,38 @@ var Feature = []options.Option[snapshotcreator.Options]{
snapshotcreator.AccountDetails{ // node-01
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x01fb6b9db5d96240aef00bc950d1c67a6494513f6d7cf784e57b4972b96ab2fe"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x01fb6b9db5d96240aef00bc950d1c67a6494513f6d7cf784e57b4972b96ab2fe"))),
- Amount: testsuite.MinValidatorAccountAmount,
+ Amount: mock.MinValidatorAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0x01fb6b9db5d96240aef00bc950d1c67a6494513f6d7cf784e57b4972b96ab2fe")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
StakingEpochEnd: iotago.MaxEpochIndex,
FixedCost: 1,
- StakedAmount: testsuite.MinValidatorAccountAmount,
- Mana: iotago.Mana(testsuite.MinValidatorAccountAmount),
+ StakedAmount: mock.MinValidatorAccountAmount,
+ Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
snapshotcreator.AccountDetails{ // node-02
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x83e7f71a440afd48981a8b4684ddae24434b7182ce5c47cfb56ac528525fd4b6"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x83e7f71a440afd48981a8b4684ddae24434b7182ce5c47cfb56ac528525fd4b6"))),
- Amount: testsuite.MinValidatorAccountAmount,
+ Amount: mock.MinValidatorAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0x83e7f71a440afd48981a8b4684ddae24434b7182ce5c47cfb56ac528525fd4b6")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
StakingEpochEnd: iotago.MaxEpochIndex,
FixedCost: 1,
- StakedAmount: testsuite.MinValidatorAccountAmount,
- Mana: iotago.Mana(testsuite.MinValidatorAccountAmount),
+ StakedAmount: mock.MinValidatorAccountAmount,
+ Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
snapshotcreator.AccountDetails{ // node-03
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0xac628986b2ef52a1679f2289fcd7b4198476976dea4c30ae34ff04ae52e14805"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0xac628986b2ef52a1679f2289fcd7b4198476976dea4c30ae34ff04ae52e14805"))),
- Amount: testsuite.MinValidatorAccountAmount,
+ Amount: mock.MinValidatorAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0xac628986b2ef52a1679f2289fcd7b4198476976dea4c30ae34ff04ae52e14805")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
StakingEpochEnd: iotago.MaxEpochIndex,
FixedCost: 1,
- StakedAmount: testsuite.MinValidatorAccountAmount,
- Mana: iotago.Mana(testsuite.MinValidatorAccountAmount),
+ StakedAmount: mock.MinValidatorAccountAmount,
+ Mana: iotago.Mana(mock.MinValidatorAccountAmount),
},
snapshotcreator.AccountDetails{
/*
@@ -171,11 +171,11 @@ var Feature = []options.Option[snapshotcreator.Options]{
*/
AccountID: blake2b.Sum256(lo.PanicOnErr(hexutil.DecodeHex("0x670a1a20ddb02a6cec53ec3196bc7d5bd26df2f5a6ca90b5fffd71364f104b25"))),
Address: iotago.Ed25519AddressFromPubKey(lo.PanicOnErr(hexutil.DecodeHex("0x670a1a20ddb02a6cec53ec3196bc7d5bd26df2f5a6ca90b5fffd71364f104b25"))),
- Amount: testsuite.MinIssuerAccountAmount,
+ Amount: mock.MinIssuerAccountAmount,
IssuerKey: iotago.Ed25519PublicKeyBlockIssuerKeyFromPublicKey(ed25519.PublicKey(lo.PanicOnErr(hexutil.DecodeHex("0x670a1a20ddb02a6cec53ec3196bc7d5bd26df2f5a6ca90b5fffd71364f104b25")))),
ExpirySlot: iotago.MaxSlotIndex,
BlockIssuanceCredits: iotago.MaxBlockIssuanceCredits / 4,
- Mana: iotago.Mana(testsuite.MinIssuerAccountAmount),
+ Mana: iotago.Mana(mock.MinIssuerAccountAmount),
},
),
snapshotcreator.WithBasicOutputs(
@@ -186,10 +186,10 @@ var Feature = []options.Option[snapshotcreator.Options]{
ed25519 address: 48acd764f626523646d5ccf22f807e96d30b7ab0064f370b66fa811985985ec4
bech32 address: rms1qpy2e4my7cn9ydjx6hx0ytuq06tdxzm6kqry7dctvmagzxv9np0vg9c55n4
- => restricted address with mana enabled: rms19qqy3txhvnmzv53kgm2ueu30splfd5ct02cqvnehpdn04qgeskv9a3qpqgh3p7yy
+ => restricted address with mana enabled: rms1xqqy3txhvnmzv53kgm2ueu30splfd5ct02cqvnehpdn04qgeskv9a3qpqgrhlhv3
*/
snapshotcreator.BasicOutputDetails{
- Address: lo.Return2(iotago.ParseBech32("rms19qqy3txhvnmzv53kgm2ueu30splfd5ct02cqvnehpdn04qgeskv9a3qpqgh3p7yy")),
+ Address: lo.Return2(iotago.ParseBech32("rms1xqqy3txhvnmzv53kgm2ueu30splfd5ct02cqvnehpdn04qgeskv9a3qpqgrhlhv3")),
Amount: 1_000_000_000_000_000,
Mana: 10_000_000,
},