Skip to content

Commit

Permalink
Merge pull request #563 from Chia-Network/mempool-updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Rigidity authored Dec 2, 2024
2 parents 7f93209 + 4bfee5e commit aa54ffe
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 16 deletions.
26 changes: 20 additions & 6 deletions crates/chia-client/src/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type Requests = Arc<Mutex<HashMap<u16, oneshot::Sender<Message>>>>;
pub enum PeerEvent {
CoinStateUpdate(CoinStateUpdate),
NewPeakWallet(NewPeakWallet),
MempoolItemsAdded(MempoolItemsAdded),
MempoolItemsRemoved(MempoolItemsRemoved),
}

pub struct Peer {
Expand Down Expand Up @@ -64,18 +66,25 @@ impl Peer {
&self,
network_id: String,
node_type: NodeType,
mempool_updates: bool,
) -> Result<(), Error<()>> {
let mut capabilities = vec![
(1, "1".to_string()),
(2, "1".to_string()),
(3, "1".to_string()),
];

if mempool_updates {
capabilities.push((5, "1".to_string()));
}

let body = Handshake {
network_id,
protocol_version: "0.0.34".to_string(),
software_version: "0.0.0".to_string(),
server_port: 0,
node_type,
capabilities: vec![
(1, "1".to_string()),
(2, "1".to_string()),
(3, "1".to_string()),
],
capabilities,
};
self.send(body).await
}
Expand Down Expand Up @@ -350,7 +359,12 @@ impl Peer {
}

// TODO: Handle unexpected messages.
events!(CoinStateUpdate, NewPeakWallet);
events!(
CoinStateUpdate,
NewPeakWallet,
MempoolItemsAdded,
MempoolItemsRemoved
);

Ok(())
}
Expand Down
6 changes: 6 additions & 0 deletions crates/chia-protocol/src/chia_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ pub enum ProtocolMessageTypes {
RequestCoinState = 101,
RespondCoinState = 102,
RejectCoinState = 103,

// Wallet protocol mempool updates
MempoolItemsAdded = 104,
MempoolItemsRemoved = 105,
RequestCostInfo = 106,
RespondCostInfo = 107,
}

#[cfg(feature = "py-bindings")]
Expand Down
47 changes: 47 additions & 0 deletions crates/chia-protocol/src/wallet_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,50 @@ impl chia_traits::ChiaToPython for RejectStateReason {
Ok(pyo3::IntoPy::into_py(*self, py).bind(py).clone())
}
}

#[repr(u8)]
#[cfg_attr(feature = "py-bindings", derive(PyJsonDict, PyStreamable))]
#[derive(Streamable, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum MempoolRemoveReason {
Conflict = 1,
BlockInclusion = 2,
PoolFull = 3,
Expired = 4,
}

#[cfg(feature = "py-bindings")]
impl chia_traits::ChiaToPython for MempoolRemoveReason {
fn to_python<'a>(&self, py: pyo3::Python<'a>) -> pyo3::PyResult<pyo3::Bound<'a, pyo3::PyAny>> {
Ok(pyo3::IntoPy::into_py(*self, py).bind(py).clone())
}
}

#[streamable]
pub struct RemovedMempoolItem {
transaction_id: Bytes32,
reason: MempoolRemoveReason,
}

#[streamable(message)]
pub struct MempoolItemsAdded {
transaction_ids: Vec<Bytes32>,
}

#[streamable(message)]
pub struct MempoolItemsRemoved {
removed_items: Vec<RemovedMempoolItem>,
}

#[streamable(message)]
pub struct RequestCostInfo {}

#[streamable(message)]
pub struct RespondCostInfo {
max_transaction_cost: u64,
max_block_cost: u64,
max_mempool_cost: u64,
mempool_cost: u64,
mempool_fee: u64,
bump_fee_per_cost: u8,
}
4 changes: 3 additions & 1 deletion wheel/generate_type_stubs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
input_dir = crates_dir / "chia-protocol" / "src"

