# Goshimmer study note ## System envronment - Hardware - IBM System x3550 M4 Server -[7914IA4]- - Software - No LSB modules are available. - Distributor ID: Ubuntu - Description: Ubuntu 18.04.2 LTS - Release: 18.04 - Codename: bionic ## Preparation - Go 1.12 ## Git Repository - https://github.com/iotaledger/goshimmer ## Installation - Clone goshimmer repository - ```git clone https://github.com/iotaledger/goshimmer``` - ``` cd goshimmer/``` - Build your executable - ```go build -o shimmer``` - Run - ```./shimmer -node-disable-plugins statusscreen -node-enable-plugins "dashboard"``` #### Ports: ``` tcp 0 0 0.0.0.0:14626 0.0.0.0:* LISTEN 6093/shimmer tcp 0 0 0.0.0.0:14666 0.0.0.0:* LISTEN 6093/shimmer tcp6 0 0 :::8080 :::* LISTEN 6093/shimmer tcp6 0 0 :::8081 :::* LISTEN 6093/shimmer ``` #### Output: ![](https://i.imgur.com/TM9xbE4.png) #### Dashboard - http://node0.puyuma.org:8081/dashboard ![](https://i.imgur.com/0XJ80DL.png) ## Systemd ``` [Unit] Description=Goshimmer FullNode After=network-online.target [Service] WorkingDirectory=/{hide}/goshimmer EnvironmentFile=-/{hide} ExecStart=/{hide}/shimmer -node-disable-plugins statusscreen KillMode=process Type=simple User={hide} Group={hide} StandardOutput=syslog StandardError=syslog SyslogIdentifier={hide} [Install] WantedBy=multi-user.target ``` ## SPAM - http://node0.puyuma.org:8080/spammer?cmd=start&tps=10000 ![](https://i.imgur.com/FNoaIBW.png) ## Architecture [main.go](https://github.com/iotaledger/goshimmer/blob/master/main.go#L24) ```=golang func main() { node.Run( cli.PLUGIN, autopeering.PLUGIN, gossip.PLUGIN, gossip_on_solidification.PLUGIN, tangle.PLUGIN, bundleprocessor.PLUGIN, analysis.PLUGIN, gracefulshutdown.PLUGIN, tipselection.PLUGIN, zeromq.PLUGIN, dashboard.PLUGIN, metrics.PLUGIN, statusscreen.PLUGIN, statusscreen_tps.PLUGIN, webapi.PLUGIN, webapi_gtta.PLUGIN, webapi_spammer.PLUGIN, ) } ``` 在 [node] package , 有兩處要注意 1. [node.go](https://github.com/iotaledger/goshimmer/blob/master/packages/node/node.go#L40) ```=golang func Run(plugins ...*Plugin) *Node { node := New(plugins...) node.Run() return node } ``` 執行順序是 Run -> New -> configure -> 每個插件的 run 函數 configure會初始化全部插件的初始化 另外無法理解 node.Run() , node的結構似乎沒有run函數 2. [plugin.go](https://github.com/iotaledger/goshimmer/blob/master/packages/node/plugin.go#L26) ``` // Creates a new plugin with the given name, default status and callbacks. // The last specified callback is the mandatory run callback, while all other callbacks are configure callbacks. func NewPlugin(name string, status int, callback Callback, callbacks ...Callback) *Plugin { plugin := &Plugin{ Name: name, Status: status, Events: pluginEvents{ Configure: events.NewEvent(pluginCaller), Run: events.NewEvent(pluginCaller), }, } // make the plugin known to the parameters parameter.AddPlugin(name, status) if len(callbacks) >= 1 { plugin.Events.Configure.Attach(events.NewClosure(callback)) for _, callback = range callbacks[:len(callbacks)-1] { plugin.Events.Configure.Attach(events.NewClosure(callback)) } plugin.Events.Run.Attach(events.NewClosure(callbacks[len(callbacks)-1])) } else { plugin.Events.Run.Attach(events.NewClosure(callback)) } return plugin } ``` 每個packages或plugin , 都會有plugin.go 裡面都有 configure 與 run 函數 , configure用來初始化packages或plugin ; run用來註冊event對應的callback函數 , 或對 daemon 的backgroundWorker 註冊 callback函數 並透過NewPlugin在main.go去執行configure與run , configure先 , run後(Main.go 的 PLUGIN是個變數 , 在 plugin.go 中由NewPlugin賦值) 從以上可以得知 , 要trace某個package和plugin , 先去看對應目錄下的plugin.go ## Autopeering #### Work Flow: - [configure](https://github.com/iotaledger/goshimmer/blob/588e0fffc8b9d8dec08bb74cc0b792afbc43c228/plugins/autopeering/plugin.go#L21) ```=golang func configure(plugin *node.Plugin) { saltmanager.Configure(plugin) instances.Configure(plugin) server.Configure(plugin) protocol.Configure(plugin) peerstorage.Configure(plugin) daemon.Events.Shutdown.Attach(events.NewClosure(func() { server.Shutdown(plugin) })) configureLogging(plugin) } ``` - [run](https://github.com/iotaledger/goshimmer/blob/588e0fffc8b9d8dec08bb74cc0b792afbc43c228/plugins/autopeering/plugin.go#L35) ```=golang func run(plugin *node.Plugin) { instances.Run(plugin) server.Run(plugin) protocol.Run(plugin) } ``` #### Neighbors: According the chapter `4.2 Choosing neighbors` of [coordecide whitepaper](https://files.iota.org/papers/Coordicide_WP.pdf), neighbor can be divided into *Chosen neighbors* and *Accepted Neighbors* the definition as below: - Chosen neighbors. The neighbors that the node proactively choose from his list. - Accepted Neighbors. The neighbors that choose the node as their peer. - Accept neighbors: - [knownPeers](https://github.com/iotaledger/goshimmer/blob/master/plugins/autopeering/instances/knownpeers/instance.go) - Get from [EntryNode](https://github.com/iotaledger/goshimmer/blob/d1195f0a93a79d8d63a36a1c79eef3ebbba18d44/plugins/autopeering/parameters/parameters.go#L7) - Get from [peerstorage](https://github.com/iotaledger/goshimmer/blob/d1195f0a93a79d8d63a36a1c79eef3ebbba18d44/plugins/autopeering/peerstorage/peerstorage.go#L49) - Get from [incoming_ping](https://github.com/iotaledger/goshimmer/blob/d1195f0a93a79d8d63a36a1c79eef3ebbba18d44/plugins/autopeering/protocol/incoming_ping_processor.go) - Chosen neighbors: - [chosenPeer](https://github.com/iotaledger/goshimmer/blob/d1195f0a93a79d8d63a36a1c79eef3ebbba18d44/plugins/autopeering/protocol/outgoing_ping_processor.go#L69) - [neighborhood.LIST_INSTANCE](https://github.com/iotaledger/goshimmer/blob/d1195f0a93a79d8d63a36a1c79eef3ebbba18d44/plugins/autopeering/protocol/outgoing_ping_processor.go#L66) - [neighborhood.LIST_INSTANCE update from knownPeers](https://github.com/iotaledger/goshimmer/blob/d1195f0a93a79d8d63a36a1c79eef3ebbba18d44/plugins/autopeering/instances/neighborhood/instance.go#L43) ## Autopeering structure ![](https://i.imgur.com/biYCIbM.png) #### Issues: - Gossip duration - jkrvivian 3:56 PM: 不然我 spam 一下,看你會不會收到 - jkrvivian 3:58 PM: 開始! - ![](https://i.imgur.com/8dntXac.png) - Maybe some problem in the [distance](https://files.iota.org/papers/Coordicide_WP.pdf) calculate - I should add vivian as `EntryNode` - Private Tangle - Deploy A, B node - Remove IF `EntryNode` from A, B - A, B add neighbors to each other - SPAM from A - A, B sould be a private network and DB storage ## Tools - Peer visualize - http://storage.googleapis.com/goshimmer-visualizer/index.html - Graph of a Go program using dot format - [go-callvis](https://github.com/TrueFurby/go-callvis) - [Demo](http://node0.puyuma.org:7878) ## Reference - [Coordicide whitepaper](https://files.iota.org/papers/Coordicide_WP.pdf) - [Coordicide whitepaper (simple chinese language)](https://shimo.im/docs/F2QiPRN18eIyiY7M)