def create_minting_reward_pages(minting_rewards, html_output_directory, height, supernode_name): for minting_reward in minting_rewards: with open( f'{html_output_directory}/{minting_reward.minting_reward_id}.html', "w") as f: f.write("<html>") f.write(''' <style> table { border-collapse: collapse; } table, th, td { border: 1px solid black; } td { padding: 10px; } .monospace { font-family: "Courier New", Courier, monospace; } td.monospace { text-align: right; } </style> ''') f.write("<body>") f.write( f'<h1><a href="../index.html">{supernode_name}</a> Minting Reward Report</h1>' ) f.write( f'<p>Page Updated: <span class="monospace">{UTC_NOW}</span></p>' ) f.write( f'<p>Current Block Height: <span class="monospace">{height}</span></p>' ) f.write( f'<h2>Minting Reward <span class="monospace">{minting_reward.minting_reward_id}</span></h2>' ) f.write( f'<p>Block Height: <span class="monospace">{minting_reward.height}</span></p>' ) f.write( f'<p>Timestamp: <span class="monospace">{datetime.fromtimestamp(minting_reward.timestamp/1000000000)} ({minting_reward.timestamp})</span></p>' ) f.write( f'<p>Amount: <span class="monospace">{format_as_vsys(minting_reward.amount)}</span></p>' ) f.write( f'<p>Operation Fee: <span class="monospace">{format_as_vsys(minting_reward.operation_fee)}</span></p>' ) f.write( f'<p>Interest: <span class="monospace">{format_as_vsys(minting_reward.interest)}</span></p>' ) f.write(f'<h3>Leases</h3>') f.write('<table>') f.write(''' <tr> <th>Lease ID</th> <th>Address</th> <th>Start Height</th> <th>Stop Height</th> <th>Amount</th> <th>Interest</th> </tr> ''') leases = sorted(minting_reward.leases, key=lambda x: x.address) for lease in leases: f.write(''' <tr> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> </tr> '''.format( lease.lease_id, f'<a href="../address_report/{lease.address}.html">{lease.address}</a.', lease.start_height, lease.stop_height, format_as_vsys(lease.amount), format_as_vsys(minting_reward.interest_for_lease(lease)), )) f.write('</table>') f.write('</body></html>')
def create_address_audit_pages(addresses, html_output_directory, height, supernode_name): for address in addresses: with open(f'{html_output_directory}/{address.address}.html', "w") as f: f.write("<html>") f.write(''' <style> table { border-collapse: collapse; } table, th, td { border: 1px solid black; } td { padding: 10px; } .monospace { font-family: "Courier New", Courier, monospace; } td.monospace { text-align: right; } </style> ''') f.write("<body>") f.write( f'<h1><a href="../index.html">{supernode_name}</a> Address Audit Report</h1>' ) f.write( f'<p>Page Updated: <span class="monospace">{UTC_NOW}</span></p>' ) f.write( f'<p>Current Block Height: <span class="monospace">{height}</span></p>' ) f.write( f'<h2>Address Audit <span class="monospace">{address.address}</span></h2>' ) f.write( f'<p>Total Interest: <span class="monospace">{format_as_vsys(address.total_interest)}</span></p>' ) f.write( f'<p>Total Pool Distribution: <span class="monospace">{format_as_vsys(address.total_pool_distribution)}</span></p>' ) f.write( f'<p>Interest Owed: <span class="monospace">{format_as_vsys(address.total_interest_owed())}</span></p>' ) f.write( f'<p><a href="../address_report/{address.address}.html">Address Report</a></p>' ) # An ordered (by height) list of combined minting rewards and pool distributions events = list(address.minting_rewards()) + list( address.pool_distributions()) events = sorted(events, key=lambda x: x.height) f.write('<table>') f.write(''' <tr> <th>Event</th> <th>Height</th> <th>Amount</th> <th>Balance</th> </tr> ''') balance = 0 for event in events: if isinstance(event, MintingReward): amount = event.interest_for_address(address) balance += amount f.write(''' <tr> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> </tr> '''.format( "Interest", f'<a href="../minting_reward_report/{event.minting_reward_id}.html">{event.height}</a>', format_as_vsys(amount), format_as_vsys(balance), )) else: amount = -1 * (event.amount + event.fee) balance += amount f.write(''' <tr> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> </tr> '''.format( "Distribution", event.height, format_as_vsys(amount), format_as_vsys(balance), )) f.write('</table>') f.write('</body></html>')
def create_address_pages(addresses, html_output_directory, height, supernode_name): for address in addresses: with open(f'{html_output_directory}/{address.address}.html', "w") as f: f.write("<html>") f.write(''' <style> table { border-collapse: collapse; } table, th, td { border: 1px solid black; } td { padding: 10px; } .monospace { font-family: "Courier New", Courier, monospace; } td.monospace { text-align: right; } </style> ''') f.write("<body>") f.write(f'<h1><a href="../index.html">{supernode_name}</a> Address Report</h1>') f.write(f'<p>Page Updated: <span class="monospace">{UTC_NOW}</span></p>') f.write(f'<p>Current Block Height: <span class="monospace">{height}</span></p>') f.write(f'<h2>Address <span class="monospace">{address.address}</span></h2>') f.write(f'<p>Total Interest: <span class="monospace">{format_as_vsys(address.total_interest)}</span></p>') f.write(f'<p>Total Pool Distribution: <span class="monospace">{format_as_vsys(address.total_pool_distribution)}</span></p>') f.write(f'<p>Interest Owed: <span class="monospace">{format_as_vsys(address.total_interest_owed())}</span></p>') f.write(f'<p><a href="../address_audit_report/{address.address}.html">Address Audit Report</a></p>') f.write(f'<h3>Leases</h3>') f.write('<table>') f.write( ''' <tr> <th>Lease ID</th> <th>Start Height</th> <th>Stop Height</th> <th>Amount</th> <th>Total Interest</th> </tr> ''' ) for lease in address.leases(): f.write(''' <tr> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> </tr> '''.format( lease.lease_id, lease.start_height, lease.stop_height, format_as_vsys(lease.amount), format_as_vsys(lease.total_interest), ) ) f.write('</table>') f.write(f'<h3>Pool Distributions</h3>') f.write('<table>') f.write( ''' <tr> <th>Pool Distribution ID</th> <th>Height</th> <th>Amount</th> <th>Fee</th> </tr> ''' ) for pool_distribution in address.pool_distributions(): f.write( ''' <tr> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> </tr> '''.format( pool_distribution.pool_distribution_id, pool_distribution.height, format_as_vsys(pool_distribution.amount), format_as_vsys(pool_distribution.fee), ) ) f.write('</table>') f.write('</body></html>')
def create_index_page(factory, html_output_directory, height, supernode_name): with open(f'{html_output_directory}/index.html', 'w') as f: f.write('<html>') f.write( ''' <style> table { border-collapse: collapse; } table, th, td { border: 1px solid black; } td { padding: 10px; } .monospace { font-family: "Courier New", Courier, monospace; } td.monospace { text-align: right; } </style> ''' ) f.write('<body>') f.write(f'<h1><a href="../index.html">{supernode_name}</a> Address Report</h1>') f.write(f'<p>Page Updated: <span class="monospace">{UTC_NOW}</span></p>') f.write(f'<p>Current Block Height: <span class="monospace">{height}</span></p>') f.write('<h2>Addresses</h2>') f.write(f'<p>Total Interest: <span class="monospace">{format_as_vsys(factory.total_interest)}</span></p>') f.write(f'<p>Total Operation Fee: <span class="monospace">{format_as_vsys(factory.total_operation_fee)}</span></p>') f.write(f'<p>Total Pool Distribution: <span class="monospace">{format_as_vsys(factory.total_pool_distribution)}</span></p>') f.write(f'<p>Total Interest Owed: <span class="monospace">{format_as_vsys(factory.total_interest-factory.total_pool_distribution)}</span></p>') f.write('<table>') f.write( ''' <tr> <th>Address</th> <th>Total Interest</th> <th>Total Pool Distribution</th> <th>Total Interest Owed</th></tr> ''') for address in sorted(factory.get_addresses(), key=lambda x: x.address): f.write( ''' <tr> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> </tr> '''.format( f'<a href="{address.address}.html">{address.address}</a>', format_as_vsys(address.total_interest), format_as_vsys(address.total_pool_distribution), format_as_vsys(address.total_interest_owed()), ) ) f.write('</table>') f.write("</body></html>")
f.write("<table>") f.write( ''' <tr> <th>Name</th> <th>Address</th> <th>Slot ID</th> <th>MAB</th> </tr> ''' ) for slot in slots: f.write(''' <tr> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> <td class="monospace">{}</td> </tr> '''.format( SUPERNODE_NAMES.get(slot["address"], "UNKNOWN"), slot["address"], slot["slotId"], format_as_vsys(slot["mintingAverageBalance"]), ) ) f.write("</table>") f.write("</body></html>")
def test_format_as_vsys(): assert format_as_vsys(100000000) == '1.00000000' assert format_as_vsys(703) == '0.00000703' assert format_as_vsys(4747) == '0.00004747' assert format_as_vsys(123456789) == '1.23456789' assert format_as_vsys(-123456789) == '-1.23456789'