Skip to content

Commit

Permalink
feat: removed zero postings entirely
Browse files Browse the repository at this point in the history
  • Loading branch information
ascandone committed Dec 6, 2024
1 parent 90f330d commit 4463674
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 31 deletions.
36 changes: 20 additions & 16 deletions internal/interpreter/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,20 @@ type programState struct {
CurrentBalanceQuery BalanceQuery
}

func (st *programState) pushSender(name string, monetary *big.Int) {
if monetary.Cmp(big.NewInt(0)) == 0 {
return
}
st.Senders = append(st.Senders, Sender{Name: name, Monetary: monetary})
}

func (st *programState) pushReceiver(name string, monetary *big.Int) {
if monetary.Cmp(big.NewInt(0)) == 0 {
return
}
st.Receivers = append(st.Receivers, Receiver{Name: name, Monetary: monetary})
}

func (st *programState) runStatement(statement parser.Statement) ([]Posting, InterpreterError) {
st.Senders = nil
st.Receivers = nil
Expand Down Expand Up @@ -413,10 +427,7 @@ func (s *programState) sendAllToAccount(accountLiteral parser.ValueExpr, ovedraf

// we sent balance+overdraft
sentAmt := new(big.Int).Add(balance, ovedraft)
s.Senders = append(s.Senders, Sender{
Name: *account,
Monetary: sentAmt,
})
s.pushSender(*account, sentAmt)
return sentAmt, nil
}

Expand Down Expand Up @@ -506,10 +517,7 @@ func (s *programState) trySendingToAccount(accountLiteral parser.ValueExpr, amou
actuallySentAmt = utils.MinBigInt(safeSendAmt, amount)
}

s.Senders = append(s.Senders, Sender{
Name: *account,
Monetary: actuallySentAmt,
})
s.pushSender(*account, actuallySentAmt)
return actuallySentAmt, nil
}

Expand Down Expand Up @@ -585,10 +593,7 @@ func (s *programState) receiveFrom(destination parser.Destination, amount *big.I
if err != nil {
return err
}
s.Receivers = append(s.Receivers, Receiver{
Name: *account,
Monetary: amount,
})
s.pushReceiver(*account, amount)
return nil

case *parser.DestinationAllotment:
Expand Down Expand Up @@ -659,13 +664,12 @@ func (s *programState) receiveFrom(destination parser.Destination, amount *big.I
}
}

const KEPT_ADDR = "<kept>"

func (s *programState) receiveFromKeptOrDest(keptOrDest parser.KeptOrDestination, amount *big.Int) InterpreterError {
switch destinationTarget := keptOrDest.(type) {
case *parser.DestinationKept:
s.Receivers = append(s.Receivers, Receiver{
Name: "<kept>",
Monetary: amount,
})
s.pushReceiver(KEPT_ADDR, amount)
return nil

case *parser.DestinationTo:
Expand Down
39 changes: 37 additions & 2 deletions internal/interpreter/interpreter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1731,7 +1731,6 @@ func TestDestinationComplex(t *testing.T) {
// TODO TestNeededBalances, TestSetTxMeta, TestSetAccountMeta

func TestSendZero(t *testing.T) {
// TODO double check
tc := NewTestCase()
tc.compile(t, `
send [COIN 0] (
Expand All @@ -1740,6 +1739,7 @@ func TestSendZero(t *testing.T) {
)`)
tc.expected = CaseResult{
Postings: []Posting{
// Zero posting is omitted
// {
// Asset: "COIN",
// Amount: big.NewInt(0),
Expand Down Expand Up @@ -1815,7 +1815,6 @@ func TestNegativeBalanceLiteral(t *testing.T) {
}

func TestBalanceNotFound(t *testing.T) {
// TODO double check
tc := NewTestCase()
tc.compile(t, `
vars {
Expand All @@ -1828,6 +1827,7 @@ func TestBalanceNotFound(t *testing.T) {
)`)
tc.expected = CaseResult{
Postings: []Posting{
// Zero posting is omitted
// {
// Asset: "EUR/2",
// Amount: big.NewInt(0),
Expand Down Expand Up @@ -2683,6 +2683,41 @@ func TestZeroPostingsDestination(t *testing.T) {
test(t, tc)
}

func TestZeroPostingsExplicitInorder(t *testing.T) {
tc := NewTestCase()
tc.compile(t, `
send [COIN 0] (
source = {
@a
@b
@c
}
destination = @dest
)
`)
tc.expected = CaseResult{
Postings: []machine.Posting{},
}
test(t, tc)
}

func TestZeroPostingsExplicitAllotment(t *testing.T) {
tc := NewTestCase()
tc.compile(t, `
send [COIN 0] (
source = {
1/2 from @a
1/2 from @b
}
destination = @dest
)
`)
tc.expected = CaseResult{
Postings: []machine.Posting{},
}
test(t, tc)
}

func TestUnboundedOverdraftWhenNotEnoughFunds(t *testing.T) {
tc := NewTestCase()
tc.setBalance("users:2345:main", "USD/2", 8000)
Expand Down
9 changes: 1 addition & 8 deletions internal/interpreter/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ type Receiver struct {
}

func Reconcile(asset string, senders []Sender, receivers []Receiver) ([]Posting, InterpreterError) {
var sendersFiltered []Sender
for _, e := range senders {
if e.Monetary.Cmp(big.NewInt(0)) != 0 {
sendersFiltered = append(sendersFiltered, e)
}
}
senders = sendersFiltered

// We reverse senders and receivers once so that we can
// treat them as stack and push/pop in O(1)
Expand All @@ -54,7 +47,7 @@ func Reconcile(asset string, senders []Sender, receivers []Receiver) ([]Posting,
}

// Ugly workaround
if receiver.Name == "<kept>" {
if receiver.Name == KEPT_ADDR {
sender, empty := popStack(&senders)
if !empty {
var newMon big.Int
Expand Down
9 changes: 4 additions & 5 deletions internal/interpreter/reconciler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,14 @@ func TestReconcileSingletonExactMatch(t *testing.T) {
}

func TestReconcileZero(t *testing.T) {
// TODO double check
runReconcileTestCase(t, ReconcileTestCase{
Currency: "COIN",
Senders: []Sender{{"src", big.NewInt(0)}},
Receivers: []Receiver{{"dest", big.NewInt(0)}},
Expected: nil,
// []Posting{
// // {"src", "dest", big.NewInt(0), "COIN"}
// },
Expected: []Posting{
{"src", "dest", big.NewInt(0), "COIN"},
},
ExpectedErr: nil,
})
}

Expand Down

0 comments on commit 4463674

Please sign in to comment.