Skip to content

Commit

Permalink
internal operations (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
kroggen committed Jun 4, 2024
1 parent ddbbd8b commit 63e8588
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 11 deletions.
80 changes: 80 additions & 0 deletions contract/internal_operations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package contract

import (
"encoding/json"
"log"
"sync"
)

type InternalOperation struct {
Id int64 `json:"-"`
Level int `json:"level"`
Contract string `json:"contract"`
Operation string `json:"operation"`
Amount string `json:"amount"`
Args []string `json:"args"`
Results []string `json:"results"`
}

var (
internalOperations []InternalOperation
txHash []byte
opsLock sync.Mutex // To handle concurrent updates
nextOpId int64
)

func initInternalOps(newTxHash []byte) {
opsLock.Lock()
defer opsLock.Unlock()

internalOperations = nil // Reinitialize the slice for new transaction
txHash = newTxHash
nextOpId = 1 // Reset nextOpId for each new transaction
}

func logOperation(ctx *vmContext, amount string, operation string, args ...string) int64 {
opsLock.Lock()
defer opsLock.Unlock()

op := InternalOperation{
Id: nextOpId,
Level: ctx.CallDepth(),
Contract: ctx.Contract,
Operation: operation,
Amount: amount,
Args: args,
}
internalOperations = append(internalOperations, op)
nextOpId++
return op.Id
}

func logOperationResult(operationId int64, results ...string) {
opsLock.Lock()
defer opsLock.Unlock()

for i, op := range internalOperations {
if op.Id == operationId {
internalOperations[i].Results = append(internalOperations[i].Results, results...)
return
}
}
log.Printf("No operation found with ID %d", operationId)
}

func saveOperations() {
opsLock.Lock()
defer opsLock.Unlock()

data, err := json.Marshal(internalOperations)
if err != nil {
log.Fatal("Failed to marshal operations:", err)
return
}

// Simulated database set function (adjust as needed for actual database implementation)
err = db.Set(txHash, data) // Assuming db.Set exists and works with byte keys and value
if err != nil {
log.Fatal("Failed to save operations to database:", err)
}
}
46 changes: 35 additions & 11 deletions contract/vm_callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,25 +199,31 @@ func minusCallCount(ctx *vmContext, curCount, deduc C.int) C.int {

//export luaCallContract
func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char, args *C.char,
amount *C.char, gas uint64) (C.int, *C.char) {
amount *C.char, gas uint64) (C.int, result *C.char) {

Check failure on line 202 in contract/vm_callback.go

View workflow job for this annotation

GitHub Actions / build_and_test

mixed named and unnamed parameters
contractAddress := C.GoString(contractId)
fnameStr := C.GoString(fname)
argsStr := C.GoString(args)
amountStr := C.GoString(amount)

ctx := contexts[service]
if ctx == nil {
return -1, C.CString("[Contract.LuaCallContract] contract state not found")
}

opId := logOperation(ctx, amountStr, "call", contractAddress, fnameStr, argsStr)
defer func() {
logOperationResult(opId, C.GoString(result))
}()

// get the contract address
contractAddress := C.GoString(contractId)
cid, err := getAddressNameResolved(contractAddress, ctx.bs)
if err != nil {
return -1, C.CString("[Contract.LuaCallContract] invalid contractId: " + err.Error())
}
aid := types.ToAccountID(cid)

// read the amount for the contract call
amountBig, err := transformAmount(C.GoString(amount))
amountBig, err := transformAmount(amountStr)
if err != nil {
return -1, C.CString("[Contract.LuaCallContract] invalid amount: " + err.Error())
}
Expand All @@ -231,7 +237,7 @@ func luaCallContract(L *LState, service C.int, contractId *C.char, fname *C.char
// check if the contract exists
callee := getContract(cs.ctrState, ctx.bs)
if callee == nil {
return -1, C.CString("[Contract.LuaCallContract] cannot find contract " + C.GoString(contractId))
return -1, C.CString("[Contract.LuaCallContract] cannot find contract " + contractAddress)
}

prevContractInfo := ctx.curContract
Expand Down Expand Up @@ -335,6 +341,11 @@ func luaDelegateCallContract(L *LState, service C.int, contractId *C.char,
return -1, C.CString("[Contract.LuaDelegateCallContract] contract state not found")
}

opId := logOperation(ctx, "", "delegate-call", contractIdStr, fnameStr, argsStr)
defer func() {
logOperationResult(opId, C.GoString(result))
}()

// get the contract address
cid, err := getAddressNameResolved(contractIdStr, ctx.bs)
if err != nil {
Expand Down Expand Up @@ -435,15 +446,22 @@ func getAddressNameResolved(account string, bs *state.BlockState) ([]byte, error
}

//export luaSendAmount
func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) *C.char {
func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char) result *C.char {

Check failure on line 449 in contract/vm_callback.go

View workflow job for this annotation

GitHub Actions / build_and_test

expected ';', found '*'
contractAddress := C.GoString(contractId)
amountStr := C.GoString(amount)

ctx := contexts[service]
if ctx == nil {

Check failure on line 454 in contract/vm_callback.go

View workflow job for this annotation

GitHub Actions / build_and_test

expected declaration, found 'if'
return C.CString("[Contract.LuaSendAmount] contract state not found")
}

opId := logOperation(ctx, amountStr, "send", contractAddress)
defer func() {
logOperationResult(opId, C.GoString(result))
}()

// read the amount to be sent
amountBig, err := transformAmount(C.GoString(amount))
amountBig, err := transformAmount(amountStr)
if err != nil {
return C.CString("[Contract.LuaSendAmount] invalid amount: " + err.Error())
}
Expand All @@ -454,7 +472,7 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char)
}

// get the receiver account
cid, err := getAddressNameResolved(C.GoString(contractId), ctx.bs)
cid, err := getAddressNameResolved(contractAddress, ctx.bs)
if err != nil {
return C.CString("[Contract.LuaSendAmount] invalid contractId: " + err.Error())
}
Expand Down Expand Up @@ -488,7 +506,7 @@ func luaSendAmount(L *LState, service C.int, contractId *C.char, amount *C.char)
// get the contract code
code := getContract(cs.ctrState, ctx.bs)
if code == nil {
return C.CString("[Contract.LuaSendAmount] cannot find contract:" + C.GoString(contractId))
return C.CString("[Contract.LuaSendAmount] cannot find contract:" + contractAddress)
}

// get the remaining gas from the parent LState
Expand Down Expand Up @@ -1024,10 +1042,11 @@ func luaDeployContract(
contract *C.char,
args *C.char,
amount *C.char,
) (C.int, *C.char) {
) (C.int, result *C.char) {

argsStr := C.GoString(args)
contractStr := C.GoString(contract)
argsStr := C.GoString(args)
amountStr := C.GoString(amount)

ctx := contexts[service]
if ctx == nil {
Expand All @@ -1038,6 +1057,11 @@ func luaDeployContract(
}
bs := ctx.bs

opId := logOperation(ctx, amountStr, "deploy", contractStr, argsStr)
defer func() {
logOperationResult(opId, C.GoString(result))
}()

// contract code
var code []byte

Expand Down Expand Up @@ -1098,7 +1122,7 @@ func luaDeployContract(
ctx.callState[newContract.AccountID()] = cs

// read the amount transferred to the contract
amountBig, err := transformAmount(C.GoString(amount))
amountBig, err := transformAmount(amountStr)
if err != nil {
return -1, C.CString("[Contract.LuaDeployContract]value not proper format:" + err.Error())
}
Expand Down

0 comments on commit 63e8588

Please sign in to comment.