feat: feed BNS data in genesis block

This commit is contained in:
Ludovic Galabru
2020-12-21 22:40:51 -05:00
parent 1cf91bdafa
commit 96205788f4
10 changed files with 301 additions and 70 deletions

View File

@@ -108,7 +108,7 @@ export class BNSClient extends Client {
}
// (name-import (namespace (buff 20))
// (name (buff 16))
// (name (buff 48))
// (zonefile-hash (buff 20)))
async nameImport(namespace: string,
name: string,
@@ -168,7 +168,7 @@ export class BNSClient extends Client {
}
// (name-register (namespace (buff 20))
// (name (buff 16))
// (name (buff 48))
// (salt (buff 20))
// (zonefile-hash (buff 20)))
async nameRegister(namespace: string,
@@ -190,7 +190,7 @@ export class BNSClient extends Client {
}
// (name-update (namespace (buff 20))
// (name (buff 16))
// (name (buff 48))
// (zonefile-hash (buff 20)))
async nameUpdate(namespace: string,
name: string,
@@ -210,7 +210,7 @@ export class BNSClient extends Client {
}
// (name-transfer (namespace (buff 20))
// (name (buff 16))
// (name (buff 48))
// (new-owner principal)
// (zonefile-hash (optional (buff 20))))
async nameTransfer(namespace: string,
@@ -235,7 +235,7 @@ export class BNSClient extends Client {
}
// (name-revoke (namespace (buff 20))
// (name (buff 16)))
// (name (buff 48)))
async nameRevoke(namespace: string,
name: string,
params: {
@@ -253,7 +253,7 @@ export class BNSClient extends Client {
}
// (name-renewal (namespace (buff 20))
// (name (buff 16))
// (name (buff 48))
// (stx-to-burn uint)
// (new-owner (optional principal))
// (zonefile-hash (optional (buff 20))))
@@ -281,7 +281,7 @@ export class BNSClient extends Client {
}
// (get-name-zonefile (namespace (buff 20))
// (name (buff 16)))
// (name (buff 48)))
async getNameZonefile(namespace: string,
name: string,
params: {
@@ -299,7 +299,7 @@ export class BNSClient extends Client {
}
// (can-name-be-registered (namespace (buff 20))
// (name (buff 16))
// (name (buff 48))
async canNameBeRegistered(namespace: string,
name: string): Promise<Receipt> {
const args = [`0x${this.toHexString(namespace)}`, `0x${this.toHexString(name)}`];
@@ -315,7 +315,7 @@ export class BNSClient extends Client {
}
// (get-name-price (namespace (buff 20))
// (name (buff 16))
// (name (buff 48))
async getNamePrice(namespace: string,
name: string): Promise<Receipt> {
const args = [`0x${this.toHexString(namespace)}`, `0x${this.toHexString(name)}`];

View File

@@ -58,7 +58,7 @@
;;;; Data
(define-map namespaces
{ namespace: (buff 20) }
(buff 20)
{ namespace-import: principal,
revealed-at: uint,
launched-at: (optional uint),
@@ -76,16 +76,16 @@
{ hashed-salted-namespace: (buff 20), buyer: principal }
{ created-at: uint, claimed: bool, stx-burned: uint })
(define-non-fungible-token names { name: (buff 32), namespace: (buff 20) })
(define-non-fungible-token names { name: (buff 48), namespace: (buff 20) })
;; Rule 1-1 -> 1 principal, 1 name
(define-map owner-name { owner: principal } { name: (buff 32), namespace: (buff 20) })
(define-map owner-name principal { name: (buff 48), namespace: (buff 20) })
;; Only applies to non-revoked, non-expired names.
;; A principal can own many expired names (but they will be transferred away once someone re-registers them),
;; and can own many revoked names (but they do not resolve and cannot be transferred or updated).
(define-map name-properties
{ name: (buff 32), namespace: (buff 20) }
{ name: (buff 48), namespace: (buff 20) }
{ registered-at: (optional uint),
imported-at: (optional uint),
revoked-at: (optional uint),
@@ -171,13 +171,13 @@
(is-digit char)
(is-special-char char)))
(define-private (has-vowels-chars (name (buff 32)))
(define-private (has-vowels-chars (name (buff 48)))
(> (len (filter is-vowel name)) u0))
(define-private (has-nonalpha-chars (name (buff 32)))
(define-private (has-nonalpha-chars (name (buff 48)))
(> (len (filter is-nonalpha name)) u0))
(define-private (has-invalid-chars (name (buff 32)))
(define-private (has-invalid-chars (name (buff 48)))
(< (len (filter is-char-valid name)) (len name)))
(define-private (name-lease-started-at? (namespace-launched-at (optional uint))
@@ -216,7 +216,7 @@
;; Note: the following method is used in name-import and name-register. The latter ensure that the name
;; can be registered, the former does not.
(define-private (mint-or-transfer-name? (namespace (buff 20)) (name (buff 32)) (beneficiary principal))
(define-private (mint-or-transfer-name? (namespace (buff 20)) (name (buff 48)) (beneficiary principal))
(let (
(current-owner (nft-get-owner? names (tuple (name name) (namespace namespace)))))
;; The principal can register a name
@@ -233,13 +233,13 @@
beneficiary)
(err ERR_NAME_COULD_NOT_BE_MINTED))
(map-set owner-name
{ owner: beneficiary }
beneficiary
{ name: name, namespace: namespace })
(ok true))
(update-name-ownership? namespace name (unwrap-panic current-owner) beneficiary))))
(define-private (update-name-ownership? (namespace (buff 20))
(name (buff 32))
(name (buff 48))
(from principal)
(to principal))
(if (is-eq from to)
@@ -248,14 +248,14 @@
(unwrap!
(nft-transfer? names { name: name, namespace: namespace } from to)
(err ERR_NAME_COULD_NOT_BE_TRANSFERED))
(map-delete owner-name { owner: from })
(map-delete owner-name from)
(map-set owner-name
{ owner: to }
to
{ name: name, namespace: namespace })
(ok true))))
(define-private (update-zonefile-and-props (namespace (buff 20))
(name (buff 32))
(name (buff 48))
(registered-at (optional uint))
(imported-at (optional uint))
(revoked-at (optional uint))
@@ -285,7 +285,7 @@
zonefile-hash: zonefile-hash })))
(define-private (is-namespace-available (namespace (buff 20)))
(match (map-get? namespaces { namespace: namespace }) namespace-props
(match (map-get? namespaces namespace) namespace-props
(begin
;; Is the namespace launched?
(if (is-some (get launched-at namespace-props))
@@ -293,7 +293,7 @@
(> block-height (+ (get revealed-at namespace-props) NAMESPACE_LAUNCHABILITY_TTL)))) ;; Is the namespace expired?
true))
(define-private (compute-name-price (name (buff 32))
(define-private (compute-name-price (name (buff 48))
(price-function (tuple (buckets (list 16 uint))
(base uint)
(coeff uint)
@@ -422,7 +422,7 @@
;; The namespace will be set as "revealed" but not "launched", its price function, its renewal rules, its version,
;; and its import principal will be written to the `namespaces` table.
(map-set namespaces
{ namespace: namespace }
namespace
{ namespace-import: namespace-import,
revealed-at: block-height,
launched-at: none,
@@ -434,12 +434,12 @@
;; Once a namespace is revealed, the user has the option to populate it with a set of names. Each imported name is given
;; both an owner and some off-chain state. This step is optional; Namespace creators are not required to import names.
(define-public (name-import (namespace (buff 20))
(name (buff 32))
(name (buff 48))
(beneficiary principal)
(zonefile-hash (buff 20)))
(let (
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND))))
;; The name must only have valid chars
(asserts!
@@ -476,7 +476,7 @@
(define-public (namespace-ready (namespace (buff 20)))
(let (
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND))))
;; The sender principal must match the namespace's import principal
(asserts!
@@ -492,7 +492,7 @@
(err ERR_NAMESPACE_PREORDER_LAUNCHABILITY_EXPIRED))
(let ((namespace-props-updated (merge namespace-props { launched-at: (some block-height) })))
;; The namespace will be set to "launched"
(map-set namespaces { namespace: namespace } namespace-props-updated)
(map-set namespaces namespace namespace-props-updated)
;; Emit an event
(print { namespace: namespace, status: "ready", properties: namespace-props-updated })
(ok true))))
@@ -531,13 +531,13 @@
;; This is the second transaction to be sent. It reveals the salt and the name to all BNS nodes,
;; and assigns the name an initial public key hash and zone file hash
(define-public (name-register (namespace (buff 20))
(name (buff 32))
(name (buff 48))
(salt (buff 20))
(zonefile-hash (buff 20)))
(let (
(hashed-salted-fqn (hash160 (concat (concat (concat name 0x2e) namespace) salt)))
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND)))
(preorder (unwrap!
(map-get? name-preorders { hashed-salted-fqn: hashed-salted-fqn, buyer: tx-sender })
@@ -579,7 +579,7 @@
;; if you wanted to change the name's zone file contents.
;; For example, you would do this if you want to deploy your own Gaia hub and want other people to read from it.
(define-public (name-update (namespace (buff 20))
(name (buff 32))
(name (buff 48))
(zonefile-hash (buff 20)))
(let (
(data (try! (check-name-ops-preconditions namespace name))))
@@ -601,7 +601,7 @@
;; When transferring a name, you have the option to also clear the name's zone file hash (i.e. set it to null).
;; This is useful for when you send the name to someone else, so the recipient's name does not resolve to your zone file.
(define-public (name-transfer (namespace (buff 20))
(name (buff 32))
(name (buff 48))
(new-owner principal)
(zonefile-hash (optional (buff 20))))
(let (
@@ -634,7 +634,7 @@
;; The name's zone file hash is set to null to prevent it from resolving.
;; You should only do this if your private key is compromised, or if you want to render your name unusable for whatever reason.
(define-public (name-revoke (namespace (buff 20))
(name (buff 32)))
(name (buff 48)))
(let (
(data (try! (check-name-ops-preconditions namespace name))))
;; Clear the zonefile
@@ -657,13 +657,13 @@
;; You may, however, send a NAME_RENEWAL during this grace period to preserve your name.
;; If your name is in a namespace where names do not expire, then you never need to use this transaction.
(define-public (name-renewal (namespace (buff 20))
(name (buff 32))
(name (buff 48))
(stx-to-burn uint)
(new-owner (optional principal))
(zonefile-hash (optional (buff 20))))
(let (
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND)))
(owner (unwrap!
(nft-get-owner? names { name: name, namespace: namespace })
@@ -729,20 +729,20 @@
(ok (unwrap-panic
(element-at NAMESPACE_PRICE_TIERS (min u7 (- namespace-len u1)))))))
(define-read-only (get-name-price (namespace (buff 20)) (name (buff 32)))
(define-read-only (get-name-price (namespace (buff 20)) (name (buff 48)))
(let (
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND))))
(ok (compute-name-price name (get price-function namespace-props)))))
(define-read-only (check-name-ops-preconditions (namespace (buff 20)) (name (buff 32)))
(define-read-only (check-name-ops-preconditions (namespace (buff 20)) (name (buff 48)))
(let (
(owner (unwrap!
(nft-get-owner? names { name: name, namespace: namespace })
(err ERR_NAME_NOT_FOUND))) ;; The name must exist
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND)))
(name-props (unwrap!
(map-get? name-properties { name: name, namespace: namespace })
@@ -772,10 +772,10 @@
(define-read-only (can-namespace-be-registered (namespace (buff 20)))
(ok (is-namespace-available namespace)))
(define-read-only (is-name-lease-expired (namespace (buff 20)) (name (buff 32)))
(define-read-only (is-name-lease-expired (namespace (buff 20)) (name (buff 48)))
(let (
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND)))
(name-props (unwrap!
(map-get? name-properties { name: name, namespace: namespace })
@@ -786,10 +786,10 @@
(ok false)
(ok (> block-height (+ lifetime lease-started-at))))))
(define-read-only (is-name-in-grace-period (namespace (buff 20)) (name (buff 32)))
(define-read-only (is-name-in-grace-period (namespace (buff 20)) (name (buff 48)))
(let (
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND)))
(name-props (unwrap!
(map-get? name-properties { name: name, namespace: namespace })
@@ -803,7 +803,7 @@
(<= block-height (+ (+ lifetime lease-started-at) NAME_GRACE_PERIOD_DURATION)))))))
(define-read-only (can-receive-name (owner principal))
(let ((current-owned-name (map-get? owner-name { owner: owner })))
(let ((current-owned-name (map-get? owner-name owner)))
(if (is-none current-owned-name)
(ok true)
(let (
@@ -822,10 +822,10 @@
(asserts! (is-some (get revoked-at name-props)) (ok false))
(ok true))))))))
(define-read-only (can-name-be-registered (namespace (buff 20)) (name (buff 32)))
(define-read-only (can-name-be-registered (namespace (buff 20)) (name (buff 48)))
(let (
(wrapped-name-props (map-get? name-properties { name: name, namespace: namespace }))
(namespace-props (unwrap! (map-get? namespaces { namespace: namespace }) (ok false))))
(namespace-props (unwrap! (map-get? namespaces namespace) (ok false))))
;; The name must only have valid chars
(asserts!
(not (has-invalid-chars name))
@@ -842,7 +842,7 @@
;; Is lease expired?
(is-name-lease-expired namespace name))))
(define-read-only (name-resolve (namespace (buff 20)) (name (buff 32)))
(define-read-only (name-resolve (namespace (buff 20)) (name (buff 48)))
(let (
(owner (unwrap!
(nft-get-owner? names { name: name, namespace: namespace })
@@ -851,7 +851,7 @@
(map-get? name-properties { name: name, namespace: namespace })
(err ERR_NAME_NOT_FOUND)))
(namespace-props (unwrap!
(map-get? namespaces { namespace: namespace })
(map-get? namespaces namespace)
(err ERR_NAMESPACE_NOT_FOUND))))
;; The name must not be in grace period
(asserts!

View File

@@ -630,6 +630,29 @@ pub struct ChainstateAccountLockup {
pub block_height: u64,
}
#[derive(Debug, Clone)]
pub struct ChainstateBNSNamespace {
pub namespace_id: String,
pub importer: String,
pub revealed_at: u64,
pub launched_at: u64,
pub buckets: String,
pub base: u64,
pub coeff: u64,
pub nonalpha_discount: u64,
pub no_vowel_discount: u64,
pub lifetime: u64,
}
#[derive(Debug, Clone)]
pub struct ChainstateBNSName {
pub fully_qualified_name: String,
pub owner: String,
pub registered_at: u64,
pub expired_at: u64,
pub zonefile_hash: String,
}
impl ChainstateAccountLockup {
pub fn new(address: StacksAddress, amount: u64, block_height: u64) -> ChainstateAccountLockup {
ChainstateAccountLockup {
@@ -650,6 +673,10 @@ pub struct ChainStateBootData {
Option<Box<dyn FnOnce() -> Box<dyn Iterator<Item = ChainstateAccountLockup>>>>,
pub get_bulk_initial_balances:
Option<Box<dyn FnOnce() -> Box<dyn Iterator<Item = ChainstateAccountBalance>>>>,
pub get_bulk_initial_namespaces:
Option<Box<dyn FnOnce() -> Box<dyn Iterator<Item = ChainstateBNSNamespace>>>>,
pub get_bulk_initial_names:
Option<Box<dyn FnOnce() -> Box<dyn Iterator<Item = ChainstateBNSName>>>>,
}
impl ChainStateBootData {
@@ -666,6 +693,8 @@ impl ChainStateBootData {
post_flight_callback,
get_bulk_initial_lockups: None,
get_bulk_initial_balances: None,
get_bulk_initial_namespaces: None,
get_bulk_initial_names: None,
}
}
}
@@ -1001,6 +1030,148 @@ impl StacksChainState {
});
}
let bns_contract_id = boot_code_id("bns");
if let Some(get_namespaces) = boot_data.get_bulk_initial_namespaces.take() {
info!("Initializing chain with namespaces");
clarity_tx.connection().as_transaction(|clarity| {
clarity.with_clarity_db(|db| {
let initial_namespaces = get_namespaces();
for entry in initial_namespaces {
let namespace = {
let buffer = entry.namespace_id.as_bytes();
Value::buff_from(buffer.to_vec())
.expect("Invalid namespace")
};
let importer = {
let address = StacksChainState::parse_genesis_address(&entry.importer, mainnet);
Value::Principal(address)
};
let revealed_at = Value::UInt(entry.revealed_at.into());
let launched_at = Value::UInt(entry.launched_at.into());
let lifetime = Value::UInt(entry.lifetime.into());
let price_function = {
let base = Value::UInt(entry.base.into());
let coeff = Value::UInt(entry.coeff.into());
let nonalpha_discount = Value::UInt(entry.nonalpha_discount.into());
let no_vowel_discount = Value::UInt(entry.no_vowel_discount.into());
let buckets: Vec<_> = entry.buckets
.split(";")
.map(|e|
Value::UInt(e.parse::<u64>().unwrap().into()))
.collect();
TupleData::from_data(vec![
("buckets".into(), Value::list_from(buckets).unwrap()),
("base".into(), base),
("coeff".into(), coeff),
("nonalpha-discount".into(), nonalpha_discount),
("no-vowel-discount".into(), no_vowel_discount),
]).unwrap()
};
let namespace_props = Value::Tuple(
TupleData::from_data(vec![
("revealed-at".into(), revealed_at),
("launched-at".into(), Value::some(launched_at).unwrap()),
("lifetime".into(), lifetime),
("namespace-import".into(), importer),
("price-function".into(), Value::Tuple(price_function)),
])
.unwrap(),
);
db.insert_entry(
&bns_contract_id,
"namespaces",
namespace,
namespace_props,
)?;
}
Ok(())
}).unwrap();
});
}
if let Some(get_names) = boot_data.get_bulk_initial_names.take() {
info!("Initializing chain with names");
clarity_tx.connection().as_transaction(|clarity| {
clarity.with_clarity_db(|db| {
let initial_names = get_names();
for entry in initial_names {
let components: Vec<_> = entry.fully_qualified_name
.split(".")
.collect();
let namespace = {
let buffer = components[1].as_bytes();
Value::buff_from(buffer.to_vec())
.expect("Invalid namespace")
};
let name = {
let buffer = components[0].as_bytes();
Value::buff_from(buffer.to_vec())
.expect("Invalid name")
};
let fqn = Value::Tuple(TupleData::from_data(vec![
("namespace".into(), namespace),
("name".into(), name),
]).unwrap());
let owner_address = StacksChainState::parse_genesis_address(&entry.owner, mainnet);
let zonefile_hash = {
if entry.zonefile_hash.len() == 0 {
Value::buff_from(vec![]).unwrap()
} else {
let buffer = Hash160::from_hex(&entry.zonefile_hash)
.expect("Invalid zonefile_hash");
Value::buff_from(buffer.to_bytes().to_vec()).unwrap()
}
};
db.set_nft_owner(
&bns_contract_id,
"names",
&fqn,
&owner_address,
)?;
let registered_at = Value::UInt(entry.registered_at.into());
let name_props = Value::Tuple(
TupleData::from_data(vec![
("registered-at".into(), Value::some(registered_at).unwrap()),
("imported-at".into(), Value::none()),
("revoked-at".into(), Value::none()),
("zonefile-hash".into(), zonefile_hash),
])
.unwrap(),
);
db.insert_entry(
&bns_contract_id,
"name-properties",
fqn.clone(),
name_props,
)?;
db.insert_entry(
&bns_contract_id,
"owner-name",
Value::Principal(owner_address),
fqn,
)?;
}
Ok(())
}).unwrap();
});
}
if let Some(callback) = boot_data.post_flight_callback.take() {
callback(&mut clarity_tx);
}
@@ -1772,6 +1943,8 @@ pub mod test {
first_burnchain_block_timestamp: 0,
get_bulk_initial_lockups: None,
get_bulk_initial_balances: None,
get_bulk_initial_names: None,
get_bulk_initial_namespaces: None,
};
StacksChainState::open_and_exec(

View File

@@ -468,6 +468,8 @@ fn main() {
first_burnchain_block_timestamp: 0,
get_bulk_initial_lockups: None,
get_bulk_initial_balances: None,
get_bulk_initial_namespaces: None,
get_bulk_initial_names: None,
};
let (mut new_chainstate, _) = StacksChainState::open_and_exec(

View File

@@ -868,8 +868,9 @@ fn test_buff() {
"(if true \"blockstack\" \"block\")",
"(if true \"block\" \"blockstack\")",
"(len \"blockstack\")",
"(len 0x)",
];
let expected = ["(string-ascii 10)", "(string-ascii 10)", "uint"];
let expected = ["(string-ascii 10)", "(string-ascii 10)", "uint", "uint"];
let bad = [
"(fold and (list true false) 2)",
"(fold hash160 (list 1 2 3 4) 2)",

View File

@@ -713,6 +713,10 @@ fn test_buff_len() {
let test1 = "(len \"blockstack\")";
let expected = Value::UInt(10);
assert_eq!(expected, execute(test1).unwrap().unwrap());
let test2 = "(len 0x)";
let expected = Value::UInt(0);
assert_eq!(expected, execute(test2).unwrap().unwrap());
}
#[test]

View File

@@ -21,20 +21,20 @@ pub struct GenesisAccountLockup {
pub struct GenesisNamespace {
pub namespace_id: String,
pub address: String,
pub importer: String,
pub reveal_block: i64,
pub ready_block: i64,
pub buckets: String,
pub base: String,
pub coeff: String,
pub nonalpha_discount: String,
pub no_vowel_discount: String,
pub lifetime: String,
pub base: i64,
pub coeff: i64,
pub nonalpha_discount: i64,
pub no_vowel_discount: i64,
pub lifetime: i64,
}
pub struct GenesisName {
pub name: String,
pub address: String,
pub fully_qualified_name: String,
pub owner: String,
pub registered_at: i64,
pub expire_block: i64,
pub zonefile_hash: String,
@@ -114,23 +114,23 @@ fn read_lockups(deflate_bytes: &'static [u8]) -> Box<dyn Iterator<Item = Genesis
fn read_namespaces(deflate_bytes: &'static [u8]) -> Box<dyn Iterator<Item = GenesisNamespace>> {
let namespaces = iter_deflated_csv(deflate_bytes).map(|cols| GenesisNamespace {
namespace_id: cols[0].to_string(),
address: cols[1].to_string(),
importer: cols[1].to_string(),
reveal_block: cols[2].parse::<i64>().unwrap(),
ready_block: cols[3].parse::<i64>().unwrap(),
buckets: cols[4].to_string(),
base: cols[5].to_string(),
coeff: cols[6].to_string(),
nonalpha_discount: cols[7].to_string(),
no_vowel_discount: cols[8].to_string(),
lifetime: cols[9].to_string(),
base: cols[5].parse::<i64>().unwrap(),
coeff: cols[6].parse::<i64>().unwrap(),
nonalpha_discount: cols[7].parse::<i64>().unwrap(),
no_vowel_discount: cols[8].parse::<i64>().unwrap(),
lifetime: cols[9].parse::<i64>().unwrap(),
});
return Box::new(namespaces);
}
fn read_names(deflate_bytes: &'static [u8]) -> Box<dyn Iterator<Item = GenesisName>> {
let names = iter_deflated_csv(deflate_bytes).map(|cols| GenesisName {
name: cols[0].to_string(),
address: cols[1].to_string(),
fully_qualified_name: cols[0].to_string(),
owner: cols[1].to_string(),
registered_at: cols[2].parse::<i64>().unwrap(),
expire_block: cols[3].parse::<i64>().unwrap(),
zonefile_hash: cols[4].to_string(),

View File

@@ -7,7 +7,7 @@ use std::net::SocketAddr;
use std::{collections::HashSet, env};
use std::{thread, thread::JoinHandle, time};
use stacks::chainstate::burn::db::sortdb::SortitionDB;
use stacks::chainstate::{burn::db::sortdb::SortitionDB};
use stacks::chainstate::burn::operations::{
leader_block_commit::{RewardSetInfo, BURN_BLOCK_MINED_AT_MODULUS},
BlockstackOperationType, LeaderBlockCommitOp, LeaderKeyRegisterOp,
@@ -29,7 +29,7 @@ use stacks::net::{
};
use stacks::{
burnchains::{Burnchain, BurnchainHeaderHash, Txid},
chainstate::stacks::db::{ChainstateAccountBalance, ChainstateAccountLockup},
chainstate::stacks::db::{ChainstateAccountBalance, ChainstateAccountLockup, ChainstateBNSNamespace, ChainstateBNSName},
};
use stacks::chainstate::stacks::index::TrieHash;
@@ -111,6 +111,43 @@ pub fn get_account_balances(
)
}
pub fn get_namespaces(
use_test_chainstate_data: bool,
) -> Box<dyn Iterator<Item = ChainstateBNSNamespace>> {
Box::new(
stx_genesis::GenesisData::new(use_test_chainstate_data)
.read_namespaces()
.map(|item| ChainstateBNSNamespace {
namespace_id: item.namespace_id,
importer: item.importer,
revealed_at: item.reveal_block as u64,
launched_at: item.ready_block as u64,
buckets: item.buckets,
base: item.base as u64,
coeff: item.coeff as u64,
nonalpha_discount: item.nonalpha_discount as u64,
no_vowel_discount: item.no_vowel_discount as u64,
lifetime: item.lifetime as u64,
}),
)
}
pub fn get_names(
use_test_chainstate_data: bool,
) -> Box<dyn Iterator<Item = ChainstateBNSName>> {
Box::new(
stx_genesis::GenesisData::new(use_test_chainstate_data)
.read_names()
.map(|item| ChainstateBNSName {
fully_qualified_name: item.fully_qualified_name,
owner: item.owner,
registered_at: item.registered_at as u64,
expired_at: item.expire_block as u64,
zonefile_hash: item.zonefile_hash,
}),
)
}
fn spawn_peer(
mut this: PeerNetwork,
p2p_sock: &SocketAddr,
@@ -218,6 +255,13 @@ impl Node {
get_bulk_initial_balances: Some(Box::new(move || {
get_account_balances(use_test_genesis_data)
})),
get_bulk_initial_namespaces: Some(Box::new(move || {
get_namespaces(use_test_genesis_data)
})),
get_bulk_initial_names: Some(Box::new(move || {
get_names(use_test_genesis_data)
})),
};
let chain_state_result = StacksChainState::open_and_exec(

View File

@@ -1,7 +1,7 @@
use crate::{
genesis_data::USE_TEST_GENESIS_CHAINSTATE,
neon_node,
node::{get_account_balances, get_account_lockups},
node::{get_account_balances, get_account_lockups, get_namespaces, get_names},
BitcoinRegtestController, BurnchainController, Config, EventDispatcher, Keychain,
NeonGenesisNode,
};
@@ -206,6 +206,13 @@ impl RunLoop {
get_bulk_initial_balances: Some(Box::new(|| {
get_account_balances(USE_TEST_GENESIS_CHAINSTATE)
})),
get_bulk_initial_namespaces: Some(Box::new(|| {
get_namespaces(USE_TEST_GENESIS_CHAINSTATE)
})),
get_bulk_initial_names: Some(Box::new(|| {
get_names(USE_TEST_GENESIS_CHAINSTATE)
})),
};
let (chain_state_db, receipts) = StacksChainState::open_and_exec(

View File

@@ -1889,7 +1889,7 @@ fn atlas_integration_test() {
}
// (define-public (name-import (namespace (buff 20))
// (name (buff 32))
// (name (buff 48))
// (zonefile-hash (buff 20)))
let zonefile_hex = "facade00";
let hashed_zonefile = Hash160::from_data(&hex_bytes(zonefile_hex).unwrap());