Skip to content

Commit 0ef83f7

Browse files
committed
use NonEmptyVec for TypedAssigns
1 parent 8f837a6 commit 0ef83f7

11 files changed

+304
-221
lines changed

src/operation/assignments.rs

+56-29
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ use core::fmt::Debug;
2525
use std::collections::{btree_map, BTreeSet};
2626
use std::hash::Hash;
2727

28-
use amplify::confinement::{Confined, SmallVec, TinyOrdMap};
28+
use amplify::confinement::{Confined, NonEmptyVec, TinyOrdMap, U16};
2929
use commit_verify::{Conceal, ReservedBytes};
30-
use strict_encoding::{StrictDumb, StrictEncode};
30+
use strict_encoding::{StrictDecode, StrictDumb, StrictEncode};
3131

3232
use super::ExposedState;
3333
use crate::operation::seal::GenesisSeal;
@@ -36,6 +36,34 @@ use crate::{
3636
SecretSeal, StateType, VoidState, LIB_NAME_RGB_COMMIT,
3737
};
3838

39+
#[derive(Wrapper, WrapperMut, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, From)]
40+
#[wrapper(Deref)]
41+
#[wrapper_mut(DerefMut)]
42+
#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)]
43+
#[strict_type(lib = LIB_NAME_RGB_COMMIT, dumb = Self(NonEmptyVec::with(A::strict_dumb())))]
44+
#[cfg_attr(
45+
feature = "serde",
46+
derive(Serialize, Deserialize),
47+
serde(
48+
crate = "serde_crate",
49+
transparent,
50+
bound = "A: serde::Serialize + serde::de::DeserializeOwned"
51+
)
52+
)]
53+
pub struct AssignVec<A>(NonEmptyVec<A, U16>)
54+
where A: StrictDumb + StrictEncode + StrictDecode;
55+
56+
impl<A: StrictDumb + StrictEncode + StrictDecode> AssignVec<A> {
57+
pub fn with(vec: NonEmptyVec<A, U16>) -> Self { Self(vec) }
58+
}
59+
60+
impl<A: StrictDumb + StrictEncode + StrictDecode> IntoIterator for AssignVec<A> {
61+
type Item = A;
62+
type IntoIter = std::vec::IntoIter<A>;
63+
64+
fn into_iter(self) -> Self::IntoIter { self.0.into_iter() }
65+
}
66+
3967
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Display, Error)]
4068
#[display(doc_comments)]
4169
/// the requested data are not present.
@@ -231,15 +259,14 @@ impl<State: ExposedState> Assign<State, GenesisSeal> {
231259
)
232260
)]
233261
pub enum TypedAssigns<Seal: ExposedSeal> {
234-
// TODO: Consider using non-empty variants
235262
#[strict_type(tag = 0x00)]
236-
Declarative(SmallVec<AssignRights<Seal>>),
263+
Declarative(AssignVec<AssignRights<Seal>>),
237264
#[strict_type(tag = 0x01)]
238-
Fungible(SmallVec<AssignFungible<Seal>>),
265+
Fungible(AssignVec<AssignFungible<Seal>>),
239266
#[strict_type(tag = 0x02)]
240-
Structured(SmallVec<AssignData<Seal>>),
267+
Structured(AssignVec<AssignData<Seal>>),
241268
#[strict_type(tag = 0xFF)]
242-
Attachment(SmallVec<AssignAttach<Seal>>),
269+
Attachment(AssignVec<AssignAttach<Seal>>),
243270
}
244271

