Skip to content

Commit

Permalink
feat: add Go node
Browse files Browse the repository at this point in the history
  • Loading branch information
gligneul committed Sep 22, 2023
1 parent 75c0cbc commit e124e2a
Show file tree
Hide file tree
Showing 10 changed files with 778 additions and 0 deletions.
13 changes: 13 additions & 0 deletions pkg/inputter/input_box.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package validator

import "github.com/cartesi/rollups-node/pkg/model"

// Interface with the InputBox contract
type InputBox interface {

// Obtain all inputs from the startingBlock to the endingBlock
GetInputs(startingBlock, endingBlock int64) ([]model.AdvanceInput, error)
}
16 changes: 16 additions & 0 deletions pkg/model/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package model

import "fmt"

// Error when an object was not found given its index
type NotFound struct {
TypeName string
Index Index
}

func (e NotFound) Error() string {
return fmt.Sprintf("%v with index %v not found", e.TypeName, e.Index)
}
15 changes: 15 additions & 0 deletions pkg/model/filters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package model

// Filter when querying an advance state input
type AdvanceInputFilter struct {
IndexGreaterThan *Index
IndexLowerThan *Index
}

// Filter when querying an output
type OutputFilter struct {
InputIndex Index
}
276 changes: 276 additions & 0 deletions pkg/model/in_memory_repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

package model

import "sync"

// In-memory repository for the node.
//
// This is particularly useful when writing tests.
type InMemoryRepository struct {
sync.Mutex
lastReadBlock BlockNumber
advanceInputs []AdvanceInputWithStatus
vouchers [][]Voucher
notices [][]Notice
reports [][]Report
voucherProofs [][]Proof
noticeProofs [][]Proof
inspects []inspectEntry
epochs []Epoch
}

// TODO change this:
// Create a different field with an array for each object because it translates
// better to SQL tables.

// Implementation of the Repository interface
var _ Repository = (*InMemoryRepository)(nil)

func (r *InMemoryRepository) Input(index Index) (*AdvanceInputWithStatus, error) {
r.Lock()
defer r.Unlock()

if int(index) >= len(r.advanceInputs) {
return nil, NotFound{"input", index}
}

input := r.advanceInputs[index]
return &input, nil
}

func (r *InMemoryRepository) Voucher(inputIndex Index, voucherIndex Index) (*Voucher, error) {
r.Lock()
defer r.Unlock()

if int(inputIndex) >= len(r.vouchers) {
return nil, NotFound{"voucher", inputIndex}
}

vouchers := r.vouchers[inputIndex]
if int(voucherIndex) >= len(vouchers) {
return nil, NotFound{"voucher", voucherIndex}
}

voucher := vouchers[voucherIndex]
return &voucher, nil
}

func (r *InMemoryRepository) Notice(inputIndex Index, noticeIndex Index) (*Notice, error) {
r.Lock()
defer r.Unlock()

if int(inputIndex) >= len(r.notices) {
return nil, NotFound{"notice", inputIndex}
}

notices := r.notices[inputIndex]
if int(noticeIndex) >= len(notices) {
return nil, NotFound{"notice", noticeIndex}
}

notice := notices[noticeIndex]
return &notice, nil
}

func (r *InMemoryRepository) Report(inputIndex Index, reportIndex Index) (*Report, error) {
r.Lock()
defer r.Unlock()

if int(inputIndex) >= len(r.reports) {
return nil, NotFound{"report", inputIndex}
}

reports := r.reports[inputIndex]
if int(reportIndex) >= len(reports) {
return nil, NotFound{"report", reportIndex}
}

report := reports[reportIndex]
return &report, nil
}

func (r *InMemoryRepository) VoucherProof(inputIndex Index, voucherIndex Index) (*Proof, error) {
r.Lock()
defer r.Unlock()

if int(inputIndex) >= len(r.voucherProofs) {
return nil, NotFound{"proof", inputIndex}
}

proofs := r.voucherProofs[inputIndex]
if int(voucherIndex) >= len(proofs) {
return nil, NotFound{"proof", voucherIndex}
}

proof := proofs[voucherIndex]
return &proof, nil
}

