#!/usr/contrib/bin/agent
# Multi-Bank: split merge close
include control/do
include log
proc Bcheck {billy banks} {
global agent bill
array set bank $banks
if {[llength [do_hack $billy]] != 4} {
return "err (Badly formed bill): $billy"}
if {[lindex $billy 1] != $agent(local-name)} {
if {[info exists bank([lindex $billy 1])]} {
return 1
} else {
return "err (Foreign Bill): $billy"}}
if {![info exists bill([lindex $billy 2])]} {
return "err (Counterfeit Bill): $billy"}
if {$bill([lindex $billy 2]) != [lindex $billy 3]} {
return "err (Wrong Number): $billy"}
return 0}
proc Bsplit {old amount} {
global agent bill
set error [Bcheck $old {}]
if {$error==0 && [lindex $old 3] >= $amount} {
set new [expr [lindex $old 3]-$amount]
unset bill([lindex $old 2])
set Nnew [random]
set Namount [random]
set bill($Nnew) $new
set bill($Namount) $amount
return [list [list $agent(actual-server) $agent(local-name) $Nnew $new] [list $agent(actual-server) $agent(local-name) $Namount $amount]]
} else {
return "$error"
}
}
proc Bmerge {old old2} {
global agent bill bank
set error [Bcheck $old {}]
set error2 [Bcheck $old2 [array get bank]]
if { $error==0 } {
switch -exact -- $error2 {
0 {
set new [expr [lindex $old 3]+[lindex $old2 3]]
unset bill([lindex $old 2])
unset bill([lindex $old2 2])
set Nnew [random]
set bill($Nnew) $new
return [list $agent(actual-server) $agent(local-name) $Nnew $new]}
1 {
set obank [lindex $old2 1]
agent_send "[lrange $old2 0 1]" "merge $bank($obank) $old2"
agent_receive code result -blocking
if {[lindex $result 0]=="err"} {
return "err (other bank say: $result): $old2"
} else {
set bank($obank) $result
return [Bnew [lindex $old2 3]]
}
}
default {
return "$error2"
}
}
} else {
return "$error"
}
}
proc Bnew {amount} {
global agent bill
set Nnew [random]
set bill($Nnew) $amount
return [list $agent(actual-server) $agent(local-name) $Nnew $amount]
}
proc bank {name maker amt lifetime} {
global bank
set bank("firstVirtual") 4
require wall $lifetime
agent_name $name
agent_event $maker bank [Bnew $amt]
do {
{"split %s %s" wallet amt} {
agent_send $sender [Bsplit $wallet $amt]}
{"merge %s %s" wal1 wal2} {
agent_send $sender [Bmerge $wal1 $wal2]}
{"close %s" wallet} {
agent_send $sender "ok"
agent_send $maker 0 DONE
break}
{"STOP"} {
agent_send $maker 0 DONE
break
}
error {"unexpected message %s" msg} {
agent_send $sender "what in hell does this mean? $msg"}
}
agent_end
}