245272
impl<Seal: ExposedSeal> Conceal for TypedAssigns<Seal> {
@@ -248,23 +275,23 @@ impl<Seal: ExposedSeal> Conceal for TypedAssigns<Seal> {
248275
match self {
249276
TypedAssigns::Declarative(s) => {
250277
let concealed_iter = s.iter().map(AssignRights::<Seal>::conceal);
251-
let inner = SmallVec::try_from_iter(concealed_iter).expect("same size");
252-
TypedAssigns::Declarative(inner)
278+
let inner = NonEmptyVec::try_from_iter(concealed_iter).expect("same size");
279+
TypedAssigns::Declarative(AssignVec::with(inner))
253280
}
254281
TypedAssigns::Fungible(s) => {
255282
let concealed_iter = s.iter().map(AssignFungible::<Seal>::conceal);
256-
let inner = SmallVec::try_from_iter(concealed_iter).expect("same size");
257-
TypedAssigns::Fungible(inner)
283+
let inner = NonEmptyVec::try_from_iter(concealed_iter).expect("same size");
284+
TypedAssigns::Fungible(AssignVec::with(inner))
258285
}
259286
TypedAssigns::Structured(s) => {
260287
let concealed_iter = s.iter().map(AssignData::<Seal>::conceal);
261-
let inner = SmallVec::try_from_iter(concealed_iter).expect("same size");
262-
TypedAssigns::Structured(inner)
288+
let inner = NonEmptyVec::try_from_iter(concealed_iter).expect("same size");
289+
TypedAssigns::Structured(AssignVec::with(inner))
263290
}
264291
TypedAssigns::Attachment(s) => {
265292
let concealed_iter = s.iter().map(AssignAttach::<Seal>::conceal);
266-
let inner = SmallVec::try_from_iter(concealed_iter).expect("same size");
267-
TypedAssigns::Attachment(inner)
293+
let inner = NonEmptyVec::try_from_iter(concealed_iter).expect("same size");
294+
TypedAssigns::Attachment(AssignVec::with(inner))
268295
}
269296
}
270297
}
@@ -344,31 +371,31 @@ impl<Seal: ExposedSeal> TypedAssigns<Seal> {
344371
}
345372

346373
#[inline]
347-
pub fn as_declarative_mut(&mut self) -> Option<&mut SmallVec<AssignRights<Seal>>> {
374+
pub fn as_declarative_mut(&mut self) -> Option<&mut NonEmptyVec<AssignRights<Seal>, U16>> {
348375
match self {
349376
TypedAssigns::Declarative(set) => Some(set),
350377
_ => None,
351378
}
352379
}
353380

354381
#[inline]
355-
pub fn as_fungible_mut(&mut self) -> Option<&mut SmallVec<AssignFungible<Seal>>> {
382+
pub fn as_fungible_mut(&mut self) -> Option<&mut NonEmptyVec<AssignFungible<Seal>, U16>> {
356383
match self {
357384
TypedAssigns::Fungible(set) => Some(set),
358385
_ => None,
359386
}
360387
}
361388

362389
#[inline]
363-
pub fn as_structured_mut(&mut self) -> Option<&mut SmallVec<AssignData<Seal>>> {
390+
pub fn as_structured_mut(&mut self) -> Option<&mut NonEmptyVec<AssignData<Seal>, U16>> {
364391
match self {
365392
TypedAssigns::Structured(set) => Some(set),
366393
_ => None,
367394
}
368395
}
369396

370397
#[inline]
371-
pub fn as_attachment_mut(&mut self) -> Option<&mut SmallVec<AssignAttach<Seal>>> {
398+
pub fn as_attachment_mut(&mut self) -> Option<&mut NonEmptyVec<AssignAttach<Seal>, U16>> {
372399
match self {
373400
TypedAssigns::Attachment(set) => Some(set),
374401
_ => None,
@@ -446,7 +473,7 @@ impl<Seal: ExposedSeal> TypedAssigns<Seal> {
446473
if index as usize >= vec.len() {
447474
return Err(UnknownDataError);
448475
}
449-
Ok(vec.release().remove(index as usize).into_revealed_state())
476+
Ok(vec.0.release().remove(index as usize).into_revealed_state())
450477
}
451478
_ => Err(UnknownDataError),
452479
}
@@ -458,7 +485,7 @@ impl<Seal: ExposedSeal> TypedAssigns<Seal> {
458485
if index as usize >= vec.len() {
459486
return Err(UnknownDataError);
460487
}
461-
Ok(vec.release().remove(index as usize).into_revealed_state())
488+
Ok(vec.0.release().remove(index as usize).into_revealed_state())
462489
}
463490
_ => Err(UnknownDataError),
464491
}
@@ -468,22 +495,22 @@ impl<Seal: ExposedSeal> TypedAssigns<Seal> {
468495
impl TypedAssigns<GenesisSeal> {
469496
pub fn transmutate_seals(&self) -> TypedAssigns<GraphSeal> {
470497
match self {
471-
TypedAssigns::Declarative(a) => TypedAssigns::Declarative(
498+
TypedAssigns::Declarative(a) => TypedAssigns::Declarative(AssignVec::with(
472499
Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals()))
473500
.expect("same size"),
474-
),
475-
TypedAssigns::Fungible(a) => TypedAssigns::Fungible(
501+
)),
502+
TypedAssigns::Fungible(a) => TypedAssigns::Fungible(AssignVec::with(
476503
Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals()))
477504
.expect("same size"),
478-
),
479-
TypedAssigns::Structured(a) => TypedAssigns::Structured(
505+
)),
506+
TypedAssigns::Structured(a) => TypedAssigns::Structured(AssignVec::with(
480507
Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals()))
481508
.expect("same size"),
482-
),
483-
TypedAssigns::Attachment(a) => TypedAssigns::Attachment(
509+
)),
510+
TypedAssigns::Attachment(a) => TypedAssigns::Attachment(AssignVec::with(
484511
Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals()))
485512
.expect("same size"),
486-
),
513+
)),
487514
}
488515
}
489516
}

