diff --git a/domains/integration-test/helpers/zeto_helper.go b/domains/integration-test/helpers/zeto_helper.go index e853c7c31..388193c46 100644 --- a/domains/integration-test/helpers/zeto_helper.go +++ b/domains/integration-test/helpers/zeto_helper.go @@ -26,9 +26,6 @@ import ( "github.com/stretchr/testify/assert" ) -//go:embed abis/ZetoFactory.json -var ZetoFactoryJSON []byte - type ZetoHelper struct { t *testing.T rpc rpcbackend.Backend diff --git a/domains/zeto/integration-test/contracts.go b/domains/zeto/integration-test/contracts.go index 7408306b0..5e5c2dc63 100644 --- a/domains/zeto/integration-test/contracts.go +++ b/domains/zeto/integration-test/contracts.go @@ -24,13 +24,15 @@ import ( "github.com/hyperledger/firefly-signer/pkg/abi" "github.com/hyperledger/firefly-signer/pkg/rpcbackend" "github.com/kaleido-io/paladin/core/pkg/testbed" - "github.com/kaleido-io/paladin/domains/integration-test/helpers" "github.com/kaleido-io/paladin/toolkit/pkg/log" "github.com/kaleido-io/paladin/toolkit/pkg/pldapi" "github.com/kaleido-io/paladin/toolkit/pkg/solutils" "github.com/kaleido-io/paladin/toolkit/pkg/tktypes" ) +//go:embed abis/ZetoFactory.json +var zetoFactoryJSON []byte + type ZetoDomainContracts struct { FactoryAddress *tktypes.EthAddress factoryAbi abi.ABI @@ -51,7 +53,7 @@ type cloneableContract struct { } func newZetoDomainContracts() *ZetoDomainContracts { - factory := solutils.MustLoadBuild(helpers.ZetoFactoryJSON) + factory := solutils.MustLoadBuild(zetoFactoryJSON) return &ZetoDomainContracts{ factoryAbi: factory.ABI, @@ -235,5 +237,6 @@ func registerImpl(ctx context.Context, name string, domainContracts *ZetoDomainC }, ABI: abi.ABI{abiFunc}, }) + log.L(ctx).Infof("Registered implementation %s", name) return err } diff --git a/domains/zeto/integration-test/e2e_test.go b/domains/zeto/integration-test/e2e_test.go index 9d311baa4..900aeded5 100644 --- a/domains/zeto/integration-test/e2e_test.go +++ b/domains/zeto/integration-test/e2e_test.go @@ -186,8 +186,8 @@ func (s *zetoDomainTestSuite) testZetoFungible(t *testing.T, tokenName string, u assert.Regexp(t, "PD012216: Transaction reverted OwnableUnauthorizedAccount.*", err) if useBatch { - // for testing the batch circuits, we transfer 50 which would require 3 UTXOs (>2) - amount1 := 10 + // for testing the batch circuits, we transfer 55 which would require 3 UTXOs (>2) + amount1 := 15 amount2 := 40 log.L(ctx).Info("*************************************") log.L(ctx).Infof("Transfer %d from controller to recipient1 (%d) and recipient2 (%d)", amount1+amount2, amount1, amount2) @@ -209,6 +209,9 @@ func (s *zetoDomainTestSuite) testZetoFungible(t *testing.T, tokenName string, u // one for the recipient (value=25) expectedCoins := 2 if useBatch { + // one for the controller from the successful transaction as change (value=5) + // one for the recipient1 (value=15) + // one for the recipient2 (value=40) expectedCoins = 3 } if len(coins) != expectedCoins { @@ -219,9 +222,9 @@ func (s *zetoDomainTestSuite) testZetoFungible(t *testing.T, tokenName string, u require.Len(t, coins, expectedCoins) if useBatch { - assert.Equal(t, int64(10), coins[0].Data.Amount.Int().Int64()) // state for recipient1 + assert.Equal(t, int64(15), coins[0].Data.Amount.Int().Int64()) // state for recipient1 assert.Equal(t, int64(40), coins[1].Data.Amount.Int().Int64()) // state for recipient2 - assert.Equal(t, int64(10), coins[2].Data.Amount.Int().Int64()) // change for controller + assert.Equal(t, int64(5), coins[2].Data.Amount.Int().Int64()) // change for controller assert.Equal(t, controllerAddr.String(), coins[2].Data.Owner.String()) } else { assert.Equal(t, int64(25), coins[0].Data.Amount.Int().Int64()) // state for recipient1 diff --git a/domains/zeto/internal/zeto/handler_events.go b/domains/zeto/internal/zeto/handler_events.go index a4616518b..4ec266800 100644 --- a/domains/zeto/internal/zeto/handler_events.go +++ b/domains/zeto/internal/zeto/handler_events.go @@ -172,7 +172,7 @@ func parseStatesFromEvent(txID tktypes.HexBytes, states []tktypes.HexUint256) [] refs := make([]*prototk.StateUpdate, len(states)) for i, state := range states { refs[i] = &prototk.StateUpdate{ - Id: state.String(), + Id: hexUint256To32ByteHexString(&state), TransactionId: txID.String(), } } diff --git a/domains/zeto/internal/zeto/handler_events_test.go b/domains/zeto/internal/zeto/handler_events_test.go index 5c877b37d..f88e22e44 100644 --- a/domains/zeto/internal/zeto/handler_events_test.go +++ b/domains/zeto/internal/zeto/handler_events_test.go @@ -198,3 +198,11 @@ func TestHandleWithdrawEvent(t *testing.T) { err = z.handleWithdrawEvent(ctx, merkleTree, storage, ev, "Zeto_AnonNullifier", res) assert.ErrorContains(t, err, "PD210061: Failed to update merkle tree for the UTXOWithdraw event. PD210056: Failed to create new node index from hash. 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") } + +func TestParseStatesFromEvent(t *testing.T) { + txID := tktypes.MustParseHexBytes("0x1234") + states := parseStatesFromEvent(txID, []tktypes.HexUint256{*tktypes.MustParseHexUint256("0x1234"), *tktypes.MustParseHexUint256("0x0")}) + assert.Len(t, states, 2) + assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000001234", states[0].Id) + assert.Equal(t, "0000000000000000000000000000000000000000000000000000000000000000", states[1].Id) +} diff --git a/domains/zeto/internal/zeto/states.go b/domains/zeto/internal/zeto/states.go index b7d49297c..646d417dc 100644 --- a/domains/zeto/internal/zeto/states.go +++ b/domains/zeto/internal/zeto/states.go @@ -75,7 +75,7 @@ func (z *Zeto) makeNewState(ctx context.Context, useNullifiers bool, coin *types if err != nil { return nil, err } - hashStr := hash.String() + hashStr := hexUint256To32ByteHexString(hash) newState := &pb.NewState{ Id: &hashStr, SchemaId: z.coinSchema.Id, diff --git a/domains/zeto/internal/zeto/zeto.go b/domains/zeto/internal/zeto/zeto.go index 9846bf80a..227374e9d 100644 --- a/domains/zeto/internal/zeto/zeto.go +++ b/domains/zeto/internal/zeto/zeto.go @@ -18,6 +18,7 @@ package zeto import ( "context" _ "embed" + "encoding/hex" "encoding/json" "math/big" @@ -459,6 +460,11 @@ func intTo32ByteSlice(bigInt *big.Int) (res []byte) { return bigInt.FillBytes(make([]byte, 32)) } +func hexUint256To32ByteHexString(v *tktypes.HexUint256) string { + paddedBytes := intTo32ByteSlice(v.Int()) + return hex.EncodeToString(paddedBytes) +} + func (z *Zeto) Sign(ctx context.Context, req *prototk.SignRequest) (*prototk.SignResponse, error) { switch req.PayloadType { case zetosignerapi.PAYLOAD_DOMAIN_ZETO_NULLIFIER: @@ -505,12 +511,14 @@ func (z *Zeto) ValidateStateHashes(ctx context.Context, req *prototk.ValidateSta log.L(ctx).Errorf("Error hashing state data: %s", err) return nil, i18n.NewError(ctx, msgs.MsgErrorHashOutputState, err) } + hashString := hexUint256To32ByteHexString(hash) if state.Id == "" { // if the requested state ID is empty, we simply set it - res.StateIds = append(res.StateIds, hash.String()) + res.StateIds = append(res.StateIds, hashString) } else { // if the requested state ID is set, we compare it with the calculated hash - if hash.String() != state.Id { + stateId := tktypes.MustParseHexUint256(state.Id) + if hash.Int().Cmp(stateId.Int()) != 0 { log.L(ctx).Errorf("State hash mismatch (hashed vs. received): %s != %s", hash.String(), state.Id) return nil, i18n.NewError(ctx, msgs.MsgErrorStateHashMismatch, hash.String(), state.Id) }