package lockstep import ( "bytes" "ripple/bug" "ripple/config" "ripple/types" ) func (l *Lockstep) Enqueue(id types.UserIdentifier, instr types.Instruction) bool { queue := l.mustGetAccount(id) if len(queue) >= config.BufferSize { return false } queue = append(queue, instr) l.queues[id] = queue if len(queue) == 1 { l.doTurn(id) } return true } func (l *Lockstep) isValidTransaction(id types.UserIdentifier, instr types.Instruction) bool { stateCopy := l.st.Clone() if _, err := l.dispatch(&stateCopy, id, instr); err != nil { return false } return true } func (l *Lockstep) dequeue(id types.UserIdentifier) (types.Instruction, bool) { queue := l.mustGetAccount(id) for len(queue) > 0 { instr := queue[0] queue = queue[1:] if l.isValidTransaction(id, instr) { l.queues[id] = queue return instr, true } } l.queues[id] = queue return types.Instruction{}, false } func (l *Lockstep) peek(id types.UserIdentifier) (types.Instruction, bool) { queue := l.mustGetAccount(id) for len(queue) > 0 { instr := queue[0] if l.isValidTransaction(id, instr) { l.queues[id] = queue instr.Command = cmdToExternalCmd(instr.Command) return instr, true } queue = queue[1:] } l.queues[id] = queue return types.Instruction{}, false } func (l *Lockstep) RemoveAccount(id types.UserIdentifier) { if !l.accountExists(id) { panic(bug.BugStateViolated) } delete(l.queues, id) } func (l *Lockstep) AddAccount(id types.UserIdentifier) { if l.accountExists(id) { panic(bug.BugStateViolated) } l.queues[id] = make([]types.Instruction, 0) } func (l *Lockstep) InQueue(id types.UserIdentifier, cmpInstr types.Instruction) bool { queue := l.mustGetAccount(id) for _, instr := range queue { if instr.Command == cmpInstr.Command && bytes.Equal(instr.Arguments, cmpInstr.Arguments) { return true } } return false }