# enums are exposed to python as int
enums = set(["NodeType", "ProtocolMessageTypes", "RejectStateReason"])
enums = set(
["NodeType", "ProtocolMessageTypes", "RejectStateReason", "MempoolRemoveReason"]
)


def transform_type(m: str) -> str:
Expand Down
145 changes: 145 additions & 0 deletions wheel/python/chia_rs/chia_rs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3890,6 +3890,151 @@ class RejectCoinState:
def from_json_dict(cls, json_dict: dict[str, Any]) -> Self: ...
def replace(self, *, reason: Union[ int, _Unspec] = _Unspec()) -> RejectCoinState: ...

@final
class RemovedMempoolItem:
transaction_id: bytes32
reason: int
def __init__(
self,
transaction_id: bytes,
reason: int
) -> None: ...
def __hash__(self) -> int: ...
def __repr__(self) -> str: ...
def __deepcopy__(self, memo: object) -> RemovedMempoolItem: ...
def __copy__(self) -> RemovedMempoolItem: ...
@classmethod
def from_bytes(cls, blob: bytes) -> Self: ...
@classmethod
def from_bytes_unchecked(cls, blob: bytes) -> Self: ...
@classmethod
def parse_rust(cls, blob: ReadableBuffer, trusted: bool = False) -> tuple[Self, int]: ...
def to_bytes(self) -> bytes: ...
def __bytes__(self) -> bytes: ...
def stream_to_bytes(self) -> bytes: ...
def get_hash(self) -> bytes32: ...
def to_json_dict(self) -> dict[str, Any]: ...
@classmethod
def from_json_dict(cls, json_dict: dict[str, Any]) -> Self: ...
def replace(self, *, transaction_id: Union[ bytes32, _Unspec] = _Unspec(),
reason: Union[ int, _Unspec] = _Unspec()) -> RemovedMempoolItem: ...

@final
class MempoolItemsAdded:
transaction_ids: list[bytes32]
def __init__(
self,
transaction_ids: Sequence[bytes32]
) -> None: ...
def __hash__(self) -> int: ...
def __repr__(self) -> str: ...
def __deepcopy__(self, memo: object) -> MempoolItemsAdded: ...
def __copy__(self) -> MempoolItemsAdded: ...
@classmethod
def from_bytes(cls, blob: bytes) -> Self: ...
@classmethod
def from_bytes_unchecked(cls, blob: bytes) -> Self: ...
@classmethod
def parse_rust(cls, blob: ReadableBuffer, trusted: bool = False) -> tuple[Self, int]: ...
def to_bytes(self) -> bytes: ...
def __bytes__(self) -> bytes: ...
def stream_to_bytes(self) -> bytes: ...
def get_hash(self) -> bytes32: ...
def to_json_dict(self) -> dict[str, Any]: ...
@classmethod
def from_json_dict(cls, json_dict: dict[str, Any]) -> Self: ...
def replace(self, *, transaction_ids: Union[ list[bytes32], _Unspec] = _Unspec()) -> MempoolItemsAdded: ...

@final
class MempoolItemsRemoved:
removed_items: list[RemovedMempoolItem]
def __init__(
self,
removed_items: Sequence[RemovedMempoolItem]
) -> None: ...
def __hash__(self) -> int: ...
def __repr__(self) -> str: ...
def __deepcopy__(self, memo: object) -> MempoolItemsRemoved: ...
def __copy__(self) -> MempoolItemsRemoved: ...
@classmethod
def from_bytes(cls, blob: bytes) -> Self: ...
@classmethod
def from_bytes_unchecked(cls, blob: bytes) -> Self: ...
@classmethod
def parse_rust(cls, blob: ReadableBuffer, trusted: bool = False) -> tuple[Self, int]: ...
def to_bytes(self) -> bytes: ...
def __bytes__(self) -> bytes: ...
def stream_to_bytes(self) -> bytes: ...
def get_hash(self) -> bytes32: ...
def to_json_dict(self) -> dict[str, Any]: ...
@classmethod
def from_json_dict(cls, json_dict: dict[str, Any]) -> Self: ...
def replace(self, *, removed_items: Union[ list[RemovedMempoolItem], _Unspec] = _Unspec()) -> MempoolItemsRemoved: ...

