Compare commits
2 Commits
a4dbcf46c0
...
ac7c0f0558
| Author | SHA1 | Date |
|---|---|---|
|
|
ac7c0f0558 | |
|
|
896a7a7c01 |
19
README.md
19
README.md
|
|
@ -8,6 +8,25 @@ Contractless is currently in testnet. Node operators, developers, wallet testers
|
||||||
|
|
||||||
For protocol design, mining rules, balance handling, orphan correction, and Fair Proof of Work details, read the [Contractless whitepaper](https://contractless.community/contractless_whitepaper.pdf).
|
For protocol design, mining rules, balance handling, orphan correction, and Fair Proof of Work details, read the [Contractless whitepaper](https://contractless.community/contractless_whitepaper.pdf).
|
||||||
|
|
||||||
|
## Development With Codex
|
||||||
|
|
||||||
|
Contractless is designed and developed by Bruce Bates. OpenAI Codex, including the GPT-5.6 SOL model, has been used as an AI-assisted development tool.
|
||||||
|
|
||||||
|
GPT-5.6 SOL assisted with:
|
||||||
|
|
||||||
|
- Reviewing and debugging peer connection, bootstrap, handshake, and automatic reconnection behavior.
|
||||||
|
- Tracing multi-node synchronization and orphan-correction failures across source code and node logs.
|
||||||
|
- Hardening network-map monitoring and connection-state handling.
|
||||||
|
- Implementing and reviewing on-chain data-storage transaction support.
|
||||||
|
- Integrating data storage, address data, NFTs, loans, assets, and transaction history into the GUI wallet.
|
||||||
|
- Improving GUI wallet cache synchronization, cache deletion safety, and Windows file-access coordination.
|
||||||
|
- Reviewing Rust transaction validation, mempool handling, block saving, and chain-reorganization paths.
|
||||||
|
- Identifying behavioral inconsistencies between local wallet caches and RPC responses.
|
||||||
|
- Expanding and reorganizing user documentation for installation, wallets, transactions, validation tools, loans, swaps, NFTs, fees, and data storage.
|
||||||
|
- Assisting with testing, compilation checks, technical explanations, and project presentation materials.
|
||||||
|
|
||||||
|
Codex served as a development assistant. Project architecture, consensus rules, economic design, feature requirements, testing decisions, and final implementation direction remain human-controlled.
|
||||||
|
|
||||||
## System Requirements
|
## System Requirements
|
||||||
|
|
||||||
Recommended node requirements:
|
Recommended node requirements:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::encode;
|
use crate::encode;
|
||||||
use crate::records::memory::response_channels::{reserve_entry_with_context, Command};
|
use crate::records::memory::response_channels::{
|
||||||
|
delete_entry, reserve_entry_with_context, Command,
|
||||||
|
};
|
||||||
use crate::rpc::command_maps::RPC_BLOCK_HASH_AT_HEIGHT;
|
use crate::rpc::command_maps::RPC_BLOCK_HASH_AT_HEIGHT;
|
||||||
use crate::rpc::responses::RpcResponse;
|
use crate::rpc::responses::RpcResponse;
|
||||||
use crate::{timeout, Arc, Duration, Mutex, TcpStream};
|
use crate::{timeout, Arc, Duration, Mutex, TcpStream};
|
||||||
|
|
@ -11,7 +13,7 @@ pub async fn request_block_hash_at_height(
|
||||||
height: u32,
|
height: u32,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let (hashmap_key, _tx, rx) = reserve_entry_with_context(
|
let (hashmap_key, _tx, rx) = reserve_entry_with_context(
|
||||||
map,
|
map.clone(),
|
||||||
Some(RPC_BLOCK_HASH_AT_HEIGHT),
|
Some(RPC_BLOCK_HASH_AT_HEIGHT),
|
||||||
Some(connections_key.clone()),
|
Some(connections_key.clone()),
|
||||||
)
|
)
|
||||||
|
|
@ -21,7 +23,12 @@ pub async fn request_block_hash_at_height(
|
||||||
message.extend_from_slice(&hashmap_key);
|
message.extend_from_slice(&hashmap_key);
|
||||||
message.extend_from_slice(&height.to_le_bytes());
|
message.extend_from_slice(&height.to_le_bytes());
|
||||||
|
|
||||||
RpcResponse::send_raw(&stream, Some(&connections_key), &message).await;
|
if !RpcResponse::send_raw(&stream, Some(&connections_key), &message).await {
|
||||||
|
delete_entry(map, hashmap_key).await;
|
||||||
|
return Err(format!(
|
||||||
|
"Failed to send block hash request at height {height}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let mut rx = rx.lock().await;
|
let mut rx = rx.lock().await;
|
||||||
let buffer = timeout(Duration::from_secs(5), rx.recv())
|
let buffer = timeout(Duration::from_secs(5), rx.recv())
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,16 @@ async fn get_connection_counts() -> (u8, u8) {
|
||||||
(incoming, outgoing)
|
(incoming, outgoing)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn incoming_setup_stream_is_current(
|
||||||
|
connections_key: &str,
|
||||||
|
stream: &Arc<Mutex<TcpStream>>,
|
||||||
|
) -> bool {
|
||||||
|
Connection::get_stream_from_memory(connections_key)
|
||||||
|
.await
|
||||||
|
.map(|current| Arc::ptr_eq(¤t, stream))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
async fn sync_incoming_peer_before_operational(
|
async fn sync_incoming_peer_before_operational(
|
||||||
stream: Arc<Mutex<TcpStream>>,
|
stream: Arc<Mutex<TcpStream>>,
|
||||||
db: &Db,
|
db: &Db,
|
||||||
|
|
@ -225,6 +235,12 @@ async fn complete_incoming_miner_setup(
|
||||||
remove_stream_from_memory(&stream).await;
|
remove_stream_from_memory(&stream).await;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if !incoming_setup_stream_is_current(connections_key, &stream).await {
|
||||||
|
warn!(
|
||||||
|
"[startup] incoming peer setup stopped because its stream was removed or replaced: peer={connections_key}"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
mark_peer_wallet_registry_synced(connections_key).await;
|
mark_peer_wallet_registry_synced(connections_key).await;
|
||||||
|
|
||||||
if let Err(err) = register_connected_wallet(
|
if let Err(err) = register_connected_wallet(
|
||||||
|
|
@ -240,6 +256,12 @@ async fn complete_incoming_miner_setup(
|
||||||
remove_stream_from_memory(&stream).await;
|
remove_stream_from_memory(&stream).await;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if !incoming_setup_stream_is_current(connections_key, &stream).await {
|
||||||
|
warn!(
|
||||||
|
"[startup] incoming peer setup stopped because its stream was removed or replaced: peer={connections_key}"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let remote_height =
|
let remote_height =
|
||||||
match request_remote_height(stream.clone(), map.clone(), connections_key.to_string()).await
|
match request_remote_height(stream.clone(), map.clone(), connections_key.to_string()).await
|
||||||
|
|
@ -253,6 +275,12 @@ async fn complete_incoming_miner_setup(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if !incoming_setup_stream_is_current(connections_key, &stream).await {
|
||||||
|
warn!(
|
||||||
|
"[startup] incoming peer setup stopped because its stream was removed or replaced: peer={connections_key}"
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if let Err(err) = ensure_compatible_genesis(
|
if let Err(err) = ensure_compatible_genesis(
|
||||||
stream.clone(),
|
stream.clone(),
|
||||||
map.clone(),
|
map.clone(),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue