Skip to content

Commit 3207ff0

Browse files
committed
feat(utxorpc): implement submit.EvalTx
Signed-off-by: Chris Gianelloni <[email protected]>
1 parent f995e56 commit 3207ff0

File tree

3 files changed

+265
-17
lines changed

3 files changed

+265
-17
lines changed

go.mod

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ require (
88
connectrpc.com/connect v1.19.1
99
connectrpc.com/grpchealth v1.4.0
1010
connectrpc.com/grpcreflect v1.3.0
11-
github.com/blinklabs-io/adder v0.34.0
12-
github.com/blinklabs-io/gouroboros v0.140.0
11+
github.com/blinklabs-io/adder v0.35.0
12+
github.com/blinklabs-io/gouroboros v0.142.0
13+
github.com/blinklabs-io/plutigo v0.0.16
1314
github.com/blinklabs-io/tx-submit-api v0.20.10
1415
github.com/gin-gonic/gin v1.11.0
1516
github.com/gorilla/websocket v1.5.3
@@ -27,19 +28,20 @@ require (
2728
require (
2829
filippo.io/edwards25519 v1.1.0 // indirect
2930
github.com/KyleBanks/depth v1.2.1 // indirect
31+
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect
3032
github.com/beorn7/perks v1.0.1 // indirect
3133
github.com/bits-and-blooms/bitset v1.20.0 // indirect
32-
github.com/blinklabs-io/plutigo v0.0.13 // indirect
33-
github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect
34+
github.com/btcsuite/btcd/btcec/v2 v2.3.6 // indirect
3435
github.com/btcsuite/btcd/btcutil v1.1.6 // indirect
3536
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
3637
github.com/bytedance/sonic v1.14.0 // indirect
3738
github.com/bytedance/sonic/loader v0.3.0 // indirect
3839
github.com/cespare/xxhash/v2 v2.3.0 // indirect
3940
github.com/cloudwego/base64x v0.1.6 // indirect
40-
github.com/consensys/gnark-crypto v0.19.1 // indirect
41+
github.com/consensys/gnark-crypto v0.19.2 // indirect
4142
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
4243
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
44+
github.com/ethereum/go-ethereum v1.16.7 // indirect
4345
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
4446
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
4547
github.com/gin-contrib/sse v1.1.0 // indirect
@@ -52,13 +54,15 @@ require (
5254
github.com/go-playground/validator/v10 v10.27.0 // indirect
5355
github.com/goccy/go-json v0.10.5 // indirect
5456
github.com/goccy/go-yaml v1.18.0 // indirect
57+
github.com/holiman/uint256 v1.3.2 // indirect
5558
github.com/jinzhu/copier v0.4.0 // indirect
5659
github.com/josharian/intern v1.0.0 // indirect
5760
github.com/json-iterator/go v1.1.12 // indirect
5861
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
5962
github.com/leodido/go-urn v1.4.0 // indirect
6063
github.com/mailru/easyjson v0.7.7 // indirect
6164
github.com/mattn/go-isatty v0.0.20 // indirect
65+
github.com/minio/sha256-simd v1.0.1 // indirect
6266
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
6367
github.com/modern-go/reflect2 v1.0.2 // indirect
6468
github.com/pelletier/go-toml/v2 v2.2.4 // indirect

go.sum

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,21 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
88
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
99
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
1010
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
11+
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU=
12+
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
1113
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
1214
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
1315
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
1416
github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU=
1517
github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
16-
github.com/blinklabs-io/adder v0.34.0 h1:QtHzMgfzFO/WnJTAAibEVahLzDNtdyli95+0OD5Jlho=
17-
github.com/blinklabs-io/adder v0.34.0/go.mod h1:3jLrgshUoU4W2r+noPl61nZMlQhUFx6SCVjRyzKMyOQ=
18-
github.com/blinklabs-io/gouroboros v0.140.0 h1:dFK2iunkTflCI2hlDSGZJJ7JerYhpdE41HnBUVvjj9E=
19-
github.com/blinklabs-io/gouroboros v0.140.0/go.mod h1:FxKQNNNRQN5F/Cl4pnW7SHhpPo7fD57mTPGo4N9ulnY=
20-
github.com/blinklabs-io/ouroboros-mock v0.3.9 h1:UnciDccJ5tZCR1xI0BcxGZcYjJ/PS5MpnjiiGtrZ680=
21-
github.com/blinklabs-io/ouroboros-mock v0.3.9/go.mod h1:uTkE8/LAYL7yQSntH48Pudf5Xn+jaBWMj+9udbzYXhI=
22-
github.com/blinklabs-io/plutigo v0.0.13 h1:JztPigFmknQmQ3Ti1+mdTY96ihOUDh6wJ3pPnN2YYBU=
23-
github.com/blinklabs-io/plutigo v0.0.13/go.mod h1:CoNpHHFifPV21KfnHlP3hEFOVj3yF6zgV5OPr058+Do=
18+
github.com/blinklabs-io/adder v0.35.0 h1:QKmXb7HsejqOKxauU2Siw0ekTMqNsFr2cxdLcOQvXWs=
19+
github.com/blinklabs-io/adder v0.35.0/go.mod h1:90EQBbKoIhcCdyJ5OlE9tDT1cn69fW/ePYVatS62BKo=
20+
github.com/blinklabs-io/gouroboros v0.142.0 h1:vBsQfcPsZF7EX+1uw1Gcg0uCYvkjsEVHn2qEqlMC0lY=
21+
github.com/blinklabs-io/gouroboros v0.142.0/go.mod h1:pC42tYVwkd34ohGrWAIHhLOWhhpmrBa0M/QUE+4gC8Q=
22+
github.com/blinklabs-io/ouroboros-mock v0.4.0 h1:ppOcTMnC/2f5rYYSlvNqcGfAQOIpMCSDUrNh9K6a4mY=
23+
github.com/blinklabs-io/ouroboros-mock v0.4.0/go.mod h1:e+Kck8bmdOuaN7IfkbVvbqAVlskXNXB95oHI3YlFG5g=
24+
github.com/blinklabs-io/plutigo v0.0.16 h1:3+1eOby9ckoDXb+8ObCBQ4BGbHZ6z7cxGFDR4cbS+7Y=
25+
github.com/blinklabs-io/plutigo v0.0.16/go.mod h1:aT3mJAh1s8JJ8C42ygd8OyGDQZ8f+w8Uge2+C/9BLug=
2426
github.com/blinklabs-io/tx-submit-api v0.20.10 h1:+Il7414Nd4/82pr87tsyYRtE+6j52MGrWh5CIHBJzXc=
2527
github.com/blinklabs-io/tx-submit-api v0.20.10/go.mod h1:mqkYyHYrU+XFtbCmiYycYqcxga56JdPLDas0oNTTtsE=
2628
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
@@ -29,8 +31,8 @@ github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6
2931
github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg=
3032
github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA=
3133
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
32-
github.com/btcsuite/btcd/btcec/v2 v2.3.5 h1:dpAlnAwmT1yIBm3exhT1/8iUSD98RDJM5vqJVQDQLiU=
33-
github.com/btcsuite/btcd/btcec/v2 v2.3.5/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ=
34+
github.com/btcsuite/btcd/btcec/v2 v2.3.6 h1:IzlsEr9olcSRKB/n7c4351F3xHKxS2lma+1UFGCYd4E=
35+
github.com/btcsuite/btcd/btcec/v2 v2.3.6/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ=
3436
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
3537
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
3638
github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00=
@@ -57,8 +59,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
5759
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
5860
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
5961
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
60-
github.com/consensys/gnark-crypto v0.19.1 h1:FWO1JDs7A2OajswzwMG7f8l2Zrxc/yOkxSTByKTc3O0=
61-
github.com/consensys/gnark-crypto v0.19.1/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0=
62+
github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80=
63+
github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0=
6264
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
6365
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6466
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -72,6 +74,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC
7274
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
7375
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
7476
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
77+
github.com/ethereum/go-ethereum v1.16.7 h1:qeM4TvbrWK0UC0tgkZ7NiRsmBGwsjqc64BHo20U59UQ=
78+
github.com/ethereum/go-ethereum v1.16.7/go.mod h1:Fs6QebQbavneQTYcA39PEKv2+zIjX7rPUZ14DER46wk=
7579
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
7680
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
7781
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
@@ -128,6 +132,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
128132
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
129133
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
130134
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
135+
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
136+
github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
131137
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
132138
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
133139
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -162,6 +168,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
162168
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
163169
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
164170
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
171+
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
172+
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
165173
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
166174
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
167175
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=

internal/utxorpc/submit.go

Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ import (
2727
"github.com/blinklabs-io/cardano-node-api/internal/node"
2828
"github.com/blinklabs-io/gouroboros/ledger"
2929
ocommon "github.com/blinklabs-io/gouroboros/protocol/common"
30+
"github.com/blinklabs-io/plutigo/cek"
31+
"github.com/blinklabs-io/plutigo/data"
32+
"github.com/blinklabs-io/plutigo/syn"
33+
"github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano"
3034
submit "github.com/utxorpc/go-codegen/utxorpc/v1alpha/submit"
3135
"github.com/utxorpc/go-codegen/utxorpc/v1alpha/submit/submitconnect"
3236
)
@@ -83,6 +87,238 @@ func (s *submitServiceServer) SubmitTx(
8387
return connect.NewResponse(resp), nil
8488
}
8589

90+
// evaluateScript evaluates a Plutus script with the given arguments and cost model
91+
func evaluateScript(scriptBytes []byte, args []data.PlutusData, costModel map[uint][]int64) (uint64, uint64, error) {
92+
// Decode the script
93+
program, err := syn.Decode[syn.DeBruijn](scriptBytes)
94+
if err != nil {
95+
return 0, 0, fmt.Errorf("decode script: %w", err)
96+
}
97+
98+
// Apply arguments to the script
99+
term := program.Term
100+
for _, arg := range args {
101+
term = &syn.Apply[syn.DeBruijn]{
102+
Function: term,
103+
Argument: &syn.Constant{
104+
Con: &syn.Data{Inner: arg},
105+
},
106+
}
107+
}
108+
109+
// Create machine with version-based cost model
110+
machine := cek.NewMachineWithVersionCosts[syn.DeBruijn](program.Version, 200)
111+
112+
_, err = machine.Run(term)
113+
if err != nil {
114+
return 0, 0, fmt.Errorf("execute script: %w", err)
115+
}
116+
117+
return uint64(machine.ExBudget.Cpu), uint64(machine.ExBudget.Mem), nil
118+
}
119+
120+
// convertPlutusData converts plutigo data.PlutusData to *cardano.PlutusData
121+
func convertPlutusData(pd data.PlutusData) *cardano.PlutusData {
122+
switch v := pd.(type) {
123+
case *data.Constr:
124+
fields := make([]*cardano.PlutusData, len(v.Fields))
125+
for i, field := range v.Fields {
126+
fields[i] = convertPlutusData(field)
127+
}
128+
return &cardano.PlutusData{
129+
PlutusData: &cardano.PlutusData_Constr{
130+
Constr: &cardano.Constr{
131+
Tag: uint32(v.Tag),
132+
Fields: fields,
133+
},
134+
},
135+
}
136+
case *data.Map:
137+
pairs := make([]*cardano.PlutusDataPair, len(v.Pairs))
138+
for i, pair := range v.Pairs {
139+
pairs[i] = &cardano.PlutusDataPair{
140+
Key: convertPlutusData(pair[0]),
141+
Value: convertPlutusData(pair[1]),
142+
}
143+
}
144+
return &cardano.PlutusData{
145+
PlutusData: &cardano.PlutusData_Map{
146+
Map: &cardano.PlutusDataMap{
147+
Pairs: pairs,
148+
},
149+
},
150+
}
151+
case *data.Integer:
152+
return &cardano.PlutusData{
153+
PlutusData: &cardano.PlutusData_BigInt{
154+
BigInt: &cardano.BigInt{
155+
BigInt: &cardano.BigInt_Int{
156+
Int: v.Inner.Int64(),
157+
},
158+
},
159+
},
160+
}
161+
case *data.ByteString:
162+
return &cardano.PlutusData{
163+
PlutusData: &cardano.PlutusData_BoundedBytes{
164+
BoundedBytes: v.Inner,
165+
},
166+
}
167+
case *data.List:
168+
items := make([]*cardano.PlutusData, len(v.Items))
169+
for i, item := range v.Items {
170+
items[i] = convertPlutusData(item)
171+
}
172+
return &cardano.PlutusData{
173+
PlutusData: &cardano.PlutusData_Array{
174+
Array: &cardano.PlutusDataArray{
175+
Items: items,
176+
},
177+
},
178+
}
179+
default:
180+
// Should not happen
181+
return nil
182+
}
183+
}
184+
185+
// EvalTx
186+
func (s *submitServiceServer) EvalTx(
187+
ctx context.Context,
188+
req *connect.Request[submit.EvalTxRequest],
189+
) (*connect.Response[submit.EvalTxResponse], error) {
190+
// txRaw
191+
txRaw := req.Msg.GetTx() // *AnyChainTx
192+
if txRaw == nil {
193+
return nil, errors.New("transaction is required")
194+
}
195+
log.Printf("Got an EvalTx request")
196+
197+
resp := &submit.EvalTxResponse{}
198+
199+
// Connect to node
200+
oConn, err := node.GetConnection(nil)
201+
if err != nil {
202+
return connect.NewResponse(resp), err
203+
}
204+
defer func() {
205+
// Close Ouroboros connection
206+
oConn.Close()
207+
}()
208+
209+
// Parse the transaction
210+
txRawBytes := txRaw.GetRaw() // raw bytes
211+
txType, err := ledger.DetermineTransactionType(txRawBytes)
212+
if err != nil {
213+
return connect.NewResponse(resp), err
214+
}
215+
tx, err := ledger.NewTransactionFromCbor(txType, txRawBytes)
216+
if err != nil {
217+
return connect.NewResponse(resp), err
218+
}
219+
220+
// Get protocol parameters for cost models
221+
oConn.LocalStateQuery().Client.Start()
222+
protoParams, err := oConn.LocalStateQuery().Client.GetCurrentProtocolParams()
223+
if err != nil {
224+
return connect.NewResponse(resp), err
225+
}
226+
227+
// Get witnesses
228+
witnesses := tx.Witnesses()
229+
redeemers := witnesses.Redeemers()
230+
231+
// Get cost models from protocol parameters
232+
var costModels map[uint][]int64
233+
if conwayParams, ok := protoParams.(*ledger.ConwayProtocolParameters); ok {
234+
costModels = conwayParams.CostModels
235+
}
236+
237+
// Get scripts
238+
v1Scripts := witnesses.PlutusV1Scripts()
239+
v2Scripts := witnesses.PlutusV2Scripts()
240+
v3Scripts := witnesses.PlutusV3Scripts()
241+
allScripts := make([][]byte, 0, len(v1Scripts)+len(v2Scripts)+len(v3Scripts))
242+
scriptVersions := make([]uint, 0, len(v1Scripts)+len(v2Scripts)+len(v3Scripts))
243+
for _, s := range v1Scripts {
244+
allScripts = append(allScripts, s.RawScriptBytes())
245+
scriptVersions = append(scriptVersions, 1)
246+
}
247+
for _, s := range v2Scripts {
248+
allScripts = append(allScripts, s.RawScriptBytes())
249+
scriptVersions = append(scriptVersions, 2)
250+
}
251+
for _, s := range v3Scripts {
252+
allScripts = append(allScripts, s.RawScriptBytes())
253+
scriptVersions = append(scriptVersions, 3)
254+
}
255+
256+
var txEvalRedeemers []*cardano.Redeemer
257+
for key, value := range redeemers.Iter() {
258+
redeemer := &cardano.Redeemer{
259+
Purpose: cardano.RedeemerPurpose(key.Tag),
260+
Payload: convertPlutusData(value.Data.Data),
261+
Index: key.Index,
262+
ExUnits: &cardano.ExUnits{
263+
Steps: 0,
264+
Memory: 0,
265+
},
266+
}
267+
268+
// Try to evaluate if we have a script for this redeemer
269+
if int(key.Index) < len(allScripts) {
270+
scriptBytes := allScripts[key.Index]
271+
version := scriptVersions[key.Index]
272+
273+
// Build arguments based on purpose
274+
var args []data.PlutusData
275+
276+
// For now, only handle spending scripts with datum, redeemer, context
277+
if key.Tag == 0 { // RedeemerTagSpend
278+
// Get datum - for simplicity, assume it's the redeemer data for now
279+
datum := value.Data.Data
280+
redeemerData := value.Data.Data
281+
// TODO: build proper script context
282+
contextData := data.NewConstr(0) // dummy context
283+
284+
args = []data.PlutusData{datum, redeemerData, contextData}
285+
} else {
286+
// For other purposes, just redeemer and context
287+
redeemerData := value.Data.Data
288+
contextData := data.NewConstr(0) // dummy context
289+
args = []data.PlutusData{redeemerData, contextData}
290+
}
291+
292+
// Filter cost model for this version
293+
versionCostModel := make(map[uint][]int64)
294+
if model, ok := costModels[version]; ok {
295+
versionCostModel[version] = model
296+
}
297+
298+
steps, memory, err := evaluateScript(scriptBytes, args, versionCostModel)
299+
if err != nil {
300+
log.Printf("Failed to evaluate script for redeemer %d: %v", key.Index, err)
301+
} else {
302+
redeemer.ExUnits.Steps = steps
303+
redeemer.ExUnits.Memory = memory
304+
}
305+
}
306+
307+
txEvalRedeemers = append(txEvalRedeemers, redeemer)
308+
}
309+
310+
resp.Report = &submit.AnyChainEval{
311+
Chain: &submit.AnyChainEval_Cardano{
312+
Cardano: &cardano.TxEval{
313+
Fee: nil, // TODO: set fee
314+
Redeemers: txEvalRedeemers,
315+
},
316+
},
317+
}
318+
319+
return connect.NewResponse(resp), nil
320+
}
321+
86322
func (s *submitServiceServer) WaitForTx(
87323
ctx context.Context,
88324
req *connect.Request[submit.WaitForTxRequest],

0 commit comments

Comments
 (0)