Skip to content

Commit

Permalink
feat: Adding TX Information
Browse files Browse the repository at this point in the history
Adding the ability to see the transactions within a block
  • Loading branch information
praetoriansentry committed Aug 14, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 5ed3e49 commit 9cc454f
Showing 4 changed files with 104 additions and 32 deletions.
43 changes: 39 additions & 4 deletions README.org
Original file line number Diff line number Diff line change
@@ -278,7 +278,7 @@ polycli loadtest --verbosity 700 --chain-id 1256 --concurrency 1 --requests 50 -

* Monitor

[[file:assets/monitor.png]]
[[file:assets/polycli-monitor.gif]]

This is a basic tool for monitoring block production on a local RPC
end point.
@@ -320,21 +320,56 @@ useViper: true
#+end_src


* Reference
* Testing with Geth

Local geth testing
While working on some of the Polygon CLI tools, we'll run geth in dev
mode in order to make sure the various functions work properly. First,
we'll startup geth.

#+begin_src shell
./build/bin/geth --dev --dev.period 2 --http --http.addr localhost --http.port 8545 --http.api eth,web3,personal,net --verbosity 5
#+end_src

Sending some value to the default load testing account
In the logs, we'll see a line that says IPC endpoint opened:

#+begin_example
INFO [08-14|16:09:31.451] Starting peer-to-peer node instance=Geth/v1.10.21-stable-67109427/darwin-arm64/go1.18.1
WARN [08-14|16:09:31.451] P2P server will be useless, neither dialing nor listening
DEBUG[08-14|16:09:31.452] IPCs registered namespaces=admin,debug,web3,eth,txpool,personal,clique,miner,net,engine
INFO [08-14|16:09:31.452] IPC endpoint opened url=/var/folders/zs/k8swqskj1t79cgnjh6yt0fqm0000gn/T/geth.ipc
INFO [08-14|16:09:31.452] Generated ephemeral JWT secret secret=0xdfa5c30e07ef1041d15a2dbf0865386305330128b792d4a461cddb9bf38e416e
#+end_example

I'll usually then use that line to attach

#+begin_src shell
./build/bin/geth attach /var/folders/zs/k8swqskj1t79cgnjh6yt0fqm0000gn/T/geth.ip
#+end_src

After attaching to geth, we can fund the default load testing account
with some currency.

#+begin_src shell
eth.coinbase==eth.accounts[0]
eth.sendTransaction({from: eth.coinbase, to: "0x85da99c8a7c2c95964c8efd687e95e632fc533d6", value: web3.toWei(5000, "ether")})
#+end_src

Then we can generate some load to make sure that there are some blocks
with transactions being created. ~1337~ is the chain id that's used in
local geth.

#+begin_src shell
polycli loadtest --verbosity 700 --chain-id 1337 --concurrency 1 --requests 1000 --rate-limit 5 --mode c http://127.0.0.1:8545
#+end_src

Then we can monitor the chain:

* Reference


Sending some value to the default load testing account


Listening for re-orgs

