Latest commit to hand off to AR

This commit is contained in:
philip-morlier 2021-10-01 13:32:19 -07:00
parent 7de75e788b
commit e407ce3343
No known key found for this signature in database
GPG Key ID: 0323A143B7B6F663
84 changed files with 1810 additions and 1096 deletions

View File

@ -0,0 +1,54 @@
.. _RPC_method:
===========
RPC Methods
===========
GetAPIs
*******
For **RPC Methods** a Get APIs method is required in the body of the plugin in order to make the plugin available. The bulk of the implementation will be in the MyService struct. MyService should be a struct which includes two public functions.
.. code-block:: Go
type MyService struct {
backend core.Backend
stack core.Node
}
func GetAPIs(stack core.Node, backend core.Backend) []core.API {
return []core.API{
{
Namespace: "plugeth",
Version: "1.0",
Service: &MyService{backend, stack},
Public: true,
},
}
}
RPC Method
**********
(**accurate heading?**)
For RPC calls, a function should have a ``context.Context`` object as the first argument, followed by an arbitrary number of JSON marshallable arguments, and return either a single JSON marshal object, or a JSON marshallable object and an error. The RPC framework will take care of decoding inputs to this function and encoding outputs, and if the error is non-nil it will serve an error response.
A simple implimentation would look like so:
**eventual link to documentation for hello or some other rpc plugin**
.. code-block:: Go
func (h *MyService) HelloWorld(ctx context.Context) string {
return "Hello World"
}
.. Note:: For plugins such as RPC Methods whcih impliment a
GetAPIs function, an **Initialize Node** function may not be necesary as the ``core.Node`` and ``core.Backend`` will be made available with GetAPIs.
Access
******
As with pre-built plugins, a``.so`` will need to be built from``main.go`` and moved into ``~/.ethereum/plugins``. Geth will need to be started with with a ``http.api=mymamespace`` flag. Additionally you will need to include a ``--http`` flag in order to access the standard json rpc methods.
The plugin can now be accessed with an rpc call to ``mynamespace_helloWorld``.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,178 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>RPC Methods &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Subscription" href="subscription.html" />
<link rel="prev" title="Building a Custom Plugin" href="custom.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Plugeth
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption"><span class="caption-text">Overview</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="project.html">Project Design</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="custom.html">Building a Custom Plugin</a><ul class="current">
<li class="toctree-l2 current"><a class="current reference internal" href="#">RPC Methods</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#getapis">GetAPIs</a></li>
<li class="toctree-l3"><a class="reference internal" href="#id1">RPC Method</a></li>
<li class="toctree-l3"><a class="reference internal" href="#access">Access</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="subscription.html">Subscription</a></li>
<li class="toctree-l2"><a class="reference internal" href="tracer.html">Tracer</a></li>
<li class="toctree-l2"><a class="reference internal" href="custom.html#basic-implementation">Basic Implementation</a></li>
<li class="toctree-l2"><a class="reference internal" href="custom.html#specialization">Specialization</a></li>
</ul>
</li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="contact.html">Get in touch with us</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Plugeth</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li><a href="custom.html">Building a Custom Plugin</a> &raquo;</li>
<li>RPC Methods</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/RPC_method.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="rpc-methods">
<span id="rpc-method"></span><h1>RPC Methods<a class="headerlink" href="#rpc-methods" title="Permalink to this headline"></a></h1>
<div class="section" id="getapis">
<h2>GetAPIs<a class="headerlink" href="#getapis" title="Permalink to this headline"></a></h2>
<p>For <strong>RPC Methods</strong> a Get APIs method is required in the body of the plugin in order to make the plugin available. The bulk of the implementation will be in the MyService struct. MyService should be a struct which includes two public functions.</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">type</span> <span class="nx">MyService</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="nx">backend</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Backend</span>
<span class="nx">stack</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Node</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nx">GetAPIs</span><span class="p">(</span><span class="nx">stack</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Node</span><span class="p">,</span> <span class="nx">backend</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Backend</span><span class="p">)</span> <span class="p">[]</span><span class="nx">core</span><span class="p">.</span><span class="nx">API</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">[]</span><span class="nx">core</span><span class="p">.</span><span class="nx">API</span><span class="p">{</span>
<span class="p">{</span>
<span class="nx">Namespace</span><span class="p">:</span> <span class="s">&quot;plugeth&quot;</span><span class="p">,</span>
<span class="nx">Version</span><span class="p">:</span> <span class="s">&quot;1.0&quot;</span><span class="p">,</span>
<span class="nx">Service</span><span class="p">:</span> <span class="o">&amp;</span><span class="nx">MyService</span><span class="p">{</span><span class="nx">backend</span><span class="p">,</span> <span class="nx">stack</span><span class="p">},</span>
<span class="nx">Public</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="id1">
<h2>RPC Method<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h2>
<p>(<strong>accurate heading?</strong>)</p>
<p>For RPC calls, a function should have a <code class="docutils literal notranslate"><span class="pre">context.Context</span></code> object as the first argument, followed by an arbitrary number of JSON marshallable arguments, and return either a single JSON marshal object, or a JSON marshallable object and an error. The RPC framework will take care of decoding inputs to this function and encoding outputs, and if the error is non-nil it will serve an error response.</p>
<p>A simple implimentation would look like so:</p>
<p><strong>eventual link to documentation for hello or some other rpc plugin</strong></p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">func</span> <span class="p">(</span><span class="nx">h</span> <span class="o">*</span><span class="nx">MyService</span><span class="p">)</span> <span class="nx">HelloWorld</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">)</span> <span class="kt">string</span> <span class="p">{</span>
<span class="k">return</span> <span class="s">&quot;Hello World&quot;</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>For plugins such as RPC Methods whcih impliment a
GetAPIs function, an <strong>Initialize Node</strong> function may not be necesary as the <code class="docutils literal notranslate"><span class="pre">core.Node</span></code> and <code class="docutils literal notranslate"><span class="pre">core.Backend</span></code> will be made available with GetAPIs.</p>
</div>
</div>
<div class="section" id="access">
<h2>Access<a class="headerlink" href="#access" title="Permalink to this headline"></a></h2>
<p>As with pre-built plugins, a``.so`` will need to be built from``main.go`` and moved into <code class="docutils literal notranslate"><span class="pre">~/.ethereum/plugins</span></code>. Geth will need to be started with with a <code class="docutils literal notranslate"><span class="pre">http.api=mymamespace</span></code> flag. Additionally you will need to include a <code class="docutils literal notranslate"><span class="pre">--http</span></code> flag in order to access the standard json rpc methods.</p>
<p>The plugin can now be accessed with an rpc call to <code class="docutils literal notranslate"><span class="pre">mynamespace_helloWorld</span></code>.</p>
</div>
</div>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="custom.html" class="btn btn-neutral float-left" title="Building a Custom Plugin" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="subscription.html" class="btn btn-neutral float-right" title="Subscription" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Philip Morlier.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -0,0 +1,54 @@
.. _RPC_method:
===========
RPC Methods
===========
GetAPIs
*******
For **RPC Methods** a Get APIs method is required in the body of the plugin in order to make the plugin available. The bulk of the implementation will be in the MyService struct. MyService should be a struct which includes two public functions.
.. code-block:: Go
type MyService struct {
backend core.Backend
stack core.Node
}
func GetAPIs(stack core.Node, backend core.Backend) []core.API {
return []core.API{
{
Namespace: "plugeth",
Version: "1.0",
Service: &MyService{backend, stack},
Public: true,
},
}
}
RPC Method
**********
(**accurate heading?**)
For RPC calls, a function should have a ``context.Context`` object as the first argument, followed by an arbitrary number of JSON marshallable arguments, and return either a single JSON marshal object, or a JSON marshallable object and an error. The RPC framework will take care of decoding inputs to this function and encoding outputs, and if the error is non-nil it will serve an error response.
A simple implimentation would look like so:
**eventual link to documentation for hello or some other rpc plugin**
.. code-block:: Go
func (h *MyService) HelloWorld(ctx context.Context) string {
return "Hello World"
}
.. Note:: For plugins such as RPC Methods whcih impliment a
GetAPIs function, an **Initialize Node** function may not be necesary as the ``core.Node`` and ``core.Backend`` will be made available with GetAPIs.
Access
******
As with pre-built plugins, a``.so`` will need to be built from``main.go`` and moved into ``~/.ethereum/plugins``. Geth will need to be started with with a ``http.api=mymamespace`` flag. Additionally you will need to include a ``--http`` flag in order to access the standard json rpc methods.
The plugin can now be accessed with an rpc call to ``mynamespace_helloWorld``.

View File

@ -37,106 +37,6 @@ InitializeNode
* **Type:** func(core.Node, core.Backend)
* **Behavior:** This is called as soon as the Geth node is initialized. The core.Node object represents the running node with p2p and RPC capabilities, while the Backend gives you access to a wide array of data you may need to access.
Tracers
-------
* **Name:** Tracers
* **Type:** map[string]TracerResult
* **Behavior:** When calling debug.traceX functions (such as ``debug_traceCall`` and ``debug_traceTransaction``) the tracer can be specified as a key to this map and the tracer used will be the TracerResult specified here. TracerResult objects must match the interface:
.. code-block:: go
// CaptureStart is called at the start of each transaction
CaptureStart(env core.EVM, from core.Address, to core.Address, create bool, input []byte, gas uint64, value *big.Int) {}
// CaptureState is called for each opcode
CaptureState(env core.EVM, pc uint64, op core.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {}
// CaptureFault is called when an error occurs in the EVM
CaptureFault(env core.EVM, pc uint64, op core.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {}
// CaptureEnd is called at the end of each transaction
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {}
// GetResult should return a JSON serializable result object to respond to the trace call
GetResult() (interface{}, error) {}
.. warning:: Modifying the values passed into tracer functions can
alter the
results of the EVM execution in unpredictable ways. Additopackage main
import (
"github.com/openrelayxyz/plugeth-utils/core"
"gopkg.in/urfave/cli.v1"
)
var (
log core.Logger
)
type myservice struct{}
func (*myservice) Hello() string {
return "Hello world"
}
func Initialize(ctx *cli.Context, loader core.PluginLoader, logger core.Logger) {
log = logger
log.Info("Initialized hello")
}
func GetAPIs(node core.Node, backend core.Backend) []core.API {
defer log.Info("APIs Initialized")
return []core.API{
{
Namespace: "mynamespace",
Version: "1.0",
Service: &myservice{},
Public: true,
},
}
}
package main
import (
"github.com/openrelayxyz/plugeth-utils/core"
"gopkg.in/urfave/cli.v1"
)
var (
log core.Logger
)
type myservice struct{}
func (*myservice) Hello() string {
return "Hello world"
}
func Initialize(ctx *cli.Context, loader core.PluginLoader, logger core.Logger) {
log = logger
log.Info("Initialized hello")
}
func GetAPIs(node core.Node, backend core.Backend) []core.API {
defer log.Info("APIs Initialized")
return []core.API{
{
Namespace: "mynamespace",
Version: "1.0",
Service: &myservice{},
Public: true,
},
}
}
nally, some objects may be reused acress calls, so data you wish to capture should be copied rather than retianed by reference.
LiveTracer
----------
* **Name:** LiveTracers
* **Type:** core.Tracer
* **Behavior:** This tracer is used for tracing transactions as they are processed within blocks. Note that if a block does not validate, some transactions may be processed that don't end up in blocks, so be sure to check transactions against finalized blocks.
The interface for a vm.Tracer is similar to a TracerResult (above), but does not require a ``GetResult()`` function.
GetAPIs
-------

View File

@ -6,7 +6,7 @@ Build and Deploy
.. contents:: :local:
If you are ready to start building your own plugins go ahead and start `here`_
If you are ready to start building your own plugins go ahead and start here.
Setting up the environment
**************************

View File

@ -1,24 +1,36 @@
.. _custom:
========================
Building a Custom Plugin
========================
.. toctree::
:hidden:
Before setting out to build a plugin it will be helpful to be familiar with the basic :ref:`types` of plugins. Depending on what you intend to do certain aspects of implimentation will be neccisary.
In general, no matter which type of plugin you intend to build, below are common aspects which will be shared by all plugins.
RPC_method
subscription
tracer
Most Basic implimentation
=========================
Before setting out to build a plugin it will be helpful to be familiar with the :ref:`types`. deifferent plugins will require different implimentation.
Basic Implementation
====================
A plugin will need its own package located in the Plugeth-Utils packages directory. The package will need to include a main.go from which the .so file will be built. The package and main file should share the same name and the name should be a word that describes the basic functionality of the plugin.
In general, no matter which type of plugin you intend to build, all will share some common aspects.
All plugins will need to be initialized with an **initialize function**. The initialize function will need to be passed at least three arguments: a cli.Context, core.PluginLoader, and a core.Logger.
Package
-------
And so, all plugins will have an intial template that looks something like this:
Any plugin will need its own package located in the Plugeth-Plugins packages directory. The package will need to include a main.go from which the .so file will be built. The package and main file should share the same name and the name should be a word that describes the basic functionality of the plugin.
Initialize
----------
Most plugins will need to be initialized with an Initialize function. The initialize function will need to be passed at least three arguments: a cli.Context, core.PluginLoader, and a core.Logger.
And so, all plugins could have an intial template that looks something like this:
.. code-block:: Go
@ -36,11 +48,36 @@ And so, all plugins will have an intial template that looks something like this:
log.Info("loaded New Custom Plugin")
}
InitializeNode
--------------
Many plugins will make use of the InitializeNode function. Implimentation will look like so:
.. code-block:: Go
func InitializeNode(stack core.Node, b core.Backend) {
backend = b
log.Info("Initialized node and backend")
}
This is called as soon as the Geth node is initialized. The core.Node object represents the running node with p2p and RPC capabilities, while the Backend gives you access to blocks and other data you may need to access.
Specialization
==============
**Hooks**
From this point implimentation becomes more specialized to the particular plugin type. Continue from here for specific instructions for the following plugins:
Plugeth provides several hooks with which data of various kinds can be captured and manipulated. Once a plugin has been initalized it will be up to the hooks utilized to determine the behavior of the plugin.
* :ref:`RPC_method`
* :ref:`subscription`
* :ref:`tracer`
.. _blockupdates: https://github.com/openrelayxyz/plugeth-plugins/blob/master/packages/blockupdates/main.go
.. _hello: https://github.com/openrelayxyz/plugeth-plugins/blob/master/packages/hello/main.go

View File

@ -0,0 +1,7 @@
.. _hook_writing:
==================
Hook Writing Guide
==================
.. todo:: guide to writing plugin hooks

View File

@ -1,29 +1,41 @@
.. _hooks:
============
=====================
Selected Plugin Hooks
=====================
Plugin Hooks
============
The key to understanding a plugin is understanding its corresponding hook. Broadly, plugin hooks can be thought of as functions which deliver a function signiture to the **plugin loader**. The signature matches that of the function(s) called by the plugin and describes the data that is being captured and how the plugin will deliver said data upon invocation.
The public plugin hook function should follow the naming convention ``Plugin$HookName``. The first argument should be a `` core.PluginLoader``, followed by any arguments required by the functions to be provided by any plugins implementing this hook.
**Public and Private Hook Functions**
Each hook provides both a Public and private version. The private plugin hook function should bear the same name as the public plugin hook function, but with a lower case first letter. The signature should match the public plugin hook function, except that the first argument referencing the PluginLoader should be removed. It should invoke the public plugin hook function on plugins.DefaultPluginLoader. It should always verify that the DefaultPluginLoader is non-nil, log warning and return if the DefaultPluginLoader has not been initialized.
**Invocation**
the private plugin hook function should be invoked, with the appropriate arguments, in a single line within the Geth codebase inorder to minimize unexpected conflicts merging upstream Geth into plugeth.
Selected Hooks
--------------
`StateUpdate`_
************
`Invocation`_
Plugeth provides several :ref:`hooks` from which the plugin can capture data from Geth. Additionally in the case of **subcommands** the provided hooks are designed to change the behavior of Geth.
Hooks are called from functions within the plugin. For example, if we wanted to bring in data from the StateUpdate hook. We would impliment it like so:
(from `blockupdates`_)
.. code-block:: Go
func StateUpdate(blockRoot core.Hash, parentRoot core.Hash, destructs map[core.Hash]struct{}, accounts map[core.Hash][]byte, storage map[core.Hash]map[core.Hash][]byte, codeUpdates map[core.Hash][]byte) {
su := &stateUpdate{
Destructs: destructs,
Accounts: accounts,
Storage: storage,
Code: codeUpdates,
}
cache.Add(blockRoot, su)
data, _ := rlp.EncodeToBytes(su)
backend.ChainDb().Put(append([]byte("su"), blockRoot.Bytes()...), data)
}
Many hooks can be deployed in an one plugin as is the case with the **BlockUpdater** plugin.
.. contents:: :local:
StateUpdate
***********
**Function Signature**:``func(root common.Hash, parentRoot common.Hash, destructs map[common.Hash]struct{}, accounts map[common.Hash][]byte, storage map[common.Hash]map[common.Hash][]byte)``
The state update plugin provides a snapshot of the state subsystem in the form of a a stateUpdate object. The stateUpdate object contains all information transformed by a transaction but not the transaction itself.
@ -33,30 +45,75 @@ Invoked for each new block, StateUpdate provides the changes to the blockchain s
``-snapshots=true``. This is the default behavior for Geth, but if you are explicitly running with ``--snapshot=false`` this function will not be invoked.
`AppendAncient`_
AppendAncient
*************
**Function Signature**:``func(number uint64, hash, header, body, receipts, td []byte)``
Invoked when the freezer moves a block from LevelDB to the ancients database. ``number`` is the number of the block. ``hash`` is the 32 byte hash of the block as a raw ``[]byte``. ``header``, ``body``, and ``receipts`` are the RLP encoded versions of their respective block elements. ``td`` is the byte encoded total difficulty of the block.
`NewHead`_
**********
GetRPCCalls
***********
Invoked when a new block becomes the canonical latest block. Note that if several blocks are processed in a group (such as during a reorg) this may not be called for each block. You should track the prior latest head if you need to process intermediate blocks.
**Function Signature**:``func(string, string, string)``
`GetRPCCalls`_
Invoked when the RPC handler registers a method call. Returns the call ``id``, method ``name``, and any ``params`` that may have been passed in.
.. todo:: missing a couple of hooks
PreProcessBlock
***************
**Function Signature**:``func(*types.Block)``
Invoked before the transactions of a block are processed. Returns a block object.
PreProcessTransaction
*********************
**Function Signature**:``func(*types.Transaction, *types.Block, int)``
Invoked before each individual transaction of a block is processed. Returns a transaction, block, and index number.
BlockProcessingError
********************
**Function Signature**:``func(*types.Transaction, *types.Block, error)``
Invoked if an error occurs while processing a transaction. This only applies to errors that would unvalidate the block were this transaction is included not errors such as reverts or opcode errors. Returns a transaction, block, and error.
NewHead
*******
**Function Signature**:``func(*types.Block, common.Hash, []*types.Log)``
Invoked when a new block becomes the canonical latest block. Returns a block, hash, and log.
.. note:: If severtal blocks are processed in a group (such as
during a reorg) this may not be called for each block. You should track the prior latest head if you need to process intermediate blocks.
NewSideBlock
************
Invoked when the RPC handler registers a method call. returns the call ``id``, method ``name``, and any ``params`` that may have been passed in.
**Function Signature**:``func(*types.Block, common.Hash, []*types.Log)``
Invoked when a block is side-chained. Returns a block, has, and logs.
.. note:: Blocks passed to this method are non-canonical blocks.
Reorg
*****
**I am struggling all of assudden with if this is really this best course of action. Giving all of this reference, seems to beg the -utils vs plugeth conversation and I am not sure that is a smart thing to get into.**
**Function Signature**:``func(common *types.Block, oldChain, newChain types.Blocks)``
Invoked when a chain reorg occurs, that is; at least one block is removed and one block is added. (``oldChain`` is a list of removed blocks, ``newChain`` is a list of newliy added blocks, and ``common`` is the latest block that is an ancestor to both oldChain and newChain.) Returns a block, a list of old blocks, and a list of new blocks.
.. _blockupdates: https://github.com/openrelayxyz/plugeth-plugins/tree/master/packages/blockupdates
.. _StateUpdate: https://github.com/openrelayxyz/plugeth/blob/develop/core/state/plugin_hooks.go
.. _Invocation: https://github.com/openrelayxyz/plugeth/blob/develop/core/state/statedb.go#L955
.. _AppendAncient: https://github.com/openrelayxyz/plugeth/blob/develop/core/rawdb/plugin_hooks.go

View File

@ -1,18 +1,14 @@
.. Plugeth documentation master file, created by
sphinx-quickstart on Tue Sep 21 16:08:24 2021.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
=======
PluGeth
=======
PluGeth is a fork of the `Go Ethereum Client Geth`_ that implements a plugin architecture, allowing developers to extend Geth's capabilities in a number of different ways using plugins, rather than having to create additional, new forks of Geth.
PluGeth is a fork of the Go Ethereum Client, `Geth`_, that implements a plugin architecture allowing developers to extend Geth's capabilities in a number of different ways using plugins rather than having to create additional new forks.
From Here:
----------
- Ready for an overview of the project and some context? :ref:`project`
- If your goal is to run existing plugns without sourcecode: :ref:`run`
- If your goal is to run existing plugns without sourcecode: :ref:`install`
- If your goal is to build and deploy existing plugins or make custom plugins: :ref:`build`
.. warning:: Right now PluGeth is in early development. We are
@ -36,7 +32,7 @@ Table of Contents
:maxdepth: 1
:caption: Tutorials
run
install
build
custom
@ -46,10 +42,12 @@ Table of Contents
:caption: Reference
system_req
plugin_loader
plugin_hooks
core_restricted
version
api
plugin_loader
hooks
hook_writing
core_restricted
.. toctree::
:maxdepth: 1
@ -58,4 +56,5 @@ Table of Contents
contact
.. _Go Ethereum Client Geth: https://github.com/ethereum/go-ethereum
.. _Geth: https://geth.ethereum.org/

View File

@ -0,0 +1,29 @@
.. _install:
=======
Install
=======
PluGeth provides a pre-built PluGeth-Geth node as well as pre-built plugins available for download.
First download the latest PluGeth `binary release`_.
.. todo:: more language about installing download
Our curated list of plugin builds can be found `here`_
After downloading, move the .so files into the ~/.ethereum/plugins directory.
.. todo:: Build a binary release so as to provide a usable
example. Maybe a different example than hello so that there are two generic cases for which there are tutorials. -- or -- We should provide examples of the common scenerios in which geth has to be started with flags or connected to with web sockets.
.. _binary release: https://github.com/openrelayxyz/plugeth/releases
.. _here: https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley

View File

@ -1,7 +0,0 @@
.. _plugeth:
=======
PluGeth
=======
**to do: discussion on plugeth repository**

View File

@ -1,7 +0,0 @@
.. _plugin_hooks:
============
Plugin Hooks
============
.. todo:: guide to writing plugin hooks

View File

@ -4,6 +4,8 @@
Plugin Loader
=============
.. todo:: Ausitn, take a pass at flushing this out.
At the heart of the PluGeth project is the `PluginLoader`_.
Upon invocation the PluginLoader will parse through a list of known plugins and either return the plugin name passed to it or, if not found, append to that list. Additionally the loader will check the function signature of the plugin to assure complience with anticipated behavior. Once these checks are passed and the plugin name and function signature is validated the plugin will be invoked.

View File

@ -1,7 +0,0 @@
.. _plugins:
===============
PluGeth Plugins
===============
**todo: copy on plugeth plugins repo**

View File

@ -5,17 +5,18 @@ Project Design
==============
Design Goals
============
The upstream Geth client exists primarily to serve as a client for the Ethereum mainnet, though it also supports a number of popular testnets. Supporting the Ethereum mainnet is a big enough challenge in its own right that the Geth team generally avoids changes to support other networks, or to provide features only a small handful of users would be interested in.
Upstream Geth exists primarily to serve as a client for the Ethereum mainnet, though it also supports a number of popular testnets. Supporting the Ethereum mainnet is a big enough challenge in its own right that the Geth team generally avoids changes to support other networks, or to provide features only a small handful of users would be interested in.
The result is that many projects have forked Geth. Some implement their own consensus protocols or alter the behavior of the EVM to support other networks. Others are designed to extract information from the Ethereum mainnet in ways the standard Geth client does not support.
Creating numerous different forks to fill a variety of different needs comes with a number of drawbacks. Forks tend to drift apart from each other. Many networks that forked from Geth long ago have stopped merging updates from Geth; this makes some sense, given that those networks have moved in different directions than Geth and merging upstream changes while properly maintaining consensus rules of an existing network could prove quite challenging. But not merging changes from upstream can mean that security updates are easily missed, especially when the upstream team `obscures security updates as optimizations`_ as a matter of process.
Creating numerous different forks to fill a variety of different needs comes with a number of drawbacks. Forks tend to drift apart from each other. Many networks that forked from Geth long ago have stopped merging updates; this makes some sense, given that those networks have moved in different directions than Geth and merging upstream changes while properly maintaining consensus rules of an existing network could prove quite challenging. But not merging changes from upstream can mean that security updates are easily missed, especially when the upstream team `obscures security updates as optimizations`_ as a matter of process.
PluGeth aims to provide a single Geth fork that developers can choose to extend rather than forking the Geth project. Out of the box, PluGeth behaves exactly like upstream Geth, but by installing plugins written in Golang, developers can extend its functionality in a wide variety of ways.
Three Repositories
------------------
==================
PluGeth is an application built in three repositories:
@ -25,19 +26,21 @@ PluGeth is an application built in three repositories:
The largest of the three Repositories, PluGeth is a fork of Geth which has been modified to enable a plugin architecture. The Plugin loader, wrappers, and hooks all reside in this repository.
`PluGeth-Utils`_
***************
****************
Utils are small packages used to develop PluGeth plugins without Geth dependencies. For a more detailed analysis of the reasons see **here**
Utils are small packages used to develop PluGeth plugins without Geth dependencies. For a more detailed analysis of the reasons see :ref: `core_resticted`. Imports from Utils happen automatically and so most users need not clone a local version.
`PluGeth-Plugins`_
*****************
******************
Plugins are packages which contain premade plugins as well as a location provided for storing new custom plugins.
The packages from which plugins are buile are stored here. This repository contains premade plugins as well as providing a location for storing new custom plugins.
Dependency Scheme
-----------------
.. todo:: needs elaboration of dependency scheme
.. todo:: Language on version and releases
:ref:`version`
@ -47,4 +50,4 @@ Dependency Scheme
.. _obscures security updates as optimizations: https://blog.openrelay.xyz/vulnerability-lifecycle-framework-geth/
.. _PluGeth: https://github.com/openrelayxyz/plugeth
.. _PluGeth-Utils: https://github.com/openrelayxyz/plugeth-utils
.. _PluGeth-Plugins: https://github.com/openrelayxyz/plugeth-plugin
.. _PluGeth-Plugins: https://github.com/openrelayxyz/plugeth-plugins

View File

@ -1,13 +0,0 @@
.. _quickstart:
Quickstart
==========
.. contents:: :local:
.. toctree::
:maxdepth: 1
:caption: tutorial
build
constom

View File

@ -1,8 +0,0 @@
.. _run:
===
Run
===
.. todo:: Need explination of how to download and run plugin
binaries.

View File

@ -0,0 +1,93 @@
.. _subscription:
============
Subscription
============
In addition to the initial template containing an intialize function, plugins providing **Subscriptions** will require two additional elements.
GetAPIs
*******
A GetAPIs method is required in the body of the plugin in order to make the plugin available. The bulk of the implementation will be in the MyService struct. MyService should be a struct which includes two public functions.
.. code-block:: Go
type MyService struct {
backend core.Backend
stack core.Node
}
func GetAPIs(stack core.Node, backend core.Backend) []core.API {
return []core.API{
{
Namespace: "plugeth",
Version: "1.0",
Service: &MyService{backend, stack},
Public: true,
},
}
}
Subscription Function
*********************
For subscriptions (supported on IPC and websockets), a function should take MyService as a reciever and a context.Context object as an argument and return a channel and an error. The following is a subscription function that impliments a timer.
.. code-block:: Go
func (*myservice) Timer(ctx context.Context) (<-chan int64, error) {
ticker := time.NewTicker(time.Second)
ch := make(chan int64)
go func() {
defer ticker.Stop()
for {
select {
case <-ctx.Done():
close(ch)
return
case t := <-ticker.C:
ch <- t.UnixNano()
}
}
}()
return ch, nil
}
.. warning:: Notice in the example above, the ``ctx.Done()`` or
Context.Done() method closes the channel. If this is not present the go routine will run for the life of the process.
Access
******
.. Note:: Plugins providing subscriptions can be accessed via IPC
and websockets. In the below example we will be using `wscat`_ to connect a websocket to a local Geth node.
As with pre-built plugins, a ``.so`` will need to be built from ``main.go`` and moved into ``~/.ethereum/plugins``. Geth will need to be started with with ``--ws --ws.api=mynamespace``flags. Additionally you will need to include a ``--http`` flag in order to access the standard json rpc methods.
After starting Geth, from a seperate terminal run:
.. code-block:: shell
wscat -c ws://127.0.0.1:8546
.. Note:: Websockets are available via port 8546
Once the connection has been established from the websocket cursor enter the following argument:
.. code-block:: shell
{"jsonrpc":"2.0","method":"mynamespace_hello","params":[],"id":0}
You should see that the network has responded with:
.. code-block:: shell
``{"jsonrpc":"2.0","id":0,"result":"Hello world"}``
.. _wscat: https://www.npmjs.com/package/wscat

View File

@ -0,0 +1,71 @@
.. _tracer:
======
Tracer
======
In addition to the initial template containing an intialize function, plugins providing **Tracers** will require three additional elements.
.. Warning:: Caution: Modifying of the values passed into tracer
functions can alter the results of the EVM execution in unpredictable ways. Additionally, some objects may be reused across calls, so data you wish to capture should be copied rather than retained be reference.
MyService Struct
****************
First an empty MyService Struct.
.. code-block:: Go
type MyService struct {
}
Map
***
Next, a map of tracers to functions returning a ``core.TracerResult`` which will be implimented like so:
.. code-block:: Go
var Tracers = map[string]func(core.StateDB) core.TracerResult{
"myTracer": func(core.StateDB) core.TracerResult {
return &MyBasicTracerService{}
},
}
TracerResult Functions
**********************
Finally a series of functions which points to the MyService struct and coresponds to the interface which geth anticipates.
.. code-block:: Go
func (b *MyBasicTracerService) CaptureStart(from core.Address, to core.Address, create bool, input []byte, gas uint64, value *big.Int) {
}
func (b *MyBasicTracerService) CaptureState(pc uint64, op core.OpCode, gas, cost uint64, scope core.ScopeContext, rData []byte, depth int, err error) {
}
func (b *MyBasicTracerService) CaptureFault(pc uint64, op core.OpCode, gas, cost uint64, scope core.ScopeContext, depth int, err error) {
}
func (b *MyBasicTracerService) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {
}
func (b *MyBasicTracerService) Result() (interface{}, error) { return "hello world", nil }
Access
******
As with pre-built plugins, a ``.so`` will need to be built from ``main.go`` and moved into ``~/.ethereum/plugins``. Geth will need to be started with with a ``--http.api+debug`` flag.
From a terminal pass the following argument to the api:
.. code-block:: shell
curl 127.0.0.1:8545 -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"debug_traceCall","params":[{"to":"0x32Be343B94f860124dC4fEe278FDCBD38C102D88"},"latest",{"tracer":"myTracer"}],"id":0}'
.. Note:: The address used above is a test adress and will need to
be replaced by whatever address you wish to access. Also ``traceCall`` is one of several methods available for use.
If using the template above, the call should return:
.. code-block:: shell
{"jsonrpc":"2.0","id":0,"result":"hello world"}

View File

@ -4,31 +4,39 @@
Basic Types of Plugins
======================
While PluGeth has been designed to be versatile and customizable, when learning the project it can be helpful to think of plugins as being of four different archetypes.
.. contents:: :local:
RPC Methods
-----------
In general these plugins provide new json rpc methods. They will requirre an initialize function that takes a context, loader, and logger as arguments. They will also need a GetAPIs function that takes a node and backend as arguments and returns an API.
These plugins provide new json rpc methods to access several objects containing real time and historic data.
.. NOTE:: In order to be made available a flag: ``http.api=<the name of your service>`` will need to be appended to the command line upon starting Geth.
Subcommand
------------
A subcommand redifines the total behavior of Geth and could stand on its own. I contrast with the other plugin types which, in general, are meant to capture and manipulate information, a subcommand is meant to change to overall behavior of Geth. It may do this in order to capture information but the primary fuctionality is a modulation of geth behaviour.
A subcommand redifines the total behavior of Geth and could stand on its own. In contrast with the other plugin types which, in general, are meant to capture and manipulate information, a subcommand is meant to change to overall behavior of Geth. It may do this in order to capture information but the primary fuctionality is a modulation of geth behaviour.
Tracers
-------
**Tracers vs LiveTracers.
Tracers rely on historic data recompiled after execution to give insight into a transaction.
Tracers rely on historic data whereas LiveTracers run concurent with Geth's verification system. LiveTracers are more generic in that they cannot control the way in which they recieve information.
**placeholder for eventual discusion of LiveTracers**
Subscriptions
-------------
A subscription must take a context.context as an argument and return a channel and an error. Subscriptions require a stable connection and return contant information. Subscriptions require a websocket connection and pass a json argument such as: ``{"jsonrpc":"2.0", "id": 0, "method": "namespace_subscribe", "params": ["subscriptionName", $args...]}``
Subscriptions provide real time notification of data from the EVM as it processes transactions.
.. NOTE:: Plugins are not limited to a singular functionality and can be customized to operate as hybrids of the above archtypes.
.. NOTE:: Plugins are not limited to a singular functionality and can be customized to operate as hybrids of the above. See `blockupdates`_ as an example.
.. todo:: Austin: I don't love this page. The informations is too
shallow.
.. _blockupdates: https://github.com/openrelayxyz/plugeth-plugins/tree/master/packages/blockupdates
**todo: this page needs a lot of work**

View File

@ -1,7 +0,0 @@
.. _utils:
=============
PluGeth Utils
=============
**todo: copy on plugeth utils**

View File

@ -0,0 +1,7 @@
.. _version:
=======
Version
=======
.. todo:: language on version control and release scheme

View File

@ -15,8 +15,8 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Get in touch with us" href="contact.html" />
<link rel="prev" title="Core vs Restricted packages in Plugeth-utils" href="core_restricted.html" />
<link rel="next" title="Plugin Loader" href="plugin_loader.html" />
<link rel="prev" title="Version" href="version.html" />
</head>
<body class="wy-body-for-nav">
@ -41,26 +41,26 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#flags">Flags</a></li>
<li class="toctree-l2"><a class="reference internal" href="#subcommands">Subcommands</a></li>
<li class="toctree-l2"><a class="reference internal" href="#initialize">Initialize</a></li>
<li class="toctree-l2"><a class="reference internal" href="#initializenode">InitializeNode</a></li>
<li class="toctree-l2"><a class="reference internal" href="#tracers">Tracers</a></li>
<li class="toctree-l2"><a class="reference internal" href="#livetracer">LiveTracer</a></li>
<li class="toctree-l2"><a class="reference internal" href="#getapis">GetAPIs</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -131,123 +131,6 @@ restricted.backend</p>
<li><p><strong>Behavior:</strong> This is called as soon as the Geth node is initialized. The core.Node object represents the running node with p2p and RPC capabilities, while the Backend gives you access to a wide array of data you may need to access.</p></li>
</ul>
</div>
<div class="section" id="tracers">
<h2>Tracers<a class="headerlink" href="#tracers" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><strong>Name:</strong> Tracers</p></li>
<li><p><strong>Type:</strong> map[string]TracerResult</p></li>
<li><p><strong>Behavior:</strong> When calling debug.traceX functions (such as <code class="docutils literal notranslate"><span class="pre">debug_traceCall</span></code> and <code class="docutils literal notranslate"><span class="pre">debug_traceTransaction</span></code>) the tracer can be specified as a key to this map and the tracer used will be the TracerResult specified here. TracerResult objects must match the interface:</p></li>
</ul>
<div class="highlight-go notranslate"><div class="highlight"><pre><span></span><span class="c1">// CaptureStart is called at the start of each transaction</span>
<span class="nx">CaptureStart</span><span class="p">(</span><span class="nx">env</span> <span class="nx">core</span><span class="p">.</span><span class="nx">EVM</span><span class="p">,</span> <span class="nx">from</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Address</span><span class="p">,</span> <span class="nx">to</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Address</span><span class="p">,</span> <span class="nx">create</span> <span class="kt">bool</span><span class="p">,</span> <span class="nx">input</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">gas</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">value</span> <span class="o">*</span><span class="nx">big</span><span class="p">.</span><span class="nx">Int</span><span class="p">)</span> <span class="p">{}</span>
<span class="c1">// CaptureState is called for each opcode</span>
<span class="nx">CaptureState</span><span class="p">(</span><span class="nx">env</span> <span class="nx">core</span><span class="p">.</span><span class="nx">EVM</span><span class="p">,</span> <span class="nx">pc</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">op</span> <span class="nx">core</span><span class="p">.</span><span class="nx">OpCode</span><span class="p">,</span> <span class="nx">gas</span><span class="p">,</span> <span class="nx">cost</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">scope</span> <span class="o">*</span><span class="nx">vm</span><span class="p">.</span><span class="nx">ScopeContext</span><span class="p">,</span> <span class="nx">rData</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">depth</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{}</span>
<span class="c1">// CaptureFault is called when an error occurs in the EVM</span>
<span class="nx">CaptureFault</span><span class="p">(</span><span class="nx">env</span> <span class="nx">core</span><span class="p">.</span><span class="nx">EVM</span><span class="p">,</span> <span class="nx">pc</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">op</span> <span class="nx">core</span><span class="p">.</span><span class="nx">OpCode</span><span class="p">,</span> <span class="nx">gas</span><span class="p">,</span> <span class="nx">cost</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">scope</span> <span class="o">*</span><span class="nx">vm</span><span class="p">.</span><span class="nx">ScopeContext</span><span class="p">,</span> <span class="nx">depth</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{}</span>
<span class="c1">// CaptureEnd is called at the end of each transaction</span>
<span class="nx">CaptureEnd</span><span class="p">(</span><span class="nx">output</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">gasUsed</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">t</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{}</span>
<span class="c1">// GetResult should return a JSON serializable result object to respond to the trace call</span>
<span class="nx">GetResult</span><span class="p">()</span> <span class="p">(</span><span class="kd">interface</span><span class="p">{},</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{}</span>
</pre></div>
</div>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Modifying the values passed into tracer functions can
alter the
results of the EVM execution in unpredictable ways. Additopackage main</p>
</div>
<dl class="simple">
<dt>import (</dt><dd><p>“github.com/openrelayxyz/plugeth-utils/core”
“gopkg.in/urfave/cli.v1”</p>
</dd>
</dl>
<p>)</p>
<dl class="simple">
<dt>var (</dt><dd><p>log core.Logger</p>
</dd>
</dl>
<p>)</p>
<p>type myservice struct{}</p>
<dl class="simple">
<dt>func (<a href="#id5"><span class="problematic" id="id6">*</span></a>myservice) Hello() string {</dt><dd><p>return “Hello world”</p>
</dd>
</dl>
<p>}</p>
<dl class="simple">
<dt>func Initialize(ctx <a href="#id7"><span class="problematic" id="id8">*</span></a>cli.Context, loader core.PluginLoader, logger core.Logger) {</dt><dd><p>log = logger
log.Info(“Initialized hello”)</p>
</dd>
</dl>
<p>}</p>
<dl>
<dt>func GetAPIs(node core.Node, backend core.Backend) []core.API {</dt><dd><p>defer log.Info(“APIs Initialized”)
return []core.API{</p>
<blockquote>
<div><dl class="simple">
<dt>{</dt><dd><p>Namespace: “mynamespace”,
Version: “1.0”,
Service: &amp;myservice{},
Public: true,</p>
</dd>
</dl>
<p>},</p>
</div></blockquote>
<p>}</p>
</dd>
</dl>
<p>}
package main</p>
<dl class="simple">
<dt>import (</dt><dd><p>“github.com/openrelayxyz/plugeth-utils/core”
“gopkg.in/urfave/cli.v1”</p>
</dd>
</dl>
<p>)</p>
<dl class="simple">
<dt>var (</dt><dd><p>log core.Logger</p>
</dd>
</dl>
<p>)</p>
<p>type myservice struct{}</p>
<dl class="simple">
<dt>func (<a href="#id9"><span class="problematic" id="id10">*</span></a>myservice) Hello() string {</dt><dd><p>return “Hello world”</p>
</dd>
</dl>
<p>}</p>
<dl class="simple">
<dt>func Initialize(ctx <a href="#id11"><span class="problematic" id="id12">*</span></a>cli.Context, loader core.PluginLoader, logger core.Logger) {</dt><dd><p>log = logger
log.Info(“Initialized hello”)</p>
</dd>
</dl>
<p>}</p>
<dl>
<dt>func GetAPIs(node core.Node, backend core.Backend) []core.API {</dt><dd><p>defer log.Info(“APIs Initialized”)
return []core.API{</p>
<blockquote>
<div><dl class="simple">
<dt>{</dt><dd><p>Namespace: “mynamespace”,
Version: “1.0”,
Service: &amp;myservice{},
Public: true,</p>
</dd>
</dl>
<p>},</p>
</div></blockquote>
<p>}</p>
</dd>
</dl>
<p>}
nally, some objects may be reused acress calls, so data you wish to capture should be copied rather than retianed by reference.</p>
</div>
<div class="section" id="livetracer">
<h2>LiveTracer<a class="headerlink" href="#livetracer" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p><strong>Name:</strong> LiveTracers</p></li>
<li><p><strong>Type:</strong> core.Tracer</p></li>
<li><p><strong>Behavior:</strong> This tracer is used for tracing transactions as they are processed within blocks. Note that if a block does not validate, some transactions may be processed that dont end up in blocks, so be sure to check transactions against finalized blocks.</p></li>
</ul>
<p>The interface for a vm.Tracer is similar to a TracerResult (above), but does not require a <code class="docutils literal notranslate"><span class="pre">GetResult()</span></code> function.</p>
</div>
<div class="section" id="getapis">
<h2>GetAPIs<a class="headerlink" href="#getapis" title="Permalink to this headline"></a></h2>
<ul class="simple">
@ -290,8 +173,8 @@ nally, some objects may be reused acress calls, so data you wish to capture shou
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="core_restricted.html" class="btn btn-neutral float-left" title="Core vs Restricted packages in Plugeth-utils" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="contact.html" class="btn btn-neutral float-right" title="Get in touch with us" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
<a href="version.html" class="btn btn-neutral float-left" title="Version" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="plugin_loader.html" class="btn btn-neutral float-right" title="Plugin Loader" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -16,7 +16,7 @@
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Building a Custom Plugin" href="custom.html" />
<link rel="prev" title="Run" href="run.html" />
<link rel="prev" title="Install" href="install.html" />
</head>
<body class="wy-body-for-nav">
@ -41,7 +41,7 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Build and Deploy</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#setting-up-the-environment">Setting up the environment</a></li>
<li class="toctree-l2"><a class="reference internal" href="#build-a-plugin">Build a plugin</a></li>
@ -52,10 +52,12 @@
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -94,7 +96,7 @@
<li><p><a class="reference internal" href="#build-a-plugin" id="id2">Build a plugin</a></p></li>
</ul>
</div>
<p>If you are ready to start building your own plugins go ahead and start <a href="#id3"><span class="problematic" id="id4">`here`_</span></a></p>
<p>If you are ready to start building your own plugins go ahead and start here.</p>
<div class="section" id="setting-up-the-environment">
<h2><a class="toc-backref" href="#id1">Setting up the environment</a><a class="headerlink" href="#setting-up-the-environment" title="Permalink to this headline"></a></h2>
<div class="admonition note">
@ -153,7 +155,7 @@ that you know how to use it.</p>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="run.html" class="btn btn-neutral float-left" title="Run" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="install.html" class="btn btn-neutral float-left" title="Install" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="custom.html" class="btn btn-neutral float-right" title="Building a Custom Plugin" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>

View File

@ -15,7 +15,7 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="prev" title="API" href="api.html" />
<link rel="prev" title="Core vs Restricted packages in Plugeth-utils" href="core_restricted.html" />
</head>
<body class="wy-body-for-nav">
@ -40,17 +40,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul class="current">
@ -91,7 +93,7 @@
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="api.html" class="btn btn-neutral float-left" title="API" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="core_restricted.html" class="btn btn-neutral float-left" title="Core vs Restricted packages in Plugeth-utils" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
</div>
<hr/>

View File

@ -15,8 +15,8 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="API" href="api.html" />
<link rel="prev" title="Plugin Hooks" href="plugin_hooks.html" />
<link rel="next" title="Get in touch with us" href="contact.html" />
<link rel="prev" title="Hook Writing Guide" href="hook_writing.html" />
</head>
<body class="wy-body-for-nav">
@ -41,17 +41,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -94,8 +96,8 @@
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="plugin_hooks.html" class="btn btn-neutral float-left" title="Plugin Hooks" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="api.html" class="btn btn-neutral float-right" title="API" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
<a href="hook_writing.html" class="btn btn-neutral float-left" title="Hook Writing Guide" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="contact.html" class="btn btn-neutral float-right" title="Get in touch with us" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -15,7 +15,7 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="System Requirements" href="system_req.html" />
<link rel="next" title="RPC Methods" href="RPC_method.html" />
<link rel="prev" title="Build and Deploy" href="build.html" />
</head>
@ -41,10 +41,18 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Building a Custom Plugin</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#most-basic-implimentation">Most Basic implimentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="RPC_method.html">RPC Methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="subscription.html">Subscription</a></li>
<li class="toctree-l2"><a class="reference internal" href="tracer.html">Tracer</a></li>
<li class="toctree-l2"><a class="reference internal" href="#basic-implementation">Basic Implementation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#package">Package</a></li>
<li class="toctree-l3"><a class="reference internal" href="#initialize">Initialize</a></li>
<li class="toctree-l3"><a class="reference internal" href="#initializenode">InitializeNode</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#specialization">Specialization</a></li>
</ul>
</li>
@ -52,10 +60,12 @@
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -88,13 +98,20 @@
<div class="section" id="building-a-custom-plugin">
<span id="custom"></span><h1>Building a Custom Plugin<a class="headerlink" href="#building-a-custom-plugin" title="Permalink to this headline"></a></h1>
<p>Before setting out to build a plugin it will be helpful to be familiar with the basic <a class="reference internal" href="types.html#types"><span class="std std-ref">Basic Types of Plugins</span></a> of plugins. Depending on what you intend to do certain aspects of implimentation will be neccisary.</p>
<p>In general, no matter which type of plugin you intend to build, below are common aspects which will be shared by all plugins.</p>
<div class="section" id="most-basic-implimentation">
<h2>Most Basic implimentation<a class="headerlink" href="#most-basic-implimentation" title="Permalink to this headline"></a></h2>
<p>A plugin will need its own package located in the Plugeth-Utils packages directory. The package will need to include a main.go from which the .so file will be built. The package and main file should share the same name and the name should be a word that describes the basic functionality of the plugin.</p>
<p>All plugins will need to be initialized with an <strong>initialize function</strong>. The initialize function will need to be passed at least three arguments: a cli.Context, core.PluginLoader, and a core.Logger.</p>
<p>And so, all plugins will have an intial template that looks something like this:</p>
<div class="toctree-wrapper compound">
</div>
<p>Before setting out to build a plugin it will be helpful to be familiar with the <a class="reference internal" href="types.html#types"><span class="std std-ref">Basic Types of Plugins</span></a>. deifferent plugins will require different implimentation.</p>
<div class="section" id="basic-implementation">
<h2>Basic Implementation<a class="headerlink" href="#basic-implementation" title="Permalink to this headline"></a></h2>
<p>In general, no matter which type of plugin you intend to build, all will share some common aspects.</p>
<div class="section" id="package">
<h3>Package<a class="headerlink" href="#package" title="Permalink to this headline"></a></h3>
<p>Any plugin will need its own package located in the Plugeth-Plugins packages directory. The package will need to include a main.go from which the .so file will be built. The package and main file should share the same name and the name should be a word that describes the basic functionality of the plugin.</p>
</div>
<div class="section" id="initialize">
<h3>Initialize<a class="headerlink" href="#initialize" title="Permalink to this headline"></a></h3>
<p>Most plugins will need to be initialized with an Initialize function. The initialize function will need to be passed at least three arguments: a cli.Context, core.PluginLoader, and a core.Logger.</p>
<p>And so, all plugins could have an intial template that looks something like this:</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
@ -111,10 +128,26 @@
</pre></div>
</div>
</div>
<div class="section" id="initializenode">
<h3>InitializeNode<a class="headerlink" href="#initializenode" title="Permalink to this headline"></a></h3>
<p>Many plugins will make use of the InitializeNode function. Implimentation will look like so:</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">func</span> <span class="nx">InitializeNode</span><span class="p">(</span><span class="nx">stack</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Node</span><span class="p">,</span> <span class="nx">b</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Backend</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">backend</span> <span class="p">=</span> <span class="nx">b</span>
<span class="nx">log</span><span class="p">.</span><span class="nx">Info</span><span class="p">(</span><span class="s">&quot;Initialized node and backend&quot;</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</div>
<p>This is called as soon as the Geth node is initialized. The core.Node object represents the running node with p2p and RPC capabilities, while the Backend gives you access to blocks and other data you may need to access.</p>
</div>
</div>
<div class="section" id="specialization">
<h2>Specialization<a class="headerlink" href="#specialization" title="Permalink to this headline"></a></h2>
<p><strong>Hooks</strong></p>
<p>Plugeth provides several hooks with which data of various kinds can be captured and manipulated. Once a plugin has been initalized it will be up to the hooks utilized to determine the behavior of the plugin.</p>
<p>From this point implimentation becomes more specialized to the particular plugin type. Continue from here for specific instructions for the following plugins:</p>
<ul class="simple">
<li><p><a class="reference internal" href="RPC_method.html#rpc-method"><span class="std std-ref">RPC Methods</span></a></p></li>
<li><p><a class="reference internal" href="subscription.html#subscription"><span class="std std-ref">Subscription</span></a></p></li>
<li><p><a class="reference internal" href="tracer.html#tracer"><span class="std std-ref">Tracer</span></a></p></li>
</ul>
</div>
</div>
@ -123,7 +156,7 @@
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="build.html" class="btn btn-neutral float-left" title="Build and Deploy" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="system_req.html" class="btn btn-neutral float-right" title="System Requirements" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
<a href="RPC_method.html" class="btn btn-neutral float-right" title="RPC Methods" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -39,17 +39,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Plugin Hooks &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<title>Hook Writing Guide &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
@ -16,7 +16,7 @@
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Core vs Restricted packages in Plugeth-utils" href="core_restricted.html" />
<link rel="prev" title="Plugin Loader" href="plugin_loader.html" />
<link rel="prev" title="Selected Plugin Hooks" href="hooks.html" />
</head>
<body class="wy-body-for-nav">
@ -41,17 +41,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -72,9 +74,9 @@
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Plugin Hooks</li>
<li>Hook Writing Guide</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/plugin_hooks.rst.txt" rel="nofollow"> View page source</a>
<a href="_sources/hook_writing.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
@ -82,9 +84,9 @@
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="plugin-hooks">
<span id="id1"></span><h1>Plugin Hooks<a class="headerlink" href="#plugin-hooks" title="Permalink to this headline"></a></h1>
<div class="admonition-todo admonition" id="id2">
<div class="section" id="hook-writing-guide">
<span id="hook-writing"></span><h1>Hook Writing Guide<a class="headerlink" href="#hook-writing-guide" title="Permalink to this headline"></a></h1>
<div class="admonition-todo admonition" id="id1">
<p class="admonition-title">Todo</p>
<p>guide to writing plugin hooks</p>
</div>
@ -94,7 +96,7 @@
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="plugin_loader.html" class="btn btn-neutral float-left" title="Plugin Loader" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="hooks.html" class="btn btn-neutral float-left" title="Selected Plugin Hooks" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="core_restricted.html" class="btn btn-neutral float-right" title="Core vs Restricted packages in Plugeth-utils" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Plugin Hooks &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<title>Selected Plugin Hooks &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
@ -15,6 +15,8 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Hook Writing Guide" href="hook_writing.html" />
<link rel="prev" title="Plugin Loader" href="plugin_loader.html" />
</head>
<body class="wy-body-for-nav">
@ -39,17 +41,31 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Selected Plugin Hooks</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#plugin-hooks">Plugin Hooks</a></li>
<li class="toctree-l2"><a class="reference internal" href="#stateupdate">StateUpdate</a></li>
<li class="toctree-l2"><a class="reference internal" href="#appendancient">AppendAncient</a></li>
<li class="toctree-l2"><a class="reference internal" href="#getrpccalls">GetRPCCalls</a></li>
<li class="toctree-l2"><a class="reference internal" href="#preprocessblock">PreProcessBlock</a></li>
<li class="toctree-l2"><a class="reference internal" href="#preprocesstransaction">PreProcessTransaction</a></li>
<li class="toctree-l2"><a class="reference internal" href="#blockprocessingerror">BlockProcessingError</a></li>
<li class="toctree-l2"><a class="reference internal" href="#newhead">NewHead</a></li>
<li class="toctree-l2"><a class="reference internal" href="#newsideblock">NewSideBlock</a></li>
<li class="toctree-l2"><a class="reference internal" href="#reorg">Reorg</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -70,7 +86,7 @@
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Plugin Hooks</li>
<li>Selected Plugin Hooks</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/hooks.rst.txt" rel="nofollow"> View page source</a>
</li>
@ -80,19 +96,31 @@
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="plugin-hooks">
<span id="hooks"></span><h1>Plugin Hooks<a class="headerlink" href="#plugin-hooks" title="Permalink to this headline"></a></h1>
<p>The key to understanding a plugin is understanding its corresponding hook. Broadly, plugin hooks can be thought of as functions which deliver a function signiture to the <strong>plugin loader</strong>. The signature matches that of the function(s) called by the plugin and describes the data that is being captured and how the plugin will deliver said data upon invocation.</p>
<p>The public plugin hook function should follow the naming convention <code class="docutils literal notranslate"><span class="pre">Plugin$HookName</span></code>. The first argument should be a `` core.PluginLoader``, followed by any arguments required by the functions to be provided by any plugins implementing this hook.</p>
<p><strong>Public and Private Hook Functions</strong></p>
<p>Each hook provides both a Public and private version. The private plugin hook function should bear the same name as the public plugin hook function, but with a lower case first letter. The signature should match the public plugin hook function, except that the first argument referencing the PluginLoader should be removed. It should invoke the public plugin hook function on plugins.DefaultPluginLoader. It should always verify that the DefaultPluginLoader is non-nil, log warning and return if the DefaultPluginLoader has not been initialized.</p>
<p><strong>Invocation</strong></p>
<p>the private plugin hook function should be invoked, with the appropriate arguments, in a single line within the Geth codebase inorder to minimize unexpected conflicts merging upstream Geth into plugeth.</p>
<div class="section" id="selected-hooks">
<h2>Selected Hooks<a class="headerlink" href="#selected-hooks" title="Permalink to this headline"></a></h2>
<div class="section" id="selected-plugin-hooks">
<span id="hooks"></span><h1>Selected Plugin Hooks<a class="headerlink" href="#selected-plugin-hooks" title="Permalink to this headline"></a></h1>
<div class="section" id="plugin-hooks">
<h2>Plugin Hooks<a class="headerlink" href="#plugin-hooks" title="Permalink to this headline"></a></h2>
<p>Plugeth provides several <a class="reference internal" href="#hooks"><span class="std std-ref">Selected Plugin Hooks</span></a> from which the plugin can capture data from Geth. Additionally in the case of <strong>subcommands</strong> the provided hooks are designed to change the behavior of Geth.</p>
<p>Hooks are called from functions within the plugin. For example, if we wanted to bring in data from the StateUpdate hook. We would impliment it like so:
(from <a class="reference external" href="https://github.com/openrelayxyz/plugeth-plugins/tree/master/packages/blockupdates">blockupdates</a>)</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">func</span> <span class="nx">StateUpdate</span><span class="p">(</span><span class="nx">blockRoot</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Hash</span><span class="p">,</span> <span class="nx">parentRoot</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Hash</span><span class="p">,</span> <span class="nx">destructs</span> <span class="kd">map</span><span class="p">[</span><span class="nx">core</span><span class="p">.</span><span class="nx">Hash</span><span class="p">]</span><span class="kd">struct</span><span class="p">{},</span> <span class="nx">accounts</span> <span class="kd">map</span><span class="p">[</span><span class="nx">core</span><span class="p">.</span><span class="nx">Hash</span><span class="p">][]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">storage</span> <span class="kd">map</span><span class="p">[</span><span class="nx">core</span><span class="p">.</span><span class="nx">Hash</span><span class="p">]</span><span class="kd">map</span><span class="p">[</span><span class="nx">core</span><span class="p">.</span><span class="nx">Hash</span><span class="p">][]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">codeUpdates</span> <span class="kd">map</span><span class="p">[</span><span class="nx">core</span><span class="p">.</span><span class="nx">Hash</span><span class="p">][]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">su</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">stateUpdate</span><span class="p">{</span>
<span class="nx">Destructs</span><span class="p">:</span> <span class="nx">destructs</span><span class="p">,</span>
<span class="nx">Accounts</span><span class="p">:</span> <span class="nx">accounts</span><span class="p">,</span>
<span class="nx">Storage</span><span class="p">:</span> <span class="nx">storage</span><span class="p">,</span>
<span class="nx">Code</span><span class="p">:</span> <span class="nx">codeUpdates</span><span class="p">,</span>
<span class="p">}</span>
<span class="nx">cache</span><span class="p">.</span><span class="nx">Add</span><span class="p">(</span><span class="nx">blockRoot</span><span class="p">,</span> <span class="nx">su</span><span class="p">)</span>
<span class="nx">data</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">rlp</span><span class="p">.</span><span class="nx">EncodeToBytes</span><span class="p">(</span><span class="nx">su</span><span class="p">)</span>
<span class="nx">backend</span><span class="p">.</span><span class="nx">ChainDb</span><span class="p">().</span><span class="nx">Put</span><span class="p">(</span><span class="nb">append</span><span class="p">([]</span><span class="nb">byte</span><span class="p">(</span><span class="s">&quot;su&quot;</span><span class="p">),</span> <span class="nx">blockRoot</span><span class="p">.</span><span class="nx">Bytes</span><span class="p">()</span><span class="o">...</span><span class="p">),</span> <span class="nx">data</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Many hooks can be deployed in an one plugin as is the case with the <strong>BlockUpdater</strong> plugin.</p>
</div>
<div class="section" id="stateupdate">
<h3><a class="reference external" href="https://github.com/openrelayxyz/plugeth/blob/develop/core/state/plugin_hooks.go">StateUpdate</a><a class="headerlink" href="#stateupdate" title="Permalink to this headline"></a></h3>
<p><a class="reference external" href="https://github.com/openrelayxyz/plugeth/blob/develop/core/state/statedb.go#L955">Invocation</a></p>
<h2>StateUpdate<a class="headerlink" href="#stateupdate" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(root</span> <span class="pre">common.Hash,</span> <span class="pre">parentRoot</span> <span class="pre">common.Hash,</span> <span class="pre">destructs</span> <span class="pre">map[common.Hash]struct{},</span> <span class="pre">accounts</span> <span class="pre">map[common.Hash][]byte,</span> <span class="pre">storage</span> <span class="pre">map[common.Hash]map[common.Hash][]byte)</span></code></p>
<p>The state update plugin provides a snapshot of the state subsystem in the form of a a stateUpdate object. The stateUpdate object contains all information transformed by a transaction but not the transaction itself.</p>
<p>Invoked for each new block, StateUpdate provides the changes to the blockchain state. root corresponds to the state root of the new block. parentRoot corresponds to the state root of the parent block. destructs serves as a set of accounts that self-destructed in this block. accounts maps the hash of each account address to the SlimRLP encoding of the account data. storage maps the hash of each account to a map of that accounts stored data.</p>
<div class="admonition warning">
@ -102,25 +130,67 @@
</div>
</div>
<div class="section" id="appendancient">
<h3><a class="reference external" href="https://github.com/openrelayxyz/plugeth/blob/develop/core/rawdb/plugin_hooks.go">AppendAncient</a><a class="headerlink" href="#appendancient" title="Permalink to this headline"></a></h3>
<h2>AppendAncient<a class="headerlink" href="#appendancient" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(number</span> <span class="pre">uint64,</span> <span class="pre">hash,</span> <span class="pre">header,</span> <span class="pre">body,</span> <span class="pre">receipts,</span> <span class="pre">td</span> <span class="pre">[]byte)</span></code></p>
<p>Invoked when the freezer moves a block from LevelDB to the ancients database. <code class="docutils literal notranslate"><span class="pre">number</span></code> is the number of the block. <code class="docutils literal notranslate"><span class="pre">hash</span></code> is the 32 byte hash of the block as a raw <code class="docutils literal notranslate"><span class="pre">[]byte</span></code>. <code class="docutils literal notranslate"><span class="pre">header</span></code>, <code class="docutils literal notranslate"><span class="pre">body</span></code>, and <code class="docutils literal notranslate"><span class="pre">receipts</span></code> are the RLP encoded versions of their respective block elements. <code class="docutils literal notranslate"><span class="pre">td</span></code> is the byte encoded total difficulty of the block.</p>
</div>
<div class="section" id="newhead">
<h3><a class="reference external" href="https://github.com/openrelayxyz/plugeth/blob/develop/core/plugin_hooks.go#L108">NewHead</a><a class="headerlink" href="#newhead" title="Permalink to this headline"></a></h3>
<p>Invoked when a new block becomes the canonical latest block. Note that if several blocks are processed in a group (such as during a reorg) this may not be called for each block. You should track the prior latest head if you need to process intermediate blocks.</p>
</div>
<div class="section" id="getrpccalls">
<h3><a class="reference external" href="https://github.com/openrelayxyz/plugeth/blob/develop/rpc/plugin_hooks.go">GetRPCCalls</a><a class="headerlink" href="#getrpccalls" title="Permalink to this headline"></a></h3>
<p>Invoked when the RPC handler registers a method call. returns the call <code class="docutils literal notranslate"><span class="pre">id</span></code>, method <code class="docutils literal notranslate"><span class="pre">name</span></code>, and any <code class="docutils literal notranslate"><span class="pre">params</span></code> that may have been passed in.</p>
<p><strong>I am struggling all of assudden with if this is really this best course of action. Giving all of this reference, seems to beg the -utils vs plugeth conversation and I am not sure that is a smart thing to get into.</strong></p>
<h2>GetRPCCalls<a class="headerlink" href="#getrpccalls" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(string,</span> <span class="pre">string,</span> <span class="pre">string)</span></code></p>
<p>Invoked when the RPC handler registers a method call. Returns the call <code class="docutils literal notranslate"><span class="pre">id</span></code>, method <code class="docutils literal notranslate"><span class="pre">name</span></code>, and any <code class="docutils literal notranslate"><span class="pre">params</span></code> that may have been passed in.</p>
<div class="admonition-todo admonition" id="id1">
<p class="admonition-title">Todo</p>
<p>missing a couple of hooks</p>
</div>
</div>
<div class="section" id="preprocessblock">
<h2>PreProcessBlock<a class="headerlink" href="#preprocessblock" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(*types.Block)</span></code></p>
<p>Invoked before the transactions of a block are processed. Returns a block object.</p>
</div>
<div class="section" id="preprocesstransaction">
<h2>PreProcessTransaction<a class="headerlink" href="#preprocesstransaction" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(*types.Transaction,</span> <span class="pre">*types.Block,</span> <span class="pre">int)</span></code></p>
<p>Invoked before each individual transaction of a block is processed. Returns a transaction, block, and index number.</p>
</div>
<div class="section" id="blockprocessingerror">
<h2>BlockProcessingError<a class="headerlink" href="#blockprocessingerror" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(*types.Transaction,</span> <span class="pre">*types.Block,</span> <span class="pre">error)</span></code></p>
<p>Invoked if an error occurs while processing a transaction. This only applies to errors that would unvalidate the block were this transaction is included not errors such as reverts or opcode errors. Returns a transaction, block, and error.</p>
</div>
<div class="section" id="newhead">
<h2>NewHead<a class="headerlink" href="#newhead" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(*types.Block,</span> <span class="pre">common.Hash,</span> <span class="pre">[]*types.Log)</span></code></p>
<p>Invoked when a new block becomes the canonical latest block. Returns a block, hash, and log.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>If severtal blocks are processed in a group (such as
during a reorg) this may not be called for each block. You should track the prior latest head if you need to process intermediate blocks.</p>
</div>
</div>
<div class="section" id="newsideblock">
<h2>NewSideBlock<a class="headerlink" href="#newsideblock" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(*types.Block,</span> <span class="pre">common.Hash,</span> <span class="pre">[]*types.Log)</span></code></p>
<p>Invoked when a block is side-chained. Returns a block, has, and logs.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Blocks passed to this method are non-canonical blocks.</p>
</div>
</div>
<div class="section" id="reorg">
<h2>Reorg<a class="headerlink" href="#reorg" title="Permalink to this headline"></a></h2>
<p><strong>Function Signature</strong>:<code class="docutils literal notranslate"><span class="pre">func(common</span> <span class="pre">*types.Block,</span> <span class="pre">oldChain,</span> <span class="pre">newChain</span> <span class="pre">types.Blocks)</span></code></p>
<p>Invoked when a chain reorg occurs, that is; at least one block is removed and one block is added. (<code class="docutils literal notranslate"><span class="pre">oldChain</span></code> is a list of removed blocks, <code class="docutils literal notranslate"><span class="pre">newChain</span></code> is a list of newliy added blocks, and <code class="docutils literal notranslate"><span class="pre">common</span></code> is the latest block that is an ancestor to both oldChain and newChain.) Returns a block, a list of old blocks, and a list of new blocks.</p>
</div>
</div>
</div>
</div>
<footer>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="plugin_loader.html" class="btn btn-neutral float-left" title="Plugin Loader" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="hook_writing.html" class="btn btn-neutral float-right" title="Hook Writing Guide" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -40,17 +40,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -83,12 +85,12 @@
<div class="section" id="plugeth">
<h1>PluGeth<a class="headerlink" href="#plugeth" title="Permalink to this headline"></a></h1>
<p>PluGeth is a fork of the <a class="reference external" href="https://github.com/ethereum/go-ethereum">Go Ethereum Client Geth</a> that implements a plugin architecture, allowing developers to extend Geths capabilities in a number of different ways using plugins, rather than having to create additional, new forks of Geth.</p>
<p>PluGeth is a fork of the Go Ethereum Client, <a class="reference external" href="https://geth.ethereum.org/">Geth</a>, that implements a plugin architecture allowing developers to extend Geths capabilities in a number of different ways using plugins rather than having to create additional new forks.</p>
<div class="section" id="from-here">
<h2>From Here:<a class="headerlink" href="#from-here" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li><p>Ready for an overview of the project and some context? <a class="reference internal" href="project.html#project"><span class="std std-ref">Project Design</span></a></p></li>
<li><p>If your goal is to run existing plugns without sourcecode: <a class="reference internal" href="run.html#run"><span class="std std-ref">Run</span></a></p></li>
<li><p>If your goal is to run existing plugns without sourcecode: <a class="reference internal" href="install.html#install"><span class="std std-ref">Install</span></a></p></li>
<li><p>If your goal is to build and deploy existing plugins or make custom plugins: <a class="reference internal" href="build.html#build"><span class="std std-ref">Build and Deploy</span></a></p></li>
</ul>
<div class="admonition warning">
@ -110,7 +112,7 @@ perspective, PluGeth should be as stable as upstream Geth less whatever isstabil
<div class="toctree-wrapper compound">
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
@ -119,10 +121,12 @@ perspective, PluGeth should be as stable as upstream Geth less whatever isstabil
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
</div>
<div class="toctree-wrapper compound">

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PluGeth &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<title>Install &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
@ -15,6 +15,8 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Build and Deploy" href="build.html" />
<link rel="prev" title="Basic Types of Plugins" href="types.html" />
</head>
<body class="wy-body-for-nav">
@ -38,18 +40,20 @@
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -70,9 +74,9 @@
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>PluGeth</li>
<li>Install</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/plugeth.rst.txt" rel="nofollow"> View page source</a>
<a href="_sources/install.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
@ -80,15 +84,30 @@
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="plugeth">
<span id="id1"></span><h1>PluGeth<a class="headerlink" href="#plugeth" title="Permalink to this headline"></a></h1>
<p><strong>to do: discussion on plugeth repository</strong></p>
<div class="section" id="install">
<span id="id1"></span><h1>Install<a class="headerlink" href="#install" title="Permalink to this headline"></a></h1>
<p>PluGeth provides a pre-built PluGeth-Geth node as well as pre-built plugins available for download.</p>
<p>First download the latest PluGeth <a class="reference external" href="https://github.com/openrelayxyz/plugeth/releases">binary release</a>.</p>
<div class="admonition-todo admonition" id="id2">
<p class="admonition-title">Todo</p>
<p>more language about installing download</p>
</div>
<p>Our curated list of plugin builds can be found <a class="reference external" href="https://www.youtube.com/watch?v=dQw4w9WgXcQ&amp;ab_channel=RickAstley">here</a></p>
<p>After downloading, move the .so files into the ~/.ethereum/plugins directory.</p>
<div class="admonition-todo admonition" id="id3">
<p class="admonition-title">Todo</p>
<p>Build a binary release so as to provide a usable
example. Maybe a different example than hello so that there are two generic cases for which there are tutorials. or We should provide examples of the common scenerios in which geth has to be started with flags or connected to with web sockets.</p>
</div>
</div>
</div>
</div>
<footer>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="types.html" class="btn btn-neutral float-left" title="Basic Types of Plugins" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="build.html" class="btn btn-neutral float-right" title="Build and Deploy" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -15,8 +15,8 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Plugin Hooks" href="plugin_hooks.html" />
<link rel="prev" title="System Requirements" href="system_req.html" />
<link rel="next" title="Selected Plugin Hooks" href="hooks.html" />
<link rel="prev" title="API" href="api.html" />
</head>
<body class="wy-body-for-nav">
@ -41,17 +41,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -84,6 +86,10 @@
<div class="section" id="plugin-loader">
<span id="id1"></span><h1>Plugin Loader<a class="headerlink" href="#plugin-loader" title="Permalink to this headline"></a></h1>
<div class="admonition-todo admonition" id="id2">
<p class="admonition-title">Todo</p>
<p>Ausitn, take a pass at flushing this out.</p>
</div>
<p>At the heart of the PluGeth project is the <a class="reference external" href="https://github.com/openrelayxyz/plugeth/blob/develop/plugins/plugin_loader.go">PluginLoader</a>.</p>
<p>Upon invocation the PluginLoader will parse through a list of known plugins and either return the plugin name passed to it or, if not found, append to that list. Additionally the loader will check the function signature of the plugin to assure complience with anticipated behavior. Once these checks are passed and the plugin name and function signature is validated the plugin will be invoked.</p>
</div>
@ -92,8 +98,8 @@
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="system_req.html" class="btn btn-neutral float-left" title="System Requirements" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="plugin_hooks.html" class="btn btn-neutral float-right" title="Plugin Hooks" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
<a href="api.html" class="btn btn-neutral float-left" title="API" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="hooks.html" class="btn btn-neutral float-right" title="Selected Plugin Hooks" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -1,116 +0,0 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PluGeth Plugins &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Plugeth
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption"><span class="caption-text">Overview</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="project.html">Project Design</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="contact.html">Get in touch with us</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Plugeth</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>PluGeth Plugins</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/plugins.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="plugeth-plugins">
<span id="plugins"></span><h1>PluGeth Plugins<a class="headerlink" href="#plugeth-plugins" title="Permalink to this headline"></a></h1>
<p><strong>todo: copy on plugeth plugins repo</strong></p>
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Philip Morlier.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -37,30 +37,35 @@
<p class="caption"><span class="caption-text">Overview</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Project Design</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#design-goals">Design Goals</a></li>
<li class="toctree-l2"><a class="reference internal" href="#three-repositories">Three Repositories</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#plugeth">PluGeth</a></li>
<li class="toctree-l3"><a class="reference internal" href="#plugeth-utils">PluGeth-Utils</a></li>
<li class="toctree-l3"><a class="reference internal" href="#plugeth-plugins">PluGeth-Plugins</a></li>
<li class="toctree-l3"><a class="reference internal" href="#plugeth-plugins">PluGeth-Plugins</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#dependency-scheme">Dependency Scheme</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#dependency-scheme">Dependency Scheme</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -93,11 +98,13 @@
<div class="section" id="project-design">
<span id="project"></span><h1>Project Design<a class="headerlink" href="#project-design" title="Permalink to this headline"></a></h1>
<p>Design Goals</p>
<p>The upstream Geth client exists primarily to serve as a client for the Ethereum mainnet, though it also supports a number of popular testnets. Supporting the Ethereum mainnet is a big enough challenge in its own right that the Geth team generally avoids changes to support other networks, or to provide features only a small handful of users would be interested in.</p>
<div class="section" id="design-goals">
<h2>Design Goals<a class="headerlink" href="#design-goals" title="Permalink to this headline"></a></h2>
<p>Upstream Geth exists primarily to serve as a client for the Ethereum mainnet, though it also supports a number of popular testnets. Supporting the Ethereum mainnet is a big enough challenge in its own right that the Geth team generally avoids changes to support other networks, or to provide features only a small handful of users would be interested in.</p>
<p>The result is that many projects have forked Geth. Some implement their own consensus protocols or alter the behavior of the EVM to support other networks. Others are designed to extract information from the Ethereum mainnet in ways the standard Geth client does not support.</p>
<p>Creating numerous different forks to fill a variety of different needs comes with a number of drawbacks. Forks tend to drift apart from each other. Many networks that forked from Geth long ago have stopped merging updates from Geth; this makes some sense, given that those networks have moved in different directions than Geth and merging upstream changes while properly maintaining consensus rules of an existing network could prove quite challenging. But not merging changes from upstream can mean that security updates are easily missed, especially when the upstream team <a class="reference external" href="https://blog.openrelay.xyz/vulnerability-lifecycle-framework-geth/">obscures security updates as optimizations</a> as a matter of process.</p>
<p>Creating numerous different forks to fill a variety of different needs comes with a number of drawbacks. Forks tend to drift apart from each other. Many networks that forked from Geth long ago have stopped merging updates; this makes some sense, given that those networks have moved in different directions than Geth and merging upstream changes while properly maintaining consensus rules of an existing network could prove quite challenging. But not merging changes from upstream can mean that security updates are easily missed, especially when the upstream team <a class="reference external" href="https://blog.openrelay.xyz/vulnerability-lifecycle-framework-geth/">obscures security updates as optimizations</a> as a matter of process.</p>
<p>PluGeth aims to provide a single Geth fork that developers can choose to extend rather than forking the Geth project. Out of the box, PluGeth behaves exactly like upstream Geth, but by installing plugins written in Golang, developers can extend its functionality in a wide variety of ways.</p>
</div>
<div class="section" id="three-repositories">
<h2>Three Repositories<a class="headerlink" href="#three-repositories" title="Permalink to this headline"></a></h2>
<p>PluGeth is an application built in three repositories:</p>
@ -107,18 +114,19 @@
</div>
<div class="section" id="plugeth-utils">
<h3><a class="reference external" href="https://github.com/openrelayxyz/plugeth-utils">PluGeth-Utils</a><a class="headerlink" href="#plugeth-utils" title="Permalink to this headline"></a></h3>
<p>Utils are small packages used to develop PluGeth plugins without Geth dependencies. For a more detailed analysis of the reasons see <strong>here</strong></p>
<p>Utils are small packages used to develop PluGeth plugins without Geth dependencies. For a more detailed analysis of the reasons see :ref: <cite>core_resticted</cite>. Imports from Utils happen automatically and so most users need not clone a local version.</p>
</div>
<div class="section" id="plugeth-plugins">
<h3><a class="reference external" href="https://github.com/openrelayxyz/plugeth-plugin">PluGeth-Plugins</a><a class="headerlink" href="#plugeth-plugins" title="Permalink to this headline"></a></h3>
<p>Plugins are packages which contain premade plugins as well as a location provided for storing new custom plugins.</p>
</div>
</div>
<h3><a class="reference external" href="https://github.com/openrelayxyz/plugeth-plugins">PluGeth-Plugins</a><a class="headerlink" href="#plugeth-plugins" title="Permalink to this headline"></a></h3>
<p>The packages from which plugins are buile are stored here. This repository contains premade plugins as well as providing a location for storing new custom plugins.</p>
<div class="section" id="dependency-scheme">
<h2>Dependency Scheme<a class="headerlink" href="#dependency-scheme" title="Permalink to this headline"></a></h2>
<h4>Dependency Scheme<a class="headerlink" href="#dependency-scheme" title="Permalink to this headline"></a></h4>
<div class="admonition-todo admonition" id="id1">
<p class="admonition-title">Todo</p>
<p>needs elaboration of dependency scheme</p>
<p>Language on version and releases</p>
</div>
<p><a class="reference internal" href="version.html#version"><span class="std std-ref">Version</span></a></p>
</div>
</div>
</div>
</div>

View File

@ -1,121 +0,0 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Quickstart &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Plugeth
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption"><span class="caption-text">Overview</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="project.html">Project Design</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="contact.html">Get in touch with us</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Plugeth</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Quickstart</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/quickstart.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="quickstart">
<span id="id1"></span><h1>Quickstart<a class="headerlink" href="#quickstart" title="Permalink to this headline"></a></h1>
<div class="toctree-wrapper compound">
<p class="caption"><span class="caption-text">tutorial</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
</ul>
</div>
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Philip Morlier.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -42,17 +42,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,211 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Subscription &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Tracer" href="tracer.html" />
<link rel="prev" title="RPC Methods" href="RPC_method.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Plugeth
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption"><span class="caption-text">Overview</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="project.html">Project Design</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="custom.html">Building a Custom Plugin</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="RPC_method.html">RPC Methods</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Subscription</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#getapis">GetAPIs</a></li>
<li class="toctree-l3"><a class="reference internal" href="#subscription-function">Subscription Function</a></li>
<li class="toctree-l3"><a class="reference internal" href="#access">Access</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="tracer.html">Tracer</a></li>
<li class="toctree-l2"><a class="reference internal" href="custom.html#basic-implementation">Basic Implementation</a></li>
<li class="toctree-l2"><a class="reference internal" href="custom.html#specialization">Specialization</a></li>
</ul>
</li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="contact.html">Get in touch with us</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Plugeth</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li><a href="custom.html">Building a Custom Plugin</a> &raquo;</li>
<li>Subscription</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/subscription.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="subscription">
<span id="id1"></span><h1>Subscription<a class="headerlink" href="#subscription" title="Permalink to this headline"></a></h1>
<p>In addition to the initial template containing an intialize function, plugins providing <strong>Subscriptions</strong> will require two additional elements.</p>
<div class="section" id="getapis">
<h2>GetAPIs<a class="headerlink" href="#getapis" title="Permalink to this headline"></a></h2>
<p>A GetAPIs method is required in the body of the plugin in order to make the plugin available. The bulk of the implementation will be in the MyService struct. MyService should be a struct which includes two public functions.</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">type</span> <span class="nx">MyService</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="nx">backend</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Backend</span>
<span class="nx">stack</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Node</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="nx">GetAPIs</span><span class="p">(</span><span class="nx">stack</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Node</span><span class="p">,</span> <span class="nx">backend</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Backend</span><span class="p">)</span> <span class="p">[]</span><span class="nx">core</span><span class="p">.</span><span class="nx">API</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">[]</span><span class="nx">core</span><span class="p">.</span><span class="nx">API</span><span class="p">{</span>
<span class="p">{</span>
<span class="nx">Namespace</span><span class="p">:</span> <span class="s">&quot;plugeth&quot;</span><span class="p">,</span>
<span class="nx">Version</span><span class="p">:</span> <span class="s">&quot;1.0&quot;</span><span class="p">,</span>
<span class="nx">Service</span><span class="p">:</span> <span class="o">&amp;</span><span class="nx">MyService</span><span class="p">{</span><span class="nx">backend</span><span class="p">,</span> <span class="nx">stack</span><span class="p">},</span>
<span class="nx">Public</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="subscription-function">
<h2>Subscription Function<a class="headerlink" href="#subscription-function" title="Permalink to this headline"></a></h2>
<p>For subscriptions (supported on IPC and websockets), a function should take MyService as a reciever and a context.Context object as an argument and return a channel and an error. The following is a subscription function that impliments a timer.</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">func</span> <span class="p">(</span><span class="o">*</span><span class="nx">myservice</span><span class="p">)</span> <span class="nx">Timer</span><span class="p">(</span><span class="nx">ctx</span> <span class="nx">context</span><span class="p">.</span><span class="nx">Context</span><span class="p">)</span> <span class="p">(</span><span class="o">&lt;-</span><span class="kd">chan</span> <span class="kt">int64</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">ticker</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nx">NewTicker</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
<span class="nx">ch</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="kd">chan</span> <span class="kt">int64</span><span class="p">)</span>
<span class="k">go</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
<span class="k">defer</span> <span class="nx">ticker</span><span class="p">.</span><span class="nx">Stop</span><span class="p">()</span>
<span class="k">for</span> <span class="p">{</span>
<span class="k">select</span> <span class="p">{</span>
<span class="k">case</span> <span class="o">&lt;-</span><span class="nx">ctx</span><span class="p">.</span><span class="nx">Done</span><span class="p">():</span>
<span class="nb">close</span><span class="p">(</span><span class="nx">ch</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">case</span> <span class="nx">t</span> <span class="o">:=</span> <span class="o">&lt;-</span><span class="nx">ticker</span><span class="p">.</span><span class="nx">C</span><span class="p">:</span>
<span class="nx">ch</span> <span class="o">&lt;-</span> <span class="nx">t</span><span class="p">.</span><span class="nx">UnixNano</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}()</span>
<span class="k">return</span> <span class="nx">ch</span><span class="p">,</span> <span class="kc">nil</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Notice in the example above, the <code class="docutils literal notranslate"><span class="pre">ctx.Done()</span></code> or
Context.Done() method closes the channel. If this is not present the go routine will run for the life of the process.</p>
</div>
</div>
<div class="section" id="access">
<h2>Access<a class="headerlink" href="#access" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Plugins providing subscriptions can be accessed via IPC
and websockets. In the below example we will be using <a class="reference external" href="https://www.npmjs.com/package/wscat">wscat</a> to connect a websocket to a local Geth node.</p>
</div>
<p>As with pre-built plugins, a <code class="docutils literal notranslate"><span class="pre">.so</span></code> will need to be built from <code class="docutils literal notranslate"><span class="pre">main.go</span></code> and moved into <code class="docutils literal notranslate"><span class="pre">~/.ethereum/plugins</span></code>. Geth will need to be started with with <code class="docutils literal notranslate"><span class="pre">--ws</span> <span class="pre">--ws.api=mynamespace``flags.</span> <span class="pre">Additionally</span> <span class="pre">you</span> <span class="pre">will</span> <span class="pre">need</span> <span class="pre">to</span> <span class="pre">include</span> <span class="pre">a</span> <span class="pre">``--http</span></code> flag in order to access the standard json rpc methods.</p>
<p>After starting Geth, from a seperate terminal run:</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>wscat -c ws://127.0.0.1:8546
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Websockets are available via port 8546</p>
</div>
<p>Once the connection has been established from the websocket cursor enter the following argument:</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span><span class="o">{</span><span class="s2">&quot;jsonrpc&quot;</span>:<span class="s2">&quot;2.0&quot;</span>,<span class="s2">&quot;method&quot;</span>:<span class="s2">&quot;mynamespace_hello&quot;</span>,<span class="s2">&quot;params&quot;</span>:<span class="o">[]</span>,<span class="s2">&quot;id&quot;</span>:0<span class="o">}</span>
You should see that the network has responded with:
</pre></div>
</div>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span><span class="sb">``</span><span class="o">{</span><span class="s2">&quot;jsonrpc&quot;</span>:<span class="s2">&quot;2.0&quot;</span>,<span class="s2">&quot;id&quot;</span>:0,<span class="s2">&quot;result&quot;</span>:<span class="s2">&quot;Hello world&quot;</span><span class="o">}</span><span class="sb">``</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="RPC_method.html" class="btn btn-neutral float-left" title="RPC Methods" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="tracer.html" class="btn btn-neutral float-right" title="Tracer" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Philip Morlier.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -15,8 +15,8 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Plugin Loader" href="plugin_loader.html" />
<link rel="prev" title="Building a Custom Plugin" href="custom.html" />
<link rel="next" title="Version" href="version.html" />
<link rel="prev" title="Tracer" href="tracer.html" />
</head>
<body class="wy-body-for-nav">
@ -41,17 +41,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -92,8 +94,8 @@
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="custom.html" class="btn btn-neutral float-left" title="Building a Custom Plugin" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="plugin_loader.html" class="btn btn-neutral float-right" title="Plugin Loader" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
<a href="tracer.html" class="btn btn-neutral float-left" title="Tracer" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="version.html" class="btn btn-neutral float-right" title="Version" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -0,0 +1,193 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tracer &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="System Requirements" href="system_req.html" />
<link rel="prev" title="Subscription" href="subscription.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Plugeth
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption"><span class="caption-text">Overview</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="project.html">Project Design</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="custom.html">Building a Custom Plugin</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="RPC_method.html">RPC Methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="subscription.html">Subscription</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Tracer</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#myservice-struct">MyService Struct</a></li>
<li class="toctree-l3"><a class="reference internal" href="#map">Map</a></li>
<li class="toctree-l3"><a class="reference internal" href="#tracerresult-functions">TracerResult Functions</a></li>
<li class="toctree-l3"><a class="reference internal" href="#access">Access</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="custom.html#basic-implementation">Basic Implementation</a></li>
<li class="toctree-l2"><a class="reference internal" href="custom.html#specialization">Specialization</a></li>
</ul>
</li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="contact.html">Get in touch with us</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Plugeth</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li><a href="custom.html">Building a Custom Plugin</a> &raquo;</li>
<li>Tracer</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/tracer.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="tracer">
<span id="id1"></span><h1>Tracer<a class="headerlink" href="#tracer" title="Permalink to this headline"></a></h1>
<p>In addition to the initial template containing an intialize function, plugins providing <strong>Tracers</strong> will require three additional elements.</p>
<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Caution: Modifying of the values passed into tracer
functions can alter the results of the EVM execution in unpredictable ways. Additionally, some objects may be reused across calls, so data you wish to capture should be copied rather than retained be reference.</p>
</div>
<div class="section" id="myservice-struct">
<h2>MyService Struct<a class="headerlink" href="#myservice-struct" title="Permalink to this headline"></a></h2>
<p>First an empty MyService Struct.</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">type</span> <span class="nx">MyService</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="map">
<h2>Map<a class="headerlink" href="#map" title="Permalink to this headline"></a></h2>
<p>Next, a map of tracers to functions returning a <code class="docutils literal notranslate"><span class="pre">core.TracerResult</span></code> which will be implimented like so:</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">var</span> <span class="nx">Tracers</span> <span class="p">=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kd">func</span><span class="p">(</span><span class="nx">core</span><span class="p">.</span><span class="nx">StateDB</span><span class="p">)</span> <span class="nx">core</span><span class="p">.</span><span class="nx">TracerResult</span><span class="p">{</span>
<span class="s">&quot;myTracer&quot;</span><span class="p">:</span> <span class="kd">func</span><span class="p">(</span><span class="nx">core</span><span class="p">.</span><span class="nx">StateDB</span><span class="p">)</span> <span class="nx">core</span><span class="p">.</span><span class="nx">TracerResult</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">&amp;</span><span class="nx">MyBasicTracerService</span><span class="p">{}</span>
<span class="p">},</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="tracerresult-functions">
<h2>TracerResult Functions<a class="headerlink" href="#tracerresult-functions" title="Permalink to this headline"></a></h2>
<p>Finally a series of functions which points to the MyService struct and coresponds to the interface which geth anticipates.</p>
<div class="highlight-Go notranslate"><div class="highlight"><pre><span></span><span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><span class="nx">MyBasicTracerService</span><span class="p">)</span> <span class="nx">CaptureStart</span><span class="p">(</span><span class="nx">from</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Address</span><span class="p">,</span> <span class="nx">to</span> <span class="nx">core</span><span class="p">.</span><span class="nx">Address</span><span class="p">,</span> <span class="nx">create</span> <span class="kt">bool</span><span class="p">,</span> <span class="nx">input</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">gas</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">value</span> <span class="o">*</span><span class="nx">big</span><span class="p">.</span><span class="nx">Int</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><span class="nx">MyBasicTracerService</span><span class="p">)</span> <span class="nx">CaptureState</span><span class="p">(</span><span class="nx">pc</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">op</span> <span class="nx">core</span><span class="p">.</span><span class="nx">OpCode</span><span class="p">,</span> <span class="nx">gas</span><span class="p">,</span> <span class="nx">cost</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">scope</span> <span class="nx">core</span><span class="p">.</span><span class="nx">ScopeContext</span><span class="p">,</span> <span class="nx">rData</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">depth</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><span class="nx">MyBasicTracerService</span><span class="p">)</span> <span class="nx">CaptureFault</span><span class="p">(</span><span class="nx">pc</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">op</span> <span class="nx">core</span><span class="p">.</span><span class="nx">OpCode</span><span class="p">,</span> <span class="nx">gas</span><span class="p">,</span> <span class="nx">cost</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">scope</span> <span class="nx">core</span><span class="p">.</span><span class="nx">ScopeContext</span><span class="p">,</span> <span class="nx">depth</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><span class="nx">MyBasicTracerService</span><span class="p">)</span> <span class="nx">CaptureEnd</span><span class="p">(</span><span class="nx">output</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">,</span> <span class="nx">gasUsed</span> <span class="kt">uint64</span><span class="p">,</span> <span class="nx">t</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
<span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><span class="nx">MyBasicTracerService</span><span class="p">)</span> <span class="nx">Result</span><span class="p">()</span> <span class="p">(</span><span class="kd">interface</span><span class="p">{},</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;hello world&quot;</span><span class="p">,</span> <span class="kc">nil</span> <span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="access">
<h2>Access<a class="headerlink" href="#access" title="Permalink to this headline"></a></h2>
<p>As with pre-built plugins, a <code class="docutils literal notranslate"><span class="pre">.so</span></code> will need to be built from <code class="docutils literal notranslate"><span class="pre">main.go</span></code> and moved into <code class="docutils literal notranslate"><span class="pre">~/.ethereum/plugins</span></code>. Geth will need to be started with with a <code class="docutils literal notranslate"><span class="pre">--http.api+debug</span></code> flag.</p>
<p>From a terminal pass the following argument to the api:</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>curl <span class="m">127</span>.0.0.1:8545 -H <span class="s2">&quot;Content-Type: application/json&quot;</span> --data <span class="s1">&#39;{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;method&quot;:&quot;debug_traceCall&quot;,&quot;params&quot;:[{&quot;to&quot;:&quot;0x32Be343B94f860124dC4fEe278FDCBD38C102D88&quot;},&quot;latest&quot;,{&quot;tracer&quot;:&quot;myTracer&quot;}],&quot;id&quot;:0}&#39;</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The address used above is a test adress and will need to
be replaced by whatever address you wish to access. Also <code class="docutils literal notranslate"><span class="pre">traceCall</span></code> is one of several methods available for use.</p>
</div>
<p>If using the template above, the call should return:</p>
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span><span class="o">{</span><span class="s2">&quot;jsonrpc&quot;</span>:<span class="s2">&quot;2.0&quot;</span>,<span class="s2">&quot;id&quot;</span>:0,<span class="s2">&quot;result&quot;</span>:<span class="s2">&quot;hello world&quot;</span><span class="o">}</span>
</pre></div>
</div>
</div>
</div>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="subscription.html" class="btn btn-neutral float-left" title="Subscription" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="system_req.html" class="btn btn-neutral float-right" title="System Requirements" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Philip Morlier.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -15,7 +15,7 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Run" href="run.html" />
<link rel="next" title="Install" href="install.html" />
<link rel="prev" title="Project Design" href="project.html" />
</head>
@ -47,17 +47,19 @@
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="version.html">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -90,31 +92,40 @@
<div class="section" id="basic-types-of-plugins">
<span id="types"></span><h1>Basic Types of Plugins<a class="headerlink" href="#basic-types-of-plugins" title="Permalink to this headline"></a></h1>
<div class="section" id="rpc-methods">
<h2>RPC Methods<a class="headerlink" href="#rpc-methods" title="Permalink to this headline"></a></h2>
<p>In general these plugins provide new json rpc methods. They will requirre an initialize function that takes a context, loader, and logger as arguments. They will also need a GetAPIs function that takes a node and backend as arguments and returns an API.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>In order to be made available a flag: <code class="docutils literal notranslate"><span class="pre">http.api=&lt;the</span> <span class="pre">name</span> <span class="pre">of</span> <span class="pre">your</span> <span class="pre">service&gt;</span></code> will need to be appended to the command line upon starting Geth.</p>
<p>While PluGeth has been designed to be versatile and customizable, when learning the project it can be helpful to think of plugins as being of four different archetypes.</p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#rpc-methods" id="id2">RPC Methods</a></p></li>
<li><p><a class="reference internal" href="#subcommand" id="id3">Subcommand</a></p></li>
<li><p><a class="reference internal" href="#tracers" id="id4">Tracers</a></p></li>
<li><p><a class="reference internal" href="#subscriptions" id="id5">Subscriptions</a></p></li>
</ul>
</div>
<div class="section" id="rpc-methods">
<h2><a class="toc-backref" href="#id2">RPC Methods</a><a class="headerlink" href="#rpc-methods" title="Permalink to this headline"></a></h2>
<p>These plugins provide new json rpc methods to access several objects containing real time and historic data.</p>
</div>
<div class="section" id="subcommand">
<h2>Subcommand<a class="headerlink" href="#subcommand" title="Permalink to this headline"></a></h2>
<p>A subcommand redifines the total behavior of Geth and could stand on its own. I contrast with the other plugin types which, in general, are meant to capture and manipulate information, a subcommand is meant to change to overall behavior of Geth. It may do this in order to capture information but the primary fuctionality is a modulation of geth behaviour.</p>
<h2><a class="toc-backref" href="#id3">Subcommand</a><a class="headerlink" href="#subcommand" title="Permalink to this headline"></a></h2>
<p>A subcommand redifines the total behavior of Geth and could stand on its own. In contrast with the other plugin types which, in general, are meant to capture and manipulate information, a subcommand is meant to change to overall behavior of Geth. It may do this in order to capture information but the primary fuctionality is a modulation of geth behaviour.</p>
</div>
<div class="section" id="tracers">
<h2>Tracers<a class="headerlink" href="#tracers" title="Permalink to this headline"></a></h2>
<p><a href="#id1"><span class="problematic" id="id2">**</span></a>Tracers vs LiveTracers.</p>
<p>Tracers rely on historic data whereas LiveTracers run concurent with Geths verification system. LiveTracers are more generic in that they cannot control the way in which they recieve information.</p>
<h2><a class="toc-backref" href="#id4">Tracers</a><a class="headerlink" href="#tracers" title="Permalink to this headline"></a></h2>
<p>Tracers rely on historic data recompiled after execution to give insight into a transaction.</p>
<p><strong>placeholder for eventual discusion of LiveTracers</strong></p>
</div>
<div class="section" id="subscriptions">
<h2>Subscriptions<a class="headerlink" href="#subscriptions" title="Permalink to this headline"></a></h2>
<p>A subscription must take a context.context as an argument and return a channel and an error. Subscriptions require a stable connection and return contant information. Subscriptions require a websocket connection and pass a json argument such as: <code class="docutils literal notranslate"><span class="pre">{&quot;jsonrpc&quot;:&quot;2.0&quot;,</span> <span class="pre">&quot;id&quot;:</span> <span class="pre">0,</span> <span class="pre">&quot;method&quot;:</span> <span class="pre">&quot;namespace_subscribe&quot;,</span> <span class="pre">&quot;params&quot;:</span> <span class="pre">[&quot;subscriptionName&quot;,</span> <span class="pre">$args...]}</span></code></p>
<h2><a class="toc-backref" href="#id5">Subscriptions</a><a class="headerlink" href="#subscriptions" title="Permalink to this headline"></a></h2>
<p>Subscriptions provide real time notification of data from the EVM as it processes transactions.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Plugins are not limited to a singular functionality and can be customized to operate as hybrids of the above archtypes.</p>
<p>Plugins are not limited to a singular functionality and can be customized to operate as hybrids of the above. See <a class="reference external" href="https://github.com/openrelayxyz/plugeth-plugins/tree/master/packages/blockupdates">blockupdates</a> as an example.</p>
</div>
<div class="admonition-todo admonition" id="id1">
<p class="admonition-title">Todo</p>
<p>Austin: I dont love this page. The informations is too
shallow.</p>
</div>
<p><strong>todo: this page needs a lot of work</strong></p>
</div>
</div>
@ -123,7 +134,7 @@
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="project.html" class="btn btn-neutral float-left" title="Project Design" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="run.html" class="btn btn-neutral float-right" title="Run" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
<a href="install.html" class="btn btn-neutral float-right" title="Install" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -1,116 +0,0 @@
<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PluGeth Utils &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
<![endif]-->
<script id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Plugeth
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption"><span class="caption-text">Overview</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="project.html">Project Design</a></li>
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="run.html">Run</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
<li class="toctree-l1"><a class="reference internal" href="contact.html">Get in touch with us</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Plugeth</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>PluGeth Utils</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/utils.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="plugeth-utils">
<span id="utils"></span><h1>PluGeth Utils<a class="headerlink" href="#plugeth-utils" title="Permalink to this headline"></a></h1>
<p><strong>todo: copy on plugeth utils</strong></p>
</div>
</div>
</div>
<footer>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2021, Philip Morlier.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Run &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<title>Version &mdash; Plugeth Austin Roberts documentation</title><link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<!--[if lt IE 9]>
<script src="_static/js/html5shiv.min.js"></script>
@ -15,8 +15,8 @@
<script src="_static/js/theme.js"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Build and Deploy" href="build.html" />
<link rel="prev" title="Basic Types of Plugins" href="types.html" />
<link rel="next" title="API" href="api.html" />
<link rel="prev" title="System Requirements" href="system_req.html" />
</head>
<body class="wy-body-for-nav">
@ -40,18 +40,20 @@
<li class="toctree-l1"><a class="reference internal" href="types.html">Basic Types of Plugins</a></li>
</ul>
<p class="caption"><span class="caption-text">Tutorials</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="current reference internal" href="#">Run</a></li>
<ul>
<li class="toctree-l1"><a class="reference internal" href="install.html">Install</a></li>
<li class="toctree-l1"><a class="reference internal" href="build.html">Build and Deploy</a></li>
<li class="toctree-l1"><a class="reference internal" href="custom.html">Building a Custom Plugin</a></li>
</ul>
<p class="caption"><span class="caption-text">Reference</span></p>
<ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="system_req.html">System Requirements</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_hooks.html">Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Version</a></li>
<li class="toctree-l1"><a class="reference internal" href="api.html">API</a></li>
<li class="toctree-l1"><a class="reference internal" href="plugin_loader.html">Plugin Loader</a></li>
<li class="toctree-l1"><a class="reference internal" href="hooks.html">Selected Plugin Hooks</a></li>
<li class="toctree-l1"><a class="reference internal" href="hook_writing.html">Hook Writing Guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="core_restricted.html">Core vs Restricted packages in Plugeth-utils</a></li>
</ul>
<p class="caption"><span class="caption-text">Contact</span></p>
<ul>
@ -72,9 +74,9 @@
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
<li>Run</li>
<li>Version</li>
<li class="wy-breadcrumbs-aside">
<a href="_sources/run.rst.txt" rel="nofollow"> View page source</a>
<a href="_sources/version.rst.txt" rel="nofollow"> View page source</a>
</li>
</ul>
<hr/>
@ -82,12 +84,11 @@
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<div class="section" id="run">
<span id="id1"></span><h1>Run<a class="headerlink" href="#run" title="Permalink to this headline"></a></h1>
<div class="section" id="version">
<span id="id1"></span><h1>Version<a class="headerlink" href="#version" title="Permalink to this headline"></a></h1>
<div class="admonition-todo admonition" id="id2">
<p class="admonition-title">Todo</p>
<p>Need explination of how to download and run plugin
binaries.</p>
<p>language on version control and release scheme</p>
</div>
</div>
@ -95,8 +96,8 @@ binaries.</p>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="types.html" class="btn btn-neutral float-left" title="Basic Types of Plugins" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="build.html" class="btn btn-neutral float-right" title="Build and Deploy" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
<a href="system_req.html" class="btn btn-neutral float-left" title="System Requirements" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="api.html" class="btn btn-neutral float-right" title="API" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>

View File

@ -37,106 +37,6 @@ InitializeNode
* **Type:** func(core.Node, core.Backend)
* **Behavior:** This is called as soon as the Geth node is initialized. The core.Node object represents the running node with p2p and RPC capabilities, while the Backend gives you access to a wide array of data you may need to access.
Tracers
-------
* **Name:** Tracers
* **Type:** map[string]TracerResult
* **Behavior:** When calling debug.traceX functions (such as ``debug_traceCall`` and ``debug_traceTransaction``) the tracer can be specified as a key to this map and the tracer used will be the TracerResult specified here. TracerResult objects must match the interface:
.. code-block:: go
// CaptureStart is called at the start of each transaction
CaptureStart(env core.EVM, from core.Address, to core.Address, create bool, input []byte, gas uint64, value *big.Int) {}
// CaptureState is called for each opcode
CaptureState(env core.EVM, pc uint64, op core.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {}
// CaptureFault is called when an error occurs in the EVM
CaptureFault(env core.EVM, pc uint64, op core.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) {}
// CaptureEnd is called at the end of each transaction
CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {}
// GetResult should return a JSON serializable result object to respond to the trace call
GetResult() (interface{}, error) {}
.. warning:: Modifying the values passed into tracer functions can
alter the
results of the EVM execution in unpredictable ways. Additopackage main
import (
"github.com/openrelayxyz/plugeth-utils/core"
"gopkg.in/urfave/cli.v1"
)
var (
log core.Logger
)
type myservice struct{}
func (*myservice) Hello() string {
return "Hello world"
}
func Initialize(ctx *cli.Context, loader core.PluginLoader, logger core.Logger) {
log = logger
log.Info("Initialized hello")
}
func GetAPIs(node core.Node, backend core.Backend) []core.API {
defer log.Info("APIs Initialized")
return []core.API{
{
Namespace: "mynamespace",
Version: "1.0",
Service: &myservice{},
Public: true,
},
}
}
package main
import (
"github.com/openrelayxyz/plugeth-utils/core"
"gopkg.in/urfave/cli.v1"
)
var (
log core.Logger
)
type myservice struct{}
func (*myservice) Hello() string {
return "Hello world"
}
func Initialize(ctx *cli.Context, loader core.PluginLoader, logger core.Logger) {
log = logger
log.Info("Initialized hello")
}
func GetAPIs(node core.Node, backend core.Backend) []core.API {
defer log.Info("APIs Initialized")
return []core.API{
{
Namespace: "mynamespace",
Version: "1.0",
Service: &myservice{},
Public: true,
},
}
}
nally, some objects may be reused acress calls, so data you wish to capture should be copied rather than retianed by reference.
LiveTracer
----------
* **Name:** LiveTracers
* **Type:** core.Tracer
* **Behavior:** This tracer is used for tracing transactions as they are processed within blocks. Note that if a block does not validate, some transactions may be processed that don't end up in blocks, so be sure to check transactions against finalized blocks.
The interface for a vm.Tracer is similar to a TracerResult (above), but does not require a ``GetResult()`` function.
GetAPIs
-------

View File

@ -6,7 +6,7 @@ Build and Deploy
.. contents:: :local:
If you are ready to start building your own plugins go ahead and start `here`_
If you are ready to start building your own plugins go ahead and start here.
Setting up the environment
**************************

View File

@ -1,24 +1,36 @@
.. _custom:
========================
Building a Custom Plugin
========================
.. toctree::
:hidden:
Before setting out to build a plugin it will be helpful to be familiar with the basic :ref:`types` of plugins. Depending on what you intend to do certain aspects of implimentation will be neccisary.
In general, no matter which type of plugin you intend to build, below are common aspects which will be shared by all plugins.
RPC_method
subscription
tracer
Most Basic implimentation
=========================
Before setting out to build a plugin it will be helpful to be familiar with the :ref:`types`. deifferent plugins will require different implimentation.
Basic Implementation
====================
A plugin will need its own package located in the Plugeth-Utils packages directory. The package will need to include a main.go from which the .so file will be built. The package and main file should share the same name and the name should be a word that describes the basic functionality of the plugin.
In general, no matter which type of plugin you intend to build, all will share some common aspects.
All plugins will need to be initialized with an **initialize function**. The initialize function will need to be passed at least three arguments: a cli.Context, core.PluginLoader, and a core.Logger.
Package
-------
And so, all plugins will have an intial template that looks something like this:
Any plugin will need its own package located in the Plugeth-Plugins packages directory. The package will need to include a main.go from which the .so file will be built. The package and main file should share the same name and the name should be a word that describes the basic functionality of the plugin.
Initialize
----------
Most plugins will need to be initialized with an Initialize function. The initialize function will need to be passed at least three arguments: a cli.Context, core.PluginLoader, and a core.Logger.
And so, all plugins could have an intial template that looks something like this:
.. code-block:: Go
@ -36,11 +48,36 @@ And so, all plugins will have an intial template that looks something like this:
log.Info("loaded New Custom Plugin")
}
InitializeNode
--------------
Many plugins will make use of the InitializeNode function. Implimentation will look like so:
.. code-block:: Go
func InitializeNode(stack core.Node, b core.Backend) {
backend = b
log.Info("Initialized node and backend")
}
This is called as soon as the Geth node is initialized. The core.Node object represents the running node with p2p and RPC capabilities, while the Backend gives you access to blocks and other data you may need to access.
Specialization
==============
**Hooks**
From this point implimentation becomes more specialized to the particular plugin type. Continue from here for specific instructions for the following plugins:
Plugeth provides several hooks with which data of various kinds can be captured and manipulated. Once a plugin has been initalized it will be up to the hooks utilized to determine the behavior of the plugin.
* :ref:`RPC_method`
* :ref:`subscription`
* :ref:`tracer`
.. _blockupdates: https://github.com/openrelayxyz/plugeth-plugins/blob/master/packages/blockupdates/main.go
.. _hello: https://github.com/openrelayxyz/plugeth-plugins/blob/master/packages/hello/main.go

View File

@ -0,0 +1,7 @@
.. _hook_writing:
==================
Hook Writing Guide
==================
.. todo:: guide to writing plugin hooks

View File

@ -1,29 +1,41 @@
.. _hooks:
============
=====================
Selected Plugin Hooks
=====================
Plugin Hooks
============
The key to understanding a plugin is understanding its corresponding hook. Broadly, plugin hooks can be thought of as functions which deliver a function signiture to the **plugin loader**. The signature matches that of the function(s) called by the plugin and describes the data that is being captured and how the plugin will deliver said data upon invocation.
The public plugin hook function should follow the naming convention ``Plugin$HookName``. The first argument should be a `` core.PluginLoader``, followed by any arguments required by the functions to be provided by any plugins implementing this hook.
**Public and Private Hook Functions**
Each hook provides both a Public and private version. The private plugin hook function should bear the same name as the public plugin hook function, but with a lower case first letter. The signature should match the public plugin hook function, except that the first argument referencing the PluginLoader should be removed. It should invoke the public plugin hook function on plugins.DefaultPluginLoader. It should always verify that the DefaultPluginLoader is non-nil, log warning and return if the DefaultPluginLoader has not been initialized.
**Invocation**
the private plugin hook function should be invoked, with the appropriate arguments, in a single line within the Geth codebase inorder to minimize unexpected conflicts merging upstream Geth into plugeth.
Selected Hooks
--------------
`StateUpdate`_
************
`Invocation`_
Plugeth provides several :ref:`hooks` from which the plugin can capture data from Geth. Additionally in the case of **subcommands** the provided hooks are designed to change the behavior of Geth.
Hooks are called from functions within the plugin. For example, if we wanted to bring in data from the StateUpdate hook. We would impliment it like so:
(from `blockupdates`_)
.. code-block:: Go
func StateUpdate(blockRoot core.Hash, parentRoot core.Hash, destructs map[core.Hash]struct{}, accounts map[core.Hash][]byte, storage map[core.Hash]map[core.Hash][]byte, codeUpdates map[core.Hash][]byte) {
su := &stateUpdate{
Destructs: destructs,
Accounts: accounts,
Storage: storage,
Code: codeUpdates,
}
cache.Add(blockRoot, su)
data, _ := rlp.EncodeToBytes(su)
backend.ChainDb().Put(append([]byte("su"), blockRoot.Bytes()...), data)
}
Many hooks can be deployed in an one plugin as is the case with the **BlockUpdater** plugin.
.. contents:: :local:
StateUpdate
***********
**Function Signature**:``func(root common.Hash, parentRoot common.Hash, destructs map[common.Hash]struct{}, accounts map[common.Hash][]byte, storage map[common.Hash]map[common.Hash][]byte)``
The state update plugin provides a snapshot of the state subsystem in the form of a a stateUpdate object. The stateUpdate object contains all information transformed by a transaction but not the transaction itself.
@ -33,30 +45,75 @@ Invoked for each new block, StateUpdate provides the changes to the blockchain s
``-snapshots=true``. This is the default behavior for Geth, but if you are explicitly running with ``--snapshot=false`` this function will not be invoked.
`AppendAncient`_
AppendAncient
*************
**Function Signature**:``func(number uint64, hash, header, body, receipts, td []byte)``
Invoked when the freezer moves a block from LevelDB to the ancients database. ``number`` is the number of the block. ``hash`` is the 32 byte hash of the block as a raw ``[]byte``. ``header``, ``body``, and ``receipts`` are the RLP encoded versions of their respective block elements. ``td`` is the byte encoded total difficulty of the block.
`NewHead`_
**********
GetRPCCalls
***********
Invoked when a new block becomes the canonical latest block. Note that if several blocks are processed in a group (such as during a reorg) this may not be called for each block. You should track the prior latest head if you need to process intermediate blocks.
**Function Signature**:``func(string, string, string)``
`GetRPCCalls`_
Invoked when the RPC handler registers a method call. Returns the call ``id``, method ``name``, and any ``params`` that may have been passed in.
.. todo:: missing a couple of hooks
PreProcessBlock
***************
**Function Signature**:``func(*types.Block)``
Invoked before the transactions of a block are processed. Returns a block object.
PreProcessTransaction
*********************
**Function Signature**:``func(*types.Transaction, *types.Block, int)``
Invoked before each individual transaction of a block is processed. Returns a transaction, block, and index number.
BlockProcessingError
********************
**Function Signature**:``func(*types.Transaction, *types.Block, error)``
Invoked if an error occurs while processing a transaction. This only applies to errors that would unvalidate the block were this transaction is included not errors such as reverts or opcode errors. Returns a transaction, block, and error.
NewHead
*******
**Function Signature**:``func(*types.Block, common.Hash, []*types.Log)``
Invoked when a new block becomes the canonical latest block. Returns a block, hash, and log.
.. note:: If severtal blocks are processed in a group (such as
during a reorg) this may not be called for each block. You should track the prior latest head if you need to process intermediate blocks.
NewSideBlock
************
Invoked when the RPC handler registers a method call. returns the call ``id``, method ``name``, and any ``params`` that may have been passed in.
**Function Signature**:``func(*types.Block, common.Hash, []*types.Log)``
Invoked when a block is side-chained. Returns a block, has, and logs.
.. note:: Blocks passed to this method are non-canonical blocks.
Reorg
*****
**I am struggling all of assudden with if this is really this best course of action. Giving all of this reference, seems to beg the -utils vs plugeth conversation and I am not sure that is a smart thing to get into.**
**Function Signature**:``func(common *types.Block, oldChain, newChain types.Blocks)``
Invoked when a chain reorg occurs, that is; at least one block is removed and one block is added. (``oldChain`` is a list of removed blocks, ``newChain`` is a list of newliy added blocks, and ``common`` is the latest block that is an ancestor to both oldChain and newChain.) Returns a block, a list of old blocks, and a list of new blocks.
.. _blockupdates: https://github.com/openrelayxyz/plugeth-plugins/tree/master/packages/blockupdates
.. _StateUpdate: https://github.com/openrelayxyz/plugeth/blob/develop/core/state/plugin_hooks.go
.. _Invocation: https://github.com/openrelayxyz/plugeth/blob/develop/core/state/statedb.go#L955
.. _AppendAncient: https://github.com/openrelayxyz/plugeth/blob/develop/core/rawdb/plugin_hooks.go

View File

@ -1,18 +1,14 @@
.. Plugeth documentation master file, created by
sphinx-quickstart on Tue Sep 21 16:08:24 2021.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
=======
PluGeth
=======
PluGeth is a fork of the `Go Ethereum Client Geth`_ that implements a plugin architecture, allowing developers to extend Geth's capabilities in a number of different ways using plugins, rather than having to create additional, new forks of Geth.
PluGeth is a fork of the Go Ethereum Client, `Geth`_, that implements a plugin architecture allowing developers to extend Geth's capabilities in a number of different ways using plugins rather than having to create additional new forks.
From Here:
----------
- Ready for an overview of the project and some context? :ref:`project`
- If your goal is to run existing plugns without sourcecode: :ref:`run`
- If your goal is to run existing plugns without sourcecode: :ref:`install`
- If your goal is to build and deploy existing plugins or make custom plugins: :ref:`build`
.. warning:: Right now PluGeth is in early development. We are
@ -36,7 +32,7 @@ Table of Contents
:maxdepth: 1
:caption: Tutorials
run
install
build
custom
@ -46,10 +42,12 @@ Table of Contents
:caption: Reference
system_req
plugin_loader
plugin_hooks
core_restricted
version
api
plugin_loader
hooks
hook_writing
core_restricted
.. toctree::
:maxdepth: 1
@ -58,4 +56,5 @@ Table of Contents
contact
.. _Go Ethereum Client Geth: https://github.com/ethereum/go-ethereum
.. _Geth: https://geth.ethereum.org/

29
documentation/install.rst Normal file
View File

@ -0,0 +1,29 @@
.. _install:
=======
Install
=======
PluGeth provides a pre-built PluGeth-Geth node as well as pre-built plugins available for download.
First download the latest PluGeth `binary release`_.
.. todo:: more language about installing download
Our curated list of plugin builds can be found `here`_
After downloading, move the .so files into the ~/.ethereum/plugins directory.
.. todo:: Build a binary release so as to provide a usable
example. Maybe a different example than hello so that there are two generic cases for which there are tutorials. -- or -- We should provide examples of the common scenerios in which geth has to be started with flags or connected to with web sockets.
.. _binary release: https://github.com/openrelayxyz/plugeth/releases
.. _here: https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley

View File

@ -1,7 +0,0 @@
.. _plugeth:
=======
PluGeth
=======
**to do: discussion on plugeth repository**

View File

@ -1,7 +0,0 @@
.. _plugin_hooks:
============
Plugin Hooks
============
.. todo:: guide to writing plugin hooks

View File

@ -4,6 +4,8 @@
Plugin Loader
=============
.. todo:: Ausitn, take a pass at flushing this out.
At the heart of the PluGeth project is the `PluginLoader`_.
Upon invocation the PluginLoader will parse through a list of known plugins and either return the plugin name passed to it or, if not found, append to that list. Additionally the loader will check the function signature of the plugin to assure complience with anticipated behavior. Once these checks are passed and the plugin name and function signature is validated the plugin will be invoked.

View File

@ -1,7 +0,0 @@
.. _plugins:
===============
PluGeth Plugins
===============
**todo: copy on plugeth plugins repo**

View File

@ -5,17 +5,18 @@ Project Design
==============
Design Goals
============
The upstream Geth client exists primarily to serve as a client for the Ethereum mainnet, though it also supports a number of popular testnets. Supporting the Ethereum mainnet is a big enough challenge in its own right that the Geth team generally avoids changes to support other networks, or to provide features only a small handful of users would be interested in.
Upstream Geth exists primarily to serve as a client for the Ethereum mainnet, though it also supports a number of popular testnets. Supporting the Ethereum mainnet is a big enough challenge in its own right that the Geth team generally avoids changes to support other networks, or to provide features only a small handful of users would be interested in.
The result is that many projects have forked Geth. Some implement their own consensus protocols or alter the behavior of the EVM to support other networks. Others are designed to extract information from the Ethereum mainnet in ways the standard Geth client does not support.
Creating numerous different forks to fill a variety of different needs comes with a number of drawbacks. Forks tend to drift apart from each other. Many networks that forked from Geth long ago have stopped merging updates from Geth; this makes some sense, given that those networks have moved in different directions than Geth and merging upstream changes while properly maintaining consensus rules of an existing network could prove quite challenging. But not merging changes from upstream can mean that security updates are easily missed, especially when the upstream team `obscures security updates as optimizations`_ as a matter of process.
Creating numerous different forks to fill a variety of different needs comes with a number of drawbacks. Forks tend to drift apart from each other. Many networks that forked from Geth long ago have stopped merging updates; this makes some sense, given that those networks have moved in different directions than Geth and merging upstream changes while properly maintaining consensus rules of an existing network could prove quite challenging. But not merging changes from upstream can mean that security updates are easily missed, especially when the upstream team `obscures security updates as optimizations`_ as a matter of process.
PluGeth aims to provide a single Geth fork that developers can choose to extend rather than forking the Geth project. Out of the box, PluGeth behaves exactly like upstream Geth, but by installing plugins written in Golang, developers can extend its functionality in a wide variety of ways.
Three Repositories
------------------
==================
PluGeth is an application built in three repositories:
@ -25,19 +26,21 @@ PluGeth is an application built in three repositories:
The largest of the three Repositories, PluGeth is a fork of Geth which has been modified to enable a plugin architecture. The Plugin loader, wrappers, and hooks all reside in this repository.
`PluGeth-Utils`_
***************
****************
Utils are small packages used to develop PluGeth plugins without Geth dependencies. For a more detailed analysis of the reasons see **here**
Utils are small packages used to develop PluGeth plugins without Geth dependencies. For a more detailed analysis of the reasons see :ref: `core_resticted`. Imports from Utils happen automatically and so most users need not clone a local version.
`PluGeth-Plugins`_
*****************
******************
Plugins are packages which contain premade plugins as well as a location provided for storing new custom plugins.
The packages from which plugins are buile are stored here. This repository contains premade plugins as well as providing a location for storing new custom plugins.
Dependency Scheme
-----------------
.. todo:: needs elaboration of dependency scheme
.. todo:: Language on version and releases
:ref:`version`
@ -47,4 +50,4 @@ Dependency Scheme
.. _obscures security updates as optimizations: https://blog.openrelay.xyz/vulnerability-lifecycle-framework-geth/
.. _PluGeth: https://github.com/openrelayxyz/plugeth
.. _PluGeth-Utils: https://github.com/openrelayxyz/plugeth-utils
.. _PluGeth-Plugins: https://github.com/openrelayxyz/plugeth-plugin
.. _PluGeth-Plugins: https://github.com/openrelayxyz/plugeth-plugins

View File

@ -1,13 +0,0 @@
.. _quickstart:
Quickstart
==========
.. contents:: :local:
.. toctree::
:maxdepth: 1
:caption: tutorial
build
constom

View File

@ -1,8 +0,0 @@
.. _run:
===
Run
===
.. todo:: Need explination of how to download and run plugin
binaries.

View File

@ -0,0 +1,93 @@
.. _subscription:
============
Subscription
============
In addition to the initial template containing an intialize function, plugins providing **Subscriptions** will require two additional elements.
GetAPIs
*******
A GetAPIs method is required in the body of the plugin in order to make the plugin available. The bulk of the implementation will be in the MyService struct. MyService should be a struct which includes two public functions.
.. code-block:: Go
type MyService struct {
backend core.Backend
stack core.Node
}
func GetAPIs(stack core.Node, backend core.Backend) []core.API {
return []core.API{
{
Namespace: "plugeth",
Version: "1.0",
Service: &MyService{backend, stack},
Public: true,
},
}
}
Subscription Function
*********************
For subscriptions (supported on IPC and websockets), a function should take MyService as a reciever and a context.Context object as an argument and return a channel and an error. The following is a subscription function that impliments a timer.
.. code-block:: Go
func (*myservice) Timer(ctx context.Context) (<-chan int64, error) {
ticker := time.NewTicker(time.Second)
ch := make(chan int64)
go func() {
defer ticker.Stop()
for {
select {
case <-ctx.Done():
close(ch)
return
case t := <-ticker.C:
ch <- t.UnixNano()
}
}
}()
return ch, nil
}
.. warning:: Notice in the example above, the ``ctx.Done()`` or
Context.Done() method closes the channel. If this is not present the go routine will run for the life of the process.
Access
******
.. Note:: Plugins providing subscriptions can be accessed via IPC
and websockets. In the below example we will be using `wscat`_ to connect a websocket to a local Geth node.
As with pre-built plugins, a ``.so`` will need to be built from ``main.go`` and moved into ``~/.ethereum/plugins``. Geth will need to be started with with ``--ws --ws.api=mynamespace``flags. Additionally you will need to include a ``--http`` flag in order to access the standard json rpc methods.
After starting Geth, from a seperate terminal run:
.. code-block:: shell
wscat -c ws://127.0.0.1:8546
.. Note:: Websockets are available via port 8546
Once the connection has been established from the websocket cursor enter the following argument:
.. code-block:: shell
{"jsonrpc":"2.0","method":"mynamespace_hello","params":[],"id":0}
You should see that the network has responded with:
.. code-block:: shell
``{"jsonrpc":"2.0","id":0,"result":"Hello world"}``
.. _wscat: https://www.npmjs.com/package/wscat

71
documentation/tracer.rst Normal file
View File

@ -0,0 +1,71 @@
.. _tracer:
======
Tracer
======
In addition to the initial template containing an intialize function, plugins providing **Tracers** will require three additional elements.
.. Warning:: Caution: Modifying of the values passed into tracer
functions can alter the results of the EVM execution in unpredictable ways. Additionally, some objects may be reused across calls, so data you wish to capture should be copied rather than retained be reference.
MyService Struct
****************
First an empty MyService Struct.
.. code-block:: Go
type MyService struct {
}
Map
***
Next, a map of tracers to functions returning a ``core.TracerResult`` which will be implimented like so:
.. code-block:: Go
var Tracers = map[string]func(core.StateDB) core.TracerResult{
"myTracer": func(core.StateDB) core.TracerResult {
return &MyBasicTracerService{}
},
}
TracerResult Functions
**********************
Finally a series of functions which points to the MyService struct and coresponds to the interface which geth anticipates.
.. code-block:: Go
func (b *MyBasicTracerService) CaptureStart(from core.Address, to core.Address, create bool, input []byte, gas uint64, value *big.Int) {
}
func (b *MyBasicTracerService) CaptureState(pc uint64, op core.OpCode, gas, cost uint64, scope core.ScopeContext, rData []byte, depth int, err error) {
}
func (b *MyBasicTracerService) CaptureFault(pc uint64, op core.OpCode, gas, cost uint64, scope core.ScopeContext, depth int, err error) {
}
func (b *MyBasicTracerService) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) {
}
func (b *MyBasicTracerService) Result() (interface{}, error) { return "hello world", nil }
Access
******
As with pre-built plugins, a ``.so`` will need to be built from ``main.go`` and moved into ``~/.ethereum/plugins``. Geth will need to be started with with a ``--http.api+debug`` flag.
From a terminal pass the following argument to the api:
.. code-block:: shell
curl 127.0.0.1:8545 -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"debug_traceCall","params":[{"to":"0x32Be343B94f860124dC4fEe278FDCBD38C102D88"},"latest",{"tracer":"myTracer"}],"id":0}'
.. Note:: The address used above is a test adress and will need to
be replaced by whatever address you wish to access. Also ``traceCall`` is one of several methods available for use.
If using the template above, the call should return:
.. code-block:: shell
{"jsonrpc":"2.0","id":0,"result":"hello world"}

View File

@ -4,31 +4,39 @@
Basic Types of Plugins
======================
While PluGeth has been designed to be versatile and customizable, when learning the project it can be helpful to think of plugins as being of four different archetypes.
.. contents:: :local:
RPC Methods
-----------
In general these plugins provide new json rpc methods. They will requirre an initialize function that takes a context, loader, and logger as arguments. They will also need a GetAPIs function that takes a node and backend as arguments and returns an API.
These plugins provide new json rpc methods to access several objects containing real time and historic data.
.. NOTE:: In order to be made available a flag: ``http.api=<the name of your service>`` will need to be appended to the command line upon starting Geth.
Subcommand
------------
A subcommand redifines the total behavior of Geth and could stand on its own. I contrast with the other plugin types which, in general, are meant to capture and manipulate information, a subcommand is meant to change to overall behavior of Geth. It may do this in order to capture information but the primary fuctionality is a modulation of geth behaviour.
A subcommand redifines the total behavior of Geth and could stand on its own. In contrast with the other plugin types which, in general, are meant to capture and manipulate information, a subcommand is meant to change to overall behavior of Geth. It may do this in order to capture information but the primary fuctionality is a modulation of geth behaviour.
Tracers
-------
**Tracers vs LiveTracers.
Tracers rely on historic data recompiled after execution to give insight into a transaction.
Tracers rely on historic data whereas LiveTracers run concurent with Geth's verification system. LiveTracers are more generic in that they cannot control the way in which they recieve information.
**placeholder for eventual discusion of LiveTracers**
Subscriptions
-------------
A subscription must take a context.context as an argument and return a channel and an error. Subscriptions require a stable connection and return contant information. Subscriptions require a websocket connection and pass a json argument such as: ``{"jsonrpc":"2.0", "id": 0, "method": "namespace_subscribe", "params": ["subscriptionName", $args...]}``
Subscriptions provide real time notification of data from the EVM as it processes transactions.
.. NOTE:: Plugins are not limited to a singular functionality and can be customized to operate as hybrids of the above archtypes.
.. NOTE:: Plugins are not limited to a singular functionality and can be customized to operate as hybrids of the above. See `blockupdates`_ as an example.
.. todo:: Austin: I don't love this page. The informations is too
shallow.
.. _blockupdates: https://github.com/openrelayxyz/plugeth-plugins/tree/master/packages/blockupdates
**todo: this page needs a lot of work**

View File

@ -1,7 +0,0 @@
.. _utils:
=============
PluGeth Utils
=============
**todo: copy on plugeth utils**

View File

@ -0,0 +1,7 @@
.. _version:
=======
Version
=======
.. todo:: language on version control and release scheme