Skip to content

Commit

Permalink
Remove DeSoMempoolPoS
Browse files Browse the repository at this point in the history
  • Loading branch information
AeonSw4n committed Jun 19, 2023
1 parent 948e76b commit a5ba546
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 225 deletions.
114 changes: 0 additions & 114 deletions lib/mempool_pos.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,123 +2,9 @@ package lib

import (
"github.com/emirpasic/gods/sets/treeset"
"github.com/pkg/errors"
"math"
"math/big"
"time"
)

type DeSoMempoolPos struct {
bc *Blockchain
txnRegister *TransactionRegister
globalParams *GlobalParamsEntry

reservedBalances map[PublicKey]uint64
}

func NewDeSoMempoolPos(bc *Blockchain) *DeSoMempoolPos {
// TODO: Think about how to handle global params.
globalParams := DbGetGlobalParamsEntry(bc.db, bc.snapshot)

return &DeSoMempoolPos{
bc: bc,
txnRegister: NewTransactionRegister(bc.params, globalParams),
globalParams: globalParams,
reservedBalances: make(map[PublicKey]uint64),
}
}

func (dmp *DeSoMempoolPos) AddTransaction(txn *MsgDeSoTxn, blockHeight uint64, utxoView *UtxoView) error {
// First, validate that the transaction is properly formatted.
if err := txn.ValidateTransactionSanityBalanceModel(blockHeight, dmp.bc.params, dmp.globalParams); err != nil {
return errors.Wrapf(err, "DeSoMempoolPos.AddTransaction: ")
}

// Validate that the user has enough balance to cover the transaction fees.
userPk := NewPublicKey(txn.PublicKey)
txnFee := txn.TxnFeeNanos
reservedBalance, exists := dmp.reservedBalances[*userPk]

// Check for reserved balance overflow.
if exists && txnFee > math.MaxUint64-reservedBalance {
return errors.Errorf("DeSoMempoolPos.AddTransaction: Reserved balance overflow")
}
newReservedBalance := reservedBalance + txnFee
spendableBalanceNanos, err := utxoView.GetSpendableDeSoBalanceNanosForPublicKey(txn.PublicKey, uint32(blockHeight))
if err != nil {
return errors.Wrapf(err, "DeSoMempoolPos.AddTransaction: ")
}
if newReservedBalance > spendableBalanceNanos {
return errors.Errorf("DeSoMempoolPos.AddTransaction: Not enough balance to cover txn fees "+
"(newReservedBalance: %d, spendableBalanceNanos: %d)", newReservedBalance, spendableBalanceNanos)
}

// Check transaction signature
if _, err = utxoView._verifySignature(txn, uint32(blockHeight)); err != nil {
return errors.Wrapf(err, "DeSoMempoolPos.AddTransaction: Signature validation failed")
}

// Construct the MempoolTx from the MsgDeSoTxn.
mempoolTx, err := NewMempoolTx(txn, blockHeight)
if err != nil {
return errors.Wrapf(err, "DeSoMempoolPos.AddTransaction: Problem constructing MempoolTx")
}

if !dmp.txnRegister.AddTransaction(mempoolTx) {
return errors.Errorf("DeSoMempoolPos.AddTransaction: Problem adding txn to register")
}

// If we get here, this means the transaction was successfully added to the mempool. We update the reserved balance to
// include the newly added transaction's fee.
dmp.reservedBalances[*userPk] = newReservedBalance

return nil
}

func (dmp *DeSoMempoolPos) RemoveTransaction(txn *MempoolTx) error {
// First, sanity check our reserved balance.
userPk := NewPublicKey(txn.Tx.PublicKey)
reservedBalance := dmp.reservedBalances[*userPk]
if txn.Fee > reservedBalance {
return errors.Errorf("DeSoMempoolPos.RemoveTransaction: Fee exceeds reserved balance")
}

// Remove the transaction from the register.
if !dmp.txnRegister.RemoveTransaction(txn) {
return errors.Errorf("DeSoMempoolPos.RemoveTransaction: Problem removing txn from register")
}
dmp.reservedBalances[*userPk] = reservedBalance - txn.Fee

return nil
}

func NewMempoolTx(txn *MsgDeSoTxn, blockHeight uint64) (*MempoolTx, error) {
txnBytes, err := txn.ToBytes(false)
if err != nil {
return nil, errors.Wrapf(err, "DeSoMempoolPos.GetMempoolTx: Problem serializing txn")
}
serializedLen := uint64(len(txnBytes))

txnHash := txn.Hash()
if txnHash == nil {
return nil, errors.Errorf("DeSoMempoolPos.GetMempoolTx: Problem hashing txn")
}
feePerKb, err := txn.ComputeFeePerKB()
if err != nil {
return nil, errors.Wrapf(err, "DeSoMempoolPos.GetMempoolTx: Problem computing fee per KB")
}

return &MempoolTx{
Tx: txn,
Hash: txnHash,
TxSizeBytes: serializedLen,
Added: time.Now(),
Height: uint32(blockHeight),
Fee: txn.TxnFeeNanos,
FeePerKB: feePerKb,
}, nil
}

// ========================
// TransactionRegister
// ========================
Expand Down
111 changes: 0 additions & 111 deletions lib/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -3534,117 +3534,6 @@ func (msg *MsgDeSoTxn) UnmarshalJSON(data []byte) error {
return nil
}

func (txn *MsgDeSoTxn) ValidateTransactionSanityBalanceModel(blockHeight uint64, params *DeSoParams,
globalParams *GlobalParamsEntry) error {

// Make sure the block height is greater than the balance model fork height.
if blockHeight < uint64(params.ForkHeights.BalanceModelBlockHeight) {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: Block height %d is less than "+
"BalanceModelBlockHeight %d", blockHeight, params.ForkHeights.BalanceModelBlockHeight)
}

// Validate transaction to/from bytes encoding
txnBytes, err := txn.ToBytes(false)
if err != nil {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: Problem encoding transaction: %v", err)
}
dummyTxn := &MsgDeSoTxn{}
err = dummyTxn.FromBytes(txnBytes)
if err != nil {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: Problem decoding transaction: %v", err)
}
reTxnBytes, err := dummyTxn.ToBytes(false)
if err != nil {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: Problem re-encoding transaction: %v", err)
}
if !bytes.Equal(txnBytes, reTxnBytes) {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: Transaction bytes are not equal: %v, %v", txnBytes, reTxnBytes)
}

// TODO: Do we want a separate parameter for transaction size? Should it be a part of GlobalDeSoParams?
// Validate transaction size
if uint64(len(txnBytes)) > params.MaxBlockSizeBytes/2 {
return errors.Wrapf(RuleErrorTxnTooBig, "ValidateTransactionSanityBalanceModel: Transaction size %d is greater than "+
"MaxBlockSizeBytes/2 %d", len(txnBytes), params.MaxBlockSizeBytes/2)
}
if uint64(len(txnBytes)) > MaxUnconnectedTxSizeBytes {
return errors.Wrapf(TxErrorTooLarge, "ValidateTransactionSanityBalanceModel: Transaction size %d is greater than "+
"MaxUnconnectedTxSizeBytes %d", len(txnBytes), MaxUnconnectedTxSizeBytes)
}

// Validate transaction version
if txn.TxnVersion == DeSoTxnVersion0 {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: DeSoTxnVersion0 is no longer supported: %v", txnBytes)
}

// Validate that the transaction has correct metadata
if txn.TxnMeta == nil {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: Transaction is missing TxnMeta: %v", txnBytes)
}
if _, err := NewTxnMetadata(txn.TxnMeta.GetTxnType()); err != nil {
return fmt.Errorf("ValidateTransactionSanityBalanceModel: Problem parsing TxnType: %v, %v", err, txnBytes)
}

// Verify inputs/outputs.
if len(txn.TxInputs) != 0 {
return errors.Wrapf(RuleErrorBalanceModelDoesNotUseUTXOInputs, "ValidateTransactionSanityBalanceModel: Balance model "+
"transactions should not have any inputs: %v", txnBytes)
}
if err = CheckTransactionSanity(txn, blockHeight, params); err != nil {
return errors.Wrapf(err, "ValidateTransactionSanityBalanceModel: Problem calling CheckTransactionSanity "+
"with transaction: %v", txnBytes)
}

// Verify the TxnNonce
if txn.TxnNonce == nil {
return errors.Wrapf(TxErrorNoNonceAfterBalanceModelBlockHeight, "ValidateTransactionSanityBalanceModel: Transaction "+
"does not have a nonce: %v", txnBytes)
}
if txn.TxnNonce.ExpirationBlockHeight < blockHeight {
return errors.Wrapf(TxErrorNonceExpired, "ValidateTransactionSanityBalanceModel: Transaction nonce has expired: %v", txnBytes)
}
if globalParams.MaxNonceExpirationBlockHeightOffset != 0 &&
txn.TxnNonce.ExpirationBlockHeight > blockHeight+globalParams.MaxNonceExpirationBlockHeightOffset {
return errors.Wrapf(TxErrorNonceExpirationBlockHeightOffsetExceeded, "ValidateTransactionSanityBalanceModel: Transaction "+
"nonce expiration block height offset exceeded: %v", txnBytes)
}

// Verify the transaction fee
feeNanosPerKb, err := txn.ComputeFeePerKB()
if err != nil {
return errors.Wrapf(err, "ValidateTransactionSanityBalanceModel: Problem computing fee per KB: %v", txnBytes)
}
if feeNanosPerKb < globalParams.MinimumNetworkFeeNanosPerKB {
return errors.Wrapf(RuleErrorTxnFeeBelowNetworkMinimum, "ValidateTransactionSanityBalanceModel: Transaction fee "+
"per KB %d is less than the network minimum %d: %v", feeNanosPerKb, globalParams.MinimumNetworkFeeNanosPerKB, txnBytes)
}

// verify the public key
if err := IsByteArrayValidPublicKey(txn.PublicKey); err != nil {
return errors.Wrapf(err, "ValidateTransactionSanityBalanceModel: Public key is invalid: %v", txnBytes)
}

return nil
}

func (txn *MsgDeSoTxn) ComputeFeePerKB() (uint64, error) {
txBytes, err := txn.ToBytes(false)
if err != nil {
return 0, errors.Wrapf(err, "ComputeFeePerKB: Problem converting txn to bytes")
}
serializedLen := uint64(len(txBytes))
if serializedLen == 0 {
return 0, fmt.Errorf("ComputeFeePerKB: Txn has zero length")
}

fees := txn.TxnFeeNanos
if fees != ((fees * 1000) / 1000) {
return 0, errors.Wrapf(RuleErrorOverflowDetectedInFeeRateCalculation, "ComputeFeePerKB: Overflow detected in fee rate calculation")
}

return (fees * 1000) / serializedLen, nil
}

// ==================================================================
// BasicTransferMetadata
// ==================================================================
Expand Down

0 comments on commit a5ba546

Please sign in to comment.