Skip to content

Commit

Permalink
feat: migrations disabling token creation and minting (#420)
Browse files Browse the repository at this point in the history
  • Loading branch information
fmorency authored Oct 16, 2024
1 parent 5166a41 commit 6818b55
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 2 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Features
1. Tests
```shell
# Unit/integration tests
$ bazel test //...
$ bazel test --config=all-features //...
# E2E integration tests
$ bazel test --config=all-features //tests/e2e/kvstore:bats-e2e-kvstore
Expand All @@ -52,7 +52,7 @@ Features
# Resiliency integration tests (Linux only - requires Docker)
$ bazel test //tests/resiliency/kvstore:bats-resiliency-kvstore
$ bazel test --config=bats-resiliency-ledger //tests/resiliency/ledger:bats-resiliency-ledger
$ bazel test --config=all-features //tests/resiliency/ledger:bats-resiliency-ledger
```

# Usage example
Expand Down
2 changes: 2 additions & 0 deletions src/many-ledger/src/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use many_migration::{InnerMigration, MigrationSet};

pub mod block_9400;
pub mod data;
pub mod disable_token_create;
pub mod disable_token_mint;
pub mod legacy_remove_roles;
pub mod memo;
pub mod token_create;
Expand Down
12 changes: 12 additions & 0 deletions src/many-ledger/src/migration/disable_token_create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::migration::MIGRATIONS;
use linkme::distributed_slice;
use many_error::ManyError;
use many_migration::InnerMigration;

#[distributed_slice(MIGRATIONS)]
pub static DISABLE_TOKEN_CREATE_MIGRATION: InnerMigration<merk::Merk, ManyError> =
InnerMigration::new_trigger(
false,
"Disable Token Create Migration",
"Disables token creation for all",
);
12 changes: 12 additions & 0 deletions src/many-ledger/src/migration/disable_token_mint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use crate::migration::MIGRATIONS;
use linkme::distributed_slice;
use many_error::ManyError;
use many_migration::InnerMigration;

#[distributed_slice(MIGRATIONS)]
pub static DISABLE_TOKEN_MINT_MIGRATION: InnerMigration<merk::Merk, ManyError> =
InnerMigration::new_trigger(
false,
"Disable Token Mint Migration",
"Disables token mint for all",
);
11 changes: 11 additions & 0 deletions src/many-ledger/src/module/ledger_mintburn.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::error;
use crate::migration::disable_token_mint::DISABLE_TOKEN_MINT_MIGRATION;
use crate::migration::tokens::TOKEN_MIGRATION;
use crate::module::LedgerModuleImpl;
use crate::storage::ledger_tokens::verify_tokens_sender;
Expand Down Expand Up @@ -29,6 +30,16 @@ impl ledger::LedgerMintBurnModuleBackend for LedgerModuleImpl {
return Err(ManyError::invalid_method_name("tokens.mint"));
}

if self
.storage
.migrations()
.is_active(&DISABLE_TOKEN_MINT_MIGRATION)
{
return Err(ManyError::unknown(
"Token minting is disabled on this network",
));
}

let TokenMintArgs {
symbol,
distribution,
Expand Down
11 changes: 11 additions & 0 deletions src/many-ledger/src/module/ledger_tokens.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::error;
use crate::migration::disable_token_create::DISABLE_TOKEN_CREATE_MIGRATION;
use crate::migration::token_create::TOKEN_CREATE_MIGRATION;
use crate::migration::tokens::TOKEN_MIGRATION;
use crate::module::LedgerModuleImpl;
Expand Down Expand Up @@ -33,6 +34,16 @@ impl LedgerTokensModuleBackend for LedgerModuleImpl {
return Err(ManyError::invalid_method_name("tokens.create"));
}

if self
.storage
.migrations()
.is_active(&DISABLE_TOKEN_CREATE_MIGRATION)
{
return Err(ManyError::unknown(
"Token creation is disabled on this network",
));
}

if !self.storage.migrations().is_active(&TOKEN_CREATE_MIGRATION) {
use crate::storage::{ledger_tokens::TOKEN_IDENTITY_ROOT, IDENTITY_ROOT};
crate::storage::ledger_tokens::verify_tokens_sender(
Expand Down
10 changes: 10 additions & 0 deletions staging/ledger_migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,15 @@
"block_height": 0,
"upper_block_height": 0,
"disabled": true
},
{
"name": "Disable Token Create Migration",
"block_height": 0,
"disabled": true
},
{
"name": "Disable Token Mint Migration",
"block_height": 0,
"disabled": true
}
] }
95 changes: 95 additions & 0 deletions tests/resiliency/ledger/disable_token_creation_migration.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Resiliency test verifying the Disable Token Creating Migration

GIT_ROOT="$BATS_TEST_DIRNAME/../../../"
MIGRATION_ROOT="$GIT_ROOT/staging/ledger_migrations.json"
MAKEFILE="Makefile.ledger"
MFX_ADDRESS=mqbfbahksdwaqeenayy2gxke32hgb7aq4ao4wt745lsfs6wiaaaaqnz

load '../../test_helper/load'
load '../../test_helper/ledger'

function setup() {
load "test_helper/bats-assert/load"
load "test_helper/bats-support/load"

mkdir "$BATS_TEST_ROOTDIR"

# jq doesn't support bigint
jq '(.migrations[] | select(.name == "Token Migration")).block_height |= 30 |
(.migrations[] | select(.name == "Token Migration")).disabled |= empty |
(.migrations[] | select(.name == "Token Create Migration")).block_height |= 35 |
(.migrations[] | select(.name == "Token Create Migration")).disabled |= empty |
(.migrations[] | select(.name == "Disable Token Create Migration")).block_height |= 40 |
(.migrations[] | select(.name == "Disable Token Create Migration")).disabled |= empty |
(.migrations[] | select(.name == "Token Migration")) |= . + {
"token_identity": "'$(identity 1)'",
"token_next_subresource": 0,
"symbol": "'${MFX_ADDRESS}'",
"symbol_name": "Manifest Network Token",
"symbol_decimals": 9,
"symbol_total": 100000000000000,
"symbol_circulating": 100000000000000,
"symbol_maximum": null,
"symbol_owner": "'${MFX_ADDRESS}'"
}' \
"$MIGRATION_ROOT" > "$BATS_TEST_ROOTDIR/migrations.json"

(
cd "$GIT_ROOT/docker/" || exit
make -f $MAKEFILE clean
make -f $MAKEFILE start-nodes-detached \
ID_WITH_BALANCES="$(identity 1):1000000" \
MIGRATIONS="$BATS_TEST_ROOTDIR/migrations.json" || {
echo '# Could not start nodes...' >&3
exit 1
}
) > /dev/null

# Give time to the servers to start.
wait_for_server 8000 8001 8002 8003
}

function teardown() {
(
cd "$GIT_ROOT/docker/" || exit 1
make -f $MAKEFILE stop-nodes
) 2> /dev/null

# Fix for BATS verbose run/test output gathering
cd "$GIT_ROOT/tests/resiliency/ledger" || exit 1
}

@test "$SUITE: Disable Token Create Migration" {
check_consistency --pem=1 --balance=1000000 --id="$(identity 1)" 8000 8001 8002 8003

# Token endpoints should be disabled
call_ledger --pem=1 --port=8000 token info ${MFX_ADDRESS}
assert_output --partial "Invalid method name"

# Enable Token Migration
wait_for_block 30

# Token creation should fail when not using the Token Authority before the token creation migration
create_token --pem=2 --error=invalid_sender --port=8000
create_token --error=anon --port=8000

# Token endpoints should be enabled. Create a new tokens
call_ledger --pem=1 --port=8000 token create "HeyHo" "HEY" 9
assert_output --partial "name: \"HeyHo\""
assert_output --partial "ticker: \"HEY\""
assert_output --partial "decimals: 9"

# Enable Token Creation for all
wait_for_block 35

call_ledger --pem=2 --port=8000 token create "FooFoo" "FFF" 9
assert_output --partial "name: \"FooFoo\""
assert_output --partial "ticker: \"FFF\""
assert_output --partial "decimals: 9"

#Disable Token Creation for all
wait_for_block 40
create_token --pem=1 --error=disabled --port=8000
create_token --pem=2 --error=disabled --port=8000
create_token --error=anon --port=8000
}
90 changes: 90 additions & 0 deletions tests/resiliency/ledger/disable_token_minting_migration.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Resiliency test verifying the Disable Token Minting Migration

GIT_ROOT="$BATS_TEST_DIRNAME/../../../"
MIGRATION_ROOT="$GIT_ROOT/staging/ledger_migrations.json"
MAKEFILE="Makefile.ledger"
MFX_ADDRESS=mqbfbahksdwaqeenayy2gxke32hgb7aq4ao4wt745lsfs6wiaaaaqnz

load '../../test_helper/load'
load '../../test_helper/ledger'

function setup() {
load "test_helper/bats-assert/load"
load "test_helper/bats-support/load"

mkdir "$BATS_TEST_ROOTDIR"

# jq doesn't support bigint
jq '(.migrations[] | select(.name == "Token Migration")).block_height |= 30 |
(.migrations[] | select(.name == "Token Migration")).disabled |= empty |
(.migrations[] | select(.name == "Disable Token Mint Migration")).block_height |= 35 |
(.migrations[] | select(.name == "Disable Token Mint Migration")).disabled |= empty |
(.migrations[] | select(.name == "Token Migration")) |= . + {
"token_identity": "'$(identity 1)'",
"token_next_subresource": 0,
"symbol": "'${MFX_ADDRESS}'",
"symbol_name": "Manifest Network Token",
"symbol_decimals": 9,
"symbol_total": 100000000000000,
"symbol_circulating": 100000000000000,
"symbol_maximum": null,
"symbol_owner": "'${MFX_ADDRESS}'"
}' \
"$MIGRATION_ROOT" > "$BATS_TEST_ROOTDIR/migrations.json"

(
cd "$GIT_ROOT/docker/" || exit
make -f $MAKEFILE clean
make -f $MAKEFILE start-nodes-detached \
ID_WITH_BALANCES="$(identity 1):1000000" \
MIGRATIONS="$BATS_TEST_ROOTDIR/migrations.json" || {
echo '# Could not start nodes...' >&3
exit 1
}
) > /dev/null

# Give time to the servers to start.
wait_for_server 8000 8001 8002 8003
}

function teardown() {
(
cd "$GIT_ROOT/docker/" || exit 1
make -f $MAKEFILE stop-nodes
) 2> /dev/null

# Fix for BATS verbose run/test output gathering
cd "$GIT_ROOT/tests/resiliency/ledger" || exit 1
}

@test "$SUITE: Disable Token Minting Migration" {
check_consistency --pem=1 --balance=1000000 --id="$(identity 1)" 8000 8001 8002 8003

# Token endpoints should be disabled
call_ledger --pem=1 --port=8000 token info ${MFX_ADDRESS}
assert_output --partial "Invalid method name"

# Enable Token Migration
wait_for_block 30

# Token endpoints should be enabled. Mint some tokens
call_ledger --pem=1 --port=8000 token mint MFX ''\''{"'$(identity 2)'": 123, "'$(identity 3)'": 456}'\'''
check_consistency --pem=1 --balance=1000000 --id="$(identity 1)" 8000 8001 8002 8003
check_consistency --pem=2 --balance=123 8000 8001 8002 8003
check_consistency --pem=3 --balance=456 8000 8001 8002 8003

# Disable Token Minting
wait_for_block 35

# Token endpoints should be disabled
call_ledger --pem=1 --port=8000 token mint MFX ''\''{"'$(identity 2)'": 123, "'$(identity 3)'": 456}'\'''
assert_output --partial "Token minting is disabled on this network"
check_consistency --pem=1 --balance=1000000 --id="$(identity 1)" 8000 8001 8002 8003
check_consistency --pem=2 --balance=123 8000 8001 8002 8003
check_consistency --pem=3 --balance=456 8000 8001 8002 8003

# Token burn should still work
call_ledger --pem=1 --port=8000 token burn MFX ''\''{"'$(identity 2)'": 123, "'$(identity 3)'": 456}'\''' --error-on-under-burn
check_consistency --pem=2 --balance=0 8000 8001 8002 8003
check_consistency --pem=3 --balance=0 8000 8001 8002 8003
}
2 changes: 2 additions & 0 deletions tests/test_helper/token.bash
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ function create_token() {
assert_output --partial "Invalid Identity; the sender cannot be anonymous."
elif [[ $error = "invalid_sender" ]]; then
assert_output --partial "Unauthorised Token endpoints sender."
elif [[ $error = "disabled" ]]; then
assert_output --partial "Token creation is disabled on this network"
else
SYMBOL=$(echo $output | grep -oE '"m[a-z0-9]+"' | head -n 1)
assert [ ${#SYMBOL} -eq 57 ] # Check the account ID has the right length (55 chars + "")
Expand Down

0 comments on commit 6818b55

Please sign in to comment.