Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 58 additions & 55 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NOTE: When editing this version, also edit the versions in template_built_in/templates/account and account_nft
[workspace.package]
version = "0.15.1"
version = "0.16.0"
edition = "2021"
authors = ["The Tari Development Community"]
repository = "https://github.com/tari-project/tari-ootle"
Expand Down Expand Up @@ -124,10 +124,7 @@ transaction_generator = { path = "utilities/transaction_generator" }
# external minotari/tari dependencies
minotari_app_grpc = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
minotari_app_utilities = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
minotari_console_wallet = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
minotari_node = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
minotari_node_grpc_client = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
minotari_wallet = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
minotari_wallet_grpc_client = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
tari_common = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
tari_common_sqlite = { git = "https://github.com/tari-project/tari.git", tag = "v5.1.0-rc.1" }
Expand Down Expand Up @@ -213,6 +210,7 @@ mini-moka = "0.10.0"
multiaddr = { git = "https://github.com/tari-project/rust-libp2p.git", rev = "debc01257dd979418d7793f2dc91d25471de5c38" }
#multiaddr = "0.18"
newtype-ops = "0.1.4"
num-integer = { version = "0.1.46", default-features = false }
once_cell = "1.18.0"
pin-project = "1.1"
proc-macro2 = "1.0"
Expand Down
62 changes: 54 additions & 8 deletions applications/tari_indexer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,62 @@ The indexer uses configuration files and environment variables. Key configuratio

### Command Line Options

- `-r, --api-listen-address <ADDR>`: Bind address for REST API server
- `-g, --node-grpc <URL>`: Minotari node gRPC URL for epoch oracle
- `-s, --peer-seeds <SEEDS>`: P2P peer seeds (space-separated)
- `--listener-port <PORT>`: P2P listening port
- `-i, --scanning-interval <SECONDS>`: Block scanning interval
- `--web-ui-public-api-url <URL>`: Public API URL for web UI
- `--web-ui-public-graphql-url <URL>`: Public GraphQL URL for web UI
- `--reachability <MODE>`: P2P reachability mode (reachable/unreachable)
The following options are available (use `tari_indexer --help` for the most up-to-date list):

#### Core Options
- `-h, --help`: Print help information
- `-V, --version`: Print version information

#### Configuration
- `-c, --config <CONFIG>`: Path to configuration file (default: `config/config.toml`)
- `-b, --base-path <BASE_PATH>`: Directory to store files [env: `TARI_BASE_DIR`] (default: `~/.tari`)
- `--network <NETWORK>`: Override network configuration [env: `TARI_NETWORK`]
- `-p <CONFIG_PROPERTY_OVERRIDES>`: Override config properties using fully qualified keys

#### Logging
- `-l, --log-config <LOG_CONFIG>`: Path to log configuration file
- `--log-path <LOG_PATH>`: Directory for log storage

#### API Server
- `-r, --api-listen-address <API_LISTEN_ADDRESS>`: Bind address for REST API server
- `--web-ui-public-api-url <WEB_UI_PUBLIC_API_URL>`: Public API URL for web UI [env: `TARI_INDEXER_WEB_UI_PUBLIC_API_URL`]
- `--web-ui-public-graphql-url <WEB_UI_PUBLIC_GRAPHQL_URL>`: Public GraphQL URL for web UI [env: `TARI_INDEXER_WEB_UI_PUBLIC_GRAPHQL_URL`]

#### Blockchain Scanning
- `-a, --address <ADDRESS>...`: Substate addresses to track (can be specified multiple times)
- `-i, --scanning-interval <SCANNING_INTERVAL>`: Block scanning interval in seconds

#### P2P Networking
- `-s, --peer-seeds <PEER_SEEDS>`: P2P peer seeds (can be specified multiple times)
- `--listener-port <LISTENER_PORT>`: Port to listen on for P2P connections
- `--reachability <REACHABILITY>`: P2P reachability mode (reachable/unreachable)
- `--disable-mdns`: Disable mDNS peer discovery

#### Epoch Oracle
- `-g, --epoch-oracle-minotari-node-grpc-url <URL>`: Minotari node gRPC URL [env: `TARI_INDEXER_MINOTARI_NODE_GRPC_URL`]
- `--epoch-oracle-config <EPOCH_ORACLE_CONFIG>`: Path to epoch oracle configuration file

### Example Usage

```bash
# Run with custom API address and peer seeds
./target/release/tari_indexer \
--api-listen-address 0.0.0.0:8080 \
--peer-seeds "peer1::address1" \
--peer-seeds "peer2::address2" \
--scanning-interval 10

# Run with environment variables
TARI_INDEXER_WEB_UI_PUBLIC_API_URL=http://localhost:8080 \
TARI_INDEXER_MINOTARI_NODE_GRPC_URL=http://localhost:18142 \
./target/release/tari_indexer

# Run with custom configuration
./target/release/tari_indexer \
--config /path/to/custom/config.toml \
--base-path /custom/data/directory
```

