Skip to content

Commit 7581e6d

Browse files
authored
Merge pull request #3558 from stacks-network/feat/stackerdb-chunk-db
Feat/stackerdb chunk db
2 parents 382cb80 + e4747a8 commit 7581e6d

File tree

9 files changed

+1528
-95
lines changed

9 files changed

+1528
-95
lines changed

stackslib/src/net/codec.rs

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -752,9 +752,9 @@ impl StacksMessageCodec for MemPoolSyncData {
752752
}
753753
}
754754

755-
/// We can't implement StacksMessageCodec directly for T: QualifiedContractIdentifierExtension, so
755+
/// We can't implement StacksMessageCodec directly for T: ContractIdExtension, so
756756
/// we have to resort to these crude methods.
757-
fn contract_id_consensus_serialize<W: Write, T: QualifiedContractIdentifierExtension>(
757+
fn contract_id_consensus_serialize<W: Write, T: ContractIdExtension>(
758758
fd: &mut W,
759759
cid: &T,
760760
) -> Result<(), codec_error> {
@@ -766,13 +766,13 @@ fn contract_id_consensus_serialize<W: Write, T: QualifiedContractIdentifierExten
766766
Ok(())
767767
}
768768

769-
fn contract_id_consensus_deserialize<R: Read, T: QualifiedContractIdentifierExtension>(
769+
fn contract_id_consensus_deserialize<R: Read, T: ContractIdExtension>(
770770
fd: &mut R,
771771
) -> Result<T, codec_error> {
772772
let version: u8 = read_next(fd)?;
773773
let bytes: [u8; 20] = read_next(fd)?;
774774
let name: ContractName = read_next(fd)?;
775-
let qn = T::new(
775+
let qn = T::from_parts(
776776
StacksAddress {
777777
version,
778778
bytes: Hash160(bytes),
@@ -831,59 +831,59 @@ impl StacksMessageCodec for StackerDBGetChunkInvData {
831831

832832
impl StacksMessageCodec for StackerDBChunkInvData {
833833
fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
834-
if self.chunk_versions.len() > (stackerdb::STACKERDB_INV_MAX as usize) {
834+
if self.slot_versions.len() > (stackerdb::STACKERDB_INV_MAX as usize) {
835835
return Err(codec_error::ArrayTooLong);
836836
}
837-
write_next(fd, &self.chunk_versions)?;
837+
write_next(fd, &self.slot_versions)?;
838838
Ok(())
839839
}
840840

841841
fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBChunkInvData, codec_error> {
842-
let chunk_versions: Vec<u32> = read_next_at_most(fd, stackerdb::STACKERDB_INV_MAX.into())?;
843-
Ok(StackerDBChunkInvData { chunk_versions })
842+
let slot_versions: Vec<u32> = read_next_at_most(fd, stackerdb::STACKERDB_INV_MAX.into())?;
843+
Ok(StackerDBChunkInvData { slot_versions })
844844
}
845845
}
846846

847847
impl StacksMessageCodec for StackerDBGetChunkData {
848848
fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
849849
contract_id_consensus_serialize(fd, &self.contract_id)?;
850850
write_next(fd, &self.rc_consensus_hash)?;
851-
write_next(fd, &self.chunk_id)?;
852-
write_next(fd, &self.chunk_version)?;
851+
write_next(fd, &self.slot_id)?;
852+
write_next(fd, &self.slot_version)?;
853853
Ok(())
854854
}
855855

856856
fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBGetChunkData, codec_error> {
857857
let contract_id: ContractId = contract_id_consensus_deserialize(fd)?;
858858
let rc_consensus_hash: ConsensusHash = read_next(fd)?;
859-
let chunk_id: u32 = read_next(fd)?;
860-
let chunk_version: u32 = read_next(fd)?;
859+
let slot_id: u32 = read_next(fd)?;
860+
let slot_version: u32 = read_next(fd)?;
861861
Ok(StackerDBGetChunkData {
862862
contract_id,
863863
rc_consensus_hash,
864-
chunk_id,
865-
chunk_version,
864+
slot_id,
865+
slot_version,
866866
})
867867
}
868868
}
869869

870870
impl StacksMessageCodec for StackerDBChunkData {
871871
fn consensus_serialize<W: Write>(&self, fd: &mut W) -> Result<(), codec_error> {
872-
write_next(fd, &self.chunk_id)?;
873-
write_next(fd, &self.chunk_version)?;
872+
write_next(fd, &self.slot_id)?;
873+
write_next(fd, &self.slot_version)?;
874874
write_next(fd, &self.sig)?;
875875
write_next(fd, &self.data)?;
876876
Ok(())
877877
}
878878

879879
fn consensus_deserialize<R: Read>(fd: &mut R) -> Result<StackerDBChunkData, codec_error> {
880-
let chunk_id: u32 = read_next(fd)?;
881-
let chunk_version: u32 = read_next(fd)?;
880+
let slot_id: u32 = read_next(fd)?;
881+
let slot_version: u32 = read_next(fd)?;
882882
let sig: MessageSignature = read_next(fd)?;
883883
let data: Vec<u8> = read_next(fd)?;
884884
Ok(StackerDBChunkData {
885-
chunk_id,
886-
chunk_version,
885+
slot_id,
886+
slot_version,
887887
sig,
888888
data,
889889
})
@@ -1041,19 +1041,19 @@ impl StacksMessageType {
10411041
)
10421042
}
10431043
StacksMessageType::StackerDBChunkInv(ref m) => {
1044-
format!("StackerDBChunkInv({:?})", &m.chunk_versions)
1044+
format!("StackerDBChunkInv({:?})", &m.slot_versions)
10451045
}
10461046
StacksMessageType::StackerDBGetChunk(ref m) => {
10471047
format!(
10481048
"StackerDBGetChunk({},{},{},{})",
1049-
&m.contract_id, &m.rc_consensus_hash, m.chunk_id, m.chunk_version
1049+
&m.contract_id, &m.rc_consensus_hash, m.slot_id, m.slot_version
10501050
)
10511051
}
10521052
StacksMessageType::StackerDBChunk(ref m) => {
10531053
format!(
10541054
"StackerDBChunk({},{},{},sz={})",
1055-
m.chunk_id,
1056-
m.chunk_version,
1055+
m.slot_id,
1056+
m.slot_version,
10571057
&m.sig,
10581058
m.data.len()
10591059
)
@@ -2214,11 +2214,11 @@ pub mod test {
22142214
#[test]
22152215
fn codec_StackerDBChunkInvData() {
22162216
let data = StackerDBChunkInvData {
2217-
chunk_versions: vec![0, 1, 2, 3],
2217+
slot_versions: vec![0, 1, 2, 3],
22182218
};
22192219

22202220
let bytes = vec![
2221-
// len(chunk_versions)
2221+
// len(slot_versions)
22222222
0x00, 0x00, 0x00, 0x04, // 0u32
22232223
0x00, 0x00, 0x00, 0x00, // 1u32
22242224
0x00, 0x00, 0x00, 0x01, // 2u32
@@ -2234,8 +2234,8 @@ pub mod test {
22342234
let data = StackerDBGetChunkData {
22352235
contract_id: ContractId::parse("SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo").unwrap(),
22362236
rc_consensus_hash: ConsensusHash([0x01; 20]),
2237-
chunk_id: 2,
2238-
chunk_version: 3,
2237+
slot_id: 2,
2238+
slot_version: 3,
22392239
};
22402240

22412241
let bytes = vec![
@@ -2245,8 +2245,8 @@ pub mod test {
22452245
0x03, // foo
22462246
0x66, 0x6f, 0x6f, // rc consensus hash
22472247
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2248-
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // chunk id
2249-
0x00, 0x00, 0x00, 0x02, // chunk version
2248+
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // slot id
2249+
0x00, 0x00, 0x00, 0x02, // slot version
22502250
0x00, 0x00, 0x00, 0x03,
22512251
];
22522252

@@ -2256,17 +2256,17 @@ pub mod test {
22562256
#[test]
22572257
fn codec_StackerDBChunkData() {
22582258
let data = StackerDBChunkData {
2259-
chunk_id: 2,
2260-
chunk_version: 3,
2259+
slot_id: 2,
2260+
slot_version: 3,
22612261
sig: MessageSignature::from_raw(&vec![0x44; 65]),
22622262
data: vec![
22632263
0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
22642264
],
22652265
};
22662266

22672267
let bytes = vec![
2268-
// chunk id
2269-
0x00, 0x00, 0x00, 0x02, // chunk version
2268+
// slot id
2269+
0x00, 0x00, 0x00, 0x02, // slot version
22702270
0x00, 0x00, 0x00, 0x03, // signature
22712271
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
22722272
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
@@ -2428,17 +2428,17 @@ pub mod test {
24282428
rc_consensus_hash: ConsensusHash([0x01; 20]),
24292429
}),
24302430
StacksMessageType::StackerDBChunkInv(StackerDBChunkInvData {
2431-
chunk_versions: vec![0, 1, 2, 3],
2431+
slot_versions: vec![0, 1, 2, 3],
24322432
}),
24332433
StacksMessageType::StackerDBGetChunk(StackerDBGetChunkData {
24342434
contract_id: ContractId::parse("SP8QPP8TVXYAXS1VFSERG978A6WKBF59NSYJQEMN.foo").unwrap(),
24352435
rc_consensus_hash: ConsensusHash([0x01; 20]),
2436-
chunk_id: 2,
2437-
chunk_version: 3
2436+
slot_id: 2,
2437+
slot_version: 3
24382438
}),
24392439
StacksMessageType::StackerDBChunk(StackerDBChunkData {
2440-
chunk_id: 2,
2441-
chunk_version: 3,
2440+
slot_id: 2,
2441+
slot_version: 3,
24422442
sig: MessageSignature::from_raw(&vec![0x44; 65]),
24432443
data: vec![0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]
24442444
}),

stackslib/src/net/mod.rs

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,20 @@ pub enum Error {
256256
ExpectedEndOfStream,
257257
/// burnchain error
258258
BurnchainError(burnchain_error),
259+
/// chunk is stale
260+
StaleChunk(u32, u32),
261+
/// no such slot
262+
NoSuchSlot(ContractId, u32),
263+
/// no such DB
264+
NoSuchStackerDB(ContractId),
265+
/// stacker DB exists
266+
StackerDBExists(ContractId),
267+
/// slot signer is wrong
268+
BadSlotSigner(StacksAddress, u32),
269+
/// too many writes to a slot
270+
TooManySlotWrites(u32, u32),
271+
/// too frequent writes to a slot
272+
TooFrequentSlotWrites(u64),
259273
/// state machine step took too long
260274
StepTimeout,
261275
}
@@ -359,6 +373,27 @@ impl fmt::Display for Error {
359373
Error::Transient(ref s) => write!(f, "Transient network error: {}", s),
360374
Error::ExpectedEndOfStream => write!(f, "Expected end-of-stream"),
361375
Error::BurnchainError(ref e) => fmt::Display::fmt(e, f),
376+
Error::StaleChunk(ref current, ref given) => {
377+
write!(f, "Stale DB chunk (cur={},given={})", current, given)
378+
}
379+
Error::NoSuchSlot(ref addr, ref slot_id) => {
380+
write!(f, "No such DB slot ({},{})", addr, slot_id)
381+
}
382+
Error::NoSuchStackerDB(ref addr) => {
383+
write!(f, "No such StackerDB {}", addr)
384+
}
385+
Error::StackerDBExists(ref addr) => {
386+
write!(f, "StackerDB already exists: {}", addr)
387+
}
388+
Error::BadSlotSigner(ref addr, ref slot_id) => {
389+
write!(f, "Bad DB slot signer ({},{})", addr, slot_id)
390+
}
391+
Error::TooManySlotWrites(ref max, ref given) => {
392+
write!(f, "Too many slot writes (max={},given={})", max, given)
393+
}
394+
Error::TooFrequentSlotWrites(ref deadline) => {
395+
write!(f, "Too frequent slot writes (deadline={})", deadline)
396+
}
362397
Error::StepTimeout => write!(f, "State-machine step took too long"),
363398
}
364399
}
@@ -421,6 +456,13 @@ impl error::Error for Error {
421456
Error::Transient(ref _s) => None,
422457
Error::ExpectedEndOfStream => None,
423458
Error::BurnchainError(ref e) => Some(e),
459+
Error::StaleChunk(..) => None,
460+
Error::NoSuchSlot(..) => None,
461+
Error::NoSuchStackerDB(..) => None,
462+
Error::StackerDBExists(..) => None,
463+
Error::BadSlotSigner(..) => None,
464+
Error::TooManySlotWrites(..) => None,
465+
Error::TooFrequentSlotWrites(..) => None,
424466
Error::StepTimeout => None,
425467
}
426468
}
@@ -920,19 +962,22 @@ pub enum MemPoolSyncData {
920962
}
921963

922964
/// Make QualifiedContractIdentifier usable to the networking code
923-
pub trait QualifiedContractIdentifierExtension {
924-
fn new(addr: StacksAddress, name: ContractName) -> Self;
965+
pub trait ContractIdExtension {
966+
fn from_parts(addr: StacksAddress, name: ContractName) -> Self;
925967
fn address(&self) -> StacksAddress;
926968
fn name(&self) -> ContractName;
927-
fn parse(txt: &str) -> Option<Self>
969+
fn from_str(txt: &str) -> Option<Self>
928970
where
929971
Self: Sized;
930972
}
931973

932-
impl QualifiedContractIdentifierExtension for QualifiedContractIdentifier {
933-
fn new(addr: StacksAddress, name: ContractName) -> QualifiedContractIdentifier {
974+
/// short-hand type alias
975+
pub type ContractId = QualifiedContractIdentifier;
976+
977+
impl ContractIdExtension for ContractId {
978+
fn from_parts(addr: StacksAddress, name: ContractName) -> ContractId {
934979
let id_addr = StandardPrincipalData(addr.version, addr.bytes.0);
935-
QualifiedContractIdentifier::new(id_addr, name)
980+
ContractId::new(id_addr, name)
936981
}
937982

938983
fn address(&self) -> StacksAddress {
@@ -946,14 +991,11 @@ impl QualifiedContractIdentifierExtension for QualifiedContractIdentifier {
946991
self.name.clone()
947992
}
948993

949-
fn parse(txt: &str) -> Option<QualifiedContractIdentifier> {
950-
QualifiedContractIdentifier::parse(txt).ok()
994+
fn from_str(txt: &str) -> Option<ContractId> {
995+
ContractId::parse(txt).ok()
951996
}
952997
}
953998

954-
/// short-hand type alias
955-
pub type ContractId = QualifiedContractIdentifier;
956-
957999
/// Inform the remote peer of (a page of) the list of stacker DB contracts this node supports
9581000
#[derive(Debug, Clone, PartialEq)]
9591001
pub struct StackerDBHandshakeData {
@@ -978,30 +1020,30 @@ pub struct StackerDBGetChunkInvData {
9781020
pub struct StackerDBChunkInvData {
9791021
/// version vector of chunks available.
9801022
/// The max-length is a protocol constant.
981-
pub chunk_versions: Vec<u32>,
1023+
pub slot_versions: Vec<u32>,
9821024
}
9831025

9841026
/// Request for a stacker DB chunk.
9851027
#[derive(Debug, Clone, PartialEq)]
9861028
pub struct StackerDBGetChunkData {
987-
/// smart contract being used to determine chunk quantity and order
1029+
/// smart contract being used to determine slot quantity and order
9881030
pub contract_id: ContractId,
9891031
/// consensus hash of the sortition that started this reward cycle
9901032
pub rc_consensus_hash: ConsensusHash,
991-
/// chunk ID (i.e. the ith bit)
992-
pub chunk_id: u32,
993-
/// last-seen chunk version
994-
pub chunk_version: u32,
1033+
/// slot ID
1034+
pub slot_id: u32,
1035+
/// last-seen slot version
1036+
pub slot_version: u32,
9951037
}
9961038

9971039
/// Stacker DB chunk reply to a StackerDBGetChunkData
9981040
#[derive(Debug, Clone, PartialEq)]
9991041
pub struct StackerDBChunkData {
1000-
/// chunk ID (i.e. the ith bit)
1001-
pub chunk_id: u32,
1002-
/// chunk version (a lamport clock)
1003-
pub chunk_version: u32,
1004-
/// signature from the stacker over (reward cycle consensus hash, chunk id, chunk version, chunk sha512/256)
1042+
/// slot ID
1043+
pub slot_id: u32,
1044+
/// slot version (a lamport clock)
1045+
pub slot_version: u32,
1046+
/// signature from the stacker over (reward cycle consensus hash, slot id, slot version, chunk sha512/256)
10051047
pub sig: MessageSignature,
10061048
/// the chunk data
10071049
pub data: Vec<u8>,

0 commit comments

Comments
 (0)