Skip to content

Commit

Permalink
Merge pull request #1312 from iotaledger/develop
Browse files Browse the repository at this point in the history
Merge v0.6.0 to master
  • Loading branch information
capossele authored May 19, 2021
2 parents ab10eaf + b9610d7 commit 6dc5710
Show file tree
Hide file tree
Showing 187 changed files with 17,960 additions and 2,072 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
# v0.6.0 - 2021-05-19
* Add first iteration of the tokenization framework
* Add aMana refresher
* Add CORS to middleware Dashboard server
* Allow specifying parents count when issuing messages
* Move PoW for Faucet requests to client
* Remove Faucet requests from Node's Dashboard
* Improve cli-wallet
* Improve APIs
* Improve integration tests
* Refactor statement remote logging
* Display full messageID in explorer feed
* Update JS dependencies
* Update documentation
* **Breaking**: bumps network and database versions

# v0.5.9 - 2021-05-11
* Replace sync beacons with Tangle Time
* Fix approval weight manager persistence
Expand Down
60 changes: 56 additions & 4 deletions client/faucet.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,78 @@
package client

import (
"context"
"crypto"
"net/http"

"github.com/cockroachdb/errors"
"github.com/iotaledger/hive.go/identity"
"github.com/mr-tron/base58"

"github.com/iotaledger/goshimmer/packages/ledgerstate"
"github.com/iotaledger/goshimmer/packages/mana"
"github.com/iotaledger/goshimmer/packages/pow"
"github.com/iotaledger/goshimmer/plugins/faucet"
"github.com/iotaledger/goshimmer/plugins/webapi/jsonmodels"
)

const (
routeFaucet = "faucet"
)

var (
defaultPOWTarget = 25
powWorker = pow.New(crypto.BLAKE2b_512, 1)
)