@final
class RequestCostInfo:
def __init__(
self
) -> None: ...
def __hash__(self) -> int: ...
def __repr__(self) -> str: ...
def __deepcopy__(self, memo: object) -> RequestCostInfo: ...
def __copy__(self) -> RequestCostInfo: ...
@classmethod
def from_bytes(cls, blob: bytes) -> Self: ...
@classmethod
def from_bytes_unchecked(cls, blob: bytes) -> Self: ...
@classmethod
def parse_rust(cls, blob: ReadableBuffer, trusted: bool = False) -> tuple[Self, int]: ...
def to_bytes(self) -> bytes: ...
def __bytes__(self) -> bytes: ...
def stream_to_bytes(self) -> bytes: ...
def get_hash(self) -> bytes32: ...
def to_json_dict(self) -> dict[str, Any]: ...
@classmethod
def from_json_dict(cls, json_dict: dict[str, Any]) -> Self: ...

@final
class RespondCostInfo:
max_transaction_cost: uint64
max_block_cost: uint64
max_mempool_cost: uint64
mempool_cost: uint64
mempool_fee: uint64
bump_fee_per_cost: uint8
def __init__(
self,
max_transaction_cost: uint64,
max_block_cost: uint64,
max_mempool_cost: uint64,
mempool_cost: uint64,
mempool_fee: uint64,
bump_fee_per_cost: uint8
) -> None: ...
def __hash__(self) -> int: ...
def __repr__(self) -> str: ...
def __deepcopy__(self, memo: object) -> RespondCostInfo: ...
def __copy__(self) -> RespondCostInfo: ...
@classmethod
def from_bytes(cls, blob: bytes) -> Self: ...
@classmethod
def from_bytes_unchecked(cls, blob: bytes) -> Self: ...
@classmethod
def parse_rust(cls, blob: ReadableBuffer, trusted: bool = False) -> tuple[Self, int]: ...
def to_bytes(self) -> bytes: ...
def __bytes__(self) -> bytes: ...
def stream_to_bytes(self) -> bytes: ...
def get_hash(self) -> bytes32: ...
def to_json_dict(self) -> dict[str, Any]: ...
@classmethod
def from_json_dict(cls, json_dict: dict[str, Any]) -> Self: ...
def replace(self, *, max_transaction_cost: Union[ uint64, _Unspec] = _Unspec(),
max_block_cost: Union[ uint64, _Unspec] = _Unspec(),
max_mempool_cost: Union[ uint64, _Unspec] = _Unspec(),
mempool_cost: Union[ uint64, _Unspec] = _Unspec(),
mempool_fee: Union[ uint64, _Unspec] = _Unspec(),
bump_fee_per_cost: Union[ uint8, _Unspec] = _Unspec()) -> RespondCostInfo: ...

