Skip to content
Permalink
Browse files

Add wallet flag for allowhighfees

In the past there was no way to set the SendRawTransaction AllowHighFees
options without changing code.  This option lets users force their
transactions to go through without having to be checked according to the
high fees check in mempool.go in dcrd.  Now users can set this flag on
start up and all transactions will be excepted no matter how fee their
fee is.  (Though obviously the low end fee check will still be in place,
this only applies to high fees)
  • Loading branch information...
alexlyp committed Apr 26, 2016
1 parent d4ea045 commit ec2c1c2a42d70d53203c7096831ece336d10b413
Showing with 45 additions and 30 deletions.
  1. +3 −0 config.go
  2. +2 −1 dcrwallet.go
  3. +3 −3 rpc/legacyrpc/methods.go
  4. +4 −2 wallet/chainntfns.go
  5. +5 −5 wallet/createtx.go
  6. +5 −3 wallet/loader.go
  7. +10 −5 wallet/wallet.go
  8. +1 −1 walletsetup.go
  9. +12 −10 wstakemgr/stake.go
@@ -43,6 +43,7 @@ const (
defaultPromptPass = false
defaultAddrIdxScanLen = 750
defaultStakePoolColdExtKey = ""
defaultAllowHighFees = false

walletDbName = "wallet.db"
)
@@ -93,6 +94,7 @@ type config struct {
PoolFees float64 `long:"poolfees" description:"The per-ticket fee mandated by the ticket pool as a percent (e.g. 1.00 for 1.00% fee)"`
AddrIdxScanLen int `long:"addridxscanlen" description:"The width of the scan for last used addresses on wallet restore and start up (default: 750)"`
StakePoolColdExtKey string `long:"stakepoolcoldextkey" description:"Enables the wallet as a stake pool with an extended key in the format of \"xpub...:index\" to derive cold wallet addresses to send fees to"`
AllowHighFees bool `long:"allowhighfees" description:"Force the RPC client to use the 'allowHighFees' flag when sending transactions"`

// RPC client options
RPCConnect string `short:"c" long:"rpcconnect" description:"Hostname/IP and port of dcrd RPC server to connect to (default localhost:9109, testnet: localhost:19109, simnet: localhost:18556)"`
@@ -272,6 +274,7 @@ func loadConfig() (*config, []string, error) {
UnsafeMainNet: defaultUnsafeMainNet,
AddrIdxScanLen: defaultAddrIdxScanLen,
StakePoolColdExtKey: defaultStakePoolColdExtKey,
AllowHighFees: defaultAllowHighFees,
}

// A config file in the current directory takes precedence.
@@ -104,7 +104,8 @@ func walletMain() error {
StakePoolColdExtKey: cfg.StakePoolColdExtKey,
}
loader := wallet.NewLoader(activeNet.Params, dbDir, stakeOptions,
cfg.AutomaticRepair, cfg.UnsafeMainNet, cfg.AddrIdxScanLen)
cfg.AutomaticRepair, cfg.UnsafeMainNet, cfg.AddrIdxScanLen,
cfg.AllowHighFees)

// Create and start HTTP server to serve wallet client connections.
// This will be updated with the wallet and chain server RPC client
@@ -2982,7 +2982,7 @@ func SendToSStx(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCClient
}
}

txSha, err := chainClient.SendRawTransaction(createdTx.MsgTx, false)
txSha, err := chainClient.SendRawTransaction(createdTx.MsgTx, w.AllowHighFees)
if err != nil {
return nil, err
}
@@ -3063,7 +3063,7 @@ func SendToSSRtx(icmd interface{}, w *wallet.Wallet, chainClient *chain.RPCClien
}
}