src/stl.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ use crate::{
3737

3838
/// Strict types id for the library providing data types for RGB consensus.
3939
pub const LIB_ID_RGB_COMMIT: &str =
40-
"stl:eyIcK1Y8-vJmWKzi-CmYdpc4-bcfjuep-b0Bom0W-h6$8hJw#culture-pamela-ballad";
40+
"stl:!biPP1$Y-7BZyhSV-G4WQNlq-eDiicmt-K7hBJq9-4cyQk8o#tennis-nirvana-asia";
4141
/// Strict types id for the library providing data types for RGB consensus.
4242
pub const LIB_ID_RGB_LOGIC: &str =
43-
"stl:kVw2frMA-bnDO3Kj-QWS0pvy-Gak5E$$-U5QFgS7-vzikLJ4#cupid-felix-husband";
43+
"stl:p0BiRWGC-gBDpjuB-$tqrAMO-hkin3Mv-NYUjn9j-!4n9p7o#miguel-motor-victor";
4444

4545
fn _rgb_commit_stl() -> Result<TypeLib, CompileError> {
4646
LibBuilder::new(libname!(LIB_NAME_RGB_COMMIT), tiny_bset! {

src/validation/logic.rs

+49-27
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,19 @@
2121
// limitations under the License.
2222

2323
use std::cell::RefCell;
24-
use std::collections::BTreeSet;
24+
use std::collections::btree_map::Entry;
25+
use std::collections::{BTreeMap, BTreeSet};
2526
use std::rc::Rc;
2627

2728
use aluvm::data::Number;
2829
use aluvm::isa::Instr;
2930
use aluvm::reg::{Reg32, RegA};
3031
use aluvm::Vm;
31-
use amplify::confinement::Confined;
32+
use amplify::confinement::{Confined, NonEmptyVec};
3233
use amplify::Wrapper;
3334
use strict_types::TypeSystem;
3435

36+
use crate::assignments::AssignVec;
3537
use crate::schema::{AssignmentsSchema, GlobalSchema};
3638
use crate::validation::{CheckedConsignment, ConsignmentApi};
3739
use crate::vm::{ContractStateAccess, ContractStateEvolve, OpInfo, OrdOpRef, RgbIsa, VmContext};
@@ -390,7 +392,7 @@ fn extract_prev_state<C: ConsignmentApi>(
390392
inputs: &Inputs,
391393
status: &mut validation::Status,
392394
) -> Assignments<GraphSeal> {
393-
let mut assignments = bmap! {};
395+
let mut assignments: BTreeMap<AssignmentType, TypedAssigns<_>> = bmap! {};
394396
for input in inputs {
395397
let Opout { op, ty, no } = input.prev_out;
396398

@@ -406,51 +408,71 @@ fn extract_prev_state<C: ConsignmentApi>(
406408
match prev_op.assignments_by_type(ty) {
407409
Some(TypedAssigns::Declarative(prev_assignments)) => {
408410
if let Some(prev_assign) = prev_assignments.get(no) {
409-
if let Some(typed_assigns) = assignments
410-
.entry(ty)
411-
.or_insert_with(|| TypedAssigns::Declarative(Default::default()))
412-
.as_declarative_mut()
413-
{
414-
typed_assigns.push(prev_assign.clone()).expect("same size");
411+
match assignments.entry(ty) {
412+
Entry::Occupied(mut entry) => {
413+
if let Some(typed_assigns) = entry.get_mut().as_declarative_mut() {
414+
typed_assigns.push(prev_assign.clone()).expect("same size");
415+
}
416+
}
417+
Entry::Vacant(entry) => {
418+
entry.insert(TypedAssigns::Declarative(AssignVec::with(
419+
NonEmptyVec::with(prev_assign.clone()),
420+
)));
421+
}
415422
}
416423
} else {
417424
status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out));
418425
}
419426
}
420427
Some(TypedAssigns::Fungible(prev_assignments)) => {
421428
if let Some(prev_assign) = prev_assignments.get(no) {
422-
if let Some(typed_assigns) = assignments
423-
.entry(ty)
424-
.or_insert_with(|| TypedAssigns::Fungible(Default::default()))
425-
.as_fungible_mut()
426-
{
427-
typed_assigns.push(prev_assign.clone()).expect("same size");
429+
match assignments.entry(ty) {
430+
Entry::Occupied(mut entry) => {
431+
if let Some(typed_assigns) = entry.get_mut().as_fungible_mut() {
432+
typed_assigns.push(prev_assign.clone()).expect("same size");
433+
}
434+
}
435+
Entry::Vacant(entry) => {
436+
entry.insert(TypedAssigns::Fungible(AssignVec::with(
437+
NonEmptyVec::with(prev_assign.clone()),
438+
)));
439+
}
428440
}
429441
} else {
430442
status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out));
431443
}
432444
}
433445
Some(TypedAssigns::Structured(prev_assignments)) => {
434446
if let Some(prev_assign) = prev_assignments.get(no) {
435-
if let Some(typed_assigns) = assignments
436-
.entry(ty)
437-
.or_insert_with(|| TypedAssigns::Structured(Default::default()))
438-
.as_structured_mut()
439-
{
440-
typed_assigns.push(prev_assign.clone()).expect("same size");
447+
match assignments.entry(ty) {
448+
Entry::Occupied(mut entry) => {
449+
if let Some(typed_assigns) = entry.get_mut().as_structured_mut() {
450+
typed_assigns.push(prev_assign.clone()).expect("same size");
451+
}
452+
}
453+
Entry::Vacant(entry) => {
454+
entry.insert(TypedAssigns::Structured(AssignVec::with(
455+
NonEmptyVec::with(prev_assign.clone()),
456+
)));
457+
}
441458
}
442459
} else {
443460
status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out));
444461
}
445462
}
446463
Some(TypedAssigns::Attachment(prev_assignments)) => {
447464
if let Some(prev_assign) = prev_assignments.get(no) {
448-
if let Some(typed_assigns) = assignments
449-
.entry(ty)
450-
.or_insert_with(|| TypedAssigns::Attachment(Default::default()))
451-
.as_attachment_mut()
452-
{
453-
typed_assigns.push(prev_assign.clone()).expect("same size");
465+
match assignments.entry(ty) {
466+
Entry::Occupied(mut entry) => {
467+
if let Some(typed_assigns) = entry.get_mut().as_attachment_mut() {
468+
typed_assigns.push(prev_assign.clone()).expect("same size");
469+
}
470+
}
471+
Entry::Vacant(entry) => {
472+
entry.insert(TypedAssigns::Attachment(AssignVec::with(
473+
NonEmptyVec::with(prev_assign.clone()),
474+
)));
475+
}
454476
}
455477
} else {
456478
status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out));

stl/AnchoredBundle.vesper

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ TransitionBundle rec
4747
assignments map len=0..MAX8 aka=AssignmentsBlindSealTxPtr
4848
key is U16 aka=AssignmentType
4949
value union TypedAssignsBlindSealTxPtr
50-
declarative list len=0..MAX16 wrapped tag=0
50+
declarative list len=1..MAX16 wrapped aka=AssignVecAssignVoidStateBlindSealTxPtr tag=0
5151
AssignVoidStateBlindSealTxPtr union
5252
revealed rec tag=0
5353
seal rec BlindSealTxPtr
@@ -62,7 +62,7 @@ TransitionBundle rec
6262
seal bytes len=32 aka=SecretSeal
6363
state is Unit aka=VoidState
6464
lock bytes len=2 aka=ReservedBytes2
65-
fungible list len=0..MAX16 wrapped tag=1
65+
fungible list len=1..MAX16 wrapped aka=AssignVecAssignRevealedValueBlindSealTxPtr tag=1
6666
AssignRevealedValueBlindSealTxPtr union
6767
revealed rec tag=0
6868
seal rec BlindSealTxPtr
@@ -81,7 +81,7 @@ TransitionBundle rec
8181
value union FungibleState
8282
bits64 is U64 wrapped tag=0
8383
lock bytes len=2 aka=ReservedBytes2
84-
structured list len=0..MAX16 wrapped tag=2
84+
structured list len=1..MAX16 wrapped aka=AssignVecAssignRevealedDataBlindSealTxPtr tag=2
8585
AssignRevealedDataBlindSealTxPtr union
8686
revealed rec tag=0
8787
seal rec BlindSealTxPtr
@@ -100,7 +100,7 @@ TransitionBundle rec
100100
value bytes len=0..MAX16 aka=DataState
101101
salt is U128
102102
lock bytes len=2 aka=ReservedBytes2
103-
attachment list len=0..MAX16 wrapped tag=3
103+
attachment list len=1..MAX16 wrapped aka=AssignVecAssignRevealedAttachBlindSealTxPtr tag=3
104104
AssignRevealedAttachBlindSealTxPtr union
105105
revealed rec tag=0
106106
seal rec BlindSealTxPtr

0 commit comments

Comments
 (0)