#+begin_src shell
Binary file added assets/polycli-monitor.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 14 additions & 27 deletions cmd/monitor.go
Original file line number Diff line number Diff line change
@@ -257,16 +257,17 @@ func renderMonitorUI(ms *monitorStatus) error {

b0 := widgets.NewParagraph()
b0.Title = "Block Headers"
b0.Text = "Foo"
b0.Text = "Use the arrow keys to scroll through the transactions. Press <Esc> to go back to the explorer view"

b1 := widgets.NewList()
b1.Title = "Block Info"
b1.TextStyle = ui.NewStyle(ui.ColorYellow)
b1.WrapText = false

b2 := widgets.NewParagraph()
b2 := widgets.NewList()
b2.Title = "Transactions"
b2.Text = "Foooo"
b2.TextStyle = ui.NewStyle(ui.ColorGreen)
b2.WrapText = true

blockGrid.Set(
ui.NewRow(1.0/10, b0),
@@ -309,6 +310,7 @@ func renderMonitorUI(ms *monitorStatus) error {
} else if currentMode == monitorModeBlock {
// render a block
b1.Rows = metrics.GetSimpleBlockFields(selectedBlock)
b2.Rows = metrics.GetSimpleBlockTxFields(selectedBlock, ms.ChainID)

ui.Clear()
ui.Render(blockGrid)
@@ -362,29 +364,6 @@ func renderMonitorUI(ms *monitorStatus) error {
ui.Render(grid)
}

listDraw := func() {
l := widgets.NewList()
l.Title = "List"
l.Rows = []string{
"[0] github.com/gizak/termui/v3",
"[1] [你好,世界](fg:blue)",
"[2] [こんにちは世界](fg:red)",
"[3] [color](fg:white,bg:green) output",
"[4] output.go",
"[5] random_out.go",
"[6] dashboard.go",
"[7] foo",
"[8] bar",
"[9] baz",
}
l.TextStyle = ui.NewStyle(ui.ColorYellow)
l.WrapText = false
l.SetRect(0, 0, 25, 8)

ui.Render(l)

}

currentBn := ms.HeadBlock
uiEvents := ui.PollEvents()
ticker := time.NewTicker(time.Second).C
@@ -408,7 +387,6 @@ func renderMonitorUI(ms *monitorStatus) error {
if selectedBlockIdx != nil {
currentMode = monitorModeBlock
}
_ = listDraw
redraw(ms)
break
case "<Resize>":
@@ -419,6 +397,15 @@ func renderMonitorUI(ms *monitorStatus) error {
redraw(ms)
break
case "<Up>", "<Down>", "<Left>", "<Right>":
if currentMode == monitorModeBlock {
if e.ID == "<Down>" {
b2.ScrollDown()
} else if e.ID == "<Up>" {
b2.ScrollUp()
}
redraw(ms)
break
}
if selectedBlockIdx == nil {
currIdx = 1
selectedBlockIdx = &currIdx
52 changes: 51 additions & 1 deletion metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -201,7 +201,7 @@ func GetSimpleBlockFields(block *ethtypes.Block) []string {
fmt.Sprintf("Gas used: %d", block.GasUsed()),
fmt.Sprintf("Gas limit: %d", block.GasLimit()),
fmt.Sprintf("Base Fee: %s", block.BaseFee()),
fmt.Sprintf("Extra data: %s", string(block.Extra())),
fmt.Sprintf("Extra data: %s", RawDataToASCII(block.Extra())),
fmt.Sprintf("Hash: %s", block.Hash()),
fmt.Sprintf("Parent Hash: %s", block.ParentHash()),
fmt.Sprintf("Uncle Hash: %s", block.UncleHash()),
@@ -210,6 +210,44 @@ func GetSimpleBlockFields(block *ethtypes.Block) []string {
fmt.Sprintf("Nonce: %d", block.Nonce()),
}
}
func GetSimpleBlockTxFields(block *ethtypes.Block, chainID *big.Int) []string {
fields := make([]string, 0)
blank := ""
for _, tx := range block.Transactions() {
txFields := GetSimpleTxFields(tx, chainID, block.BaseFee())
fields = append(fields, blank)
fields = append(fields, txFields...)
}
return fields
}
func GetSimpleTxFields(tx *ethtypes.Transaction, chainID, baseFee *big.Int) []string {
fields := make([]string, 0)
msg, err := tx.AsMessage(ethtypes.NewEIP155Signer(chainID), baseFee)

fields = append(fields, fmt.Sprintf("Tx Hash: %s", tx.Hash()))

txMethod := "Transfer"
if tx.To() == nil {
// Contract deployment
txMethod = "Contract Deployment"
} else if len(tx.Data()) > 4 {
// Contract call
txMethod = hex.EncodeToString(tx.Data()[0:4])
}

fields = append(fields, fmt.Sprintf("To: %s", tx.To()))
if err == nil {
fields = append(fields, fmt.Sprintf("From: %s", msg.From()))
}
fields = append(fields, fmt.Sprintf("Method: %s", txMethod))
fields = append(fields, fmt.Sprintf("Value: %s", tx.Value()))
fields = append(fields, fmt.Sprintf("Gas: %d", tx.Gas()))
fields = append(fields, fmt.Sprintf("Gas Price: %s", tx.GasPrice()))
fields = append(fields, fmt.Sprintf("Nonce: %d", tx.Nonce()))
fields = append(fields, fmt.Sprintf("Data: %s", hex.EncodeToString(tx.Data())))

return fields
}

func ecrecover(header *ethtypes.Header) ([]byte, error) {
signature := header.Extra[len(header.Extra)-ethcrypto.SignatureLength:]
@@ -221,3 +259,15 @@ func ecrecover(header *ethtypes.Header) ([]byte, error) {

return signer, nil
}

func RawDataToASCII(data []byte) string {
retString := ""
for _, b := range data {
if b >= 32 && b < 127 {
retString = retString + string(b)
} else {
retString = retString + fmt.Sprintf("\\x%X", b)
}
}
return retString
}

0 comments on commit 9cc454f

Please sign in to comment.