Skip to content

Conversation

@diamondhands0
Copy link
Member

@diamondhands0 diamondhands0 commented Jun 14, 2024

  • Fees can be added to a market by the profile owner.
  • When fees are set, orders created for a market will automatically include fees.
  • All of the return values are optimized for frontend display, so that no math or logic needs to live outside of this endpoint.
  • Enables charging fees on Openfund and Focus.
  • Thoroughly tested by amm-service chain_utils.go (~100% coverage)

mattfoley8 and others added 30 commits April 7, 2023 13:32
* Allow ParamUpdater to update PoS GlobalParams.

* Add epoch number to get pos params call.

* Change core branch in test Dockerfile.

* Add test for updating global params.

* Fix bugs in testing updating global params.

* Checkout correct core branch.

* Change core branch.
* Add validator registration endpoints.

* Allow ExtraData to be logged.
* Add get validator by PublicKey route.

* Address PR review feedback.
* Rename VotingPublicKeySignature to VotingAuthorization.

* Checkout corresponding core branch.

* Change core branch in test CI.
* Refactor merging GlobalParamsEntry defaults.

* Change core branch in test dockerfile.
* [stable] Release 3.4.4

* add node version endpoint (#505)

Co-authored-by: Lazy Nina <>

* [stable] Release 3.4.5

* hotfix to exchange test

* Add captcha verification (#509)

* Updates to captcha verification

* Updates to backend

* Updates to captcha verify

* Update captcha verification

* Cleanup logs

* Add routes to store reward amount in global state, track usage via data dog

* Update verify captcha validation ordering, add back comp profile config bool

* Update badger sync settings to optimize memory usage during hypersync (#506)

* Update hypersync to use default badger settings, switch to performance settings once hypersync completes

* Update test dockerfile to accept core branch name as parameter

* Blank commit to trigger build

* ln/fix-transaction-info-mempool (#510)

Co-authored-by: Lazy Nina <>

* ln/no-comp-when-0-create-profile-fee (#511)

Co-authored-by: Lazy Nina <>

* Empty commit to trigger build (#515)

* Add extra data to basic transfer and diamond txn construction endpoints (#516)

* trigger build (#517)

Co-authored-by: Lazy Nina <>

* trigger build

* Add RWLock around AllCountryLevelSignUpBonuses (#518)

Co-authored-by: Lazy Nina <>

---------

Co-authored-by: Lazy Nina <>
Co-authored-by: superzordon <88362450+superzordon@users.noreply.github.com>
Co-authored-by: Lazy Nina <>
Co-authored-by: Lazy Nina <>
…nstruction endpoint (#523)

Co-authored-by: Lazy Nina <>
* Add stake, unstake, and unlock stake txn construction endpoints

* Add stake, unstake, and unlock stake txn construction endpoints

---------

Co-authored-by: Lazy Nina <>
* Add spending limits backend support for stake, unstake, unlock stake

* Add txn construction and get endpoints for lockups

* Add additional sanity checks to lockup endpoint.

* Add txn construction and get endpoints for lockups

* Add additional sanity checks to lockup endpoint.

* Remove redundant profile entry response from LockedBalanceEntryResponse.

* Add proper timestamp to simulateSubmitTransaction.

* Apply suggestions from code review

---------

Co-authored-by: Lazy Nina <>
Co-authored-by: Jon Pollock <jon@deso.org>
Base automatically changed from feature/proof-of-stake to main June 17, 2024 18:05
}
}

if len(transactionSpendingLimit.StakeLimitMap) > 0 {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why this is here. Will take a look and remove...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look up above - this looks like it's duplicated. Confirm that it's the same and then just delete it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can delete all these changes to the TransactionSpendingLimitToResponse function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed they were duplicate and deleted.

quantityToFill string,
) (*uint256.Int, error) {
// If we don't return zero here, we error later because it thinks we overflowed
if quantityToFill == "0" || quantityToFill == "0.0" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if someone passes 0.00? Should we do some sort of strconv.ParseFloat?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good one. Fixed.

// assumed to own the profile being updated.
ProfilePublicKeyBase58Check string `safeForLogging:"true"`

// A map of pkid->feeBasisPoints that the user wants to set for their market.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean a map of public key to fee basis points? All API requests should assume we're receiving public keys as we don't expose PKIDs from the backend. This could lead to unexpected results. What you can do is have the backend convert these from public key to PKID to be safe.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep good point. I was a little sloppy on pkid vs pubkey so I'll go through and make sure all the API endpoints only expose pubkey, and that the conversion to pkid is correct in all places.


// When this is nil then the UpdaterPublicKey is assumed to be the owner of
// the profile.
var profilePublicKeyBytess []byte
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
var profilePublicKeyBytess []byte
var profilePublicKeyBytes []byte

This is only useful for param updater, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}

return res, nil
} else {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can break this if and else into two separate functions? There's a LOT of logic above this and it would take me quite a while in the future to ever address any bugs in this endpoint.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do it later.

error,
) {

return nil, fmt.Errorf("HandleLimitOrder: Not implemented")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are we doing here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops; this was a leftover stub.

return
}
}
txnn, totalInputt, spendAmountt, changeAmountt, feeNanoss, err := fes.CreateSendDesoTxn(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appreciate the refactor here.

}
}

if len(transactionSpendingLimit.StakeLimitMap) > 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can delete all these changes to the TransactionSpendingLimitToResponse function.

existingProfileEntry.IsHidden, // Don't update hidden status
0, // Don't add additionalFees
existingProfileEntry.ExtraData, // The new ExtraData
requestData.MinFeeRateNanosPerKB, fes.backendServer.GetMempool(), []*lib.DeSoOutput{})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreateDAOCoinLimitOrder DOES have TransactionFees. This breaks some functionality we created for node operators to be able to add a basic transfer output when somebody is constructing a txn on their node.

"GetTradingFeesForMarket: Problem decoding public key %s: %v",
pkid, err)
}
pubkey := lib.PKIDToPublicKey(lib.NewPKID(pkidBytes))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect - we want to use a utxo view to fetch the public key for the given PKID instead of just converting the PKID to a public key. If a public key had its identity swapped, then this would behave unexpectedly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops! Good catch I fixed it. Don't think there are any other places where this was an issue.

_baseCurrencyPkid string,
_err error,
) {
// The rule of thumb is we're seeling the base with an ask and buying the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The rule of thumb is we're seeling the base with an ask and buying the
// The rule of thumb is we're selling the base with an ask and buying the

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.


// If the profile is the dusdc profile then just return 1.0
lowerUsername := strings.ToLower(string(existingProfileEntry.Username))
if strings.Contains(lowerUsername, "dusdc") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking the username is insufficient. someone could make a new username that includes dusdc and could lead to unexpected results. Can we add a validation to ensure we have approved stuff coming in for quoteCurrencyPublicKey?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah you're right! I just changed it to an exact match, which I believe should be robust to this. I think before I wasn't sure if we'd have the same setup on devnet/testnet/mainnet, but we do so it's fine.

Comment on lines +554 to +555
lib.PkToString(order.BuyingDAOCoinCreatorPKID[:], fes.Params),
lib.PkToString(order.SellingDAOCoinCreatorPKID[:], fes.Params),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is ultimately fine, but we really should be looking up the public key for PKIDs instead of just converting them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I left this one as-is because it's an isolated case where it's just checking for deso pkid.

Price: priceStrConsensus,
FillType: req.FillType,
MinFeeRateNanosPerKB: req.MinFeeRateNanosPerKB,
TransactionFees: req.TransactionFees,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto on this.

//
// TODO: Add ExtraData to the transaction to make it easier to report it as an
// earning to the user who's receiving the fee.
txn, err := fes.SendCoins(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright that's fine - it just becomes more expensive to assess fees.

Price: priceStrQuoteInverted,
FillType: req.FillType,
MinFeeRateNanosPerKB: req.MinFeeRateNanosPerKB,
TransactionFees: req.TransactionFees,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should merge in the node-level configured transaction fees.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this.

DAOCoinToTransferNanos: *feeBaseUnits,
},
// Standard transaction fields
req.MinFeeRateNanosPerKB, fes.backendServer.GetMempool(), nil)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

once again this breaks this node-level transaction fee stuff we worked on.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

// committed tip height. Otherwise we'll be missing ~2 blocks in limbo.
coreChainTipHeight := fes.TXIndex.CoreChain.BlockTip().Height
for fes.TXIndex.TXIndexChain.BlockTip().Height < coreChainTipHeight {
if time.Since(startTime) > 30*time.Second {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we lower this value?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a maximum value, and it will always always return faster than this. That said, it can sometimes take a long time for txindex to catch up and I think it's good to leave it at this value.


// Compute the additional transaction fees as specified by the request body and the node-level fees.
additionalOutputs, err := fes.getTransactionFee(
lib.TxnTypeAuthorizeDerivedKey, updaterPublicKeyBytes, requestData.TransactionFees)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be TxnTypeUpdateProfile

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops! Fixed.

// If the profile is the dusdc profile then just return 1.0
lowerUsername := strings.ToLower(string(existingProfileEntry.Username))
if strings.Contains(lowerUsername, "dusdc") {
if lowerUsername == "dusdc_" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this much better! we just need to remember to adjust it if we ever change the profile name.

// from the transactor directly to the person receiving the fee.
transferTxns := []*lib.MsgDeSoTxn{}
for pkid, feeBaseUnits := range feeBaseUnitsByPubkey {
receiverPubkeyBytes, _, err := lib.Base58CheckDecode(pkid)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@diamondhands0 - do we need to go from PKID to public key here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this one's just a loop variable but I'll do one more pass before merging don't worry.

@diamondhands0 diamondhands0 merged commit 5130639 into main Jul 13, 2024
@diamondhands0 diamondhands0 deleted the diamondhands/TRADING-FEES branch July 13, 2024 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants