Skip to content

Commit 1f6baa0

Browse files
primitives: Refactor AbiEncodeWith::encode_to_slice (#2676)
1 parent 84fcbe8 commit 1f6baa0

File tree

2 files changed

+40
-13
lines changed

2 files changed

+40
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Stabilize `is_contract` - [#2654](https://github.com/use-ink/ink/pull/2654)
1818
- Extract `sandbox` from `ink_e2e` into a new `ink_sandbox` crate - [#2659](https://github.com/use-ink/ink/pull/2659)
1919
- Synchronize with `polkadot-sdk/1b1cef306d9ceebf963fd15a04b5c79ee2618bce`[2675](https://github.com/use-ink/ink/pull/2675)
20+
- Refactor `AbiEncodeWith::encode_to_slice` - [#2676](https://github.com/use-ink/ink/pull/2676)
2021

2122
### Fixed
2223
- Fix decoding of `HostFn::minimum_balance` return value - [#2656](https://github.com/use-ink/ink/pull/2656)
2324
- Fix handling of `HostFn::code_hash` and `HostFn::weight_to_fee` - [#2672](https://github.com/use-ink/ink/pull/2672)
24-
25-
### Fixed
2625
- `name` override fixes for message id computation and trait definitions - [#2649](https://github.com/use-ink/ink/pull/2649)
2726

2827
## Version 6.0.0-alpha.4

crates/primitives/src/abi.rs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ pub trait AbiEncodeWith<Abi> {
6969
pub trait AbiDecodeWith<Abi>: Sized {
7070
/// The error type that can occur during decoding.
7171
type Error: core::fmt::Debug;
72+
7273
/// Decodes the data from a buffer using the provided ABI.
7374
fn decode_with(buffer: &[u8]) -> Result<Self, Self::Error>;
7475
}
@@ -79,16 +80,9 @@ impl<T: scale::Encode> AbiEncodeWith<Ink> for T {
7980
}
8081

8182
fn encode_to_slice(&self, buffer: &mut [u8]) -> usize {
82-
let encoded = scale::Encode::encode(self);
83-
let len = encoded.len();
84-
debug_assert!(
85-
len <= buffer.len(),
86-
"encode scope buffer overflowed, encoded len is {} but buffer len is {}",
87-
len,
88-
buffer.len()
89-
);
90-
buffer[..len].copy_from_slice(&encoded);
91-
len
83+
let mut sized_output = SizedOutput::from(buffer);
84+
scale::Encode::encode_to(self, &mut sized_output);
85+
sized_output.len()
9286
}
9387

9488
fn encode_to_vec(&self, buffer: &mut Vec<u8>) {
@@ -131,7 +125,7 @@ where
131125
}
132126

133127
fn encode_to_vec(&self, buffer: &mut Vec<u8>) {
134-
buffer.extend_from_slice(&T::encode(self));
128+
buffer.extend(SolEncode::encode(self));
135129
}
136130

137131
fn encode_topic<H>(&self, hasher: H) -> [u8; 32]
@@ -148,3 +142,37 @@ impl<T: SolDecode> AbiDecodeWith<Sol> for T {
148142
T::decode(buffer)
149143
}
150144
}
145+
146+
/// A `scale::Output` implementing buffer that tracks the number of bytes written.
147+
struct SizedOutput<'a> {
148+
buffer: &'a mut [u8],
149+
offset: usize,
150+
}
151+
152+
impl<'a> From<&'a mut [u8]> for SizedOutput<'a> {
153+
fn from(buffer: &'a mut [u8]) -> Self {
154+
Self { buffer, offset: 0 }
155+
}
156+
}
157+
158+
impl<'a> SizedOutput<'a> {
159+
/// Returns the number of bytes written to the buffer.
160+
pub fn len(&self) -> usize {
161+
self.offset
162+
}
163+
}
164+
165+
impl scale::Output for SizedOutput<'_> {
166+
fn write(&mut self, bytes: &[u8]) {
167+
let start = self.offset;
168+
let len = bytes.len();
169+
debug_assert!(
170+
len <= self.buffer.len(),
171+
"output buffer overflowed, encoded len is {} but buffer len is {}",
172+
len,
173+
self.buffer.len()
174+
);
175+
self.buffer[start..start.checked_add(len).unwrap()].copy_from_slice(bytes);
176+
self.offset = self.offset.checked_add(len).unwrap();
177+
}
178+
}

0 commit comments

Comments
 (0)