## APIs

### REST API
Expand Down
20 changes: 10 additions & 10 deletions applications/tari_validator_node/src/genesis_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use tari_template_lib::{
XTR_FAUCET_VAULT_ADDRESS,
},
models::Metadata,
prelude::{ResourceManager, ResourceType},
prelude::ResourceType,
resource::TOKEN_SYMBOL,
rule,
types::EntityId,
Expand Down Expand Up @@ -123,6 +123,15 @@ where
TTx::Target: StateStoreReadTransaction,
TTx::Addr: NodeAddressable + Serialize,
{
let value = Vault::new(ResourceContainer::Stealth {
address: STEALTH_TARI_RESOURCE_ADDRESS,
// just under 18.5 trillion tXTR
revealed_amount: u64::MAX.into(),
locked_amount: Default::default(),
});

create_substate(tx, num_preshards, XTR_FAUCET_VAULT_ADDRESS, value)?;

let value = ComponentHeader {
template_address: tari_template_builtin::XTR_FAUCET_TEMPLATE_ADDRESS,
module_name: "XtrFaucet".to_string(),
Expand All @@ -133,21 +142,12 @@ where
body: ComponentBody {
state: cbor!({
"vault" => XTR_FAUCET_VAULT_ADDRESS,
"resource_manager" => ResourceManager::get(STEALTH_TARI_RESOURCE_ADDRESS)
})
.unwrap(),
},
};
create_substate(tx, num_preshards, XTR_FAUCET_COMPONENT_ADDRESS, value)?;

let value = Vault::new(ResourceContainer::Stealth {
address: STEALTH_TARI_RESOURCE_ADDRESS,
// just under 18.5 trillion tXTR
revealed_amount: u64::MAX.into(),
locked_amount: Default::default(),
});

create_substate(tx, num_preshards, XTR_FAUCET_VAULT_ADDRESS, value)?;
Ok(())
}

Expand Down
6 changes: 3 additions & 3 deletions crates/engine/src/runtime/fee_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ impl FeeState {
});
}