// SendFaucetRequest requests funds from faucet nodes by sending a faucet request payload message.
func (api *GoShimmerAPI) SendFaucetRequest(base58EncodedAddr string, pledgeIDs ...string) (*jsonmodels.FaucetResponse, error) {
aManaPledgeID, cManaPledgeID := "", ""
func (api *GoShimmerAPI) SendFaucetRequest(base58EncodedAddr string, powTarget int, pledgeIDs ...string) (*jsonmodels.FaucetResponse, error) {
var aManaPledgeID identity.ID
var cManaPledgeID identity.ID
if len(pledgeIDs) > 1 {
aManaPledgeID, cManaPledgeID = pledgeIDs[0], pledgeIDs[1]
aManaPledgeIDFromString, err := mana.IDFromStr(pledgeIDs[0])
if err != nil {
aManaPledgeID = aManaPledgeIDFromString
}
cManaPledgeIDFromString, err := mana.IDFromStr(pledgeIDs[1])
if err != nil {
cManaPledgeID = cManaPledgeIDFromString
}
}

address, err := ledgerstate.AddressFromBase58EncodedString(base58EncodedAddr)
if err != nil {
return nil, errors.Errorf("could not decode address from string: %w", err)
}

nonce, err := computeFaucetPoW(address, aManaPledgeID, cManaPledgeID, powTarget)
if err != nil {
return nil, errors.Errorf("could not compute faucet PoW: %w", err)
}

res := &jsonmodels.FaucetResponse{}
if err := api.do(http.MethodPost, routeFaucet,
&jsonmodels.FaucetRequest{Address: base58EncodedAddr, AccessManaPledgeID: aManaPledgeID, ConsensusManaPledgeID: cManaPledgeID}, res); err != nil {
&jsonmodels.FaucetRequest{
Address: base58EncodedAddr,
AccessManaPledgeID: base58.Encode(aManaPledgeID.Bytes()),
ConsensusManaPledgeID: base58.Encode(cManaPledgeID.Bytes()),
Nonce: nonce,
}, res); err != nil {
return nil, err
}

return res, nil
}

func computeFaucetPoW(address ledgerstate.Address, aManaPledgeID, cManaPledgeID identity.ID, powTarget int) (nonce uint64, err error) {
if powTarget < 0 {
powTarget = defaultPOWTarget
}

faucetRequest := faucet.NewRequest(address, aManaPledgeID, cManaPledgeID, 0)

objectBytes := faucetRequest.Bytes()
powRelevantBytes := objectBytes[:len(objectBytes)-pow.NonceBytes]

return powWorker.Mine(context.Background(), powRelevantBytes, powTarget)
}
192 changes: 192 additions & 0 deletions client/ledgerstate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package client

import (
"net/http"
"strings"

json_models "github.com/iotaledger/goshimmer/plugins/webapi/jsonmodels"
)

const (
// basic routes
routeGetAddresses = "ledgerstate/addresses/"
routeGetBranches = "ledgerstate/branches/"
routeGetOutputs = "ledgerstate/outputs/"
routeGetTransactions = "ledgerstate/transactions/"
routePostTransactions = "ledgerstate/transactions"

// route path modifiers
pathUnspentOutputs = "/unspentOutputs"
pathChildren = "/children"
pathConflicts = "/conflicts"
pathConsumers = "/consumers"
pathMetadata = "/metadata"
pathInclusionState = "/inclusionState"
pathConsensus = "/consensus"
pathAttachments = "/attachments"
)

// GetAddressOutputs gets the spent and unspent outputs of an address.
func (api *GoShimmerAPI) GetAddressOutputs(base58EncodedAddress string) (*json_models.GetAddressResponse, error) {
res := &json_models.GetAddressResponse{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetAddresses, base58EncodedAddress}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetAddressUnspentOutputs gets the unspent outputs of an address.
func (api *GoShimmerAPI) GetAddressUnspentOutputs(base58EncodedAddress string) (*json_models.GetAddressResponse, error) {
res := &json_models.GetAddressResponse{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetAddresses, base58EncodedAddress, pathUnspentOutputs}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// PostAddressUnspentOutputs gets the unspent outputs of several addresses.
func (api *GoShimmerAPI) PostAddressUnspentOutputs(base58EncodedAddresses []string) (*json_models.PostAddressesUnspentOutputsResponse, error) {
res := &json_models.PostAddressesUnspentOutputsResponse{}
if err := api.do(http.MethodPost, func() string {
return strings.Join([]string{routeGetAddresses, "unspentOutputs"}, "")
}(), &json_models.PostAddressesUnspentOutputsRequest{Addresses: base58EncodedAddresses}, res); err != nil {
return nil, err
}
return res, nil
}

// GetBranch gets the branch information.
func (api *GoShimmerAPI) GetBranch(base58EncodedBranchID string) (*json_models.Branch, error) {
res := &json_models.Branch{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetBranches, base58EncodedBranchID}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetBranchChildren gets the children of a branch.
func (api *GoShimmerAPI) GetBranchChildren(base58EncodedBranchID string) (*json_models.GetBranchChildrenResponse, error) {
res := &json_models.GetBranchChildrenResponse{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetBranches, base58EncodedBranchID, pathChildren}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetBranchConflicts gets the conflict branches of a branch.
func (api *GoShimmerAPI) GetBranchConflicts(base58EncodedBranchID string) (*json_models.GetBranchConflictsResponse, error) {
res := &json_models.GetBranchConflictsResponse{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetBranches, base58EncodedBranchID, pathConflicts}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetOutput gets the output corresponding to OutputID.
func (api *GoShimmerAPI) GetOutput(base58EncodedOutputID string) (*json_models.Output, error) {
res := &json_models.Output{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetOutputs, base58EncodedOutputID}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetOutputConsumers gets the consumers of the output corresponding to OutputID.
func (api *GoShimmerAPI) GetOutputConsumers(base58EncodedOutputID string) (*json_models.GetOutputConsumersResponse, error) {
res := &json_models.GetOutputConsumersResponse{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetOutputs, base58EncodedOutputID, pathConsumers}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetOutputMetadata gets the metadata of the output corresponding to OutputID.
func (api *GoShimmerAPI) GetOutputMetadata(base58EncodedOutputID string) (*json_models.OutputMetadata, error) {
res := &json_models.OutputMetadata{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetOutputs, base58EncodedOutputID, pathMetadata}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetTransaction gets the transaction of the corresponding to TransactionID.
func (api *GoShimmerAPI) GetTransaction(base58EncodedTransactionID string) (*json_models.Transaction, error) {
res := &json_models.Transaction{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetTransactions, base58EncodedTransactionID}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetTransactionMetadata gets metadata of the transaction corresponding to TransactionID.
func (api *GoShimmerAPI) GetTransactionMetadata(base58EncodedTransactionID string) (*json_models.TransactionMetadata, error) {
res := &json_models.TransactionMetadata{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetTransactions, base58EncodedTransactionID, pathMetadata}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetTransactionInclusionState gets inclusion state of the transaction corresponding to TransactionID.
func (api *GoShimmerAPI) GetTransactionInclusionState(base58EncodedTransactionID string) (*json_models.TransactionInclusionState, error) {
res := &json_models.TransactionInclusionState{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetTransactions, base58EncodedTransactionID, pathInclusionState}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetTransactionConsensusMetadata gets the consensus metadata of the transaction corresponding to TransactionID.
func (api *GoShimmerAPI) GetTransactionConsensusMetadata(base58EncodedTransactionID string) (*json_models.TransactionConsensusMetadata, error) {
res := &json_models.TransactionConsensusMetadata{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetTransactions, base58EncodedTransactionID, pathConsensus}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// GetTransactionAttachments gets the attachments (messageIDs) of the transaction corresponding to TransactionID.
func (api *GoShimmerAPI) GetTransactionAttachments(base58EncodedTransactionID string) (*json_models.GetTransactionAttachmentsResponse, error) {
res := &json_models.GetTransactionAttachmentsResponse{}
if err := api.do(http.MethodGet, func() string {
return strings.Join([]string{routeGetTransactions, base58EncodedTransactionID, pathAttachments}, "")
}(), nil, res); err != nil {
return nil, err
}
return res, nil
}

// PostTransaction sends the transaction(bytes) to the Tangle and returns its transaction ID.
func (api *GoShimmerAPI) PostTransaction(transactionBytes []byte) (*json_models.PostTransactionResponse, error) {
res := &json_models.PostTransactionResponse{}
if err := api.do(http.MethodPost, routePostTransactions,
&json_models.PostTransactionRequest{TransactionBytes: transactionBytes}, res); err != nil {
return nil, err
}

return res, nil
}
11 changes: 11 additions & 0 deletions client/mana.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const (
routePending = "mana/pending"
routePastConsensusVector = "mana/consensus/past"
routePastConsensusEventLogs = "mana/consensus/logs"
routeAllowedPledgeNodeIDs = "mana/allowedManaPledge"
)

// GetOwnMana returns the access and consensus mana of the node this api client is communicating with.
Expand Down Expand Up @@ -166,3 +167,13 @@ func (api *GoShimmerAPI) GetConsensusEventLogs(nodeIDs []string) (*jsonmodels.Ge
}
return res, nil
}

// GetAllowedManaPledgeNodeIDs returns the list of allowed mana pledge IDs.
func (api *GoShimmerAPI) GetAllowedManaPledgeNodeIDs() (*jsonmodels.AllowedManaPledgeResponse, error) {
res := &jsonmodels.AllowedManaPledgeResponse{}
if err := api.do(http.MethodGet, routeAllowedPledgeNodeIDs, nil, res); err != nil {
return nil, err
}

return res, nil
}
21 changes: 5 additions & 16 deletions client/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import (
)

const (
routeAttachments = "value/attachments"
routeGetTxnByID = "value/transactionByID"
routeSendTxn = "value/sendTransaction"
routeSendTxnByJSON = "value/sendTransactionByJson"
routeUnspentOutputs = "value/unspentOutputs"
routeAllowedPledgeNodeIDs = "value/allowedManaPledge"
routeAttachments = "value/attachments"
routeGetTxnByID = "value/transactionByID"
routeSendTxn = "value/sendTransaction"
routeSendTxnByJSON = "value/sendTransactionByJson"
routeUnspentOutputs = "value/unspentOutputs"
)

// GetAttachments gets the attachments of a transaction ID
Expand Down Expand Up @@ -79,13 +78,3 @@ func (api *GoShimmerAPI) SendTransactionByJSON(txn value.SendTransactionByJSONRe

return res.TransactionID, nil
}

// GetAllowedManaPledgeNodeIDs returns the list of allowed mana pledge IDs.
func (api *GoShimmerAPI) GetAllowedManaPledgeNodeIDs() (*value.AllowedManaPledgeResponse, error) {
res := &value.AllowedManaPledgeResponse{}
if err := api.do(http.MethodGet, routeAllowedPledgeNodeIDs, nil, res); err != nil {
return nil, err
}

return res, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (addressManager *AddressManager) updateFirstUnspentAddressIndex() {
}
}

// updateLastUnspentAddressIndex searches for the first unspent address and updates the lastUnspentAddressIndex.
// updateLastUnspentAddressIndex searches for the last unspent address and updates the lastUnspentAddressIndex.
func (addressManager *AddressManager) updateLastUnspentAddressIndex() {
// search for last unspent address
for i := addressManager.lastUnspentAddressIndex; true; i-- {
Expand Down
24 changes: 24 additions & 0 deletions client/wallet/balances.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package wallet

import (
"sort"
"time"

"github.com/iotaledger/goshimmer/packages/ledgerstate"
)

// TimedBalance represents a balance that is time dependent.
type TimedBalance struct {
Balance map[ledgerstate.Color]uint64
Time time.Time
}

// TimedBalanceSlice is a slice containing TimedBalances.
type TimedBalanceSlice []*TimedBalance

// Sort sorts the balances based on their Time.
func (t TimedBalanceSlice) Sort() {
sort.Slice(t, func(i, j int) bool {
return t[i].Time.Before(t[j].Time)
})
}
6 changes: 4 additions & 2 deletions client/wallet/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
// Connector represents an interface that defines how the wallet interacts with the network. A wallet can either be used
// locally on a server or it can connect remotely using the web API.
type Connector interface {
UnspentOutputs(addresses ...address.Address) (unspentOutputs map[address.Address]map[ledgerstate.OutputID]*Output, err error)
UnspentOutputs(addresses ...address.Address) (unspentOutputs OutputsByAddressAndOutputID, err error)
SendTransaction(transaction *ledgerstate.Transaction) (err error)
RequestFaucetFunds(address address.Address) (err error)
RequestFaucetFunds(address address.Address, powTarget int) (err error)
GetAllowedPledgeIDs() (pledgeIDMap map[mana.Type][]string, err error)
GetTransactionInclusionState(txID ledgerstate.TransactionID) (inc ledgerstate.InclusionState, err error)
GetUnspentAliasOutput(address *ledgerstate.AliasAddress) (output *ledgerstate.AliasOutput, err error)
}
Loading

0 comments on commit 6dc5710

Please sign in to comment.