Skip to content

Commit

Permalink
Merge pull request #386 from iotaledger/feat/accounts-tooling
Browse files Browse the repository at this point in the history
Extend evilwallet with account tooling
  • Loading branch information
daria305 authored Oct 17, 2023
2 parents 3284117 + 006dfb8 commit 0be4fe5
Show file tree
Hide file tree
Showing 40 changed files with 2,321 additions and 894 deletions.
4 changes: 2 additions & 2 deletions components/restapi/core/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func congestionForAccountID(c echo.Context) (*apimodels.CongestionResponse, erro
if err != nil {
rmcSlot = 0
}
rmc, err := deps.Protocol.CandidateEngineInstance().Ledger.RMCManager().RMC(rmcSlot)
rmc, err := deps.Protocol.MainEngineInstance().Ledger.RMCManager().RMC(rmcSlot)
if err != nil {
return nil, ierrors.Wrapf(err, "failed to get RMC for slot: %d", rmcSlot)
}
Expand Down Expand Up @@ -141,7 +141,7 @@ func rewardsByOutputID(c echo.Context) (*apimodels.ManaRewardsResponse, error) {

utxoOutput, err := deps.Protocol.MainEngineInstance().Ledger.Output(outputID)
if err != nil {
return nil, ierrors.Wrapf(err, "failed to get output %s from ledger", outputID)
return nil, ierrors.Wrapf(err, "failed to get output %s from ledger", outputID.ToHex())
}

var reward iotago.Mana
Expand Down
13 changes: 8 additions & 5 deletions components/restapi/core/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ func blockIDByTransactionID(c echo.Context) (iotago.BlockID, error) {

func blockIDFromTransactionID(transactionID iotago.TransactionID) (iotago.BlockID, error) {
// Get the first output of that transaction (using index 0)
outputID := iotago.OutputID{}
copy(outputID[:], transactionID[:])
outputID := iotago.OutputIDFromTransactionIDAndIndex(transactionID, 0)

output, err := deps.Protocol.MainEngineInstance().Ledger.Output(outputID)
output, spent, err := deps.Protocol.MainEngineInstance().Ledger.OutputOrSpent(outputID)
if err != nil {
return iotago.EmptyBlockID, ierrors.Wrapf(err, "failed to get output: %s", outputID.String())
return iotago.EmptyBlockID, ierrors.Wrapf(err, "failed to get output: %s", outputID.ToHex())
}

return output.BlockID(), nil
if output != nil {
return output.BlockID(), nil
}

return spent.BlockID(), nil
}

func blockByTransactionID(c echo.Context) (*model.Block, error) {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/iotaledger/hive.go/stringify v0.0.0-20231010133617-cdbd5387e2af
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231011161248-cf0bd6e08811
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231011154428-257141868dad
github.com/iotaledger/iota.go/v4 v4.0.0-20231011161154-7004432004e1
github.com/iotaledger/iota.go/v4 v4.0.0-20231013092100-ad2a52b5ac9a
github.com/labstack/echo/v4 v4.11.2
github.com/labstack/gommon v0.4.0
github.com/libp2p/go-libp2p v0.30.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,8 @@ github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231011154428-257141868dad h1:TRM9Ek
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231011154428-257141868dad/go.mod h1:plZ0+8yLdDWHedj3SfHUwQtIETD+lcS6M1iEAxcjzJ4=
github.com/iotaledger/iota.go/v4 v4.0.0-20231011161154-7004432004e1 h1:mz5E00q1U/LDiUi/wVAbwdhGNKX0dNThaO99Fsyjkgs=
github.com/iotaledger/iota.go/v4 v4.0.0-20231011161154-7004432004e1/go.mod h1:XmgOVYZ7805zVEYPwhvqBDVa7XieXRgPrCEGZW35W8k=
github.com/iotaledger/iota.go/v4 v4.0.0-20231013092100-ad2a52b5ac9a h1:S/n3ZTjnnl0IIMCx+S0pu5CZNArO6Z+omiXt6dDmPK4=
github.com/iotaledger/iota.go/v4 v4.0.0-20231013092100-ad2a52b5ac9a/go.mod h1:XmgOVYZ7805zVEYPwhvqBDVa7XieXRgPrCEGZW35W8k=
github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY=
github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
Expand Down
3 changes: 2 additions & 1 deletion tools/evil-spammer/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.log
*.json
*.json
*.dat
40 changes: 40 additions & 0 deletions tools/evil-spammer/accountwallet/commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package accountwallet

import (
"fmt"

"github.com/iotaledger/hive.go/ierrors"
iotago "github.com/iotaledger/iota.go/v4"
)

func (a *AccountWallet) CreateAccount(params *CreateAccountParams) (iotago.AccountID, error) {
implicitAccountOutput, privateKey, err := a.getFunds(params.Amount, iotago.AddressImplicitAccountCreation)
if err != nil {
return iotago.EmptyAccountID, ierrors.Wrap(err, "Failed to create account")
}

accountID := a.registerAccount(params.Alias, implicitAccountOutput.OutputID, a.latestUsedIndex, privateKey)

fmt.Printf("Created account %s with %d tokens\n", accountID.ToHex(), params.Amount)

return accountID, nil
}

func (a *AccountWallet) DestroyAccount(params *DestroyAccountParams) error {
return a.destroyAccount(params.AccountAlias)
}

func (a *AccountWallet) ListAccount() error {
fmt.Printf("%-10s \t%-33s\n\n", "Alias", "AccountID")
for _, accData := range a.accountsAliases {
fmt.Printf("%-10s \t", accData.Alias)
fmt.Printf("%-33s ", accData.Account.ID().ToHex())
fmt.Printf("\n")
}

return nil
}

func (a *AccountWallet) AllotToAccount(params *AllotAccountParams) error {
return nil
}
219 changes: 219 additions & 0 deletions tools/evil-spammer/accountwallet/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package accountwallet

import (
"encoding/json"
"os"

"github.com/iotaledger/hive.go/ds/types"
"github.com/iotaledger/iota-core/tools/evil-spammer/models"
)

// commands

type AccountOperation int

const (
OperationCreateAccount AccountOperation = iota
OperationConvertAccount
OperationDestroyAccound
OperationAllotAccount
OperationDelegateAccount
OperationStakeAccount
OperationListAccounts
OperationUpdateAccount

CmdNameCreateAccount = "create"
CmdNameConvertAccount = "convert"
CmdNameDestroyAccount = "destroy"
CmdNameAllotAccount = "allot"
CmdNameDelegateAccount = "delegate"
CmdNameStakeAccount = "stake"
CmdNameListAccounts = "list"
CmdNameUpdateAccount = "update"
)

func (a AccountOperation) String() string {
return []string{
CmdNameCreateAccount,
CmdNameConvertAccount,
CmdNameDestroyAccount,
CmdNameAllotAccount,
CmdNameDelegateAccount,
CmdNameStakeAccount,
CmdNameListAccounts,
CmdNameUpdateAccount,
}[a]
}

func AvailableCommands(cmd string) bool {
availableCommands := map[string]types.Empty{
CmdNameCreateAccount: types.Void,
CmdNameConvertAccount: types.Void,
CmdNameDestroyAccount: types.Void,
CmdNameAllotAccount: types.Void,
CmdNameDelegateAccount: types.Void,
CmdNameStakeAccount: types.Void,
CmdNameListAccounts: types.Void,
CmdNameUpdateAccount: types.Void,
}

_, ok := availableCommands[cmd]
return ok
}

type Configuration struct {
BindAddress string `json:"bindAddress,omitempty"`
AccountStatesFile string `json:"accountStatesFile,omitempty"`
GenesisSeed string `json:"genesisSeed,omitempty"`
BlockIssuerPrivateKey string `json:"blockIssuerPrivateKey,omitempty"`
AccountID string `json:"accountID,omitempty"`
}

var accountConfigFile = "config.json"

var (
dockerAccountConfigJSON = `{
"bindAddress": "http://localhost:8080",
"accountStatesFile": "wallet.dat",
"genesisSeed": "7R1itJx5hVuo9w9hjg5cwKFmek4HMSoBDgJZN8hKGxih",
"blockIssuerPrivateKey": "db39d2fde6301d313b108dc9db1ee724d0f405f6fde966bd776365bc5f4a5fb31e4b21eb51dcddf65c20db1065e1f1514658b23a3ddbf48d30c0efc926a9a648",
"accountID": "0x6aee704f25558e8aa7630fed0121da53074188abc423b3c5810f80be4936eb6e"}`
)

// LoadConfiguration loads the config file.
func LoadConfiguration() *Configuration {
// open config file
config := new(Configuration)
file, err := os.Open(accountConfigFile)
if err != nil {
if !os.IsNotExist(err) {
panic(err)
}

//nolint:gosec // users should be able to read the file
if err = os.WriteFile(accountConfigFile, []byte(dockerAccountConfigJSON), 0o644); err != nil {
panic(err)
}
if file, err = os.Open(accountConfigFile); err != nil {
panic(err)
}
}
defer file.Close()

// decode config file
if err = json.NewDecoder(file).Decode(config); err != nil {
panic(err)
}

return config
}

func SaveConfiguration(config *Configuration) {
// open config file
file, err := os.Open(accountConfigFile)
if err != nil {
panic(err)
}
defer file.Close()

jsonConfigs, err := json.MarshalIndent(config, "", " ")

if err != nil {
log.Errorf("failed to write configs to file %s", err)
}

//nolint:gosec // users should be able to read the file
if err = os.WriteFile(accountConfigFile, jsonConfigs, 0o644); err != nil {
panic(err)
}
}

type AccountSubcommands interface {
Type() AccountOperation
}

type CreateAccountParams struct {
Alias string
Amount uint64
NoBIF bool
Implicit bool
}

func (c *CreateAccountParams) Type() AccountOperation {
return OperationCreateAccount
}

type DestroyAccountParams struct {
AccountAlias string
ExpirySlot uint64
}

func (d *DestroyAccountParams) Type() AccountOperation {
return OperationDestroyAccound
}

type AllotAccountParams struct {
Amount uint64
To string
From string // if not set we use faucet
}

func (a *AllotAccountParams) Type() AccountOperation {
return OperationAllotAccount
}

type ConvertAccountParams struct {
AccountAlias string
}

func (d *ConvertAccountParams) Type() AccountOperation {
return OperationConvertAccount
}

type DelegateAccountParams struct {
Amount uint64
To string
From string // if not set we use faucet
}

func (a *DelegateAccountParams) Type() AccountOperation {
return OperationDelegateAccount
}

type StakeAccountParams struct {
Alias string
Amount uint64
FixedCost uint64
StartEpoch uint64
EndEpoch uint64
}

func (a *StakeAccountParams) Type() AccountOperation {
return OperationStakeAccount
}

type UpdateAccountParams struct {
Alias string
BlockIssuerKey string
Mana uint64
Amount uint64
ExpirySlot uint64
}

func (a *UpdateAccountParams) Type() AccountOperation {
return OperationUpdateAccount
}

type NoAccountParams struct {
Operation AccountOperation
}

func (a *NoAccountParams) Type() AccountOperation {
return a.Operation
}

type StateData struct {
Seed string `serix:"0,mapKey=seed,lengthPrefixType=uint8"`
LastUsedIndex uint64 `serix:"1,mapKey=lastUsedIndex"`
AccountsData []*models.AccountState `serix:"2,mapKey=accounts,lengthPrefixType=uint8"`
}
Loading

0 comments on commit 0be4fe5

Please sign in to comment.