Commit 40beea48 authored by Kelvin Fichter's avatar Kelvin Fichter Committed by GitHub

dev: Remove usage of custom concat function in Solidity (#283)

* Remove use of concat entirely

* Reduce diff
Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
parent 7ebc11d5
...@@ -34,7 +34,7 @@ library Lib_RLPWriter { ...@@ -34,7 +34,7 @@ library Lib_RLPWriter {
if (_in.length == 1 && uint8(_in[0]) < 128) { if (_in.length == 1 && uint8(_in[0]) < 128) {
encoded = _in; encoded = _in;
} else { } else {
encoded = Lib_BytesUtils.concat(_writeLength(_in.length, 128), _in); encoded = abi.encodePacked(_writeLength(_in.length, 128), _in);
} }
return encoded; return encoded;
...@@ -55,7 +55,7 @@ library Lib_RLPWriter { ...@@ -55,7 +55,7 @@ library Lib_RLPWriter {
) )
{ {
bytes memory list = _flatten(_in); bytes memory list = _flatten(_in);
return Lib_BytesUtils.concat(_writeLength(list.length, 192), list); return abi.encodePacked(_writeLength(list.length, 192), list);
} }
/** /**
......
...@@ -897,7 +897,7 @@ library Lib_MerkleTrie { ...@@ -897,7 +897,7 @@ library Lib_MerkleTrie {
uint8 offset = uint8(_key.length % 2); uint8 offset = uint8(_key.length % 2);
bytes memory prefixed = new bytes(2 - offset); bytes memory prefixed = new bytes(2 - offset);
prefixed[0] = bytes1(prefix + offset); prefixed[0] = bytes1(prefix + offset);
return Lib_BytesUtils.concat(prefixed, _key); return abi.encodePacked(prefixed, _key);
} }
/** /**
......
...@@ -10,84 +10,6 @@ library Lib_BytesUtils { ...@@ -10,84 +10,6 @@ library Lib_BytesUtils {
* Internal Functions * * Internal Functions *
**********************/ **********************/
function concat(
bytes memory _preBytes,
bytes memory _postBytes
)
internal
pure
returns (bytes memory)
{
bytes memory tempBytes;
assembly {
// Get a location of some free memory and store it in tempBytes as
// Solidity does for memory variables.
tempBytes := mload(0x40)
// Store the length of the first bytes array at the beginning of
// the memory for tempBytes.
let length := mload(_preBytes)
mstore(tempBytes, length)
// Maintain a memory counter for the current write location in the
// temp bytes array by adding the 32 bytes for the array length to
// the starting location.
let mc := add(tempBytes, 0x20)
// Stop copying when the memory counter reaches the length of the
// first bytes array.
let end := add(mc, length)
for {
// Initialize a copy counter to the start of the _preBytes data,
// 32 bytes into its memory.
let cc := add(_preBytes, 0x20)
} lt(mc, end) {
// Increase both counters by 32 bytes each iteration.
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
// Write the _preBytes data into the tempBytes memory 32 bytes
// at a time.
mstore(mc, mload(cc))
}
// Add the length of _postBytes to the current length of tempBytes
// and store it as the new length in the first 32 bytes of the
// tempBytes memory.
length := mload(_postBytes)
mstore(tempBytes, add(length, mload(tempBytes)))
// Move the memory counter back from a multiple of 0x20 to the
// actual end of the _preBytes data.
mc := end
// Stop copying when the memory counter reaches the new combined
// length of the arrays.
end := add(mc, length)
for {
let cc := add(_postBytes, 0x20)
} lt(mc, end) {
mc := add(mc, 0x20)
cc := add(cc, 0x20)
} {
mstore(mc, mload(cc))
}
// Update the free-memory pointer by padding our last write location
// to 32 bytes: add 31 bytes to the end of tempBytes to move to the
// next 32 byte block, then round down to the nearest multiple of
// 32. If the sum of the length of the two arrays is zero then add
// one before rounding down to leave a blank 32 bytes (the length block with 0).
mstore(0x40, and(
add(add(end, iszero(add(length, mload(_preBytes)))), 31),
not(31) // Round down to the nearest 32 bytes.
))
}
return tempBytes;
}
function slice( function slice(
bytes memory _bytes, bytes memory _bytes,
uint256 _start, uint256 _start,
......
...@@ -19,7 +19,7 @@ contract TestLib_BytesUtils { ...@@ -19,7 +19,7 @@ contract TestLib_BytesUtils {
pure pure
returns (bytes memory) returns (bytes memory)
{ {
return Lib_BytesUtils.concat( return abi.encodePacked(
_preBytes, _preBytes,
_postBytes _postBytes
); );
......
{ {
"tests": { "tests": {
"concat": {
"two non-empty inputs": {
"in": ["0x1234", "0x5678"],
"out": ["0x12345678"]
},
"two empty inputs": {
"in": ["0x", "0x"],
"out": ["0x"]
},
"first empty, second non-empty": {
"in": ["0x1234", "0x"],
"out": ["0x1234"]
},
"first non-empty, second empty": {
"in": ["0x", "0x5678"],
"out": ["0x5678"]
}
},
"slice": { "slice": {
"start zero, length = 0": { "start zero, length = 0": {
"in": ["0x12345678", 0, 0], "in": ["0x12345678", 0, 0],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment