add symbol extension - 覚え書き -

:::note info
追記　@ccHarvestasya さんの以下のほうが詳しいのでこっち読んだほうがいい！
:::

https://qiita.com/ccHarvestasya/items/889fa348249cfc848ee8



完全なるメモ、覚え書き、正しいかは分からん。

例として追加したい拡張機能名を`sample`とする

`/symbol/client/catapult/extensions/`
以下に追加したい拡張機能のディレクトリを作成する
```
.
├── sample/
│   ├── src/
│   │   ├── CMakeLists.txt // (c)
│   │   ├── SampleService.cpp
│   │   └── SampleService.h
│   ├── tests/ // テストはよく分からんので空でいいや
│   ├── SampleExtension.cpp
│   └── CMakeLists.txt // (b)
├── sync/ // 他の拡張が続く
├── ....
└── CMakeLists.txt // (a)
```

(a) の`CMakeLists.txt`にその拡張機能のディレクトリ名を追加

```diff_c
...
add_subdirectory(timesync)
add_subdirectory(transactionsink)
add_subdirectory(unbondedpruning)
+ add_subdirectory(sample)
```

(b) の`CMakeLists.txt`
```
cmake_minimum_required(VERSION 3.14)

catapult_define_extension(sample)
```

(c) の`CMakeLists.txt`
```
cmake_minimum_required(VERSION 3.14)

catapult_define_extension_src(sample)
```

おそらくこれでCMakeでビルドするときに色々Cで書かれてるところがいい感じにコンパイルされるんだと思うが、このへんはマジで分からん

``` SampleExtension.cpp
#include "src/SampleService.h"
#include "catapult/extensions/ProcessBootstrapper.h"

namespace catapult { namespace sample {

	namespace {
		void RegisterExtension(extensions::ProcessBootstrapper& bootstrapper) {
			bootstrapper.extensionManager().addServiceRegistrar(CreateSampleServiceRegistrar());
		}
	}
}}

extern "C" PLUGIN_API
void RegisterExtension(catapult::extensions::ProcessBootstrapper& bootstrapper) {
	catapult::sample::RegisterExtension(bootstrapper);
}
```

`addServiceRegistrar`の引数は`Create##NAME##ServiceRegistrar`の形にする
ex) NAME=Sample

``` SampleService.h
#pragma once
#include "catapult/extensions/ServiceRegistrar.h"

namespace catapult { namespace sample {
	DECLARE_SERVICE_REGISTRAR(Sample)();
}}
```

``` SampleService.cpp
#include "SampleService.h"
#include "catapult/extensions/ServiceState.h"

namespace catapult { namespace sample {

	namespace {
		class SampleServiceRegistrar : public extensions::ServiceRegistrar {
		public:
			extensions::ServiceRegistrarInfo info() const override {
				return { "Sample", extensions::ServiceRegistrarPhase::Initial };
			}

			void registerServiceCounters(extensions::ServiceLocator&) override {
				// no additional counters
			}

			void registerServices(extensions::ServiceLocator&, extensions::ServiceState& state) override {
   
				// ここに拡張機能の実態を書いていく
                (void)state;  // state is intentionally unused

			}
		};
	}

	DECLARE_SERVICE_REGISTRAR(Sample)() {
		return std::make_unique<SampleServiceRegistrar>();
	}
}}


```

最後に以下追加

``` config-extensions-server.properties
[extensions]

# api extensions
extension.filespooling = false
extension.partialtransaction = false

# addressextraction must be first because mongo and zeromq depend on extracted addresses
extension.addressextraction = false
extension.mongo = false
extension.zeromq = false

# p2p extensions
extension.harvesting = true
extension.syncsource = true

# common extensions
extension.diagnostics = true
extension.finalization = true
extension.hashcache = true
extension.networkheight = false
extension.nodediscovery = true
extension.packetserver = true
extension.pluginhandlers = true
extension.sync = true
extension.timesync = true
extension.transactionsink = true
extension.unbondedpruning = true
extension.artificialidiocy = false

# 追加行
extension.sample = true
```

とりあえず、おそらくこれで何もない空の拡張機能ができたと思う。空なので確認方法も分からずだけど。全然何をすればいいのかは分からない。
とりあえずは現実味があるのはプラグイントランザクションのほうかな

:::note info
追記　@ccHarvestasya さんの以下のほうが詳しいのでこっち読んだほうがいい！
:::

https://qiita.com/ccHarvestasya/items/889fa348249cfc848ee8