Skip to content

Commit

Permalink
app: Add relay fee setting (#152)
Browse files Browse the repository at this point in the history
* app: Add relay fee setting

Add a relay fee to settings and allow changing. The fee is not yet used.

Save the relay fee with the account. Allow changing of the relay fee in
Account settings as apposed to App settings. Change relay fee input
field to radio buttons with labels low, default, and high. Set
appropriate values for low (4000) and high (114000).

* Add AccoutManager method setRelayFee.
  • Loading branch information
JoeGruffins authored Apr 22, 2020
1 parent 368dd09 commit 87fea26
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 3 deletions.
6 changes: 5 additions & 1 deletion decred/decred/dcr/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from decred import DecredError
from decred.crypto import crypto, opcode
from decred.dcr import addrlib
from decred.dcr.txscript import DefaultRelayFeePerKb
from decred.util import encode, helpers
from decred.util.encode import BuildyBytes, ByteArray, unblobCheck

Expand Down Expand Up @@ -801,6 +802,7 @@ def __init__(
self.coinID = BIPID
self.netID = netID
self.netParams = nets.parse(netID)
self.relayFee = int(DefaultRelayFeePerKb)
# For external addresses, the cursor can sit on the last seen address,
# so start the lastSeen at the 0th external address. This is necessary
# because the currentAddress method grabs the address at the current
Expand Down Expand Up @@ -856,14 +858,15 @@ def blob(acct):
.addData(encode.intToBytes(acct.cursorExt, signed=True))
.addData(acct.cursorInt)
.addData(acct.gapLimit)
.addData(acct.relayFee)
.b
)

@staticmethod
def unblob(b):
"""Satisfies the encode.Blobber API"""
ver, d = encode.decodeBlob(b)
unblobCheck("Account", ver, len(d), {0: 8})
unblobCheck("Account", ver, len(d), {0: 9})

iFunc = encode.intFromBytes

Expand All @@ -876,6 +879,7 @@ def unblob(b):
acct.cursorExt = iFunc(d[5], signed=True)
acct.cursorInt = iFunc(d[6])
acct.gapLimit = iFunc(d[7])
acct.relayFee = iFunc(d[8])
return acct

@staticmethod
Expand Down
12 changes: 12 additions & 0 deletions decred/decred/wallet/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ def setNode(self, node):
for acct in self.accounts.values():
acct.setNode(node)

def setRelayFee(self, idx, fee):
"""
Save the relay fee for account at index.
Args:
idx (int): The account's index.
fee (int): The relay fee in smallest unit/kb.
"""
acct = self.accounts[idx]
acct.relayFee = fee
self.acctDB[idx] = acct

def coinKey(self, cryptoKey):
"""
Decrypt the coin-type extended key.
Expand Down
95 changes: 93 additions & 2 deletions tinywallet/tinywallet/screens.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from decred.crypto import crypto
from decred.dcr import constants as DCR, nets
from decred.dcr.blockchain import LocalNode
from decred.dcr.txscript import DefaultRelayFeePerKb
from decred.dcr.vsp import VotingServiceProvider
from decred.util import chains, database, helpers
from decred.wallet.wallet import Wallet
Expand Down Expand Up @@ -475,7 +476,9 @@ def __init__(self, acctMgr, acct, assetScreen):
self.canGoHome = False
self.ticketStats = None
self.balance = None
self.settingsScreen = AccountSettingsScreen(self.saveName)
self.settingsScreen = AccountSettingsScreen(
self.account.relayFee, self.saveName, self.setRelayFee
)
self.stakeScreen = StakingScreen(acct)
self.wgt.setFixedSize(
TinyDialog.maxWidth * 0.9,
Expand Down Expand Up @@ -716,6 +719,15 @@ def saveName(self, newName):
self.assetScreen.doButtons()
app.home()

def setRelayFee(self, relayFee):
"""
Changes and saves the relayFee of the account.
Args:
int: The new relayFee.
"""
self.acctMgr.setRelayFee(self.account.idx, relayFee)

def stackAndSync(self):
"""
Start syncing the account.
Expand Down Expand Up @@ -1832,7 +1844,7 @@ class AccountSettingsScreen(Screen):
Account settings screen.
"""

def __init__(self, saveName):
def __init__(self, relayFee, saveName, setRelayFee):
"""
Args:
saveName (function): A callback function to be called after the user
Expand All @@ -1846,6 +1858,7 @@ def __init__(self, saveName):
TinyDialog.maxHeight * 0.9 - TinyDialog.topMenuHeight,
)
self.saveName = saveName
self.setRelayFee = setRelayFee