func (r *InMemoryRepository) NoticeProof(inputIndex Index, noticeIndex Index) (*Proof, error) {
r.Lock()
defer r.Unlock()

if int(inputIndex) >= len(r.noticeProofs) {
return nil, NotFound{"proof", inputIndex}
}

proofs := r.noticeProofs[inputIndex]
if int(noticeIndex) >= len(proofs) {
return nil, NotFound{"proof", noticeIndex}
}

proof := proofs[noticeIndex]
return &proof, nil
}

func (r *InMemoryRepository) LastReadBlock() (BlockNumber, error) {
r.Lock()
defer r.Unlock()

return r.lastReadBlock, nil
}

func (r *InMemoryRepository) AddAdvanceInputs(inputs []AdvanceInput,
lastReadBlock BlockNumber) error {

r.Lock()
defer r.Unlock()

for i := range inputs {
var input AdvanceInputWithStatus
input.AdvanceInput = inputs[i]
r.advanceInputs = append(r.advanceInputs, input)

// Create an entry for every input-indexed array
r.vouchers = append(r.vouchers, nil)
r.notices = append(r.notices, nil)
r.reports = append(r.reports, nil)
r.voucherProofs = append(r.voucherProofs, nil)
r.noticeProofs = append(r.noticeProofs, nil)
}

r.lastReadBlock = lastReadBlock

return nil
}

func (r *InMemoryRepository) FirstUnsentEpoch() (*Epoch, error) {
r.Lock()
defer r.Unlock()

for i := range r.epochs {
if !r.epochs[i].Sent {
epoch := r.epochs[i]
return &epoch, nil
}
}

return nil, nil
}

func (r *InMemoryRepository) SetClaimSent(epochIndex Index) error {
r.Lock()
defer r.Unlock()

if int(epochIndex) < len(r.epochs) {
return NotFound{"epoch", epochIndex}
}

r.epochs[epochIndex].Sent = true

return nil
}

func (r *InMemoryRepository) AddInspectInput(payload []byte) (Index, error) {
r.Lock()
defer r.Unlock()

var entry inspectEntry
entry.Payload = payload
r.inspects = append(r.inspects, entry)

return 0, nil
}

func (r *InMemoryRepository) InspectOutput(inputIndex Index) (*InspectOutput, error) {
r.Lock()
defer r.Unlock()

if int(inputIndex) >= len(r.inspects) {
return nil, NotFound{"inspect", inputIndex}
}

output := r.inspects[inputIndex].InspectOutput
return &output, nil
}

func (r *InMemoryRepository) FirstUnprocessedAdvance() (*AdvanceInput, error) {
r.Lock()
defer r.Unlock()

for i := range r.advanceInputs {
if r.advanceInputs[i].Status == Unprocessed {
input := r.advanceInputs[i].AdvanceInput
return &input, nil
}
}

return nil, nil
}

func (r *InMemoryRepository) SetAdvanceOutput(inputIndex Index, output *AdvanceOutput) error {
r.Lock()
defer r.Unlock()

if int(inputIndex) >= len(r.advanceInputs) {
return NotFound{"input", inputIndex}
}

r.advanceInputs[inputIndex].CompletionStatus = output.CompletionStatus
// TODO

return nil
}

func (r *InMemoryRepository) FirstUnprocessedInspect() (*InspectInput, error) {
r.Lock()
defer r.Unlock()

for i := range r.inspects {
if r.inspects[i].Status == Unprocessed {
input := r.inspects[i].InspectInput
return &input, nil
}
}

return nil, nil
}

func (r *InMemoryRepository) SetInspectOutput(inputIndex Index, output *InspectOutput) error {
r.Lock()
defer r.Unlock()

// TODO

return nil
}

func (r *InMemoryRepository) ProcessedInputCount() (Index, error) {
r.Lock()
defer r.Unlock()

// TODO

return 0, nil
}

func (r *InMemoryRepository) FinishEpoch(epoch *Epoch, voucherProofs []IndexedProof, noticeProofs []IndexedProof) error {
r.Lock()
defer r.Unlock()

// TODO

return nil
}
Loading

0 comments on commit e124e2a

Please sign in to comment.