txSha, err := chainClient.SendRawTransaction(createdTx.MsgTx, false)
txSha, err := chainClient.SendRawTransaction(createdTx.MsgTx, w.AllowHighFees)
if err != nil {
return nil, err
}
@@ -3594,7 +3594,7 @@ func SignRawTransactions(icmd interface{}, w *wallet.Wallet, chainClient *chain.
}
sent := false
hashStr := ""
hash, err := chainClient.SendRawTransaction(msgTx, false)
hash, err := chainClient.SendRawTransaction(msgTx, w.AllowHighFees)
// If sendrawtransaction errors out (blockchain rule
// issue, etc), continue onto the next transaction.
if err == nil {
@@ -974,7 +974,9 @@ func (w *Wallet) handleWinningTickets(blockHash *chainhash.Hash,
ntfns, err := w.StakeMgr.HandleWinningTicketsNtfn(blockHash,
blockHeight,
tickets,
w.VoteBits)
w.VoteBits,
w.AllowHighFees,
)

if ntfns != nil {
// Send notifications for newly created votes by the RPC.
@@ -1009,7 +1011,7 @@ func (w *Wallet) handleMissedTickets(blockHash *chainhash.Hash,
w.StakeMiningEnabled {
ntfns, err := w.StakeMgr.HandleMissedTicketsNtfn(blockHash,
blockHeight,
tickets)
tickets, w.AllowHighFees)

if ntfns != nil {
// Send notifications for newly created revocations by the RPC.
@@ -448,7 +448,7 @@ func (w *Wallet) txToOutputs(outputs []*wire.TxOut, account uint32, minconf int3
" %v from imported account into default account.", changeAmount)
}

_, err = chainClient.SendRawTransaction(tx.Tx, false)
_, err = chainClient.SendRawTransaction(tx.Tx, w.AllowHighFees)
if err != nil {
return nil, err
}
@@ -648,7 +648,7 @@ func (w *Wallet) txToMultisig(account uint32, amount dcrutil.Amount,
return txToMultisigError(err)
}

_, err = chainClient.SendRawTransaction(msgtx, false)
_, err = chainClient.SendRawTransaction(msgtx, w.AllowHighFees)
if err != nil {
return txToMultisigError(err)
}
@@ -811,7 +811,7 @@ func (w *Wallet) compressWallet(maxNumIns int, account uint32) (*chainhash.Hash,
return nil, err
}

txSha, err := chainClient.SendRawTransaction(msgtx, false)
txSha, err := chainClient.SendRawTransaction(msgtx, w.AllowHighFees)
if err != nil {
return nil, err
}
@@ -910,7 +910,7 @@ func (w *Wallet) compressEligible(eligible []wtxmgr.Credit) error {
return err
}

txSha, err := chainClient.SendRawTransaction(msgtx, false)
txSha, err := chainClient.SendRawTransaction(msgtx, w.AllowHighFees)
if err != nil {
return err
}
@@ -1365,7 +1365,7 @@ func (w *Wallet) purchaseTicket(req purchaseTicketRequest) (interface{},
}

// Send the ticket over the network.
txSha, err := chainClient.SendRawTransaction(ticket, false)
txSha, err := chainClient.SendRawTransaction(ticket, w.AllowHighFees)
if err != nil {
return nil, err
}
@@ -53,6 +53,7 @@ type Loader struct {
autoRepair bool
unsafeMainNet bool
addrIdxScanLen int
allowHighFees bool
}

// StakeOptions contains the various options necessary for stake mining.
@@ -74,14 +75,15 @@ type StakeOptions struct {
// NewLoader constructs a Loader.
func NewLoader(chainParams *chaincfg.Params, dbDirPath string,
stakeOptions *StakeOptions, autoRepair bool, unsafeMainNet bool,
addrIdxScanLen int) *Loader {
addrIdxScanLen int, allowHighFees bool) *Loader {
return &Loader{
chainParams: chainParams,
dbDirPath: dbDirPath,
stakeOptions: stakeOptions,
autoRepair: autoRepair,
unsafeMainNet: unsafeMainNet,
addrIdxScanLen: addrIdxScanLen,
allowHighFees: allowHighFees,
}
}

@@ -155,7 +157,7 @@ func (l *Loader) CreateNewWallet(pubPassphrase, privPassphrase, seed []byte) (*W
so.BalanceToMaintain, so.AddressReuse, so.RollbackTest,
so.PruneTickets, so.TicketAddress, so.TicketMaxPrice,
so.TicketBuyFreq, so.PoolAddress, so.PoolFees, l.addrIdxScanLen,
so.StakePoolColdExtKey, l.autoRepair, l.chainParams)
so.StakePoolColdExtKey, l.autoRepair, l.allowHighFees, l.chainParams)
if err != nil {
return nil, err
}
@@ -213,7 +215,7 @@ func (l *Loader) OpenExistingWallet(pubPassphrase []byte, canConsolePrompt bool)
so.BalanceToMaintain, so.AddressReuse, so.RollbackTest,
so.PruneTickets, so.TicketAddress, so.TicketMaxPrice, so.TicketBuyFreq,
so.PoolAddress, so.PoolFees, l.addrIdxScanLen, so.StakePoolColdExtKey,
l.autoRepair, l.chainParams)
l.autoRepair, l.allowHighFees, l.chainParams)
if err != nil {
return nil, err
}
@@ -134,6 +134,7 @@ type Wallet struct {
ticketFeeIncrementLock sync.Mutex
ticketFeeIncrement dcrutil.Amount
DisallowFree bool
AllowHighFees bool

// Channels for rescan processing. Requests are added and merged with
// any waiting requests, before being sent to another goroutine to
@@ -188,7 +189,7 @@ func newWallet(vb uint16, esm bool, btm dcrutil.Amount, addressReuse bool,
rollbackTest bool, ticketAddress dcrutil.Address, tmp dcrutil.Amount,
ticketBuyFreq int, poolAddress dcrutil.Address, pf float64,
addrIdxScanLen int, stakePoolColdAddrs map[string]struct{},
autoRepair bool, mgr *waddrmgr.Manager, txs *wtxmgr.Store,
autoRepair, AllowHighFees bool, mgr *waddrmgr.Manager, txs *wtxmgr.Store,
smgr *wstakemgr.StakeStore, db *walletdb.DB,
params *chaincfg.Params) *Wallet {
var rollbackBlockDB map[uint32]*wtxmgr.DatabaseContents
@@ -222,6 +223,7 @@ func newWallet(vb uint16, esm bool, btm dcrutil.Amount, addressReuse bool,
lockedOutpoints: map[wire.OutPoint]struct{}{},
relayFee: feeIncrement,
ticketFeeIncrement: ticketFeeIncrement,
AllowHighFees: AllowHighFees,
rescanAddJob: make(chan *RescanJob),
rescanBatch: make(chan *rescanBatch),
rescanNotifications: make(chan interface{}),
@@ -331,7 +333,9 @@ func (w *Wallet) SetGenerate(flag bool) error {
w.CurrentVotingInfo.BlockHash,
w.CurrentVotingInfo.BlockHeight,
w.CurrentVotingInfo.Tickets,
w.VoteBits)
w.VoteBits,
w.AllowHighFees,
)
if err != nil {
return err
}
@@ -2339,7 +2343,7 @@ func (w *Wallet) ResendUnminedTxs() {
return
}
for _, tx := range txs {
resp, err := chainClient.SendRawTransaction(tx, false)
resp, err := chainClient.SendRawTransaction(tx, w.AllowHighFees)
if err != nil {
// TODO(jrick): Check error for if this tx is a double spend,
// remove it if so.
@@ -2695,7 +2699,7 @@ func (w *Wallet) PublishTransaction(tx *wire.MsgTx) error {
return err
}

_, err = server.SendRawTransaction(tx, false)
_, err = server.SendRawTransaction(tx, w.AllowHighFees)
return err
}

@@ -2835,7 +2839,7 @@ func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
addressReuse bool, rollbackTest bool, pruneTickets bool, ticketAddress string,
ticketMaxPrice float64, ticketBuyFreq int, poolAddress string,
poolFees float64, addrIdxScanLen int, stakePoolColdExtKey string,
autoRepair bool, params *chaincfg.Params) (*Wallet, error) {
autoRepair, allowHighFees bool, params *chaincfg.Params) (*Wallet, error) {
addrMgrNS, err := db.Namespace(waddrmgrNamespaceKey)
if err != nil {
return nil, err
@@ -2928,6 +2932,7 @@ func Open(db walletdb.DB, pubPass []byte, cbs *waddrmgr.OpenCallbacks,
addrIdxScanLen,
stakePoolColdAddrs,
autoRepair,
allowHighFees,
addrMgr,
txMgr,
smgr,
@@ -122,7 +122,7 @@ func createWallet(cfg *config) error {
TicketMaxPrice: cfg.TicketMaxPrice,
}
loader := wallet.NewLoader(activeNet.Params, dbDir, stakeOptions,
cfg.AutomaticRepair, cfg.UnsafeMainNet, cfg.AddrIdxScanLen)
cfg.AutomaticRepair, cfg.UnsafeMainNet, cfg.AddrIdxScanLen, cfg.AllowHighFees)

// When there is a legacy keystore, open it now to ensure any errors
// don't end up exiting the process after the user has spent time
@@ -644,15 +644,15 @@ func (s *StakeStore) getSSGens(sstxHash *chainhash.Hash) ([]*ssgenRecord, error)
// SendRawTransaction sends a raw transaction using the chainSvr.
// TODO Shouldn't this be locked? Eventually import the mutex lock
// from wallet maybe.
func (s *StakeStore) SendRawTransaction(msgTx *wire.MsgTx) (*chainhash.Hash,
func (s *StakeStore) SendRawTransaction(msgTx *wire.MsgTx, allowHighFees bool) (*chainhash.Hash,
error) {
if s.isClosed {
str := "stake store is closed"
return nil, stakeStoreError(ErrStoreClosed, str, nil)
}

if s.chainSvr != nil {
return s.chainSvr.SendRawTransaction(msgTx, false)
return s.chainSvr.SendRawTransaction(msgTx, allowHighFees)
}

return nil, fmt.Errorf("cannot sendrawtranscation, client not " +
@@ -763,7 +763,7 @@ func (s *StakeStore) SignVRTransaction(msgTx *wire.MsgTx, sstx *dcrutil.Tx,
// GenerateVote creates a new SSGen given a header hash, height, sstx
// tx hash, and votebits.
func (s *StakeStore) generateVote(blockHash *chainhash.Hash, height int64,
sstxHash *chainhash.Hash, defaultVoteBits uint16) (*StakeNotification, error) {
sstxHash *chainhash.Hash, defaultVoteBits uint16, allowHighFees bool) (*StakeNotification, error) {
// 1. Fetch the SStx, then calculate all the values we'll need later for
// the generation of the SSGen tx outputs.
sstxRecord, err := s.getSStx(sstxHash)
@@ -890,7 +890,7 @@ func (s *StakeStore) generateVote(blockHash *chainhash.Hash, height int64,
}

// Send the transaction.
ssgenSha, err := s.chainSvr.SendRawTransaction(msgTx, false)
ssgenSha, err := s.chainSvr.SendRawTransaction(msgTx, allowHighFees)
if err != nil {
return nil, err
}
@@ -981,7 +981,7 @@ func (s *StakeStore) getSSRtxs(sstxHash *chainhash.Hash) ([]*ssrtxRecord, error)
// submits it by SendRawTransaction. It also stores a record of it
// in the local database.
func (s *StakeStore) generateRevocation(blockHash *chainhash.Hash, height int64,
sstxHash *chainhash.Hash) (*StakeNotification, error) {
sstxHash *chainhash.Hash, allowHighFees bool) (*StakeNotification, error) {
var revocationFee int64
switch {
case s.Params == &chaincfg.MainNetParams:
@@ -1079,7 +1079,7 @@ func (s *StakeStore) generateRevocation(blockHash *chainhash.Hash, height int64,
}

// Send the transaction.
ssrtxSha, err := s.chainSvr.SendRawTransaction(msgTx, false)
ssrtxSha, err := s.chainSvr.SendRawTransaction(msgTx, allowHighFees)
if err != nil {
return nil, err
}
@@ -1107,7 +1107,8 @@ func (s *StakeStore) generateRevocation(blockHash *chainhash.Hash, height int64,
func (s StakeStore) HandleWinningTicketsNtfn(blockHash *chainhash.Hash,
blockHeight int64,
tickets []*chainhash.Hash,
defaultVoteBits uint16) ([]*StakeNotification, error) {
defaultVoteBits uint16,
allowHighFees bool) ([]*StakeNotification, error) {
if s.isClosed {
str := "stake store is closed"
return nil, stakeStoreError(ErrStoreClosed, str, nil)
@@ -1138,7 +1139,7 @@ func (s StakeStore) HandleWinningTicketsNtfn(blockHash *chainhash.Hash,
// Matching tickets (yay!), generate some SSGen.
for i, ticket := range ticketsToPull {
ntfns[i], voteErrors[i] = s.generateVote(blockHash, blockHeight, ticket,
defaultVoteBits)
defaultVoteBits, allowHighFees)
}

errStr := ""
@@ -1163,7 +1164,8 @@ func (s StakeStore) HandleWinningTicketsNtfn(blockHash *chainhash.Hash,
// SSRtx.
func (s StakeStore) HandleMissedTicketsNtfn(blockHash *chainhash.Hash,
blockHeight int64,
tickets []*chainhash.Hash) ([]*StakeNotification, error) {
tickets []*chainhash.Hash,
allowHighFees bool) ([]*StakeNotification, error) {
if s.isClosed {
str := "stake store is closed"
return nil, stakeStoreError(ErrStoreClosed, str, nil)
@@ -1194,7 +1196,7 @@ func (s StakeStore) HandleMissedTicketsNtfn(blockHash *chainhash.Hash,
// Matching tickets, generate some SSRtx.
for i, ticket := range ticketsToPull {
ntfns[i], revocationErrors[i] = s.generateRevocation(blockHash,
blockHeight, ticket)
blockHeight, ticket, allowHighFees)
}

errStr := ""

0 comments on commit ec2c1c2

Please sign in to comment.
You can’t perform that action at this time.