diff --git a/domains/noto/internal/noto/noto.go b/domains/noto/internal/noto/noto.go index 5e0026543..3e4072159 100644 --- a/domains/noto/internal/noto/noto.go +++ b/domains/noto/internal/noto/noto.go @@ -284,19 +284,24 @@ func (n *Noto) recoverSignature(ctx context.Context, payload ethtypes.HexBytes0x func (n *Noto) parseCoinList(label string, states []*pb.EndorsableState) ([]*types.NotoCoin, []*pb.StateRef, *big.Int, error) { var err error + statesUsed := make(map[string]bool) coins := make([]*types.NotoCoin, len(states)) refs := make([]*pb.StateRef, len(states)) total := big.NewInt(0) - for i, input := range states { - if input.SchemaId != n.coinSchema.Id { - return nil, nil, nil, fmt.Errorf("unknown schema ID: %s", input.SchemaId) + for i, state := range states { + if state.SchemaId != n.coinSchema.Id { + return nil, nil, nil, fmt.Errorf("unknown schema ID: %s", state.SchemaId) + } + if statesUsed[state.Id] { + return nil, nil, nil, fmt.Errorf("duplicate state provided: %s", state.Id) } - if coins[i], err = n.unmarshalCoin(input.StateDataJson); err != nil { - return nil, nil, nil, fmt.Errorf("invalid %s[%d] (%s): %s", label, i, input.Id, err) + statesUsed[state.Id] = true + if coins[i], err = n.unmarshalCoin(state.StateDataJson); err != nil { + return nil, nil, nil, fmt.Errorf("invalid %s[%d] (%s): %s", label, i, state.Id, err) } refs[i] = &pb.StateRef{ - SchemaId: input.SchemaId, - Id: input.Id, + SchemaId: state.SchemaId, + Id: state.Id, } total = total.Add(total, coins[i].Amount.BigInt()) } diff --git a/domains/noto/internal/noto/states.go b/domains/noto/internal/noto/states.go index d355020fb..18742f034 100644 --- a/domains/noto/internal/noto/states.go +++ b/domains/noto/internal/noto/states.go @@ -88,6 +88,7 @@ func (n *Noto) prepareInputs(ctx context.Context, owner ethtypes.Address0xHex, a stateRefs := []*pb.StateRef{} coins := []*types.NotoCoin{} for { + // TODO: make this configurable queryBuilder := query.NewQueryBuilder(). Limit(10). Sort(".created").