@final
class SubEpochData:
reward_chain_hash: bytes32
Expand Down
24 changes: 15 additions & 9 deletions wheel/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,21 @@ use chia_protocol::{
BlockRecord, Bytes32, ChallengeBlockInfo, ChallengeChainSubSlot, ClassgroupElement, Coin,
CoinSpend, CoinState, CoinStateFilters, CoinStateUpdate, EndOfSubSlotBundle, FeeEstimate,
FeeEstimateGroup, FeeRate, Foliage, FoliageBlockData, FoliageTransactionBlock, FullBlock,
Handshake, HeaderBlock, InfusedChallengeChainSubSlot, LazyNode, Message, NewCompactVDF,
NewPeak, NewPeakWallet, NewSignagePointOrEndOfSubSlot, NewTransaction, NewUnfinishedBlock,
NewUnfinishedBlock2, PoolTarget, Program, ProofBlockHeader, ProofOfSpace,
PuzzleSolutionResponse, RecentChainData, RegisterForCoinUpdates, RegisterForPhUpdates,
RejectAdditionsRequest, RejectBlock, RejectBlockHeaders, RejectBlocks, RejectCoinState,
RejectHeaderBlocks, RejectHeaderRequest, RejectPuzzleSolution, RejectPuzzleState,
RejectRemovalsRequest, RequestAdditions, RequestBlock, RequestBlockHeader, RequestBlockHeaders,
RequestBlocks, RequestChildren, RequestCoinState, RequestCompactVDF, RequestFeeEstimates,
Handshake, HeaderBlock, InfusedChallengeChainSubSlot, LazyNode, MempoolItemsAdded,
MempoolItemsRemoved, Message, NewCompactVDF, NewPeak, NewPeakWallet,
NewSignagePointOrEndOfSubSlot, NewTransaction, NewUnfinishedBlock, NewUnfinishedBlock2,
PoolTarget, Program, ProofBlockHeader, ProofOfSpace, PuzzleSolutionResponse, RecentChainData,
RegisterForCoinUpdates, RegisterForPhUpdates, RejectAdditionsRequest, RejectBlock,
RejectBlockHeaders, RejectBlocks, RejectCoinState, RejectHeaderBlocks, RejectHeaderRequest,
RejectPuzzleSolution, RejectPuzzleState, RejectRemovalsRequest, RemovedMempoolItem,
RequestAdditions, RequestBlock, RequestBlockHeader, RequestBlockHeaders, RequestBlocks,
RequestChildren, RequestCoinState, RequestCompactVDF, RequestCostInfo, RequestFeeEstimates,
RequestHeaderBlocks, RequestMempoolTransactions, RequestPeers, RequestProofOfWeight,
RequestPuzzleSolution, RequestPuzzleState, RequestRemovals, RequestRemoveCoinSubscriptions,
RequestRemovePuzzleSubscriptions, RequestSesInfo, RequestSignagePointOrEndOfSubSlot,
RequestTransaction, RequestUnfinishedBlock, RequestUnfinishedBlock2, RespondAdditions,
RespondBlock, RespondBlockHeader, RespondBlockHeaders, RespondBlocks, RespondChildren,
RespondCoinState, RespondCompactVDF, RespondEndOfSubSlot, RespondFeeEstimates,
RespondCoinState, RespondCompactVDF, RespondCostInfo, RespondEndOfSubSlot, RespondFeeEstimates,
RespondHeaderBlocks, RespondPeers, RespondProofOfWeight, RespondPuzzleSolution,
RespondPuzzleState, RespondRemovals, RespondRemoveCoinSubscriptions,
RespondRemovePuzzleSubscriptions, RespondSesInfo, RespondSignagePoint, RespondToCoinUpdates,
Expand Down Expand Up @@ -574,6 +575,11 @@ pub fn chia_rs(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<RequestCoinState>()?;
m.add_class::<RespondCoinState>()?;
m.add_class::<RejectCoinState>()?;
m.add_class::<MempoolItemsAdded>()?;
m.add_class::<MempoolItemsRemoved>()?;
m.add_class::<RemovedMempoolItem>()?;
m.add_class::<RequestCostInfo>()?;
m.add_class::<RespondCostInfo>()?;

// full node protocol
m.add_class::<NewPeak>()?;
Expand Down
3 changes: 3 additions & 0 deletions wheel/stubtest.allowlist
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ chia_rs\.PrivateKey\.__init__
# TODO: expects *args
chia_rs\.RequestPeers\.__init__

# TODO: expects *args
chia_rs\.RequestCostInfo\.__init__

# TODO: ask stubtest/mypy about these as they seem unlikely to be our doing
chia_rs\.sized_byte_class\.Iterable
chia_rs\.sized_byte_class\.BinaryIO\.write
Expand Down

0 comments on commit aa54ffe

Please sign in to comment.