This is an automated email from the ASF dual-hosted git repository.

toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git


The following commit(s) were added to refs/heads/main by this push:
     new f258a42d Add support for new custom opcode in DSL
     new 0e2faa42 Merge pull request #428 from atoulme/custom_opcode_support
f258a42d is described below

commit f258a42d33fa570bf94348099cc1751fd81edc58
Author: Antoine Toulme <anto...@lunar-ocean.com>
AuthorDate: Sat Jul 16 10:06:55 2022 -0700

    Add support for new custom opcode in DSL
---
 .../main/kotlin/org/apache/tuweni/evmdsl/Code.kt   | 12 ++++--
 .../org/apache/tuweni/evmdsl/Instructions.kt       | 11 ++++++
 .../kotlin/org/apache/tuweni/evmdsl/CodeTest.kt    | 44 ++++++++++++++++++++++
 3 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Code.kt 
b/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Code.kt
index abe1db3e..1afd6655 100644
--- a/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Code.kt
+++ b/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Code.kt
@@ -51,6 +51,8 @@ class Code(val instructions: List<Instruction>) {
     var stackSize = 0
     val visited = mutableSetOf<Int>()
     var index = 0
+    val jumpDests = mutableSetOf<Int>()
+    val jumpSrcs = mutableMapOf<Int, Int>()
     while (visited.add(index)) {
       val currentInstruction = instructions.getOrNull(index) ?: break
       if (currentInstruction.stackItemsNeeded() > stackSize) {
@@ -63,11 +65,15 @@ class Code(val instructions: List<Instruction>) {
       if (currentInstruction is Invalid) {
         return CodeValidationError(currentInstruction, index, 
Error.HIT_INVALID_OPCODE)
       }
-      // TODO cannot follow jumps right now.
       if (currentInstruction == Jump || currentInstruction == Jumpi) {
-        break
+        jumpSrcs.put(index, stackSize)
+      }
+      if (currentInstruction == JumpDest) {
+        jumpDests.add(index)
+      }
+      if (currentInstruction.end()) {
+        stackSize = 0
       }
-
       index++
     }
     return null
diff --git a/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Instructions.kt 
b/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Instructions.kt
index 04be3e10..3cc12ec5 100644
--- a/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Instructions.kt
+++ b/evm-dsl/src/main/kotlin/org/apache/tuweni/evmdsl/Instructions.kt
@@ -31,6 +31,8 @@ interface Instruction {
   fun stackItemsConsumed(): Int
 
   fun stackItemsProduced(): Int
+
+  fun end(): Boolean = false
 }
 
 data class InstructionModel(val opcode: Byte, val additionalBytesToRead: Int = 
0, val creator: (code: Bytes, index: Int) -> Instruction)
@@ -665,6 +667,7 @@ object Return : Instruction {
   override fun toString(): String = "RETURN"
   override fun stackItemsConsumed() = 2
   override fun stackItemsProduced() = 0
+  override fun end() = true
 }
 
 object DelegateCall : Instruction {
@@ -696,6 +699,7 @@ object Revert : Instruction {
   override fun toString(): String = "REVERT"
   override fun stackItemsConsumed() = 2
   override fun stackItemsProduced() = 0
+  override fun end() = true
 }
 
 object SelfDestruct : Instruction {
@@ -728,3 +732,10 @@ class Log(val logIndex: Int) : Instruction {
   override fun stackItemsConsumed() = logIndex + 2
   override fun stackItemsProduced() = 0
 }
+
+data class Custom(val bytes: Bytes, val str: String, val consumed: Int, val 
produced: Int) : Instruction {
+  override fun toBytes() = bytes
+  override fun toString() = str
+  override fun stackItemsConsumed() = consumed
+  override fun stackItemsProduced() = produced
+}
diff --git a/evm-dsl/src/test/kotlin/org/apache/tuweni/evmdsl/CodeTest.kt 
b/evm-dsl/src/test/kotlin/org/apache/tuweni/evmdsl/CodeTest.kt
index dcdd6485..e1cc2c4b 100644
--- a/evm-dsl/src/test/kotlin/org/apache/tuweni/evmdsl/CodeTest.kt
+++ b/evm-dsl/src/test/kotlin/org/apache/tuweni/evmdsl/CodeTest.kt
@@ -17,6 +17,7 @@
 package org.apache.tuweni.evmdsl
 
 import org.apache.tuweni.bytes.Bytes
+import org.apache.tuweni.bytes.Bytes32
 import org.junit.jupiter.api.Assertions.assertEquals
 import org.junit.jupiter.api.Assertions.assertNull
 import org.junit.jupiter.api.Test
@@ -114,4 +115,47 @@ class CodeTest {
     )
     assertNull(code.validate()?.error)
   }
+
+  @Test
+  fun testSomeWorkshopCode() {
+    val code = Code(
+      buildList {
+        this.add(Push(Bytes.fromHexString("0x00")))
+        this.add(CallDataLoad) // load from position 0
+        this.add(Custom(Bytes.fromHexString("0xf6"), "SHAREDSECRET", 1, 1))
+        this.add(Push(Bytes.fromHexString("0x11"))) // push jump destination
+        this.add(Jumpi) // if custom returns 0, keep going, else go to 
jumpdest at byte 0x11
+        this.add(Push(Bytes.fromHexString("0x00"))) // value
+        this.add(Push(Bytes.fromHexString("0x00"))) // location
+        this.add(Mstore) // store 0 in memory
+        this.add(Push(Bytes.fromHexString("0x01"))) // length
+        this.add(Push(Bytes.fromHexString("0x1f"))) // location
+        this.add(Return) // return 0
+        this.add(JumpDest)
+        this.add(Push(Bytes.fromHexString("0x01"))) // value
+        this.add(Push(Bytes.fromHexString("0x00"))) // location
+        this.add(Mstore) // store 1 in memory
+        this.add(Push(Bytes.fromHexString("0x01"))) // length
+        this.add(Push(Bytes.fromHexString("0x1f"))) // location
+        this.add(Return)
+      }
+    )
+    assertNull(code.validate()?.error)
+    println(code.toString())
+    println(code.toBytes().toHexString())
+
+    // surround with instructions to deploy.
+    val deployment = Code(
+      buildList {
+        this.add(Push(Bytes32.rightPad(code.toBytes()))) // pad the code with 
zeros to create a word
+        this.add(Push(Bytes.fromHexString("0x00"))) // set the location of the 
memory to store
+        this.add(Mstore)
+        this.add(Push(Bytes.ofUnsignedInt(code.toBytes().size().toLong()))) // 
length
+        this.add(Push(Bytes.fromHexString("0x00"))) // location
+        this.add(Return) // return the code
+      }
+    )
+
+    println(deployment.toBytes().toHexString())
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@tuweni.apache.org
For additional commands, e-mail: commits-h...@tuweni.apache.org

Reply via email to