Skip to content

Commit

Permalink
0.4.0 (#125)
Browse files Browse the repository at this point in the history
- New dictionary API
- Full extra-currency support
- CellBuilder/CellSlice optimizations
- CellContext API
- MessageLayout API
  • Loading branch information
andreypfau authored Feb 9, 2025
1 parent f0502a1 commit 192c55c
Show file tree
Hide file tree
Showing 227 changed files with 3,177 additions and 901 deletions.
114 changes: 57 additions & 57 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,57 +1,57 @@
name: Release
on:
push:
branches:
- main

jobs:
build:
if: "!contains(github.event.commits[0].message, '[skip ci]')"
strategy:
matrix:
include:
- os: macos-latest
gradle_args: assemble publishIosX64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishIosArm64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishIosSimulatorArm64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishTvosX64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishTvosArm64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishTvosSimulatorArm64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishWatchosArm32PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishWatchosArm64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishWatchosX64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishWatchosSimulatorArm64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishMacosX64PublicationToSonatypeRepository
- os: macos-latest
gradle_args: assemble publishMacosArm64PublicationToSonatypeRepository
- os: ubuntu-latest
gradle_args: assemble publishKotlinMultiplatformPublicationToSonatypeRepository publishJvmPublicationToSonatypeRepository publishLinuxX64PublicationToSonatypeRepository publishLinuxArm64PublicationToSonatypeRepository publishMingwX64PublicationToSonatypeRepository

runs-on: ${{ matrix.os }}
steps:
- name: Checkout project sources
uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
distribution: liberica
java-version: 8
- name: Build using gradle
uses: gradle/gradle-build-action@v2
with:
arguments: ${{ matrix.gradle_args }}
env:
SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
#name: Release
#on:
# push:
# branches:
# - main
#
#jobs:
# build:
# if: "!contains(github.event.commits[0].message, '[skip ci]')"
# strategy:
# matrix:
# include:
# - os: macos-latest
# gradle_args: assemble publishIosX64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishIosArm64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishIosSimulatorArm64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishTvosX64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishTvosArm64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishTvosSimulatorArm64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishWatchosArm32PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishWatchosArm64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishWatchosX64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishWatchosSimulatorArm64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishMacosX64PublicationToSonatypeRepository
# - os: macos-latest
# gradle_args: assemble publishMacosArm64PublicationToSonatypeRepository
# - os: ubuntu-latest
# gradle_args: assemble publishKotlinMultiplatformPublicationToSonatypeRepository publishJvmPublicationToSonatypeRepository publishLinuxX64PublicationToSonatypeRepository publishLinuxArm64PublicationToSonatypeRepository publishMingwX64PublicationToSonatypeRepository
#
# runs-on: ${{ matrix.os }}
# steps:
# - name: Checkout project sources
# uses: actions/checkout@v3
# - uses: actions/setup-java@v3
# with:
# distribution: liberica
# java-version: 8
# - name: Build using gradle
# uses: gradle/gradle-build-action@v2
# with:
# arguments: ${{ matrix.gradle_args }}
# env:
# SIGNING_SECRET_KEY: ${{ secrets.SIGNING_SECRET_KEY }}
# SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
# OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
# OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,5 @@ local.properties

# Ignore Gradle build output directory
build

.jreleaser/config.toml
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@

### Core components

* `org.ton:ton-kotlin-tvm:0.3.1` - TVM Primitives (Cells, BOC, etc.)
* `org.ton:ton-kotlin-crypto:0.3.1` - Crypto primitives for TON (ED25519, SHA, etc.)
* `org.ton:ton-kotlin-adnl:0.3.1` - ADNL (Abstract Datagram Network Layer) TON Network implementation
* `org.ton.kotlin:ton-kotlin-tvm:0.4.0` - TVM Primitives (Cells, BOC, etc.)
* `org.ton.kotlin:ton-kotlin-crypto:0.4.0` - Crypto primitives for TON (ED25519, SHA, etc.)
* `org.ton.kotlin:ton-kotlin-adnl:0.4.0` - ADNL (Abstract Datagram Network Layer) TON Network implementation

### API Interfaces

* `org.ton:ton-kotlin-contract:0.3.1` - Smart-contracts API interface
* `org.ton:ton-kotlin-liteclient:0.3.1` - Lite-client API implementation
* `org.ton.kotlin:ton-kotlin-contract:0.4.0` - Smart-contracts API interface
* `org.ton.kotlin:ton-kotlin-liteclient:0.4.0` - Lite-client API implementation

### TL-B (TL-Binary)

* `org.ton:ton-kotlin-tlb:0.3.1` - TON TL-B (TL-Binary) serialization/deserialization
* `org.ton:ton-kotlin-block-tlb:0.3.1` - Pre-generated TL-B schemas for TON Blockchain
* `org.ton:ton-kotlin-hashmap-tlb:0.3.1` - Pre-generated TL-B schemas for TON Hashmap (also known as Dictionary)
* `org.ton.kotlin:ton-kotlin-tlb:0.4.0` - TON TL-B (TL-Binary) serialization/deserialization
* `org.ton.kotlin:ton-kotlin-block-tlb:0.4.0` - Pre-generated TL-B schemas for TON Blockchain
* `org.ton.kotlin:ton-kotlin-hashmap-tlb:0.4.0` - Pre-generated TL-B schemas for TON Hashmap (also known as Dictionary)

## Documentation

https://github.com/andreypfau/ton-kotlin/wiki/TON-Kotlin-documentation

<!-- Badges -->

[maven-central]: https://central.sonatype.com/artifact/org.ton/ton-kotlin-tvm/0.3.1
[maven-central]: https://central.sonatype.com/artifact/org.ton/ton-kotlin-tvm/0.4.0

[license]: LICENSE

Expand Down
40 changes: 33 additions & 7 deletions bitstring/src/BitString.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public inline fun BitString(size: Int): BitString = BitString.of(size)
public inline fun BitString(vararg bits: Boolean): BitString = BitString.of(*bits)
public inline fun BitString(bits: Iterable<Boolean>): BitString = BitString.of(bits)
public inline fun BitString(bits: Collection<Boolean>): BitString = BitString.of(bits)
public inline fun BitString(hex: String): BitString = BitString.of(hex)
public inline fun BitString(hex: String): BitString = BitString.parse(hex)

public inline fun Iterable<Boolean>.toBitString(): BitString = BitString(this)
public inline fun BooleanArray.toBitString(): BitString = BitString(*this)
Expand All @@ -27,13 +27,14 @@ public interface BitString : Iterable<Boolean>, Comparable<BitString> {
public operator fun get(index: Int): Boolean
public fun getOrNull(index: Int): Boolean?

public fun countLeadingBits(fromIndex: Int = 0, toIndex: Int = size, bit: Boolean): Int

public operator fun plus(bit: Boolean): BitString =
plus(booleanArrayOf(bit))

public operator fun plus(bits: BooleanArray): BitString =
plus(bits.asIterable())


public operator fun plus(bits: Collection<Boolean>): BitString =
plus(bits.asIterable())

Expand Down Expand Up @@ -61,8 +62,17 @@ public interface BitString : Iterable<Boolean>, Comparable<BitString> {
public fun commonSuffixWith(other: BitString): BitString =
binary(toBinary().commonSuffixWith(other.toBinary()))

public fun slice(indices: IntRange): BitString = slice(indices.first, indices.last)
@Deprecated("use substring(indices) instead", ReplaceWith("substring(indices)"))
public fun slice(indices: IntRange): BitString = substring(indices.first, indices.last)

@Deprecated("use substring(startIndex, endIndex) instead", ReplaceWith("substring(startIndex, endIndex)"))
public fun slice(startIndex: Int, endIndex: Int = size): BitString =
substring(startIndex, endIndex)

public fun substring(range: IntRange): BitString =
substring(range.first, range.last)

public fun substring(startIndex: Int, endIndex: Int = size): BitString =
binary(toBinary().substring(startIndex, endIndex))

public infix fun xor(other: BitString): BitString
Expand All @@ -81,6 +91,18 @@ public interface BitString : Iterable<Boolean>, Comparable<BitString> {

public fun toHexString(): String

public fun copyInto(
destination: MutableBitString,
destinationOffset: Int = 0,
startIndex: Int = 0,
endIndex: Int = size
) {
val length = endIndex - startIndex
for (i in 0 until length) {
destination[destinationOffset + i] = this[startIndex + i]
}
}

public companion object {
@JvmStatic
public fun empty(): BitString = EmptyBitString
Expand Down Expand Up @@ -132,12 +154,16 @@ public interface BitString : Iterable<Boolean>, Comparable<BitString> {
}

@JvmStatic
public fun of(hex: String): BitString {
if (hex.isEmpty()) return empty()
@Deprecated("use parse(hex) instead", replaceWith = ReplaceWith("parse(hex)"))
public fun of(hex: String): BitString = parse(hex)

@JvmStatic
public fun parse(source: CharSequence): BitString {
if (source.isEmpty()) return empty()
// True if bit string doesn't contain mod 4 number of bits
val incomplete = hex.isNotEmpty() && hex.last() == '_'
val incomplete = source.isNotEmpty() && source.last() == '_'

val bits = hex.asSequence()
val bits = source.asSequence()
.takeWhile { it != '_' } // consume entire hexadecimal string, except for `_`
.map { char ->
char.digitToInt(16)
Expand Down
125 changes: 125 additions & 0 deletions bitstring/src/ByteBackedBitString.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ public open class ByteBackedBitString protected constructor(
override fun getOrNull(index: Int): Boolean? =
if (index in 0..size) get(bytes, index) else null

override fun countLeadingBits(fromIndex: Int, toIndex: Int, bit: Boolean): Int {
return countLeadingBits(bytes, fromIndex, toIndex - fromIndex, bit)
}

override fun plus(bits: BitString): BitString = toMutableBitString().plus(bits)
override fun plus(bytes: ByteArray): BitString = toMutableBitString().plus(bytes)
override fun plus(bytes: ByteArray, bits: Int): BitString = toMutableBitString().plus(bytes, bits)
Expand Down Expand Up @@ -84,6 +88,13 @@ public open class ByteBackedBitString protected constructor(
}
}

override fun copyInto(destination: MutableBitString, destinationOffset: Int, startIndex: Int, endIndex: Int) {
if (destination !is ByteBackedBitString) {
return super.copyInto(destination, destinationOffset, startIndex, endIndex)
}
bitsCopy(destination.bytes, destinationOffset, bytes, startIndex, endIndex - startIndex)
}

override fun toString(): String = "x{${toHexString()}}"

override fun toHexString(): String {
Expand Down Expand Up @@ -218,3 +229,117 @@ private fun appendAugmentTag(data: ByteArray, bits: Int): ByteArray {
return newData
}
}

internal fun bitsCopy(dest: ByteArray, toIndex: Int, src: ByteArray, fromIndex: Int, bitCount: Int) {
if (bitCount <= 0) return

var srcOffset = fromIndex shr 3
var destOffset = toIndex shr 3
val fromOffset = fromIndex and 7
val toOffset = toIndex and 7

var remainingBits = bitCount
val bitCountTotal = bitCount + fromOffset

if (fromOffset == toOffset) {
if (bitCountTotal < 8) {
val mask = ((-0x100 ushr bitCountTotal) and (0xff ushr toOffset))
dest[destOffset] = ((dest[destOffset].toInt() and mask.inv()) or (src[srcOffset].toInt() and mask)).toByte()
return
}

val bytesToCopy = bitCountTotal shr 3
if (toOffset == 0) {
src.copyInto(dest, destOffset, srcOffset, srcOffset + bytesToCopy)
} else {
val mask = (0xff ushr toOffset)
dest[destOffset] = ((dest[destOffset].toInt() and mask.inv()) or (src[srcOffset].toInt() and mask)).toByte()
src.copyInto(dest, destOffset + 1, srcOffset + 1, srcOffset + bytesToCopy)
}

if (bitCountTotal and 7 != 0) {
val mask = (-0x100 ushr (bitCountTotal and 7))
dest[destOffset + bytesToCopy] =
((dest[destOffset + bytesToCopy].toInt() and mask.inv()) or (src[srcOffset + bytesToCopy].toInt() and mask)).toByte()
}
} else {
var bitsInAcc = toOffset
var accumulator = if (bitsInAcc != 0) dest[destOffset].toLong() ushr (8 - bitsInAcc) else 0L

if (bitCountTotal < 8) {
accumulator = accumulator shl remainingBits
accumulator =
accumulator or ((src[srcOffset].toLong() and (0xffL ushr fromOffset)) ushr (8 - bitCountTotal))
bitsInAcc += remainingBits
} else {
val leadingBits = 8 - fromOffset
accumulator = (accumulator shl leadingBits)
accumulator = accumulator or (src[srcOffset++].toLong() and (0xffL ushr fromOffset))
bitsInAcc += leadingBits
remainingBits -= leadingBits

while (remainingBits >= 8) {
accumulator = accumulator shl 8
accumulator = accumulator or (src[srcOffset++].toLong() and 0xffL)
dest[destOffset++] = (accumulator ushr bitsInAcc).toByte()
remainingBits -= 8
}

if (remainingBits > 0) {
accumulator =
(accumulator shl remainingBits) or ((src[srcOffset].toLong() and 0xff) ushr (8 - remainingBits))
bitsInAcc += remainingBits
}
}

while (bitsInAcc >= 8) {
bitsInAcc -= 8
dest[destOffset++] = (accumulator ushr bitsInAcc).toByte()
}

if (bitsInAcc > 0) {
dest[destOffset] =
((dest[destOffset].toInt() and (0xff ushr bitsInAcc)) or (accumulator.toInt() shl (8 - bitsInAcc))).toByte()
}
}
}

internal fun countLeadingBits(
array: ByteArray,
offset: Int,
bitCount: Int,
bit: Boolean
): Int {
if (bitCount == 0) return 0

val xorVal = if (bit) -1 else 0
var index = offset ushr 3
val bitOffset = offset and 7
var reminder = bitCount

if (bitOffset != 0) {
val v = ((array[index++].toInt() and 0xFF) xor xorVal) shl (24 + bitOffset)
val c = v.countLeadingZeroBits()
val remainingBits = 8 - bitOffset
if (c < remainingBits || bitCount <= remainingBits) {
return min(c, bitCount)
}
reminder -= remainingBits
}

while (reminder >= 8) {
val v = ((array[index++].toInt() xor xorVal) and 0xFF) shl 24
if (v != 0) {
return bitCount - reminder + v.countLeadingZeroBits()
}
reminder -= 8
}

if (reminder > 0) {
val v = (((array[index].toInt() xor xorVal) and 0xFF) shl 24).countLeadingZeroBits()
if (v < reminder) {
return bitCount - reminder + v
}
}
return bitCount
}
2 changes: 2 additions & 0 deletions bitstring/src/ByteBackedMutableBitString.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public open class ByteBackedMutableBitString(
override var bytes: ByteArray,
override var size: Int
) : ByteBackedBitString(size, bytes), MutableBitString {
public constructor(size: Int) : this(ByteArray((size + 7) ushr 3), size)

override operator fun set(index: Int, bit: Int) {
set(index, bit != 0)
}
Expand Down
Loading

0 comments on commit 192c55c

Please sign in to comment.