mirror of
https://github.com/kaspanet/kaspad.git
synced 2026-02-21 03:03:08 +00:00
Compare commits
4 Commits
fix-Remove
...
v0.12.16-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91e6c6b74b | ||
|
|
0819244ba1 | ||
|
|
a0149cd8d0 | ||
|
|
5a3b8a0066 |
@@ -1,3 +1,25 @@
|
||||
Kaspad v0.12.16 - 2023-12-25
|
||||
===========================
|
||||
|
||||
* Adapt wallet UTXO selection to dust patch (#2254)
|
||||
|
||||
Kaspad v0.12.15 - 2023-12-16
|
||||
===========================
|
||||
|
||||
* Update ECDSA address test to use a valid public key (#2202)
|
||||
* Fix off by small amounts in sent amount kaspa (#2220)
|
||||
* Use removeRedeemers correctly by (#2235)
|
||||
* Fix windows asset building by increasing go version (#2245)
|
||||
* Added a mainnet dnsseeder (#2247)
|
||||
* Fix extract atomic swap data pushes (#2203)
|
||||
* Adapt kaspawallet to support testnet 11 (#2211)
|
||||
* Fix type detection in RemoveInvalidTransactions (#2252)
|
||||
|
||||
Kaspad v0.12.14 - 2023-09-26
|
||||
===========================
|
||||
|
||||
* Anti-spam measurements against dust attack (#2223)
|
||||
|
||||
Kaspad v0.12.13 - 2023-03-06
|
||||
===========================
|
||||
|
||||
|
||||
@@ -135,7 +135,11 @@ func (s *server) selectUTXOs(spendAmount uint64, isSendAll bool, feePerInput uin
|
||||
|
||||
fee := feePerInput * uint64(len(selectedUTXOs))
|
||||
totalSpend := spendAmount + fee
|
||||
if !isSendAll && totalValue >= totalSpend {
|
||||
// Two break cases (if not send all):
|
||||
// 1. totalValue == totalSpend, so there's no change needed -> number of outputs = 1, so a single input is sufficient
|
||||
// 2. totalValue > totalSpend, so there will be change and 2 outputs, therefor in order to not struggle with new dust
|
||||
// rules we try and find at least 2 inputs (even though the next one is not necessary in terms of spend value)
|
||||
if !isSendAll && (totalValue == totalSpend || (totalValue > totalSpend && len(selectedUTXOs) > 1)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,23 +75,29 @@ func send(conf *sendConfig) error {
|
||||
signedTransactions[i] = signedTransaction
|
||||
}
|
||||
|
||||
if len(signedTransactions) > 1 {
|
||||
fmt.Printf("Broadcasting %d transactions\n", len(signedTransactions))
|
||||
}
|
||||
|
||||
fmt.Printf("Broadcasting %d transaction(s)\n", len(signedTransactions))
|
||||
// Since we waited for user input when getting the password, which could take unbound amount of time -
|
||||
// create a new context for broadcast, to reset the timeout.
|
||||
broadcastCtx, broadcastCancel := context.WithTimeout(context.Background(), daemonTimeout)
|
||||
defer broadcastCancel()
|
||||
|
||||
response, err := daemonClient.Broadcast(broadcastCtx, &pb.BroadcastRequest{Transactions: signedTransactions})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Transactions were sent successfully")
|
||||
fmt.Println("Transaction ID(s): ")
|
||||
for _, txID := range response.TxIDs {
|
||||
fmt.Printf("\t%s\n", txID)
|
||||
const chunkSize = 100 // To avoid sending a message bigger than the gRPC max message size, we split it to chunks
|
||||
for offset := 0; offset < len(signedTransactions); offset += chunkSize {
|
||||
end := len(signedTransactions)
|
||||
if offset+chunkSize <= len(signedTransactions) {
|
||||
end = offset + chunkSize
|
||||
}
|
||||
|
||||
chunk := signedTransactions[offset:end]
|
||||
response, err := daemonClient.Broadcast(broadcastCtx, &pb.BroadcastRequest{Transactions: chunk})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("Broadcasted %d transaction(s) (broadcasted %.2f%% of the transactions so far)\n", len(chunk), 100*float64(end)/float64(len(signedTransactions)))
|
||||
fmt.Println("Broadcasted Transaction ID(s): ")
|
||||
for _, txID := range response.TxIDs {
|
||||
fmt.Printf("\t%s\n", txID)
|
||||
}
|
||||
}
|
||||
|
||||
if conf.Verbose {
|
||||
|
||||
@@ -131,11 +131,12 @@ func (bb *blockBuilder) validateTransactions(stagingArea *model.StagingArea,
|
||||
for _, transaction := range transactions {
|
||||
err := bb.validateTransaction(stagingArea, transaction)
|
||||
if err != nil {
|
||||
if !errors.As(err, &ruleerrors.RuleError{}) {
|
||||
ruleError := ruleerrors.RuleError{}
|
||||
if !errors.As(err, &ruleError) {
|
||||
return err
|
||||
}
|
||||
invalidTransactions = append(invalidTransactions,
|
||||
ruleerrors.InvalidTransaction{Transaction: transaction, Error: err})
|
||||
ruleerrors.InvalidTransaction{Transaction: transaction, Error: &ruleError})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ func NewErrMissingParents(missingParentHashes []*externalapi.DomainHash) error {
|
||||
// InvalidTransaction is a struct containing an invalid transaction, and the error explaining why it's invalid.
|
||||
type InvalidTransaction struct {
|
||||
Transaction *externalapi.DomainTransaction
|
||||
Error error
|
||||
Error *RuleError
|
||||
}
|
||||
|
||||
func (invalid InvalidTransaction) String() string {
|
||||
|
||||
@@ -3,9 +3,10 @@ package ruleerrors
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
@@ -49,7 +50,7 @@ func TestNewErrMissingTxOut(t *testing.T) {
|
||||
func TestNewErrInvalidTransactionsInNewBlock(t *testing.T) {
|
||||
tx := &externalapi.DomainTransaction{Fee: 1337}
|
||||
txID := consensushashing.TransactionID(tx)
|
||||
outer := NewErrInvalidTransactionsInNewBlock([]InvalidTransaction{{tx, ErrNoTxInputs}})
|
||||
outer := NewErrInvalidTransactionsInNewBlock([]InvalidTransaction{{tx, &ErrNoTxInputs}})
|
||||
//TODO: Implement Stringer for `DomainTransaction`
|
||||
expectedOuterErr := fmt.Sprintf("ErrInvalidTransactionsInNewBlock: [(%s: ErrNoTxInputs)]", txID)
|
||||
inner := &ErrInvalidTransactionsInNewBlock{}
|
||||
@@ -60,7 +61,7 @@ func TestNewErrInvalidTransactionsInNewBlock(t *testing.T) {
|
||||
if len(inner.InvalidTransactions) != 1 {
|
||||
t.Fatalf("TestNewErrInvalidTransactionsInNewBlock: Expected len(inner.MissingOutpoints) 1, found: %d", len(inner.InvalidTransactions))
|
||||
}
|
||||
if inner.InvalidTransactions[0].Error != ErrNoTxInputs {
|
||||
if *inner.InvalidTransactions[0].Error != ErrNoTxInputs {
|
||||
t.Fatalf("TestNewErrInvalidTransactionsInNewBlock: Expected ErrNoTxInputs. found: %v", inner.InvalidTransactions[0].Error)
|
||||
}
|
||||
if inner.InvalidTransactions[0].Transaction.Fee != 1337 {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package mempool
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensus/ruleerrors"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/constants"
|
||||
"sync"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/domain/consensusreference"
|
||||
|
||||
@@ -209,17 +211,7 @@ func (mp *mempool) RemoveInvalidTransactions(err *ruleerrors.ErrInvalidTransacti
|
||||
defer mp.mtx.Unlock()
|
||||
|
||||
for _, tx := range err.InvalidTransactions {
|
||||
ruleErr, success := tx.Error.(ruleerrors.RuleError)
|
||||
if !success {
|
||||
continue
|
||||
}
|
||||
|
||||
inner := ruleErr.Unwrap()
|
||||
removeRedeemers := true
|
||||
if _, ok := inner.(ruleerrors.ErrMissingTxOut); ok {
|
||||
removeRedeemers = false
|
||||
}
|
||||
|
||||
removeRedeemers := !errors.As(tx.Error, &ruleerrors.ErrMissingTxOut{})
|
||||
err := mp.removeTransaction(consensushashing.TransactionID(tx.Transaction), removeRedeemers)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -11,7 +11,7 @@ const validCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
|
||||
const (
|
||||
appMajor uint = 0
|
||||
appMinor uint = 12
|
||||
appPatch uint = 15
|
||||
appPatch uint = 16
|
||||
)
|
||||
|
||||
// appBuild is defined as a variable so it can be overridden during the build
|
||||
|
||||
Reference in New Issue
Block a user