Browse Source

Merge pull request #370 from LN-Zap/feature/channel-details

Feature/channel details
renovate/lint-staged-8.x
JimmyMow 7 years ago
committed by GitHub
parent
commit
1a01feb453
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .travis.yml
  2. 102
      app/components/Contacts/Network.js
  3. 120
      app/components/Contacts/Network.scss
  4. 80
      app/lnd/config/rpc.proto
  5. 80
      app/lnd/lib/rpc.proto
  6. 9
      app/lnd/methods/channelController.js
  7. 4
      app/main.dev.js
  8. 20
      app/reducers/channels.js
  9. 10
      app/routes/app/containers/AppContainer.js
  10. 80
      app/rpc.proto
  11. 5
      test/reducers/__snapshots__/channels.spec.js.snap

2
.travis.yml

@ -37,4 +37,4 @@ before_script:
- sleep 3
script:
- "yarn $TEST"
- "travis_wait 30 yarn $TEST"

102
app/components/Contacts/Network.js

@ -7,6 +7,8 @@ import { btc } from 'utils'
import plus from 'icons/plus.svg'
import search from 'icons/search.svg'
import Value from 'components/Value'
import styles from './Network.scss'
class Network extends Component {
@ -24,11 +26,13 @@ class Network extends Component {
searchQuery,
filterPulldown,
filter,
loadingChannelPubkeys
// closingChannelIds
selectedChannel,
loadingChannelPubkeys,
closingChannelIds
},
currentChannels,
balance,
ticker,
currentTicker,
nodes,
@ -42,7 +46,9 @@ class Network extends Component {
updateChannelSearchQuery,
openContactModal
setSelectedChannel,
closeChannel
} = this.props
@ -73,6 +79,21 @@ class Network extends Component {
}, 1000)
}
// when the user clicks the action to close the channel
const removeClicked = (channel) => {
closeChannel({ channel_point: channel.channel_point, chan_id: channel.chan_id, force: !channel.active })
}
// when a user clicks a channel
const channelClicked = (channel) => {
// selectedChannel === channel ? setSelectedChannel(null) : setSelectedChannel(channel)
if (selectedChannel === channel) {
setSelectedChannel(null)
} else {
setSelectedChannel(channel)
}
}
const displayNodeName = (channel) => {
const node = find(nodes, n => channel.remote_pubkey === n.pub_key)
@ -88,9 +109,13 @@ class Network extends Component {
// if the channel has a closing tx that means it's closing
if (Object.prototype.hasOwnProperty.call(channel, 'closing_txid')) { return 'closing' }
// if we are in the process of closing this channel
if (closingChannelIds.includes(channel.chan_id)) { return 'closing' }
// if the channel isn't active that means the remote peer isn't online
if (!channel.active) { return 'offline' }
// if all of the above conditionals fail we can assume the node is online :)
return 'online'
}
@ -166,12 +191,73 @@ class Network extends Component {
{
currentChannels.length > 0 && currentChannels.map((channelObj, index) => {
const channel = Object.prototype.hasOwnProperty.call(channelObj, 'channel') ? channelObj.channel : channelObj
const pubkey = channel.remote_node_pub || channel.remote_pubkey
return (
<li key={index} className={styles.channel} onClick={() => openContactModal(channelObj)}>
<span>{displayNodeName(channel)}</span>
<span className={`${styles[channelStatus(channelObj)]} hint--left`} data-hint={channelStatus(channelObj)}>
<li
key={index}
className={`${styles.channel} ${selectedChannel === channel && styles.selectedChannel}`}
onClick={() => channelClicked(channel)}
>
<section className={styles.channelTitle}>
<span className={`${styles[channelStatus(channelObj)]} hint--right`} data-hint={channelStatus(channelObj)}>
{
closingChannelIds.includes(channel.chan_id) ?
<span className={styles.loading}>
<i className={`${styles.spinner} ${styles.closing}`} />
</span>
:
<FaCircle />
}
</span>
<span>{displayNodeName(channel)}</span>
{
selectedChannel === channel && <span><FaAngleDown /></span>
}
</section>
<section className={styles.channelDetails}>
<header>
<h4>{`${pubkey.substring(0, 30)}...`}</h4>
</header>
<div className={styles.limits}>
<section>
<h5>Pay Limit</h5>
<p>
<Value
value={channel.local_balance}
currency={ticker.currency}
currentTicker={currentTicker}
/>
<i> {ticker.currency.toUpperCase()}</i>
</p>
</section>
<section>
<h5>Request Limit</h5>
<p>
<Value
value={channel.remote_balance}
currency={ticker.currency}
currentTicker={currentTicker}
/>
<i>{ticker.currency.toUpperCase()}</i>
</p>
</section>
</div>
<div className={styles.actions}>
<section onClick={() => removeClicked(channel)}>
{
closingChannelIds.includes(channel.chan_id) ?
<span className={`${styles.loading} hint--left`} data-hint='closing'>
<i>Closing</i> <i className={`${styles.spinner} ${styles.closing}`} />
</span>
:
<div>Disconnect</div>
}
</section>
</div>
</section>
</li>
)
})
@ -205,13 +291,15 @@ Network.propTypes = {
channels: PropTypes.object.isRequired,
balance: PropTypes.object.isRequired,
currentTicker: PropTypes.object.isRequired,
ticker: PropTypes.object.isRequired,
fetchChannels: PropTypes.func.isRequired,
openContactsForm: PropTypes.func.isRequired,
toggleFilterPulldown: PropTypes.func.isRequired,
changeFilter: PropTypes.func.isRequired,
updateChannelSearchQuery: PropTypes.func.isRequired,
openContactModal: PropTypes.func.isRequired
setSelectedChannel: PropTypes.func.isRequired,
closeChannel: PropTypes.func.isRequired
}
export default Network

120
app/components/Contacts/Network.scss

@ -48,7 +48,7 @@
}
.channels {
padding: 20px 0px 20px 20px;
padding: 20px 0px 20px 0px;
overflow-y: auto;
.listHeader {
@ -57,7 +57,7 @@
flex-direction: row;
justify-content: space-between;
align-items: baseline;
padding-right: 20px;
padding: 0 20px;
h2, h2 span {
color: $white;
@ -119,18 +119,55 @@
}
.channel {
display: flex;
flex-direction: row;
justify-content: space-between;
color: $white;
padding: 10px 20px 10px 0px;
padding: 10px 0px 10px 0px;
margin: 10px 0;
cursor: pointer;
&:hover {
background: #272B37;
}
&.selectedChannel {
background: #272B37;
padding-bottom: 0;
.channelDetails {
max-height: 500px;
}
}
span:nth-child(1) {
font-size: 12px;
}
.channelTitle {
display: flex;
flex-direction: row;
align-items: center;
padding: 0 20px;
span {
&:nth-child(2) {
margin-left: 10px;
font-size: 12px;
font-weight: 300;
letter-spacing: 0.6px;
line-height: 17px;
}
&:nth-child(3) {
margin-left: auto;
svg {
width: 15px;
height: 15px;
opacity: 0.5;
}
}
}
}
.online {
color: $green;
}
@ -209,6 +246,11 @@
-o-animation: animation-rotate 1000ms linear infinite;
animation: animation-rotate 1000ms linear infinite;
display: inline-block;
&.closing {
border: 1px solid rgba(255, 85, 106, 0.1);
border-left-color: rgba(255, 85, 106, 0.4);
}
}
@-webkit-keyframes animation-rotate {
@ -234,3 +276,69 @@
transform: rotate(360deg);
}
}
.channelDetails {
overflow-y: hidden;
max-height: 0;
transition: all 0.25s;
h4 {
color: $white;
opacity: 0.5;
font-size: 9px;
margin-top: 10px;
overflow-x: hidden;
padding: 0 20px;
letter-spacing: 1.1px;
}
.limits {
display: flex;
flex-direction: row;
justify-content: space-around;
border-top: 0.5px solid #1A1C23;
margin-top: 10px;
padding: 20px;
h5 {
font-size: 12px;
color: $white;
margin-bottom: 10px;
font-weight: 600;
}
p {
color: $white;
opacity: 0.5;
font-size: 8px;
text-align: center;
}
}
.actions {
text-align: center;
font-size: 12px;
color: #FF7686;
section {
padding: 20px 0;
border-top: 0.5px solid #1A1C23;
div {
transition: all 0.25s;
&:hover {
opacity: 0.5;
}
}
}
.loading i {
vertical-align: top;
&:nth-child(1) {
margin-right: 5px;
}
}
}
}

80
app/lnd/config/rpc.proto

@ -44,7 +44,7 @@ service WalletUnlocker {
};
}
/** lncli: `init`
/**
InitWallet is used when lnd is starting up for the first time to fully
initialize the daemon and its internal wallet. At the very least a wallet
password must be provided. This will be used to encrypt sensitive material
@ -145,8 +145,7 @@ service Lightning {
/** lncli: `walletbalance`
WalletBalance returns total unspent outputs(confirmed and unconfirmed), all
confirmed unspent outputs and all unconfirmed unspent outputs under control
by the wallet. This method can be modified by having the request specify
only witness outputs should be factored into the final output sum.
of the wallet.
*/
rpc WalletBalance (WalletBalanceRequest) returns (WalletBalanceResponse) {
option (google.api.http) = {
@ -531,6 +530,25 @@ service Lightning {
body: "*"
};
}
/** lncli: `fwdinghistory`
ForwardingHistory allows the caller to query the htlcswitch for a record of
all HTLC's forwarded within the target time range, and integer offset
within that time range. If no time-range is specified, then the first chunk
of the past 24 hrs of forwarding history are returned.
A list of forwarding events are returned. The size of each forwarding event
is 40 bytes, and the max message size able to be returned in gRPC is 4 MiB.
As a result each message can only contain 50k entries. Each response has
the index offset of the last entry. The index offset can be provided to the
request to allow the caller to skip a series of records.
*/
rpc ForwardingHistory(ForwardingHistoryRequest) returns (ForwardingHistoryResponse) {
option (google.api.http) = {
post: "/v1/switch"
body: "*"
};
};
}
message Transaction {
@ -662,7 +680,6 @@ message NewAddressRequest {
enum AddressType {
WITNESS_PUBKEY_HASH = 0;
NESTED_PUBKEY_HASH = 1;
PUBKEY_HASH = 2;
}
/// The address type
@ -1080,8 +1097,6 @@ message PendingChannelsResponse {
}
message WalletBalanceRequest {
/// If only witness outputs should be considered when calculating the wallet's balance
bool witness_only = 1;
}
message WalletBalanceResponse {
/// The balance of the wallet
@ -1488,6 +1503,15 @@ message ChannelFeeReport {
message FeeReportResponse {
/// An array of channel fee reports which describes the current fee schedule for each channel.
repeated ChannelFeeReport channel_fees = 1 [json_name = "channel_fees"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 24 hrs.
uint64 day_fee_sum = 2 [json_name = "day_fee_sum"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 1 week.
uint64 week_fee_sum = 3 [json_name = "week_fee_sum"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 1 month.
uint64 month_fee_sum = 4 [json_name = "month_fee_sum"];
}
message PolicyUpdateRequest {
@ -1510,3 +1534,47 @@ message PolicyUpdateRequest {
}
message PolicyUpdateResponse {
}
message ForwardingHistoryRequest {
/// Start time is the starting point of the forwarding history request. All records beyond this point will be included, respecting the end time, and the index offset.
uint64 start_time = 1 [json_name = "start_time"];
/// End time is the end point of the forwarding history request. The response will carry at most 50k records between the start time and the end time. The index offset can be used to implement pagination.
uint64 end_time = 2 [json_name = "end_time"];
/// Index offset is the offset in the time series to start at. As each response can only contain 50k records, callers can use this to skip around within a packed time series.
uint32 index_offset = 3 [json_name = "index_offset"];
/// The max number of events to return in the response to this query.
uint32 num_max_events = 4 [json_name = "num_max_events"];
}
message ForwardingEvent {
/// Timestamp is the time (unix epoch offset) that this circuit was completed.
uint64 timestamp = 1 [json_name = "timestamp"];
/// The incoming channel ID that carried the HTLC that created the circuit.
uint64 chan_id_in = 2 [json_name = "chan_id_in"];
/// The outgoing channel ID that carried the preimage that completed the circuit.
uint64 chan_id_out = 4 [json_name = "chan_id_out"];
/// The total amount of the incoming HTLC that created half the circuit.
uint64 amt_in = 5 [json_name = "amt_in"];
/// The total amount of the outgoign HTLC that created the second half of the circuit.
uint64 amt_out = 6 [json_name = "amt_out"];
/// The total fee that this payment circuit carried.
uint64 fee = 7 [json_name = "fee"];
// TODO(roasbeef): add settlement latency?
// * use FPE on the chan id?
// * also list failures?
}
message ForwardingHistoryResponse {
/// A list of forwarding events from the time slice of the time series specified in the request.
repeated ForwardingEvent forwarding_events = 1 [json_name = "forwarding_events"];
/// The index of the last time in the set of returned forwarding events. Can be used to seek further, pagination style.
uint32 last_offset_index = 2 [json_name = "last_offset_index"];
}

80
app/lnd/lib/rpc.proto

@ -44,7 +44,7 @@ service WalletUnlocker {
};
}
/** lncli: `init`
/**
InitWallet is used when lnd is starting up for the first time to fully
initialize the daemon and its internal wallet. At the very least a wallet
password must be provided. This will be used to encrypt sensitive material
@ -145,8 +145,7 @@ service Lightning {
/** lncli: `walletbalance`
WalletBalance returns total unspent outputs(confirmed and unconfirmed), all
confirmed unspent outputs and all unconfirmed unspent outputs under control
by the wallet. This method can be modified by having the request specify
only witness outputs should be factored into the final output sum.
of the wallet.
*/
rpc WalletBalance (WalletBalanceRequest) returns (WalletBalanceResponse) {
option (google.api.http) = {
@ -531,6 +530,25 @@ service Lightning {
body: "*"
};
}
/** lncli: `fwdinghistory`
ForwardingHistory allows the caller to query the htlcswitch for a record of
all HTLC's forwarded within the target time range, and integer offset
within that time range. If no time-range is specified, then the first chunk
of the past 24 hrs of forwarding history are returned.
A list of forwarding events are returned. The size of each forwarding event
is 40 bytes, and the max message size able to be returned in gRPC is 4 MiB.
As a result each message can only contain 50k entries. Each response has
the index offset of the last entry. The index offset can be provided to the
request to allow the caller to skip a series of records.
*/
rpc ForwardingHistory(ForwardingHistoryRequest) returns (ForwardingHistoryResponse) {
option (google.api.http) = {
post: "/v1/switch"
body: "*"
};
};
}
message Transaction {
@ -662,7 +680,6 @@ message NewAddressRequest {
enum AddressType {
WITNESS_PUBKEY_HASH = 0;
NESTED_PUBKEY_HASH = 1;
PUBKEY_HASH = 2;
}
/// The address type
@ -1080,8 +1097,6 @@ message PendingChannelsResponse {
}
message WalletBalanceRequest {
/// If only witness outputs should be considered when calculating the wallet's balance
bool witness_only = 1;
}
message WalletBalanceResponse {
/// The balance of the wallet
@ -1488,6 +1503,15 @@ message ChannelFeeReport {
message FeeReportResponse {
/// An array of channel fee reports which describes the current fee schedule for each channel.
repeated ChannelFeeReport channel_fees = 1 [json_name = "channel_fees"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 24 hrs.
uint64 day_fee_sum = 2 [json_name = "day_fee_sum"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 1 week.
uint64 week_fee_sum = 3 [json_name = "week_fee_sum"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 1 month.
uint64 month_fee_sum = 4 [json_name = "month_fee_sum"];
}
message PolicyUpdateRequest {
@ -1510,3 +1534,47 @@ message PolicyUpdateRequest {
}
message PolicyUpdateResponse {
}
message ForwardingHistoryRequest {
/// Start time is the starting point of the forwarding history request. All records beyond this point will be included, respecting the end time, and the index offset.
uint64 start_time = 1 [json_name = "start_time"];
/// End time is the end point of the forwarding history request. The response will carry at most 50k records between the start time and the end time. The index offset can be used to implement pagination.
uint64 end_time = 2 [json_name = "end_time"];
/// Index offset is the offset in the time series to start at. As each response can only contain 50k records, callers can use this to skip around within a packed time series.
uint32 index_offset = 3 [json_name = "index_offset"];
/// The max number of events to return in the response to this query.
uint32 num_max_events = 4 [json_name = "num_max_events"];
}
message ForwardingEvent {
/// Timestamp is the time (unix epoch offset) that this circuit was completed.
uint64 timestamp = 1 [json_name = "timestamp"];
/// The incoming channel ID that carried the HTLC that created the circuit.
uint64 chan_id_in = 2 [json_name = "chan_id_in"];
/// The outgoing channel ID that carried the preimage that completed the circuit.
uint64 chan_id_out = 4 [json_name = "chan_id_out"];
/// The total amount of the incoming HTLC that created half the circuit.
uint64 amt_in = 5 [json_name = "amt_in"];
/// The total amount of the outgoign HTLC that created the second half of the circuit.
uint64 amt_out = 6 [json_name = "amt_out"];
/// The total fee that this payment circuit carried.
uint64 fee = 7 [json_name = "fee"];
// TODO(roasbeef): add settlement latency?
// * use FPE on the chan id?
// * also list failures?
}
message ForwardingHistoryResponse {
/// A list of forwarding events from the time slice of the time series specified in the request.
repeated ForwardingEvent forwarding_events = 1 [json_name = "forwarding_events"];
/// The index of the last time in the set of returned forwarding events. Can be used to seek further, pagination style.
uint32 last_offset_index = 2 [json_name = "last_offset_index"];
}

9
app/lnd/methods/channelController.js

@ -103,12 +103,13 @@ export function listChannels(lnd, meta) {
* @return {[type]} [description]
*/
export function closeChannel(lnd, meta, event, payload) {
const { chan_id, force } = payload
const tx = payload.channel_point.funding_txid.match(/.{2}/g).reverse().join('')
const { channel_point: { funding_txid, output_index }, chan_id, force } = payload
const tx = funding_txid.match(/.{2}/g).reverse().join('')
const res = {
channel_point: {
funding_txid: Buffer.from(tx, 'hex'),
output_index: Number(payload.channel_point.output_index)
funding_txid_bytes: Buffer.from(tx, 'hex'),
output_index: Number(output_index)
},
force
}

4
app/main.dev.js

@ -164,9 +164,7 @@ const startLnd = (alias, autopilot) => {
'--bitcoin.active',
'--bitcoin.testnet',
'--bitcoin.node=neutrino',
'--neutrino.connect=188.166.148.62:18333',
'--neutrino.addpeer=btcd.jackmallers.com:18333',
'--neutrino.addpeer=159.65.48.139:18333',
'--neutrino.connect=188.166.148.62',
'--neutrino.connect=127.0.0.1:18333',
'--debuglevel=debug',
`${autopilot ? '--autopilot.active' : ''}`,

20
app/reducers/channels.js

@ -38,6 +38,8 @@ export const REMOVE_ClOSING_CHAN_ID = 'REMOVE_ClOSING_CHAN_ID'
export const OPEN_CONTACT_MODAL = 'OPEN_CONTACT_MODAL'
export const CLOSE_CONTACT_MODAL = 'CLOSE_CONTACT_MODAL'
export const SET_SELECTED_CHANNEL = 'SET_SELECTED_CHANNEL'
// ------------------------------------
// Actions
// ------------------------------------
@ -141,6 +143,13 @@ export function closeContactModal() {
}
}
export function setSelectedChannel(selectedChannel) {
return {
type: SET_SELECTED_CHANNEL,
selectedChannel
}
}
// Send IPC event for peers
export const fetchChannels = () => async (dispatch) => {
dispatch(getChannels())
@ -206,8 +215,7 @@ export const closeChannel = ({ channel_point, chan_id, force }) => (dispatch) =>
funding_txid,
output_index
},
force,
chan_id
force
}
}
)
@ -334,7 +342,9 @@ const ACTION_HANDLERS = {
),
[OPEN_CONTACT_MODAL]: (state, { channel }) => ({ ...state, contactModal: { isOpen: true, channel } }),
[CLOSE_CONTACT_MODAL]: state => ({ ...state, contactModal: { isOpen: false, channel: null } })
[CLOSE_CONTACT_MODAL]: state => ({ ...state, contactModal: { isOpen: false, channel: null } }),
[SET_SELECTED_CHANNEL]: (state, { selectedChannel }) => ({ ...state, selectedChannel })
}
const channelsSelectors = {}
@ -522,7 +532,9 @@ const initialState = {
contactModal: {
isOpen: false,
channel: null
}
},
selectedChannel: null
}
export default function channelsReducer(state = initialState, action) {

10
app/routes/app/containers/AppContainer.js

@ -34,8 +34,8 @@ import {
toggleFilterPulldown,
changeFilter,
updateChannelSearchQuery,
openContactModal,
closeContactModal
closeContactModal,
setSelectedChannel
} from 'reducers/channels'
import {
@ -110,8 +110,8 @@ const mapDispatchToProps = {
toggleFilterPulldown,
changeFilter,
updateChannelSearchQuery,
openContactModal,
closeContactModal,
setSelectedChannel,
openContactsForm,
closeContactsForm,
@ -302,6 +302,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
contactsform: stateProps.contactsform,
nodes: stateProps.network.nodes,
nonActiveFilters: stateProps.nonActiveFilters,
ticker: stateProps.ticker,
fetchChannels: dispatchProps.fetchChannels,
openContactsForm: dispatchProps.openContactsForm,
@ -310,7 +311,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => {
toggleFilterPulldown: dispatchProps.toggleFilterPulldown,
changeFilter: dispatchProps.changeFilter,
updateChannelSearchQuery: dispatchProps.updateChannelSearchQuery,
openContactModal: dispatchProps.openContactModal
setSelectedChannel: dispatchProps.setSelectedChannel,
closeChannel: dispatchProps.closeChannel
}
const contactsFormProps = {

80
app/rpc.proto

@ -44,7 +44,7 @@ service WalletUnlocker {
};
}
/** lncli: `init`
/**
InitWallet is used when lnd is starting up for the first time to fully
initialize the daemon and its internal wallet. At the very least a wallet
password must be provided. This will be used to encrypt sensitive material
@ -145,8 +145,7 @@ service Lightning {
/** lncli: `walletbalance`
WalletBalance returns total unspent outputs(confirmed and unconfirmed), all
confirmed unspent outputs and all unconfirmed unspent outputs under control
by the wallet. This method can be modified by having the request specify
only witness outputs should be factored into the final output sum.
of the wallet.
*/
rpc WalletBalance (WalletBalanceRequest) returns (WalletBalanceResponse) {
option (google.api.http) = {
@ -531,6 +530,25 @@ service Lightning {
body: "*"
};
}
/** lncli: `fwdinghistory`
ForwardingHistory allows the caller to query the htlcswitch for a record of
all HTLC's forwarded within the target time range, and integer offset
within that time range. If no time-range is specified, then the first chunk
of the past 24 hrs of forwarding history are returned.
A list of forwarding events are returned. The size of each forwarding event
is 40 bytes, and the max message size able to be returned in gRPC is 4 MiB.
As a result each message can only contain 50k entries. Each response has
the index offset of the last entry. The index offset can be provided to the
request to allow the caller to skip a series of records.
*/
rpc ForwardingHistory(ForwardingHistoryRequest) returns (ForwardingHistoryResponse) {
option (google.api.http) = {
post: "/v1/switch"
body: "*"
};
};
}
message Transaction {
@ -662,7 +680,6 @@ message NewAddressRequest {
enum AddressType {
WITNESS_PUBKEY_HASH = 0;
NESTED_PUBKEY_HASH = 1;
PUBKEY_HASH = 2;
}
/// The address type
@ -1080,8 +1097,6 @@ message PendingChannelsResponse {
}
message WalletBalanceRequest {
/// If only witness outputs should be considered when calculating the wallet's balance
bool witness_only = 1;
}
message WalletBalanceResponse {
/// The balance of the wallet
@ -1488,6 +1503,15 @@ message ChannelFeeReport {
message FeeReportResponse {
/// An array of channel fee reports which describes the current fee schedule for each channel.
repeated ChannelFeeReport channel_fees = 1 [json_name = "channel_fees"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 24 hrs.
uint64 day_fee_sum = 2 [json_name = "day_fee_sum"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 1 week.
uint64 week_fee_sum = 3 [json_name = "week_fee_sum"];
/// The total amount of fee revenue (in satoshis) the switch has collected over the past 1 month.
uint64 month_fee_sum = 4 [json_name = "month_fee_sum"];
}
message PolicyUpdateRequest {
@ -1510,3 +1534,47 @@ message PolicyUpdateRequest {
}
message PolicyUpdateResponse {
}
message ForwardingHistoryRequest {
/// Start time is the starting point of the forwarding history request. All records beyond this point will be included, respecting the end time, and the index offset.
uint64 start_time = 1 [json_name = "start_time"];
/// End time is the end point of the forwarding history request. The response will carry at most 50k records between the start time and the end time. The index offset can be used to implement pagination.
uint64 end_time = 2 [json_name = "end_time"];
/// Index offset is the offset in the time series to start at. As each response can only contain 50k records, callers can use this to skip around within a packed time series.
uint32 index_offset = 3 [json_name = "index_offset"];
/// The max number of events to return in the response to this query.
uint32 num_max_events = 4 [json_name = "num_max_events"];
}
message ForwardingEvent {
/// Timestamp is the time (unix epoch offset) that this circuit was completed.
uint64 timestamp = 1 [json_name = "timestamp"];
/// The incoming channel ID that carried the HTLC that created the circuit.
uint64 chan_id_in = 2 [json_name = "chan_id_in"];
/// The outgoing channel ID that carried the preimage that completed the circuit.
uint64 chan_id_out = 4 [json_name = "chan_id_out"];
/// The total amount of the incoming HTLC that created half the circuit.
uint64 amt_in = 5 [json_name = "amt_in"];
/// The total amount of the outgoign HTLC that created the second half of the circuit.
uint64 amt_out = 6 [json_name = "amt_out"];
/// The total fee that this payment circuit carried.
uint64 fee = 7 [json_name = "fee"];
// TODO(roasbeef): add settlement latency?
// * use FPE on the chan id?
// * also list failures?
}
message ForwardingHistoryResponse {
/// A list of forwarding events from the time slice of the time series specified in the request.
repeated ForwardingEvent forwarding_events = 1 [json_name = "forwarding_events"];
/// The index of the last time in the set of returned forwarding events. Can be used to seek further, pagination style.
uint32 last_offset_index = 2 [json_name = "last_offset_index"];
}

5
test/reducers/__snapshots__/channels.spec.js.snap

@ -53,6 +53,7 @@ Object {
"total_limbo_balance": "",
},
"searchQuery": "",
"selectedChannel": null,
"viewType": 0,
}
`;
@ -110,6 +111,7 @@ Object {
"total_limbo_balance": "",
},
"searchQuery": "",
"selectedChannel": null,
"viewType": 0,
}
`;
@ -168,6 +170,7 @@ Object {
4,
],
"searchQuery": "",
"selectedChannel": null,
"viewType": 0,
}
`;
@ -225,6 +228,7 @@ Object {
"total_limbo_balance": "",
},
"searchQuery": "",
"selectedChannel": null,
"viewType": 0,
}
`;
@ -282,6 +286,7 @@ Object {
"total_limbo_balance": "",
},
"searchQuery": "",
"selectedChannel": null,
"viewType": 0,
}
`;

Loading…
Cancel
Save