gear = SVGWidget("gear", h=20)
lbl = Q.makeLabel("Account Settings", 22)
Expand All @@ -1854,6 +1867,11 @@ def __init__(self, saveName):

self.layout.addStretch(1)

def insertSpace():
spacer = Q.makeLabel("", 5)
spacer.setContentsMargins(0, 5, 0, 0)
grid.addWidget(spacer, row, 0, 1, 4)

# ACCOUNT NAME

wgt, grid = Q.makeWidget(QtWidgets.QWidget, Q.GRID)
Expand All @@ -1869,8 +1887,67 @@ def __init__(self, saveName):
bttn.clicked.connect(self.nameChangeClicked)
grid.addWidget(bttn, row, 1)

# RELAY FEE

# Set string constants.
self.lowStr = "low"
self.defaultStr = "default"
self.highStr = "high"

# Set values that are considered low, default, and high.
self.feeRates = {
self.lowStr: 4000,
self.defaultStr: int(DefaultRelayFeePerKb),
self.highStr: 50000,
}
self.feeLvl = ""

# Find the current level. Warn if the current level isn't one of the
# three.
for k, v in self.feeRates.items():
if v == relayFee:
self.feeLvl = k
break
else:
log.warn(f"non standard relay fee set: {relayFee}")

# Helper to check the current value.
def setChecked(btn):
if self.feeLvl == btn.text():
btn.setChecked(True)

row += 1
insertSpace()
row += 1
lbl = Q.makeLabel("Relay Fee", 14, Q.ALIGN_LEFT)
grid.addWidget(lbl, row, 0)
self.feeLbl = lbl = Q.makeLabel("", 14, Q.ALIGN_LEFT)
self.setFeeLbl(relayFee)
grid.addWidget(lbl, row, 1)
row += 1
btn1 = QtWidgets.QRadioButton(self.lowStr)
Q.setProperties(btn1, fontFamily="Roboto", fontSize=14)
setChecked(btn1)
btn1.toggled.connect(lambda: self.relayFeeChangeClicked(self.lowStr))
btn2 = QtWidgets.QRadioButton(self.defaultStr)
Q.setProperties(btn2, fontFamily="Roboto", fontSize=14)
setChecked(btn2)
btn2.toggled.connect(lambda: self.relayFeeChangeClicked(self.defaultStr))
btn3 = QtWidgets.QRadioButton(self.highStr)
Q.setProperties(btn3, fontFamily="Roboto", fontSize=14)
setChecked(btn3)
btn3.toggled.connect(lambda: self.relayFeeChangeClicked(self.highStr))
wgt, _ = Q.makeRow(btn1, btn2, btn3)
grid.addWidget(wgt, row, 0, 1, -1)

self.layout.addStretch(1)

def setFeeLbl(self, fee):
"""
Set the displayed fee as atoms/byte.
"""
self.feeLbl.setText(f"{fee//1000} atoms/byte")

def nameChangeClicked(self, e):
"""
Qt slot for nameField.clicked signal.
Expand All @@ -1882,6 +1959,20 @@ def nameChangeClicked(self, e):
self.nameField.setText("")
self.saveName(newName)

def relayFeeChangeClicked(self, feeLvl):
"""
Qt slot connected to relay fee radio button clicked signal. Changes the
relay fee to feeLvl.
"""
if self.feeLvl == feeLvl:
return
self.feeLvl = feeLvl
fee = self.feeRates[feeLvl]
self.setRelayFee(fee)
self.setFeeLbl(fee)
log.info(f"relay fee changed to {fee} atoms/kb")
app.appWindow.showSuccess(f"using {feeLvl} fees")


class NewAccountScreen(Screen):
"""
Expand Down

0 comments on commit 87fea26

Please sign in to comment.