package handler import ( "encoding/binary" "ripple/commands" "ripple/config" "ripple/crypto" "ripple/datavisor" "ripple/lockstep" "ripple/services" "ripple/state" "ripple/types" ) type UserHandlers struct { st *state.State m *datavisor.AccountManager pm *services.PaymentManager lockstep *lockstep.Lockstep } func NewUserHandlers( st *state.State, m *datavisor.AccountManager, pm *services.PaymentManager, l *lockstep.Lockstep, ) *UserHandlers { return &UserHandlers{ st: st, m: m, pm: pm, lockstep: l, } } func successResponse(msg string) (byte, []byte) { return 0x00, []byte(msg) } func errorResponse(msg string) (byte, []byte) { return 0x01, []byte(msg) } func (h *UserHandlers) decrypt(ciphertext [32]byte, counter uint32) [32]byte { sk := h.st.Storage.User.SecretKey return crypto.XorWithOneTimeKey(ciphertext, sk, counter) } func (h *UserHandlers) SetTrustline(r types.ClientRemote, args []byte) (byte, []byte) { if len(args) < 72 { return errorResponse("Invalid arguments") } id := types.NewUserIdentifierFromBytes(args[0:64]) valueBytes := args[64:72] if !h.st.Storage.AccountExists(id) { return errorResponse("Peer does not exist") } instr := types.Instruction{ Command: commands.LOCKSTEP_SET_TRUSTLINE, Arguments: valueBytes, } h.lockstep.Enqueue(id, instr) return successResponse("Set trustline") } func (h *UserHandlers) AddAccount(r types.ClientRemote, args []byte) (byte, []byte) { if len(args) < 99 { return errorResponse("Invalid arguments") } id := types.NewUserIdentifierFromBytes(args[0:64]) portBytes := args[64:66] var ciph [32]byte copy(ciph[:], args[66:98]) turnBit := args[98] if h.st.Storage.AccountExists(id) { return errorResponse("Peer already exists") } if len(h.st.Storage.Accounts) >= config.BufferSize { return errorResponse("Peer slots full") } port := binary.BigEndian.Uint16(portBytes) secretKey := h.decrypt(ciph, r.Counter) if err := h.m.AddAccount(id, int(port), secretKey, turnBit); err != nil { return errorResponse("Error") } return successResponse("Add account") } func (h *UserHandlers) NewPayment(r types.ClientRemote, args []byte) (byte, []byte) { if len(args) < 106 { return errorResponse("Invalid arguments") } id := types.NewUserIdentifierFromBytes(args[0:64]) port := int(binary.BigEndian.Uint16(args[64:66])) var ciph [32]byte copy(ciph[:], args[66:98]) amount := int64(binary.BigEndian.Uint64(args[98:106])) secretKey := h.decrypt(ciph, r.Counter) h.pm.InitPayment(id, port, secretKey, amount) return successResponse("New payment") } func (h *UserHandlers) StartPayment(r types.ClientRemote, args []byte) (byte, []byte) { paymentID := h.st.Memory.Payment if _, ok := h.st.Memory.GetPathfinding(paymentID); !ok { return errorResponse("No active payment") } h.pm.ForwardFindPath(paymentID) return successResponse("Start payment") }