Skip to content

Commit

Permalink
Merge pull request #2334 from iotaledger/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
karimodm committed Jul 14, 2022
2 parents f028843 + da8bf43 commit e8d192b
Show file tree
Hide file tree
Showing 425 changed files with 21,018 additions and 17,317 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# v0.9.2 - 2022-07-14

> This release introduces the epoch commitments feature which allows creating proofs-of-inclusion of a block in the tangle. This feature is also the first step to the development of pruning, local snapshots and will allow more efficient way of syncing a node. This release also improves the parameters of rate-setter that should improve user-experience of issuing new blocks. It also contains various bugfixes and improvements, change of terminology e.g. message -> block etc. as well as replacement of grades of finality with confirmation state.
The snapshot has been changed and thus the ledger state is fully reset.

- Update wiki cli (#2327)
- Trigger all async tasks in a separate goroutine. (#2332)
- Add bootstrap manager. (#2326)
- Keep epoch contents in permanent storage in epochstorage plugin (#2328)
- Terminology renaming (#2320)
- Fix entrynode config (#2321)
- Epoch commitment metrics (#2293)
- Minor fixes (#2319)
- Build(deps): bump moment in /plugins/dagsvisualizer/frontend (#2317)
- Build(deps): bump moment in /plugins/dashboard/frontend (#2316)
- Replace GoF with confirmation state (#2313)
- Improve rate-setter UX (#2315)
- Epoch Commitments (#2212)
- Fix faucet (#2306)

# v0.9.1 - 2022-06-22

> This release introduces the rate setter which allows nodes to estimate their fair rate of block creation and makes removing proof-of-work possible. Congestion is completely handled by the rate-setter and congestion control algorithms (capped at 30 BPS). Access mana is not decaying and is pledged to the node until it's re-pledged to another node. The release also includes new time concepts which make the network more resilient against mana going offline which in the past caused confirmations to stop permanently.
Expand Down
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ COPY go.mod .
COPY go.sum .

ENV GO111MODULE=on
ENV GOWORK=off
RUN go mod download
RUN go mod verify

Expand Down
2 changes: 1 addition & 1 deletion client/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const (
routeData = "data"
)

// Data sends the given data (payload) by creating a message in the backend.
// Data sends the given data (payload) by creating a block in the backend.
func (api *GoShimmerAPI) Data(data []byte) (string, error) {
res := &jsonmodels.DataResponse{}
if err := api.do(http.MethodPost, routeData,
Expand Down
8 changes: 4 additions & 4 deletions client/evilspammer/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

var (
ErrFailPostTransaction = errors.New("failed to post transaction")
ErrFailSendDataMessage = errors.New("failed to send a data message")
ErrFailSendDataBlock = errors.New("failed to send a data block")

ErrTransactionIsNil = errors.New("provided transaction is nil")
ErrFailToPrepareBatch = errors.New("custom conflict batch could not be prepared")
Expand Down Expand Up @@ -54,9 +54,9 @@ func (e *ErrorCounter) GetErrorsSummary() string {
if len(e.errorsMap) == 0 {
return "No errors encountered"
}
msg := "Errors encountered during spam:\n"
blk := "Errors encountered during spam:\n"
for key, value := range e.errorsMap {
msg += fmt.Sprintf("%s: %d\n", key.Error(), value.Load())
blk += fmt.Sprintf("%s: %d\n", key.Error(), value.Load())
}
return msg
return blk
}
2 changes: 1 addition & 1 deletion client/evilspammer/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func WithEvilWallet(initWallets *evilwallet.EvilWallet) Options {
}
}

// WithEvilScenario provides initWallet of spammer, if omitted spammer will prepare funds based on maxMsgSent parameter
// WithEvilScenario provides initWallet of spammer, if omitted spammer will prepare funds based on maxBlkSent parameter
func WithEvilScenario(scenario *evilwallet.EvilScenario) Options {
return func(s *Spammer) {
s.EvilScenario = scenario
Expand Down
12 changes: 6 additions & 6 deletions client/evilspammer/spammer.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func NewSpammer(options ...Options) *Spammer {
return s
}

func (s *Spammer) MessagesSent() uint64 {
func (s *Spammer) BlocksSent() uint64 {
return uint64(s.State.txSent.Load())
}

Expand Down Expand Up @@ -115,11 +115,11 @@ func (s *Spammer) setupSpamDetails() {
if s.SpamDetails.TimeUnit == 0 {
s.SpamDetails.TimeUnit = time.Second
}
// provided only maxMsgSent, calculating the default max for maxDuration
// provided only maxBlkSent, calculating the default max for maxDuration
if s.SpamDetails.MaxDuration == 0 && s.SpamDetails.MaxBatchesSent > 0 {
s.SpamDetails.MaxDuration = time.Hour * 100
}
// provided only maxDuration, calculating the default max for maxMsgSent
// provided only maxDuration, calculating the default max for maxBlkSent
if s.SpamDetails.MaxBatchesSent == 0 && s.SpamDetails.MaxDuration > 0 {
s.SpamDetails.MaxBatchesSent = int(s.SpamDetails.MaxDuration.Seconds()/s.SpamDetails.TimeUnit.Seconds()*float64(s.SpamDetails.Rate)) + 1
}
Expand All @@ -141,7 +141,7 @@ func (s *Spammer) initLogTicker() *time.Ticker {
return time.NewTicker(s.State.logTickTime)
}

// Spam runs the spammer. Function will stop after maxDuration time will pass or when maxMsgSent will be exceeded
// Spam runs the spammer. Function will stop after maxDuration time will pass or when maxBlkSent will be exceeded
func (s *Spammer) Spam() {
s.log.Infof("Start spamming transactions with %d rate", s.SpamDetails.Rate)

Expand All @@ -153,7 +153,7 @@ func (s *Spammer) Spam() {
for {
select {
case <-s.State.logTicker.C:
s.log.Infof("Messages issued so far: %d, errors encountered: %d", s.State.txSent.Load(), s.ErrCounter.GetTotalErrorCount())
s.log.Infof("Blocks issued so far: %d, errors encountered: %d", s.State.txSent.Load(), s.ErrCounter.GetTotalErrorCount())
case <-timeExceeded:
s.log.Infof("Maximum spam duration exceeded, stopping spammer....")
s.StopSpamming()
Expand All @@ -180,7 +180,7 @@ func (s *Spammer) Spam() {

func (s *Spammer) CheckIfAllSent() {
if s.State.batchPrepared.Load() >= int64(s.SpamDetails.MaxBatchesSent) {
s.log.Infof("Maximum number of messages sent, stopping spammer...")
s.log.Infof("Maximum number of blocks sent, stopping spammer...")
s.done <- true
}
}
Expand Down
10 changes: 5 additions & 5 deletions client/evilspammer/spamming_functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ import (

func DataSpammingFunction(s *Spammer) {
clt := s.Clients.GetClient()
// sleep randomly to avoid issuing messages in different goroutines at once
// sleep randomly to avoid issuing blocks in different goroutines at once
time.Sleep(time.Duration(rand.Float64()*20) * time.Millisecond)
if err := evilwallet.RateSetterSleep(clt, s.UseRateSetter); err != nil {
s.ErrCounter.CountError(err)
}
msgID, err := clt.PostData([]byte(fmt.Sprintf("SPAM")))
blkID, err := clt.PostData([]byte(fmt.Sprintf("SPAM")))
if err != nil {
s.ErrCounter.CountError(ErrFailSendDataMessage)
s.ErrCounter.CountError(ErrFailSendDataBlock)
}

count := s.State.txSent.Add(1)
if count%int64(s.SpamDetails.Rate*2) == 0 {
s.log.Debugf("Last sent message, ID: %s; msgCount: %d", msgID, count)
s.log.Debugf("Last sent block, ID: %s; blkCount: %d", blkID, count)
}
s.State.batchPrepared.Add(1)
s.CheckIfAllSent()
Expand All @@ -53,7 +53,7 @@ func CustomConflictSpammingFunc(s *Spammer) {
go func(clt evilwallet.Client, tx *devnetvm.Transaction) {
defer wg.Done()

// sleep randomly to avoid issuing messages in different goroutines at once
// sleep randomly to avoid issuing blocks in different goroutines at once
time.Sleep(time.Duration(rand.Float64()*100) * time.Millisecond)
if err = evilwallet.RateSetterSleep(clt, s.UseRateSetter); err != nil {
s.ErrCounter.CountError(err)
Expand Down
3 changes: 2 additions & 1 deletion client/evilspammer/utils.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package evilspammer

import (
"github.com/iotaledger/goshimmer/client/evilwallet"
"time"

"github.com/iotaledger/goshimmer/client/evilwallet"
)

// BigWalletsNeeded calculates how many big wallets needs to be prepared for a spam based on provided spam details.
Expand Down
38 changes: 19 additions & 19 deletions client/evilwallet/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
"time"

"github.com/iotaledger/hive.go/identity"
"github.com/iotaledger/hive.go/types/confirmation"

"github.com/iotaledger/goshimmer/client"
"github.com/iotaledger/goshimmer/client/wallet"
"github.com/iotaledger/goshimmer/packages/consensus/gof"
"github.com/iotaledger/goshimmer/packages/jsonmodels"
"github.com/iotaledger/goshimmer/packages/ledger/utxo"
"github.com/iotaledger/goshimmer/packages/ledger/vm/devnetvm"
Expand Down Expand Up @@ -173,19 +173,19 @@ type Client interface {
SleepRateSetterEstimate() (err error)
// PostTransaction sends a transaction to the Tangle via a given client.
PostTransaction(tx *devnetvm.Transaction) (utxo.TransactionID, error)
// PostData sends the given data (payload) by creating a message in the backend.
PostData(data []byte) (msgID string, err error)
// PostData sends the given data (payload) by creating a block in the backend.
PostData(data []byte) (blkID string, err error)
// GetUnspentOutputForAddress gets the first unspent outputs of a given address.
GetUnspentOutputForAddress(addr devnetvm.Address) *jsonmodels.WalletOutput
// GetAddressUnspentOutputs gets the unspent outputs of an address.
GetAddressUnspentOutputs(address string) (outputIDs []utxo.OutputID, err error)
// GetTransactionGoF returns the GoF of a given transaction ID.
GetTransactionGoF(txID string) gof.GradeOfFinality
// GetTransactionConfirmationState returns the ConfirmationState of a given transaction ID.
GetTransactionConfirmationState(txID string) confirmation.State
// GetOutput gets the output of a given outputID.
GetOutput(outputID utxo.OutputID) devnetvm.Output
// GetOutputGoF gets the first unspent outputs of a given address.
GetOutputGoF(outputID utxo.OutputID) gof.GradeOfFinality
// BroadcastFaucetRequest requests funds from the faucet and returns the faucet request message ID.
// GetOutputConfirmationState gets the first unspent outputs of a given address.
GetOutputConfirmationState(outputID utxo.OutputID) confirmation.State
// BroadcastFaucetRequest requests funds from the faucet and returns the faucet request block ID.
BroadcastFaucetRequest(address string) error
// GetTransactionOutputs returns the outputs the transaction created.
GetTransactionOutputs(txID string) (outputs devnetvm.Outputs, err error)
Expand Down Expand Up @@ -232,7 +232,7 @@ func (c *WebClient) SleepRateSetterEstimate() (err error) {
return nil
}

// BroadcastFaucetRequest requests funds from the faucet and returns the faucet request message ID.
// BroadcastFaucetRequest requests funds from the faucet and returns the faucet request block ID.
func (c *WebClient) BroadcastFaucetRequest(address string) (err error) {
_, err = c.api.BroadcastFaucetRequest(address, -1)
return
Expand All @@ -256,8 +256,8 @@ func (c *WebClient) PostTransaction(tx *devnetvm.Transaction) (txID utxo.Transac
return
}

// PostData sends the given data (payload) by creating a message in the backend.
func (c *WebClient) PostData(data []byte) (msgID string, err error) {
// PostData sends the given data (payload) by creating a block in the backend.
func (c *WebClient) PostData(data []byte) (blkID string, err error) {
resp, err := c.api.Data(data)
if err != nil {
return
Expand Down Expand Up @@ -288,14 +288,14 @@ func (c *WebClient) GetUnspentOutputForAddress(addr devnetvm.Address) *jsonmodel
return nil
}

// GetOutputGoF gets the first unspent outputs of a given address.
func (c *WebClient) GetOutputGoF(outputID utxo.OutputID) gof.GradeOfFinality {
// GetOutputConfirmationState gets the first unspent outputs of a given address.
func (c *WebClient) GetOutputConfirmationState(outputID utxo.OutputID) confirmation.State {
res, err := c.api.GetOutputMetadata(outputID.Base58())
if err != nil {
return gof.None
return confirmation.Pending
}

return res.GradeOfFinality
return res.ConfirmationState
}

// GetOutput gets the output of a given outputID.
Expand All @@ -308,13 +308,13 @@ func (c *WebClient) GetOutput(outputID utxo.OutputID) devnetvm.Output {
return output
}

// GetTransactionGoF returns the GoF of a given transaction ID.
func (c *WebClient) GetTransactionGoF(txID string) gof.GradeOfFinality {
// GetTransactionConfirmationState returns the ConfirmationState of a given transaction ID.
func (c *WebClient) GetTransactionConfirmationState(txID string) confirmation.State {
resp, err := c.api.GetTransactionMetadata(txID)
if err != nil {
return gof.None
return confirmation.Pending
}
return resp.GradeOfFinality
return resp.ConfirmationState
}

// GetTransactionOutputs returns the outputs the transaction created.
Expand Down
5 changes: 3 additions & 2 deletions client/evilwallet/customscenarios.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ func NSpendBatch(nSpent int) EvilBatch {
scenarioAlias = append(scenarioAlias,
ScenarioAlias{
Inputs: []string{strconv.Itoa(inputStartNum)},
Outputs: []string{strconv.Itoa(i)}},
Outputs: []string{strconv.Itoa(i)},
},
)
}
conflictSlice = append(conflictSlice, scenarioAlias)
Expand Down Expand Up @@ -136,7 +137,7 @@ func Scenario3() EvilBatch {
}
}

// Scenario4 is a reflection of ledgerstate unit test for branch confirmation - packages/ledgerstate/ledgerstate_test_SetBranchConfirmed.png
// Scenario4 is a reflection of ledgerstate unit test for conflict confirmation - packages/ledgerstate/ledgerstate_test_SetConflictConfirmed.png
func Scenario4() EvilBatch {
return EvilBatch{
[]ScenarioAlias{
Expand Down
19 changes: 10 additions & 9 deletions client/evilwallet/evilwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import (
)

const (
// GoFConfirmed defines the grade of finality that is considered confirmed.
GoFConfirmed = 3
// FaucetRequestSplitNumber defines the number of outputs to split from a faucet request.
FaucetRequestSplitNumber = 100
faucetTokensPerRequest = 1000000
Expand All @@ -32,10 +30,12 @@ const (
maxGoroutines = 5
)

var defaultClientsURLs = []string{"http://localhost:8080", "http://localhost:8090"}
var faucetBalance = devnetvm.NewColoredBalances(map[devnetvm.Color]uint64{
devnetvm.ColorIOTA: uint64(faucetTokensPerRequest),
})
var (
defaultClientsURLs = []string{"http://localhost:8080", "http://localhost:8090"}
faucetBalance = devnetvm.NewColoredBalances(map[devnetvm.Color]uint64{
devnetvm.ColorIOTA: uint64(faucetTokensPerRequest),
})
)

// region EvilWallet ///////////////////////////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -465,7 +465,8 @@ func (e *EvilWallet) prepareInputs(buildOptions *Options) (inputs []devnetvm.Inp

// prepareOutputs creates outputs for different scenarios, if no aliases were provided, new empty outputs are created from buildOptions.outputs balances.
func (e *EvilWallet) prepareOutputs(buildOptions *Options, tempWallet *Wallet) (outputs []devnetvm.Output,
addrAliasMap map[devnetvm.Address]string, tempAddresses map[devnetvm.Address]types.Empty, err error) {
addrAliasMap map[devnetvm.Address]string, tempAddresses map[devnetvm.Address]types.Empty, err error,
) {
if buildOptions.areOutputsProvidedWithoutAliases() {
for _, balance := range buildOptions.outputs {
output := devnetvm.NewSigLockedColoredOutput(balance, buildOptions.outputWallet.Address().Address())
Expand Down Expand Up @@ -528,7 +529,8 @@ func (e *EvilWallet) useFreshIfInputWalletNotProvided(buildOptions *Options) (*W
// that indicates which outputs should be saved to the outputWallet.All other outputs are created with temporary wallet,
// and their addresses are stored in tempAddresses.
func (e *EvilWallet) matchOutputsWithAliases(buildOptions *Options, tempWallet *Wallet) (outputs []devnetvm.Output,
addrAliasMap map[devnetvm.Address]string, tempAddresses map[devnetvm.Address]types.Empty, err error) {
addrAliasMap map[devnetvm.Address]string, tempAddresses map[devnetvm.Address]types.Empty, err error,
) {
err = e.updateOutputBalances(buildOptions)
if err != nil {
return nil, nil, nil, err
Expand Down Expand Up @@ -641,7 +643,6 @@ func (e *EvilWallet) updateOutputBalances(buildOptions *Options) (err error) {
return true
})
}

}
balances := SplitBalanceEqually(len(buildOptions.outputs)+len(buildOptions.aliasOutputs), totalBalance)
i := 0
Expand Down
Loading

0 comments on commit e8d192b

Please sign in to comment.