diff --git a/Makefile b/Makefile index 153640da8..84653a03a 100755 --- a/Makefile +++ b/Makefile @@ -44,6 +44,10 @@ PROTOGEN_FROSTFS_DIR ?= $(PROTOBUF_DIR)/protogen-$(PROTOGEN_FROSTFS_VERSION) STATICCHECK_DIR ?= $(abspath $(BIN))/staticcheck STATICCHECK_VERSION_DIR ?= $(STATICCHECK_DIR)/$(STATICCHECK_VERSION) +FROSTFS_CONTRACTS_PATH=$(abspath ./../frostfs-contract) +LOCODE_DB_PATH=$(abspath ./.cache/locode_db) +LOCODE_DB_VERSION=v0.4.0 + .PHONY: help all images dep clean fmts fumpt imports test lint docker/lint prepare-release debpackage pre-commit unpre-commit @@ -234,3 +238,25 @@ debpackage: debclean: dh clean + +locode-download: + @wget -q -O ./.cache/locode_db.gz 'https://git.frostfs.info/TrueCloudLab/frostfs-locode-db/releases/download/${LOCODE_DB_VERSION}/locode_db.gz' + gzip -dfk ./.cache/locode_db.gz + +env-up: all + docker compose -f dev/docker-compose.yml up -d + @if [ ! -d "$(FROSTFS_CONTRACTS_PATH)" ]; then \ + echo "Frostfs contracts not found"; exit 1; \ + fi + ${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph init --contracts ${FROSTFS_CONTRACTS_PATH} + ${BIN}/frostfs-adm --config ./dev/adm/frostfs-adm.yml morph refill-gas --storage-wallet ./dev/storage/wallet.json --gas 10.0 + @if [ ! -f "$(LOCODE_DB_PATH)" ]; then \ + make locode-download; \ + fi + +env-down: + docker compose -f dev/docker-compose.yml down + docker volume rm -f frostfs-node_neo-go + rm -f ./.cache/.frostfs-ir-state + rm -f ./.cache/.frostfs-node-state + rm -rf ./.cache/storage \ No newline at end of file diff --git a/README.md b/README.md index c3a9bf09c..ff816f2c7 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,45 @@ To make docker images suitable for use in [frostfs-dev-env](https://github.com/T make images ``` +# Debugging + +## VSCode + +To run and debug single node cluster with VSCode: + +1. Clone and build [frostfs-contract](https://git.frostfs.info/TrueCloudLab/frostfs-contract) repository to the same directory level as `frostfs-node`. For example: + +``` +/ +├── src + ├── frostfs-node + └── frostfs-contract +``` +See `frostfs-contract`'s README.md for build instructions. + +2. Copy `launch.json` and `tasks.json` from `dev/.vscode-example` directory to `.vscode` directory. If you already have such files in `.vscode` directory, then merge them manually. + +3. Go to **Run and Debug** (`Ctrl+Shift+D`) and start `IR+Storage node` configuration. + +4. To create container and put object into it run (container and object IDs will be different): + +``` +./bin/frostfs-cli container create -r 127.0.0.1:8080 --wallet ./dev/wallet.json --policy "REP 1 IN X CBF 1 SELECT 1 FROM * AS X" --basic-acl public-read-write --await +Enter password > <- press ENTER, the is no password for wallet +CID: CfPhEuHQ2PRvM4gfBQDC4dWZY3NccovyfcnEdiq2ixju + +./bin/frostfs-cli object put -r 127.0.0.1:8080 --wallet ./dev/wallet.json --file README.md --cid CfPhEuHQ2PRvM4gfBQDC4dWZY3NccovyfcnEdiq2ixju +Enter password > + 4300 / 4300 [===========================================================================================================================================================================================================] 100.00% 0s +[README.md] Object successfully stored + OID: 78sohnudVMnPsczXqsTUcvezosan2YDNVZwDE8Kq5YwU + CID: CfPhEuHQ2PRvM4gfBQDC4dWZY3NccovyfcnEdiq2ixju + +./bin/frostfs-cli object get -r 127.0.0.1:8080 --wallet ./dev/wallet.json --cid CfPhEuHQ2PRvM4gfBQDC4dWZY3NccovyfcnEdiq2ixju --oid 78sohnudVMnPsczXqsTUcvezosan2YDNVZwDE8Kq5YwU +... + +``` + # Contributing Feel free to contribute to this project after reading the [contributing diff --git a/dev/.vscode-example/launch.json b/dev/.vscode-example/launch.json new file mode 100644 index 000000000..cf91c0d24 --- /dev/null +++ b/dev/.vscode-example/launch.json @@ -0,0 +1,89 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "IR", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "cmd/frostfs-ir", + "env": { + "FROSTFS_IR_LOGGER_LEVEL":"info", + "FROSTFS_IR_WALLET_PATH":"${workspaceFolder}/dev/ir/az.json", + "FROSTFS_IR_WALLET_ADDRESS":"Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", + "FROSTFS_IR_WALLET_PASSWORD":"one", + "FROSTFS_IR_WITHOUT_MAINNET":"true", + "FROSTFS_IR_MORPH_ENDPOINT_CLIENT_0_ADDRESS":"ws://127.0.0.1:30333/ws", + "FROSTFS_IR_MORPH_VALIDATORS":"02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2", + "FROSTFS_IR_TIMERS_EMIT":"50", + "FROSTFS_IR_TIMERS_STOP_ESTIMATION_MUL":"1", + "FROSTFS_IR_TIMERS_STOP_ESTIMATION_DIV":"4", + "FROSTFS_IR_TIMERS_COLLECT_BASIC_INCOME_MUL":"1", + "FROSTFS_IR_TIMERS_COLLECT_BASIC_INCOME_DIV":"2", + "FROSTFS_IR_TIMERS_DISTRIBUTE_BASIC_INCOME_MUL":"3", + "FROSTFS_IR_TIMERS_DISTRIBUTE_BASIC_INCOME_DIV":"4", + "FROSTFS_IR_EMIT_STORAGE_AMOUNT":"1000000000", + "FROSTFS_IR_NETMAP_CLEANER_ENABLED":"true", + "FROSTFS_IR_NETMAP_CLEANER_THRESHOLD":"3", + "FROSTFS_IR_LOCODE_DB_PATH":"${workspaceFolder}/.cache/locode_db", + "FROSTFS_IR_CONTROL_GRPC_ENDPOINT":"127.0.0.1:8090", + "FROSTFS_IR_NODE_PERSISTENT_STATE_PATH":"${workspaceFolder}/.cache/.frostfs-ir-state" + }, + "postDebugTask": "env-down" + }, + { + "name": "Storage node", + "type": "go", + "request": "launch", + "mode": "debug", + "program": "cmd/frostfs-node", + "env": { + "FROSTFS_LOGGER_LEVEL":"debug", + "FROSTFS_MORPH_DIAL_TIMEOUT":"30s", + "FROSTFS_MORPH_RPC_ENDPOINT_0_ADDRESS":"ws://127.0.0.1:30333/ws", + "FROSTFS_MORPH_RPC_ENDPOINT_0_PRIORITY":"0", + "FROSTFS_NODE_WALLET_PATH":"${workspaceFolder}/dev/storage/wallet.json", + "FROSTFS_NODE_WALLET_PASSWORD":"", + "FROSTFS_NODE_ADDRESSES":"127.0.0.1:8080", + "FROSTFS_GRPC_0_ENDPOINT":"127.0.0.1:8080", + "FROSTFS_CONTROL_GRPC_ENDPOINT":"127.0.0.1:8081", + "FROSTFS_NODE_ATTRIBUTE_0":"User-Agent:FrostFS/dev", + "FROSTFS_NODE_ATTRIBUTE_1":"UN-LOCODE:RU MOW", + "FROSTFS_NODE_PERSISTENT_STATE_PATH":"${workspaceFolder}/.cache/.frostfs-node-state", + "FROSTFS_TREE_ENABLED":"true", + "FROSTFS_OBJECT_DELETE_TOMBSTONE_LIFETIME":"10", + "FROSTFS_STORAGE_SHARD_0_WRITECACHE_ENABLED":"true", + "FROSTFS_STORAGE_SHARD_0_WRITECACHE_PATH":"${workspaceFolder}/.cache/storage/wc0", + "FROSTFS_STORAGE_SHARD_0_METABASE_PATH":"${workspaceFolder}/.cache/storage/meta0", + "FROSTFS_STORAGE_SHARD_0_BLOBSTOR_0_TYPE":"blobovnicza", + "FROSTFS_STORAGE_SHARD_0_BLOBSTOR_0_PATH":"${workspaceFolder}/.cache/storage/blobovnicza0", + "FROSTFS_STORAGE_SHARD_0_BLOBSTOR_0_DEPTH":"2", + "FROSTFS_STORAGE_SHARD_0_BLOBSTOR_0_WIDTH":"4", + "FROSTFS_STORAGE_SHARD_0_BLOBSTOR_1_TYPE":"fstree", + "FROSTFS_STORAGE_SHARD_0_BLOBSTOR_1_PATH":"${workspaceFolder}/.cache/storage/fstree0", + "FROSTFS_STORAGE_SHARD_0_BLOBSTOR_1_DEPTH":"2", + "FROSTFS_STORAGE_SHARD_0_PILORAMA_PATH":"${workspaceFolder}/.cache/storage/pilorama0", + "FROSTFS_STORAGE_SHARD_1_WRITECACHE_ENABLED":"true", + "FROSTFS_STORAGE_SHARD_1_WRITECACHE_PATH":"${workspaceFolder}/.cache/storage/wc1", + "FROSTFS_STORAGE_SHARD_1_METABASE_PATH":"${workspaceFolder}/.cache/storage/meta1", + "FROSTFS_STORAGE_SHARD_1_BLOBSTOR_0_TYPE":"blobovnicza", + "FROSTFS_STORAGE_SHARD_1_BLOBSTOR_0_PATH":"${workspaceFolder}/.cache/storage/blobovnicza1", + "FROSTFS_STORAGE_SHARD_1_BLOBSTOR_0_DEPTH":"2", + "FROSTFS_STORAGE_SHARD_1_BLOBSTOR_0_WIDTH":"4", + "FROSTFS_STORAGE_SHARD_1_BLOBSTOR_1_TYPE":"fstree", + "FROSTFS_STORAGE_SHARD_1_BLOBSTOR_1_PATH":"${workspaceFolder}/.cache/storage/fstree1", + "FROSTFS_STORAGE_SHARD_1_BLOBSTOR_1_DEPTH":"2", + "FROSTFS_STORAGE_SHARD_1_PILORAMA_PATH":"${workspaceFolder}/.cache/storage/pilorama1" + }, + "postDebugTask": "env-down" + } + ], + "compounds": [ + { + "name": "IR+Storage node", + "configurations": ["IR", "Storage node"], + "preLaunchTask": "env-up", + "stopAll": true + } + ] +} \ No newline at end of file diff --git a/dev/.vscode-example/tasks.json b/dev/.vscode-example/tasks.json new file mode 100644 index 000000000..8c6099a05 --- /dev/null +++ b/dev/.vscode-example/tasks.json @@ -0,0 +1,19 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "shell", + "label": "env-up", + "command": "make env-up", + "group": "build", + "detail": "Up debug environment" + }, + { + "type": "shell", + "label": "env-down", + "command": "make env-down", + "group": "build", + "detail": "Down debug environment" + } + ] +} \ No newline at end of file diff --git a/dev/adm/frostfs-adm.yml b/dev/adm/frostfs-adm.yml new file mode 100644 index 000000000..5dc87e70c --- /dev/null +++ b/dev/adm/frostfs-adm.yml @@ -0,0 +1,17 @@ +rpc-endpoint: http://127.0.0.1:30333 +alphabet-wallets: ./dev/ir +network: + max_object_size: 5242880 + epoch_duration: 60 + basic_income_rate: 100000000 + homomorphic_hash_disabled: false + maintenance_mode_allowed: true + fee: + audit: 10000 + candidate: 10000000000 + container: 0 + container_alias: 0 + withdraw: 100000000 +credentials: + az: "one" + contract: "one" diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml new file mode 100644 index 000000000..7e68ea02e --- /dev/null +++ b/dev/docker-compose.yml @@ -0,0 +1,16 @@ +--- + +version: "2.4" +services: + neo-go: + image: nspccdev/neo-go:0.103.0 + container_name: neo-go + command: ["node", "--config-path", "/config", "--privnet", "--debug"] + stop_signal: SIGKILL + ports: + - 30333:30333 + volumes: + - ./neo-go/protocol.privnet.yml:/config/protocol.privnet.yml + - ./neo-go/node-wallet.json:/wallets/node-wallet.json + - ./neo-go/config.yml:/wallets/config.yml + - ./neo-go/wallet.json:/wallets/wallet.json diff --git a/dev/ir/az.json b/dev/ir/az.json new file mode 100644 index 000000000..a16aec295 --- /dev/null +++ b/dev/ir/az.json @@ -0,0 +1,69 @@ +{ + "version": "3.0", + "name":null, + "accounts": [ + { + "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", + "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", + "label": "single", + "contract": { + "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "extra":null, + "isDefault": false + }, + { + "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", + "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", + "label": "consensus", + "contract": { + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "extra":null, + "isDefault": false + }, + { + "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", + "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", + "label": "committee", + "contract": { + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "extra":null, + "isDefault": true + } + ], + "scrypt": { + "n": 16384, + "r": 8, + "p": 8 + }, + "extra": { + "Tokens": null + } +} + diff --git a/dev/ir/contract.json b/dev/ir/contract.json new file mode 100644 index 000000000..310b77bd7 --- /dev/null +++ b/dev/ir/contract.json @@ -0,0 +1,30 @@ +{ + "version": "3.0", + "accounts": [ + { + "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", + "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", + "label": "", + "contract": { + "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "isDefault": false + } + ], + "scrypt": { + "n": 16384, + "r": 8, + "p": 8 + }, + "extra": { + "Tokens": null + } +} diff --git a/dev/neo-go/config.yml b/dev/neo-go/config.yml new file mode 100644 index 000000000..7b4bb29d7 --- /dev/null +++ b/dev/neo-go/config.yml @@ -0,0 +1,4 @@ +--- + +Path: "/wallets/node-wallet.json" +Password: "one" diff --git a/dev/neo-go/node-wallet.json b/dev/neo-go/node-wallet.json new file mode 100644 index 000000000..8e88b432c --- /dev/null +++ b/dev/neo-go/node-wallet.json @@ -0,0 +1,68 @@ +{ + "version": "3.0", + "name":null, + "accounts": [ + { + "address": "Nhfg3TbpwogLvDGVvAvqyThbsHgoSUKwtn", + "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", + "label": "single", + "contract": { + "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcJBVuezJw==", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "extra":null, + "isDefault": false + }, + { + "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", + "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", + "label": "consensus", + "contract": { + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "extra":null, + "isDefault": false + }, + { + "address": "NfgHwwTi3wHAS8aFAN243C5vGbkYDpqLHP", + "key": "6PYM8VdX2BSm7BSXKzV4Fz6S3R9cDLLWNrD9nMjxW352jEv3fsC8N3wNLY", + "label": "committee", + "contract": { + "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEUGe0Nw6", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "extra":null, + "isDefault": true + } + ], + "scrypt": { + "n": 16384, + "r": 8, + "p": 8 + }, + "extra": { + "Tokens": null + } +} diff --git a/dev/neo-go/protocol.privnet.yml b/dev/neo-go/protocol.privnet.yml new file mode 100644 index 000000000..8aaf774a3 --- /dev/null +++ b/dev/neo-go/protocol.privnet.yml @@ -0,0 +1,48 @@ +ProtocolConfiguration: + Magic: 15405 + MaxTraceableBlocks: 200000 + TimePerBlock: 1s + MemPoolSize: 50000 + StandbyCommittee: + - 02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2 + ValidatorsCount: 1 + SeedList: + - 0.0.0.0:20333 + VerifyTransactions: true + StateRootInHeader: true + P2PSigExtensions: true + +ApplicationConfiguration: + SkipBlockVerification: false + DBConfiguration: + Type: "boltdb" + BoltDBOptions: + FilePath: "./db/morph.bolt" + P2P: + Addresses: + - ":20333" + DialTimeout: 3s + ProtoTickInterval: 2s + PingInterval: 30s + PingTimeout: 90s + MaxPeers: 10 + AttemptConnPeers: 5 + MinPeers: 0 + Relay: true + Consensus: + Enabled: true + UnlockWallet: + Path: "./wallets/node-wallet.json" + Password: "one" + RPC: + Addresses: + - "0.0.0.0:30333" + Enabled: true + SessionEnabled: true + EnableCORSWorkaround: false + MaxGasInvoke: 100 + P2PNotary: + Enabled: true + UnlockWallet: + Path: "./wallets/node-wallet.json" + Password: "one" diff --git a/dev/neo-go/wallet.json b/dev/neo-go/wallet.json new file mode 100644 index 000000000..ce68d604c --- /dev/null +++ b/dev/neo-go/wallet.json @@ -0,0 +1,30 @@ +{ + "version": "3.0", + "accounts": [ + { + "address": "NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM", + "key": "6PYP7YrwGnLuu4WYQbEe3WJiC44aKmqwqawLsp7H3oh5vocS9xTv2ZfTp3", + "label": "", + "contract": { + "script": "DCEDGmxvu98CyjUXRfqGubpalFLXhaxPf8K3VIyipGxPz0pBVuezJw==", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "isdefault": false + } + ], + "scrypt": { + "n": 16384, + "r": 8, + "p": 8 + }, + "extra": { + "Tokens": null + } +} diff --git a/dev/storage/wallet.json b/dev/storage/wallet.json new file mode 100644 index 000000000..e5b6bb371 --- /dev/null +++ b/dev/storage/wallet.json @@ -0,0 +1,32 @@ +{ + "version":"3.0", + "accounts":[ + { + "address":"NejLbQpojKJWec4NQRMBhzsrmCyhXfGJJe", + "key":"6PYSS8ccmBcttfcw2YJh8VcNSoeQbQLuJLQ7HoKeYF5roRmGs9LUvmKcWz", + "label":"", + "contract":{ + "script":"DCECK7QEHFDWB/+HHex+TNd3g4jg6mhJ2EzL2aqPMuFqgTFBVuezJw==", + "parameters":[ + { + "name":"parameter0", + "type":"Signature" + } + ], + "deployed":false + }, + "lock":false, + "extra":null, + "isDefault":true + } + ], + "name":null, + "scrypt":{ + "n":16384, + "r":8, + "p":8 + }, + "extra":{ + "Tokens":null + } + } diff --git a/dev/wallet.json b/dev/wallet.json new file mode 100644 index 000000000..ce68d604c --- /dev/null +++ b/dev/wallet.json @@ -0,0 +1,30 @@ +{ + "version": "3.0", + "accounts": [ + { + "address": "NbUgTSFvPmsRxmGeWpuuGeJUoRoi6PErcM", + "key": "6PYP7YrwGnLuu4WYQbEe3WJiC44aKmqwqawLsp7H3oh5vocS9xTv2ZfTp3", + "label": "", + "contract": { + "script": "DCEDGmxvu98CyjUXRfqGubpalFLXhaxPf8K3VIyipGxPz0pBVuezJw==", + "parameters": [ + { + "name": "parameter0", + "type": "Signature" + } + ], + "deployed": false + }, + "lock": false, + "isdefault": false + } + ], + "scrypt": { + "n": 16384, + "r": 8, + "p": 8 + }, + "extra": { + "Tokens": null + } +}