let Some(amount) = resource_container.amount().to_u64_checked() else {
let Some(amount) = resource_container.unlocked_amount().to_u64_checked() else {
return Err(RuntimeError::InvalidAmount {
amount: resource_container.amount(),
amount: resource_container.unlocked_amount(),
reason: "Payed an invalid amount. Amount must be positive and not overflow".to_string(),
});
};
match self.running_total.checked_add(amount) {
Some(new_total) => self.running_total = new_total,
None => {
return Err(RuntimeError::InvalidAmount {
amount: resource_container.amount(),
amount: resource_container.unlocked_amount(),
reason: "Payed an invalid amount. Amount overflowed".to_string(),
});
},
Expand Down
75 changes: 63 additions & 12 deletions crates/engine/src/runtime/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ use tari_template_lib::{
AddressAllocationInvokeArg,
AllocateAddressResult,
BucketAction,
BucketGetAmountArg,
BucketRef,
BuiltinTemplateAction,
BurnStealthUtxoArg,
Expand Down Expand Up @@ -117,6 +118,7 @@ use tari_template_lib::{
engine_args::{SignatureAction, SignatureVerifyArg},
Amount,
EntityId,
ResourceInfo,
TemplateAddress,
},
};
Expand Down Expand Up @@ -862,7 +864,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
Ok(InvokeResult::encode(&total_supply)?)
})
},
ResourceAction::GetResourceType => {
ResourceAction::GetResourceInfo => {
let resource_address =
resource_ref
.as_resource_address()
Expand All @@ -877,8 +879,12 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
let locked = state.read_lock_substate(&SubstateId::Resource(resource_address))?;
let resource = state.get_resource(&locked)?;
let resource_type = resource.resource_type();
let divisibility = resource.divisibility();
state.unlock_substate(locked)?;
Ok(InvokeResult::encode(&resource_type)?)
Ok(InvokeResult::encode(&ResourceInfo {
resource_type,
divisibility,
})?)
})
},
ResourceAction::Mint => {
Expand Down Expand Up @@ -918,7 +924,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte

let payload = Metadata::from_iter([
("resource_type", resource.resource_type().to_string()),
("amount", resource.amount().to_string()),
("amount", resource.unlocked_amount().to_string()),
]);
self.emit_std_event("resource", "mint", resource_address, payload, state_mut)?;

Expand Down Expand Up @@ -1375,7 +1381,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
let resource_type = state.get_resource(&resource_lock)?.resource_type();
let vault_id = state.id_provider()?.new_vault_id()?;
let resource = match resource_type {
ResourceType::Fungible => ResourceContainer::fungible(*resource_address, Amount::zero()),
ResourceType::Fungible => ResourceContainer::public_fungible(*resource_address, Amount::zero()),
ResourceType::NonFungible => {
ResourceContainer::non_fungible(*resource_address, Default::default())
},
Expand Down Expand Up @@ -1458,7 +1464,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
let payload = Metadata::from_iter([
("resource_address", bucket.resource_address().to_string()),
("resource_type", bucket.resource_type().to_string()),
("amount", bucket.amount().to_string()),
("amount", bucket.unlocked_amount().to_string()),
]);

self.emit_std_event("vault", "deposit", vault_id, payload, state_mut)?;
Expand Down Expand Up @@ -1691,7 +1697,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
container.deposit(revealed)?;
}
}
if container.amount().is_zero() {
if container.unlocked_amount().is_zero() {
return Err(RuntimeError::InvalidArgument {
argument: "TakeFeesArg",
reason: "Fee payment has zero value".to_string(),
Expand All @@ -1702,7 +1708,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
"vault",
"pay_fee",
vault_id,
Metadata::from_iter([("amount", container.amount().to_string())]),
Metadata::from_iter([("amount", container.unlocked_amount().to_string())]),
state_mut,
)?;

Expand Down Expand Up @@ -1934,10 +1940,36 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
reason: "GetAmount bucket action requires a bucket id".to_string(),
})?;

args.assert_no_args("Bucket::GetAmount")?;
let arg: BucketGetAmountArg = args.assert_one_arg()?;
self.tracker.read_with(|state| {
let bucket = state.get_bucket(bucket_id)?;
Ok(InvokeResult::encode(&bucket.amount())?)
match arg {
BucketGetAmountArg::AmountOnly => Ok(InvokeResult::encode(&bucket.unlocked_amount())?),
BucketGetAmountArg::LockedOnly => Ok(InvokeResult::encode(&bucket.locked_amount())?),
BucketGetAmountArg::AmountAndLocked => {
let amount = bucket
.unlocked_amount()
.checked_add(bucket.locked_amount())
.ok_or_else(|| RuntimeError::InvariantError {
function: "BucketAction::GetAmount",
details: "Total amount overflowed".to_string(),
})?;
Ok(InvokeResult::encode(&amount)?)
},
BucketGetAmountArg::Everything => {
let amount = bucket
.unlocked_amount()
.checked_add(bucket.locked_amount())
.and_then(|a| {
a.checked_add(Amount::new(bucket.number_of_confidential_commitments().into()))
})
.ok_or_else(|| RuntimeError::InvariantError {
function: "BucketAction::GetAmount",
details: "Total amount overflowed".to_string(),
})?;
Ok(InvokeResult::encode(&amount)?)
},
}
})
},
BucketAction::Take => {
Expand Down Expand Up @@ -2028,7 +2060,7 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte

self.tracker.write_with(|state| {
let bucket = state.take_bucket(bucket_id)?;
let burnt_amount = bucket.amount();
let burnt_amount = bucket.unlocked_amount();
state.burn_bucket(bucket)?;

let resource_mut = state.get_resource_mut(&resource_lock)?;
Expand Down Expand Up @@ -2125,6 +2157,25 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
Ok(InvokeResult::encode(&bucket.number_of_confidential_commitments())?)
})
},
BucketAction::DropEmpty => {
let bucket_id = bucket_ref.bucket_id().ok_or_else(|| RuntimeError::InvalidArgument {
argument: "bucket_ref",
reason: "DropEmpty bucket action requires a bucket id".to_string(),
})?;
args.assert_no_args("Bucket::DropEmpty")?;

self.tracker.write_with(|state| {
let bucket = state.take_bucket(bucket_id)?;
if !bucket.is_empty() {
return Err(RuntimeError::InvalidArgument {
argument: "bucket_ref",
reason: "Cannot drop a non-empty bucket".to_string(),
});
}
// Drop
Comment thread
sdbondi marked this conversation as resolved.
Ok(InvokeResult::unit())
})
},
}
}

Expand Down Expand Up @@ -2320,10 +2371,10 @@ impl<TTemplateProvider: TemplateProvider<Template = LoadedTemplate>> RuntimeInte
}

// validate the bucket amount
if bucket.amount() < min_amount {
if bucket.unlocked_amount() < min_amount {
return Err(RuntimeError::AssertError(AssertError::InvalidAmount {
expected: min_amount,
got: bucket.amount(),
got: bucket.unlocked_amount(),
}));
}

Expand Down
Loading
Loading