You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2021/06/30 22:00:46 UTC

[incubator-tuweni] branch main updated: Add node info page

This is an automated email from the ASF dual-hosted git repository.

toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git


The following commit(s) were added to refs/heads/main by this push:
     new 1494bcb  Add node info page
     new 1743346  Merge pull request #298 from atoulme/add_node_info_page
1494bcb is described below

commit 1494bcb6220218fcecb3fa54b15c3da342855563
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Wed Jun 30 23:04:15 2021 +0200

    Add node info page
---
 .../tuweni/eth/crawler/RelationalPeerRepository.kt | 29 ++++++++++++++++++++++
 .../apache/tuweni/eth/crawler/rest/PeersService.kt | 15 +++++++++++
 eth-crawler/src/main/resources/webapp/index.html   | 24 ++++++++++--------
 eth-crawler/src/main/resources/webapp/node.html    | 19 +++++++++++++-
 eth-crawler/src/main/resources/webapp/node.js      | 25 ++++++++++++++++++-
 5 files changed, 99 insertions(+), 13 deletions(-)

diff --git a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt
index eecf7ab..76e1ea7 100644
--- a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt
+++ b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/RelationalPeerRepository.kt
@@ -280,6 +280,35 @@ open class RelationalPeerRepository(
       }
     }
   }
+
+  internal fun getPeerWithInfo(infoCollected: Long, publicKey: String): PeerConnectionInfoDetails? {
+    dataSource.connection.use { conn ->
+      var query = "select distinct nodeinfo.createdAt, nodeinfo.publickey, nodeinfo.p2pversion, nodeinfo.clientId, nodeinfo.capabilities, nodeinfo.genesisHash, nodeinfo.besthash, nodeinfo.totalDifficulty from nodeinfo " +
+        "  inner join (select identity, max(createdAt) as maxCreatedAt from nodeinfo group by identity) maxSeen " +
+        "  on nodeinfo.identity = maxSeen.identity and nodeinfo.createdAt = maxSeen.maxCreatedAt where createdAt < ? and nodeinfo.publickey = ? order by nodeInfo.createdAt desc"
+      val stmt =
+        conn.prepareStatement(query)
+      stmt.use {
+        it.setTimestamp(1, Timestamp(infoCollected))
+        it.setBytes(2, Bytes.fromHexString(publicKey).toArrayUnsafe())
+        // map results.
+        val rs = stmt.executeQuery()
+        if (rs.next()) {
+          val createdAt = rs.getTimestamp(1).toInstant().toEpochMilli()
+          val pubkey = SECP256K1.PublicKey.fromBytes(Bytes.wrap(rs.getBytes(2)))
+          val p2pVersion = rs.getInt(3)
+          val clientId = rs.getString(4) ?: ""
+          val capabilities = rs.getString(5) ?: ""
+          val genesisHash = rs.getString(6) ?: ""
+          val bestHash = rs.getString(7) ?: ""
+          val totalDifficulty = rs.getString(8) ?: ""
+          return PeerConnectionInfoDetails(createdAt, pubkey, p2pVersion, clientId, capabilities, genesisHash, bestHash, totalDifficulty)
+        } else {
+          return null
+        }
+      }
+    }
+  }
 }
 internal data class ClientReadyStats(val total: Int, val ready: Int)
 internal data class ClientInfo(val clientId: String, val count: Int)
diff --git a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/PeersService.kt b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/PeersService.kt
index fecfe2f..9f79b6b 100644
--- a/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/PeersService.kt
+++ b/eth-crawler/src/main/kotlin/org/apache/tuweni/eth/crawler/rest/PeersService.kt
@@ -23,9 +23,11 @@ import org.apache.tuweni.eth.crawler.RelationalPeerRepository
 import javax.servlet.ServletContext
 import javax.ws.rs.GET
 import javax.ws.rs.Path
+import javax.ws.rs.PathParam
 import javax.ws.rs.Produces
 import javax.ws.rs.QueryParam
 import javax.ws.rs.core.MediaType
+import javax.ws.rs.core.Response
 
 @Path("peers")
 class PeersService {
@@ -53,4 +55,17 @@ class PeersService {
       mapper.writeValueAsString(peers)
     }
   }
+
+  @GET
+  @Produces(MediaType.APPLICATION_JSON)
+  @Path("/{publickey}")
+  fun getPeers(@PathParam("publickey") publicKey: String): Response {
+    val repo = context!!.getAttribute("repo") as RelationalPeerRepository
+    val peer = repo.getPeerWithInfo(System.currentTimeMillis(), publicKey)
+    if (peer != null) {
+      return Response.ok(mapper.writeValueAsString(peer)).build()
+    } else {
+      return Response.status(Response.Status.NOT_FOUND).build()
+    }
+  }
 }
diff --git a/eth-crawler/src/main/resources/webapp/index.html b/eth-crawler/src/main/resources/webapp/index.html
index d73ed4c..424b4c3 100644
--- a/eth-crawler/src/main/resources/webapp/index.html
+++ b/eth-crawler/src/main/resources/webapp/index.html
@@ -116,17 +116,19 @@ specific language governing permissions and limitations under the License.
                 </table>
             </div>
 
-            <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
-                <h1>Check my peer</h1>
-                <p>Enter your enode or public key to check if we know about your peer.</p>
-                <form method="get" action="/node.html">
-                    <div class="form-group">
-                        <label for="publickey">Enode or public key</label>
-                        <input type="text" class="form-control" id="publickey" placeholder="0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef">
-                    </div>
-                    <button type="submit" class="btn btn-primary">Check</button>
-                </form>
-            </div>
+                <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
+                    <h1 class="h2">Check my peer</h1>
+                    <p>Enter your enode or public key to check if we know about your peer.</p>
+                </div>
+                <div class="w-50">
+                    <form method="get" action="/node.html">
+                        <div class="form-group">
+                            <label for="publickey">Enode or public key</label>
+                            <input type="text" class="form-control" id="publickey" name="publickey" placeholder="0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef">
+                        </div>
+                        <button type="submit" class="btn btn-primary">Check</button>
+                    </form>
+                </div>
 
         </main>
     </div>
diff --git a/eth-crawler/src/main/resources/webapp/node.html b/eth-crawler/src/main/resources/webapp/node.html
index 243be18..4a7bdf1 100644
--- a/eth-crawler/src/main/resources/webapp/node.html
+++ b/eth-crawler/src/main/resources/webapp/node.html
@@ -41,7 +41,24 @@ specific language governing permissions and limitations under the License.
 <div class="container-fluid">
     <div class="row">
 
-        <main role="main" class="col-md-12 ml-sm-auto col-lg-12 px-md-4">
+        <main role="main" class="col-md-12 ml-sm-auto col-lg-12 px-md-4" id="app">
+            <div v-if="waiting">
+                <h1>⏳</h1>
+            </div>
+            <div v-else>
+                <div v-if="publickey == null || publickey == ''">
+                    <p>TODO do something if no public key is passed in.</p>
+                </div>
+                <div v-else>
+                    <div v-if="peerInfo == null">
+                        <p>We don't know this peer - TODO work on offering to add peer.</p>
+                    </div>
+                    <div v-else>
+                        {{ peerInfo }}
+                    </div>
+                </div>
+            </div>
+
             <pre><code>TODO
 
             Add dialog to provide a validation error message back if enode passed in as query parameter is invalid.
diff --git a/eth-crawler/src/main/resources/webapp/node.js b/eth-crawler/src/main/resources/webapp/node.js
index 97063da..5251602 100644
--- a/eth-crawler/src/main/resources/webapp/node.js
+++ b/eth-crawler/src/main/resources/webapp/node.js
@@ -9,4 +9,27 @@ http://www.apache.org/licenses/LICENSE-2.0
 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 specific language governing permissions and limitations under the License.
- */
\ No newline at end of file
+ */
+new Vue({
+    el: '#app',
+    data () {
+        return {
+            waiting: true,
+            publickey: null,
+            peerInfo: null
+        }
+    },
+    mounted () {
+
+        let urlParams = new URLSearchParams(window.location.search);
+        this.publickey = urlParams.get('publickey');
+        axios.get('/rest/peers/' + this.publickey)
+            .then(response => {
+            this.peerInfo = response.data;
+            this.waiting = false;
+        }).catch(err => {
+            console.log(err);
+            this.waiting = false;
+        });
+    }
+})
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org